// ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field, return_of_invalid_type, void_checks, annotate_overrides, no_leading_underscores_for_local_identifiers, library_private_types_in_public_api

// AUTO GENERATED FILE, DO NOT EDIT.
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint
import 'dart:ffi' as ffi;
import 'package:ffi/ffi.dart' as pkg_ffi;

/// Bindings for AVFAudio.
class AVFAudio {
  /// Holds the symbol lookup function.
  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
      _lookup;

  /// The symbols are looked up in [dynamicLibrary].
  AVFAudio(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;

  /// The symbols are looked up with [lookup].
  AVFAudio.fromLookup(
      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
          lookup)
      : _lookup = lookup;

  ffi.Pointer<ObjCSel> _registerName1(String name) {
    final cstr = name.toNativeUtf8();
    final sel = _sel_registerName(cstr.cast());
    pkg_ffi.calloc.free(cstr);
    return sel;
  }

  ffi.Pointer<ObjCSel> _sel_registerName(
    ffi.Pointer<ffi.Char> str,
  ) {
    return __sel_registerName(
      str,
    );
  }

  late final __sel_registerNamePtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCSel> Function(
              ffi.Pointer<ffi.Char>)>>('sel_registerName');
  late final __sel_registerName = __sel_registerNamePtr
      .asFunction<ffi.Pointer<ObjCSel> Function(ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<ObjCObject> _getClass1(String name) {
    final cstr = name.toNativeUtf8();
    final clazz = _objc_getClass(cstr.cast());
    pkg_ffi.calloc.free(cstr);
    if (clazz == ffi.nullptr) {
      throw Exception('Failed to load Objective-C class: $name');
    }
    return clazz;
  }

  ffi.Pointer<ObjCObject> _objc_getClass(
    ffi.Pointer<ffi.Char> str,
  ) {
    return __objc_getClass(
      str,
    );
  }

  late final __objc_getClassPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ffi.Char>)>>('objc_getClass');
  late final __objc_getClass = __objc_getClassPtr
      .asFunction<ffi.Pointer<ObjCObject> Function(ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<ObjCObject> _objc_retain(
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_retain(
      value,
    );
  }

  late final __objc_retainPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>)>>('objc_retain');
  late final __objc_retain = __objc_retainPtr
      .asFunction<ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>)>();

  void _objc_release(
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_release(
      value,
    );
  }

  late final __objc_releasePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject>)>>(
          'objc_release');
  late final __objc_release =
      __objc_releasePtr.asFunction<void Function(ffi.Pointer<ObjCObject>)>();

  late final _objc_releaseFinalizer2 =
      ffi.NativeFinalizer(__objc_releasePtr.cast());
  late final _class_NSObject1 = _getClass1("NSObject");
  late final _sel_load1 = _registerName1("load");
  void _objc_msgSend_1(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1 = __objc_msgSend_1Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_initialize1 = _registerName1("initialize");
  late final _sel_init1 = _registerName1("init");
  instancetype _objc_msgSend_2(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_2(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_2Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_2 = __objc_msgSend_2Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_new1 = _registerName1("new");
  late final _sel_allocWithZone_1 = _registerName1("allocWithZone:");
  instancetype _objc_msgSend_3(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_NSZone> zone,
  ) {
    return __objc_msgSend_3(
      obj,
      sel,
      zone,
    );
  }

  late final __objc_msgSend_3Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_NSZone>)>>('objc_msgSend');
  late final __objc_msgSend_3 = __objc_msgSend_3Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_NSZone>)>();

  late final _sel_alloc1 = _registerName1("alloc");
  late final _sel_dealloc1 = _registerName1("dealloc");
  late final _sel_finalize1 = _registerName1("finalize");
  late final _sel_copy1 = _registerName1("copy");
  late final _sel_mutableCopy1 = _registerName1("mutableCopy");
  late final _sel_copyWithZone_1 = _registerName1("copyWithZone:");
  late final _sel_mutableCopyWithZone_1 =
      _registerName1("mutableCopyWithZone:");
  late final _sel_instancesRespondToSelector_1 =
      _registerName1("instancesRespondToSelector:");
  bool _objc_msgSend_4(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
  ) {
    return __objc_msgSend_4(
      obj,
      sel,
      aSelector,
    );
  }

  late final __objc_msgSend_4Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_4 = __objc_msgSend_4Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>)>();

  bool _objc_msgSend_0(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> clazz,
  ) {
    return __objc_msgSend_0(
      obj,
      sel,
      clazz,
    );
  }

  late final __objc_msgSend_0Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_0 = __objc_msgSend_0Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_isKindOfClass_1 = _registerName1("isKindOfClass:");
  late final _class_Protocol1 = _getClass1("Protocol");
  late final _sel_conformsToProtocol_1 = _registerName1("conformsToProtocol:");
  bool _objc_msgSend_5(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> protocol,
  ) {
    return __objc_msgSend_5(
      obj,
      sel,
      protocol,
    );
  }

  late final __objc_msgSend_5Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_5 = __objc_msgSend_5Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_methodForSelector_1 = _registerName1("methodForSelector:");
  IMP _objc_msgSend_6(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
  ) {
    return __objc_msgSend_6(
      obj,
      sel,
      aSelector,
    );
  }

  late final __objc_msgSend_6Ptr = _lookup<
      ffi.NativeFunction<
          IMP Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_6 = __objc_msgSend_6Ptr.asFunction<
      IMP Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>)>();

  late final _sel_instanceMethodForSelector_1 =
      _registerName1("instanceMethodForSelector:");
  late final _sel_doesNotRecognizeSelector_1 =
      _registerName1("doesNotRecognizeSelector:");
  void _objc_msgSend_7(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
  ) {
    return __objc_msgSend_7(
      obj,
      sel,
      aSelector,
    );
  }

  late final __objc_msgSend_7Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_7 = __objc_msgSend_7Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>)>();

  late final _sel_forwardingTargetForSelector_1 =
      _registerName1("forwardingTargetForSelector:");
  ffi.Pointer<ObjCObject> _objc_msgSend_8(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
  ) {
    return __objc_msgSend_8(
      obj,
      sel,
      aSelector,
    );
  }

  late final __objc_msgSend_8Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_8 = __objc_msgSend_8Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCSel>)>();

  late final _class_NSInvocation1 = _getClass1("NSInvocation");
  late final _class_NSMethodSignature1 = _getClass1("NSMethodSignature");
  late final _sel_signatureWithObjCTypes_1 =
      _registerName1("signatureWithObjCTypes:");
  ffi.Pointer<ObjCObject> _objc_msgSend_9(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> types,
  ) {
    return __objc_msgSend_9(
      obj,
      sel,
      types,
    );
  }

  late final __objc_msgSend_9Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ffi.Char>)>>('objc_msgSend');
  late final __objc_msgSend_9 = __objc_msgSend_9Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ffi.Char>)>();

  late final _sel_numberOfArguments1 = _registerName1("numberOfArguments");
  int _objc_msgSend_10(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_10(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_10Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_10 = __objc_msgSend_10Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_getArgumentTypeAtIndex_1 =
      _registerName1("getArgumentTypeAtIndex:");
  ffi.Pointer<ffi.Char> _objc_msgSend_11(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int idx,
  ) {
    return __objc_msgSend_11(
      obj,
      sel,
      idx,
    );
  }

  late final __objc_msgSend_11Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Char> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_11 = __objc_msgSend_11Ptr.asFunction<
      ffi.Pointer<ffi.Char> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_frameLength1 = _registerName1("frameLength");
  late final _sel_isOneway1 = _registerName1("isOneway");
  bool _objc_msgSend_12(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_12(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_12Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_12 = __objc_msgSend_12Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_methodReturnType1 = _registerName1("methodReturnType");
  ffi.Pointer<ffi.Char> _objc_msgSend_13(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_13(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_13Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Char> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_13 = __objc_msgSend_13Ptr.asFunction<
      ffi.Pointer<ffi.Char> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_methodReturnLength1 = _registerName1("methodReturnLength");
  late final _sel_cancelPreviousPerformRequestsWithTarget_selector_object_1 =
      _registerName1(
          "cancelPreviousPerformRequestsWithTarget:selector:object:");
  void _objc_msgSend_14(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aTarget,
    ffi.Pointer<ObjCSel> aSelector,
    ffi.Pointer<ObjCObject> anArgument,
  ) {
    return __objc_msgSend_14(
      obj,
      sel,
      aTarget,
      aSelector,
      anArgument,
    );
  }

  late final __objc_msgSend_14Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_14 = __objc_msgSend_14Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_cancelPreviousPerformRequestsWithTarget_1 =
      _registerName1("cancelPreviousPerformRequestsWithTarget:");
  void _objc_msgSend_15(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aTarget,
  ) {
    return __objc_msgSend_15(
      obj,
      sel,
      aTarget,
    );
  }

  late final __objc_msgSend_15Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_15 = __objc_msgSend_15Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_accessInstanceVariablesDirectly1 =
      _registerName1("accessInstanceVariablesDirectly");
  late final _sel_useStoredAccessor1 = _registerName1("useStoredAccessor");
  late final _class_NSSet1 = _getClass1("NSSet");
  late final _sel_count1 = _registerName1("count");
  late final _sel_member_1 = _registerName1("member:");
  ffi.Pointer<ObjCObject> _objc_msgSend_16(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> object,
  ) {
    return __objc_msgSend_16(
      obj,
      sel,
      object,
    );
  }

  late final __objc_msgSend_16Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_16 = __objc_msgSend_16Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _class_NSEnumerator1 = _getClass1("NSEnumerator");
  late final _sel_nextObject1 = _registerName1("nextObject");
  late final _class_NSString1 = _getClass1("NSString");
  late final _sel_length1 = _registerName1("length");
  late final _sel_characterAtIndex_1 = _registerName1("characterAtIndex:");
  int _objc_msgSend_17(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
  ) {
    return __objc_msgSend_17(
      obj,
      sel,
      index,
    );
  }

  late final __objc_msgSend_17Ptr = _lookup<
      ffi.NativeFunction<
          unichar Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_17 = __objc_msgSend_17Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _class_NSCoder1 = _getClass1("NSCoder");
  late final _sel_encodeValueOfObjCType_at_1 =
      _registerName1("encodeValueOfObjCType:at:");
  void _objc_msgSend_18(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> type,
    ffi.Pointer<ffi.Void> addr,
  ) {
    return __objc_msgSend_18(
      obj,
      sel,
      type,
      addr,
    );
  }

  late final __objc_msgSend_18Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_18 = __objc_msgSend_18Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Void>)>();

  late final _class_NSData1 = _getClass1("NSData");
  late final _sel_bytes1 = _registerName1("bytes");
  ffi.Pointer<ffi.Void> _objc_msgSend_19(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_19(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_19Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Void> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_19 = __objc_msgSend_19Ptr.asFunction<
      ffi.Pointer<ffi.Void> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_description1 = _registerName1("description");
  ffi.Pointer<ObjCObject> _objc_msgSend_20(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_20(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_20Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_20 = __objc_msgSend_20Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_getBytes_length_1 = _registerName1("getBytes:length:");
  void _objc_msgSend_21(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> buffer,
    int length,
  ) {
    return __objc_msgSend_21(
      obj,
      sel,
      buffer,
      length,
    );
  }

  late final __objc_msgSend_21Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_21 = __objc_msgSend_21Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>, int)>();

  late final _sel_getBytes_range_1 = _registerName1("getBytes:range:");
  void _objc_msgSend_22(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> buffer,
    NSRange range,
  ) {
    return __objc_msgSend_22(
      obj,
      sel,
      buffer,
      range,
    );
  }

  late final __objc_msgSend_22Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_22 = __objc_msgSend_22Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>, NSRange)>();

  late final _sel_isEqualToData_1 = _registerName1("isEqualToData:");
  bool _objc_msgSend_23(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> other,
  ) {
    return __objc_msgSend_23(
      obj,
      sel,
      other,
    );
  }

  late final __objc_msgSend_23Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_23 = __objc_msgSend_23Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_subdataWithRange_1 = _registerName1("subdataWithRange:");
  ffi.Pointer<ObjCObject> _objc_msgSend_24(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
  ) {
    return __objc_msgSend_24(
      obj,
      sel,
      range,
    );
  }

  late final __objc_msgSend_24Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_24 = __objc_msgSend_24Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _sel_writeToFile_atomically_1 =
      _registerName1("writeToFile:atomically:");
  bool _objc_msgSend_25(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    bool useAuxiliaryFile,
  ) {
    return __objc_msgSend_25(
      obj,
      sel,
      path,
      useAuxiliaryFile,
    );
  }

  late final __objc_msgSend_25Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_25 = __objc_msgSend_25Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool)>();

  late final _class_NSURL1 = _getClass1("NSURL");
  late final _sel_initWithScheme_host_path_1 =
      _registerName1("initWithScheme:host:path:");
  instancetype _objc_msgSend_26(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> scheme,
    ffi.Pointer<ObjCObject> host,
    ffi.Pointer<ObjCObject> path,
  ) {
    return __objc_msgSend_26(
      obj,
      sel,
      scheme,
      host,
      path,
    );
  }

  late final __objc_msgSend_26Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_26 = __objc_msgSend_26Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initFileURLWithPath_isDirectory_relativeToURL_1 =
      _registerName1("initFileURLWithPath:isDirectory:relativeToURL:");
  instancetype _objc_msgSend_27(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    bool isDir,
    ffi.Pointer<ObjCObject> baseURL,
  ) {
    return __objc_msgSend_27(
      obj,
      sel,
      path,
      isDir,
      baseURL,
    );
  }

  late final __objc_msgSend_27Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_27 = __objc_msgSend_27Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool, ffi.Pointer<ObjCObject>)>();

  late final _sel_initFileURLWithPath_relativeToURL_1 =
      _registerName1("initFileURLWithPath:relativeToURL:");
  instancetype _objc_msgSend_28(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ObjCObject> baseURL,
  ) {
    return __objc_msgSend_28(
      obj,
      sel,
      path,
      baseURL,
    );
  }

  late final __objc_msgSend_28Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_28 = __objc_msgSend_28Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initFileURLWithPath_isDirectory_1 =
      _registerName1("initFileURLWithPath:isDirectory:");
  instancetype _objc_msgSend_29(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    bool isDir,
  ) {
    return __objc_msgSend_29(
      obj,
      sel,
      path,
      isDir,
    );
  }

  late final __objc_msgSend_29Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_29 = __objc_msgSend_29Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_initFileURLWithPath_1 =
      _registerName1("initFileURLWithPath:");
  instancetype _objc_msgSend_30(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
  ) {
    return __objc_msgSend_30(
      obj,
      sel,
      path,
    );
  }

  late final __objc_msgSend_30Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_30 = __objc_msgSend_30Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_fileURLWithPath_isDirectory_relativeToURL_1 =
      _registerName1("fileURLWithPath:isDirectory:relativeToURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_31(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    bool isDir,
    ffi.Pointer<ObjCObject> baseURL,
  ) {
    return __objc_msgSend_31(
      obj,
      sel,
      path,
      isDir,
      baseURL,
    );
  }

  late final __objc_msgSend_31Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_31 = __objc_msgSend_31Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          bool,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_fileURLWithPath_relativeToURL_1 =
      _registerName1("fileURLWithPath:relativeToURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_32(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ObjCObject> baseURL,
  ) {
    return __objc_msgSend_32(
      obj,
      sel,
      path,
      baseURL,
    );
  }

  late final __objc_msgSend_32Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_32 = __objc_msgSend_32Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_fileURLWithPath_isDirectory_1 =
      _registerName1("fileURLWithPath:isDirectory:");
  ffi.Pointer<ObjCObject> _objc_msgSend_33(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    bool isDir,
  ) {
    return __objc_msgSend_33(
      obj,
      sel,
      path,
      isDir,
    );
  }

  late final __objc_msgSend_33Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_33 = __objc_msgSend_33Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_fileURLWithPath_1 = _registerName1("fileURLWithPath:");
  ffi.Pointer<ObjCObject> _objc_msgSend_34(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
  ) {
    return __objc_msgSend_34(
      obj,
      sel,
      path,
    );
  }

  late final __objc_msgSend_34Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_34 = __objc_msgSend_34Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initFileURLWithFileSystemRepresentation_isDirectory_relativeToURL_1 =
      _registerName1(
          "initFileURLWithFileSystemRepresentation:isDirectory:relativeToURL:");
  instancetype _objc_msgSend_35(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> path,
    bool isDir,
    ffi.Pointer<ObjCObject> baseURL,
  ) {
    return __objc_msgSend_35(
      obj,
      sel,
      path,
      isDir,
      baseURL,
    );
  }

  late final __objc_msgSend_35Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>,
              ffi.Bool,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_35 = __objc_msgSend_35Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>, bool, ffi.Pointer<ObjCObject>)>();

  late final _sel_fileURLWithFileSystemRepresentation_isDirectory_relativeToURL_1 =
      _registerName1(
          "fileURLWithFileSystemRepresentation:isDirectory:relativeToURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_36(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> path,
    bool isDir,
    ffi.Pointer<ObjCObject> baseURL,
  ) {
    return __objc_msgSend_36(
      obj,
      sel,
      path,
      isDir,
      baseURL,
    );
  }

  late final __objc_msgSend_36Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>,
              ffi.Bool,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_36 = __objc_msgSend_36Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>,
          bool,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithString_1 = _registerName1("initWithString:");
  late final _sel_initWithString_relativeToURL_1 =
      _registerName1("initWithString:relativeToURL:");
  late final _sel_URLWithString_1 = _registerName1("URLWithString:");
  late final _sel_URLWithString_relativeToURL_1 =
      _registerName1("URLWithString:relativeToURL:");
  late final _sel_initWithDataRepresentation_relativeToURL_1 =
      _registerName1("initWithDataRepresentation:relativeToURL:");
  instancetype _objc_msgSend_37(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
    ffi.Pointer<ObjCObject> baseURL,
  ) {
    return __objc_msgSend_37(
      obj,
      sel,
      data,
      baseURL,
    );
  }

  late final __objc_msgSend_37Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_37 = __objc_msgSend_37Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_URLWithDataRepresentation_relativeToURL_1 =
      _registerName1("URLWithDataRepresentation:relativeToURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_38(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
    ffi.Pointer<ObjCObject> baseURL,
  ) {
    return __objc_msgSend_38(
      obj,
      sel,
      data,
      baseURL,
    );
  }

  late final __objc_msgSend_38Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_38 = __objc_msgSend_38Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initAbsoluteURLWithDataRepresentation_relativeToURL_1 =
      _registerName1("initAbsoluteURLWithDataRepresentation:relativeToURL:");
  late final _sel_absoluteURLWithDataRepresentation_relativeToURL_1 =
      _registerName1("absoluteURLWithDataRepresentation:relativeToURL:");
  late final _sel_dataRepresentation1 = _registerName1("dataRepresentation");
  ffi.Pointer<ObjCObject> _objc_msgSend_39(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_39(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_39Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_39 = __objc_msgSend_39Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_absoluteString1 = _registerName1("absoluteString");
  late final _sel_relativeString1 = _registerName1("relativeString");
  late final _sel_baseURL1 = _registerName1("baseURL");
  ffi.Pointer<ObjCObject> _objc_msgSend_40(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_40(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_40Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_40 = __objc_msgSend_40Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_absoluteURL1 = _registerName1("absoluteURL");
  late final _sel_scheme1 = _registerName1("scheme");
  late final _sel_resourceSpecifier1 = _registerName1("resourceSpecifier");
  late final _sel_host1 = _registerName1("host");
  late final _class_NSNumber1 = _getClass1("NSNumber");
  late final _class_NSValue1 = _getClass1("NSValue");
  late final _sel_getValue_size_1 = _registerName1("getValue:size:");
  late final _sel_objCType1 = _registerName1("objCType");
  late final _sel_initWithBytes_objCType_1 =
      _registerName1("initWithBytes:objCType:");
  instancetype _objc_msgSend_41(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> value,
    ffi.Pointer<ffi.Char> type,
  ) {
    return __objc_msgSend_41(
      obj,
      sel,
      value,
      type,
    );
  }

  late final __objc_msgSend_41Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>)>>('objc_msgSend');
  late final __objc_msgSend_41 = __objc_msgSend_41Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>)>();

  late final _sel_initWithCoder_1 = _registerName1("initWithCoder:");
  instancetype _objc_msgSend_42(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> coder,
  ) {
    return __objc_msgSend_42(
      obj,
      sel,
      coder,
    );
  }

  late final __objc_msgSend_42Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_42 = __objc_msgSend_42Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_valueWithBytes_objCType_1 =
      _registerName1("valueWithBytes:objCType:");
  ffi.Pointer<ObjCObject> _objc_msgSend_43(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> value,
    ffi.Pointer<ffi.Char> type,
  ) {
    return __objc_msgSend_43(
      obj,
      sel,
      value,
      type,
    );
  }

  late final __objc_msgSend_43Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>,
              ffi.Pointer<ffi.Char>)>>('objc_msgSend');
  late final __objc_msgSend_43 = __objc_msgSend_43Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>,
          ffi.Pointer<ffi.Char>)>();

  late final _sel_value_withObjCType_1 = _registerName1("value:withObjCType:");
  late final _sel_valueWithNonretainedObject_1 =
      _registerName1("valueWithNonretainedObject:");
  ffi.Pointer<ObjCObject> _objc_msgSend_44(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anObject,
  ) {
    return __objc_msgSend_44(
      obj,
      sel,
      anObject,
    );
  }

  late final __objc_msgSend_44Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_44 = __objc_msgSend_44Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_nonretainedObjectValue1 =
      _registerName1("nonretainedObjectValue");
  late final _sel_valueWithPointer_1 = _registerName1("valueWithPointer:");
  ffi.Pointer<ObjCObject> _objc_msgSend_45(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> pointer,
  ) {
    return __objc_msgSend_45(
      obj,
      sel,
      pointer,
    );
  }

  late final __objc_msgSend_45Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_45 = __objc_msgSend_45Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ffi.Void>)>();

  late final _sel_pointerValue1 = _registerName1("pointerValue");
  late final _sel_isEqualToValue_1 = _registerName1("isEqualToValue:");
  bool _objc_msgSend_46(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_46(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_46Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_46 = __objc_msgSend_46Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_getValue_1 = _registerName1("getValue:");
  void _objc_msgSend_47(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> value,
  ) {
    return __objc_msgSend_47(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_47Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_47 = __objc_msgSend_47Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_valueWithRange_1 = _registerName1("valueWithRange:");
  ffi.Pointer<ObjCObject> _objc_msgSend_48(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
  ) {
    return __objc_msgSend_48(
      obj,
      sel,
      range,
    );
  }

  late final __objc_msgSend_48Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_48 = __objc_msgSend_48Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _sel_rangeValue1 = _registerName1("rangeValue");
  NSRange _objc_msgSend_49(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_49(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_49Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_49 = __objc_msgSend_49Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_valueWithPoint_1 = _registerName1("valueWithPoint:");
  ffi.Pointer<ObjCObject> _objc_msgSend_50(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSPoint point,
  ) {
    return __objc_msgSend_50(
      obj,
      sel,
      point,
    );
  }

  late final __objc_msgSend_50Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSPoint)>>('objc_msgSend');
  late final __objc_msgSend_50 = __objc_msgSend_50Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSPoint)>();

  late final _sel_valueWithSize_1 = _registerName1("valueWithSize:");
  ffi.Pointer<ObjCObject> _objc_msgSend_51(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSSize size,
  ) {
    return __objc_msgSend_51(
      obj,
      sel,
      size,
    );
  }

  late final __objc_msgSend_51Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSSize)>>('objc_msgSend');
  late final __objc_msgSend_51 = __objc_msgSend_51Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSSize)>();

  late final _sel_valueWithRect_1 = _registerName1("valueWithRect:");
  ffi.Pointer<ObjCObject> _objc_msgSend_52(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRect rect,
  ) {
    return __objc_msgSend_52(
      obj,
      sel,
      rect,
    );
  }

  late final __objc_msgSend_52Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSRect)>>('objc_msgSend');
  late final __objc_msgSend_52 = __objc_msgSend_52Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRect)>();

  late final _sel_valueWithEdgeInsets_1 =
      _registerName1("valueWithEdgeInsets:");
  ffi.Pointer<ObjCObject> _objc_msgSend_53(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSEdgeInsets insets,
  ) {
    return __objc_msgSend_53(
      obj,
      sel,
      insets,
    );
  }

  late final __objc_msgSend_53Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSEdgeInsets)>>('objc_msgSend');
  late final __objc_msgSend_53 = __objc_msgSend_53Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSEdgeInsets)>();

  late final _sel_pointValue1 = _registerName1("pointValue");
  NSPoint _objc_msgSend_54(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_54(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_54Ptr = _lookup<
      ffi.NativeFunction<
          NSPoint Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_54 = __objc_msgSend_54Ptr.asFunction<
      NSPoint Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_sizeValue1 = _registerName1("sizeValue");
  NSSize _objc_msgSend_55(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_55(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_55Ptr = _lookup<
      ffi.NativeFunction<
          NSSize Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_55 = __objc_msgSend_55Ptr.asFunction<
      NSSize Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_rectValue1 = _registerName1("rectValue");
  NSRect _objc_msgSend_56(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_56(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_56Ptr = _lookup<
      ffi.NativeFunction<
          NSRect Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_56 = __objc_msgSend_56Ptr.asFunction<
      NSRect Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_edgeInsetsValue1 = _registerName1("edgeInsetsValue");
  NSEdgeInsets _objc_msgSend_57(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_57(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_57Ptr = _lookup<
      ffi.NativeFunction<
          NSEdgeInsets Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_57 = __objc_msgSend_57Ptr.asFunction<
      NSEdgeInsets Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_keyPathsForValuesAffectingValueForKey_1 =
      _registerName1("keyPathsForValuesAffectingValueForKey:");
  ffi.Pointer<ObjCObject> _objc_msgSend_58(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_58(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_58Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_58 = __objc_msgSend_58Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_automaticallyNotifiesObserversForKey_1 =
      _registerName1("automaticallyNotifiesObserversForKey:");
  bool _objc_msgSend_59(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_59(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_59Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_59 = __objc_msgSend_59Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _class_NSArray1 = _getClass1("NSArray");
  late final _sel_objectAtIndex_1 = _registerName1("objectAtIndex:");
  ffi.Pointer<ObjCObject> _objc_msgSend_60(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
  ) {
    return __objc_msgSend_60(
      obj,
      sel,
      index,
    );
  }

  late final __objc_msgSend_60Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_60 = __objc_msgSend_60Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithObjects_count_1 =
      _registerName1("initWithObjects:count:");
  instancetype _objc_msgSend_61(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
    int cnt,
  ) {
    return __objc_msgSend_61(
      obj,
      sel,
      objects,
      cnt,
    );
  }

  late final __objc_msgSend_61Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_61 = __objc_msgSend_61Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>, int)>();

  late final _sel_arrayByAddingObject_1 =
      _registerName1("arrayByAddingObject:");
  ffi.Pointer<ObjCObject> _objc_msgSend_62(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anObject,
  ) {
    return __objc_msgSend_62(
      obj,
      sel,
      anObject,
    );
  }

  late final __objc_msgSend_62Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_62 = __objc_msgSend_62Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_arrayByAddingObjectsFromArray_1 =
      _registerName1("arrayByAddingObjectsFromArray:");
  ffi.Pointer<ObjCObject> _objc_msgSend_63(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> otherArray,
  ) {
    return __objc_msgSend_63(
      obj,
      sel,
      otherArray,
    );
  }

  late final __objc_msgSend_63Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_63 = __objc_msgSend_63Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_componentsJoinedByString_1 =
      _registerName1("componentsJoinedByString:");
  ffi.Pointer<ObjCObject> _objc_msgSend_64(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> separator,
  ) {
    return __objc_msgSend_64(
      obj,
      sel,
      separator,
    );
  }

  late final __objc_msgSend_64Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_64 = __objc_msgSend_64Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_containsObject_1 = _registerName1("containsObject:");
  late final _sel_descriptionWithLocale_1 =
      _registerName1("descriptionWithLocale:");
  ffi.Pointer<ObjCObject> _objc_msgSend_65(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> locale,
  ) {
    return __objc_msgSend_65(
      obj,
      sel,
      locale,
    );
  }

  late final __objc_msgSend_65Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_65 = __objc_msgSend_65Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_descriptionWithLocale_indent_1 =
      _registerName1("descriptionWithLocale:indent:");
  ffi.Pointer<ObjCObject> _objc_msgSend_66(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> locale,
    int level,
  ) {
    return __objc_msgSend_66(
      obj,
      sel,
      locale,
      level,
    );
  }

  late final __objc_msgSend_66Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_66 = __objc_msgSend_66Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, int)>();

  late final _sel_firstObjectCommonWithArray_1 =
      _registerName1("firstObjectCommonWithArray:");
  ffi.Pointer<ObjCObject> _objc_msgSend_67(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> otherArray,
  ) {
    return __objc_msgSend_67(
      obj,
      sel,
      otherArray,
    );
  }

  late final __objc_msgSend_67Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_67 = __objc_msgSend_67Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_getObjects_range_1 = _registerName1("getObjects:range:");
  void _objc_msgSend_68(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
    NSRange range,
  ) {
    return __objc_msgSend_68(
      obj,
      sel,
      objects,
      range,
    );
  }

  late final __objc_msgSend_68Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_68 = __objc_msgSend_68Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>, NSRange)>();

  late final _sel_indexOfObject_1 = _registerName1("indexOfObject:");
  int _objc_msgSend_69(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anObject,
  ) {
    return __objc_msgSend_69(
      obj,
      sel,
      anObject,
    );
  }

  late final __objc_msgSend_69Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_69 = __objc_msgSend_69Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_indexOfObject_inRange_1 =
      _registerName1("indexOfObject:inRange:");
  int _objc_msgSend_70(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anObject,
    NSRange range,
  ) {
    return __objc_msgSend_70(
      obj,
      sel,
      anObject,
      range,
    );
  }

  late final __objc_msgSend_70Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_70 = __objc_msgSend_70Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, NSRange)>();

  late final _sel_indexOfObjectIdenticalTo_1 =
      _registerName1("indexOfObjectIdenticalTo:");
  late final _sel_indexOfObjectIdenticalTo_inRange_1 =
      _registerName1("indexOfObjectIdenticalTo:inRange:");
  late final _sel_isEqualToArray_1 = _registerName1("isEqualToArray:");
  bool _objc_msgSend_71(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> otherArray,
  ) {
    return __objc_msgSend_71(
      obj,
      sel,
      otherArray,
    );
  }

  late final __objc_msgSend_71Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_71 = __objc_msgSend_71Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_firstObject1 = _registerName1("firstObject");
  late final _sel_lastObject1 = _registerName1("lastObject");
  late final _sel_objectEnumerator1 = _registerName1("objectEnumerator");
  ffi.Pointer<ObjCObject> _objc_msgSend_72(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_72(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_72Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_72 = __objc_msgSend_72Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_reverseObjectEnumerator1 =
      _registerName1("reverseObjectEnumerator");
  late final _sel_sortedArrayHint1 = _registerName1("sortedArrayHint");
  late final _sel_sortedArrayUsingFunction_context_1 =
      _registerName1("sortedArrayUsingFunction:context:");
  ffi.Pointer<ObjCObject> _objc_msgSend_73(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<
            ffi.NativeFunction<
                NSInteger Function(ffi.Pointer<ObjCObject>,
                    ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>
        comparator,
    ffi.Pointer<ffi.Void> context,
  ) {
    return __objc_msgSend_73(
      obj,
      sel,
      comparator,
      context,
    );
  }

  late final __objc_msgSend_73Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<
                  ffi.NativeFunction<
                      NSInteger Function(ffi.Pointer<ObjCObject>,
                          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>,
              ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_73 = __objc_msgSend_73Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<
              ffi.NativeFunction<
                  NSInteger Function(ffi.Pointer<ObjCObject>,
                      ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_sortedArrayUsingFunction_context_hint_1 =
      _registerName1("sortedArrayUsingFunction:context:hint:");
  ffi.Pointer<ObjCObject> _objc_msgSend_74(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<
            ffi.NativeFunction<
                NSInteger Function(ffi.Pointer<ObjCObject>,
                    ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>
        comparator,
    ffi.Pointer<ffi.Void> context,
    ffi.Pointer<ObjCObject> hint,
  ) {
    return __objc_msgSend_74(
      obj,
      sel,
      comparator,
      context,
      hint,
    );
  }

  late final __objc_msgSend_74Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<
                  ffi.NativeFunction<
                      NSInteger Function(ffi.Pointer<ObjCObject>,
                          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>,
              ffi.Pointer<ffi.Void>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_74 = __objc_msgSend_74Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<
              ffi.NativeFunction<
                  NSInteger Function(ffi.Pointer<ObjCObject>,
                      ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>,
          ffi.Pointer<ffi.Void>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_sortedArrayUsingSelector_1 =
      _registerName1("sortedArrayUsingSelector:");
  ffi.Pointer<ObjCObject> _objc_msgSend_75(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> comparator,
  ) {
    return __objc_msgSend_75(
      obj,
      sel,
      comparator,
    );
  }

  late final __objc_msgSend_75Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_75 = __objc_msgSend_75Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCSel>)>();

  late final _sel_subarrayWithRange_1 = _registerName1("subarrayWithRange:");
  ffi.Pointer<ObjCObject> _objc_msgSend_76(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
  ) {
    return __objc_msgSend_76(
      obj,
      sel,
      range,
    );
  }

  late final __objc_msgSend_76Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_76 = __objc_msgSend_76Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _class_NSError1 = _getClass1("NSError");
  late final _sel_initWithDomain_code_userInfo_1 =
      _registerName1("initWithDomain:code:userInfo:");
  instancetype _objc_msgSend_77(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSErrorDomain domain,
    int code,
  ) {
    return __objc_msgSend_77(
      obj,
      sel,
      domain,
      code,
    );
  }

  late final __objc_msgSend_77Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSErrorDomain, NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_77 = __objc_msgSend_77Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSErrorDomain, int)>();

  late final _sel_errorWithDomain_code_userInfo_1 =
      _registerName1("errorWithDomain:code:userInfo:");
  late final _sel_domain1 = _registerName1("domain");
  late final _sel_code1 = _registerName1("code");
  int _objc_msgSend_78(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_78(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_78Ptr = _lookup<
      ffi.NativeFunction<
          NSInteger Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_78 = __objc_msgSend_78Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setKeys_triggerChangeNotificationsForDependentKey_1 =
      _registerName1("setKeys:triggerChangeNotificationsForDependentKey:");
  void _objc_msgSend_79(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> keys,
    ffi.Pointer<ObjCObject> dependentKey,
  ) {
    return __objc_msgSend_79(
      obj,
      sel,
      keys,
      dependentKey,
    );
  }

  late final __objc_msgSend_79Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_79 = __objc_msgSend_79Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_classFallbacksForKeyedArchiver1 =
      _registerName1("classFallbacksForKeyedArchiver");
  ffi.Pointer<ObjCObject> _objc_msgSend_80(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_80(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_80Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_80 = __objc_msgSend_80Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_classForKeyedUnarchiver1 =
      _registerName1("classForKeyedUnarchiver");
  late final _sel_writeToURL_error_1 = _registerName1("writeToURL:error:");
  bool _objc_msgSend_81(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_81(
      obj,
      sel,
      url,
      error,
    );
  }

  late final __objc_msgSend_81Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_81 = __objc_msgSend_81Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_makeObjectsPerformSelector_1 =
      _registerName1("makeObjectsPerformSelector:");
  late final _sel_makeObjectsPerformSelector_withObject_1 =
      _registerName1("makeObjectsPerformSelector:withObject:");
  void _objc_msgSend_82(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
    ffi.Pointer<ObjCObject> argument,
  ) {
    return __objc_msgSend_82(
      obj,
      sel,
      aSelector,
      argument,
    );
  }

  late final __objc_msgSend_82Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_82 = __objc_msgSend_82Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _class_NSIndexSet1 = _getClass1("NSIndexSet");
  late final _sel_indexSet1 = _registerName1("indexSet");
  late final _sel_indexSetWithIndex_1 = _registerName1("indexSetWithIndex:");
  late final _sel_indexSetWithIndexesInRange_1 =
      _registerName1("indexSetWithIndexesInRange:");
  instancetype _objc_msgSend_83(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
  ) {
    return __objc_msgSend_83(
      obj,
      sel,
      range,
    );
  }

  late final __objc_msgSend_83Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_83 = __objc_msgSend_83Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _sel_initWithIndexesInRange_1 =
      _registerName1("initWithIndexesInRange:");
  late final _sel_initWithIndexSet_1 = _registerName1("initWithIndexSet:");
  instancetype _objc_msgSend_84(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> indexSet,
  ) {
    return __objc_msgSend_84(
      obj,
      sel,
      indexSet,
    );
  }

  late final __objc_msgSend_84Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_84 = __objc_msgSend_84Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithIndex_1 = _registerName1("initWithIndex:");
  late final _sel_isEqualToIndexSet_1 = _registerName1("isEqualToIndexSet:");
  bool _objc_msgSend_85(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> indexSet,
  ) {
    return __objc_msgSend_85(
      obj,
      sel,
      indexSet,
    );
  }

  late final __objc_msgSend_85Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_85 = __objc_msgSend_85Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_firstIndex1 = _registerName1("firstIndex");
  late final _sel_lastIndex1 = _registerName1("lastIndex");
  late final _sel_indexGreaterThanIndex_1 =
      _registerName1("indexGreaterThanIndex:");
  int _objc_msgSend_86(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_86(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_86Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_86 = __objc_msgSend_86Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_indexLessThanIndex_1 = _registerName1("indexLessThanIndex:");
  late final _sel_indexGreaterThanOrEqualToIndex_1 =
      _registerName1("indexGreaterThanOrEqualToIndex:");
  late final _sel_indexLessThanOrEqualToIndex_1 =
      _registerName1("indexLessThanOrEqualToIndex:");
  late final _sel_getIndexes_maxCount_inIndexRange_1 =
      _registerName1("getIndexes:maxCount:inIndexRange:");
  int _objc_msgSend_87(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSUInteger> indexBuffer,
    int bufferSize,
    NSRangePointer range,
  ) {
    return __objc_msgSend_87(
      obj,
      sel,
      indexBuffer,
      bufferSize,
      range,
    );
  }

  late final __objc_msgSend_87Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSUInteger>,
              NSUInteger,
              NSRangePointer)>>('objc_msgSend');
  late final __objc_msgSend_87 = __objc_msgSend_87Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSUInteger>, int, NSRangePointer)>();

  late final _sel_countOfIndexesInRange_1 =
      _registerName1("countOfIndexesInRange:");
  int _objc_msgSend_88(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
  ) {
    return __objc_msgSend_88(
      obj,
      sel,
      range,
    );
  }

  late final __objc_msgSend_88Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_88 = __objc_msgSend_88Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _sel_containsIndex_1 = _registerName1("containsIndex:");
  bool _objc_msgSend_89(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_89(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_89Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_89 = __objc_msgSend_89Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_containsIndexesInRange_1 =
      _registerName1("containsIndexesInRange:");
  bool _objc_msgSend_90(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
  ) {
    return __objc_msgSend_90(
      obj,
      sel,
      range,
    );
  }

  late final __objc_msgSend_90Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_90 = __objc_msgSend_90Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _sel_containsIndexes_1 = _registerName1("containsIndexes:");
  late final _sel_intersectsIndexesInRange_1 =
      _registerName1("intersectsIndexesInRange:");
  ffi.Pointer<_ObjCBlockDesc> _newBlockDesc1() {
    final d =
        pkg_ffi.calloc.allocate<_ObjCBlockDesc>(ffi.sizeOf<_ObjCBlockDesc>());
    d.ref.size = ffi.sizeOf<_ObjCBlock>();
    return d;
  }

  late final _objc_block_desc1 = _newBlockDesc1();
  late final _objc_concrete_global_block1 =
      _lookup<ffi.Void>('_NSConcreteGlobalBlock');
  ffi.Pointer<_ObjCBlock> _newBlock1(
      ffi.Pointer<ffi.Void> invoke, ffi.Pointer<ffi.Void> target) {
    final b = pkg_ffi.calloc.allocate<_ObjCBlock>(ffi.sizeOf<_ObjCBlock>());
    b.ref.isa = _objc_concrete_global_block1;
    b.ref.invoke = invoke;
    b.ref.target = target;
    b.ref.descriptor = _objc_block_desc1;
    final copy = _Block_copy(b.cast()).cast<_ObjCBlock>();
    pkg_ffi.calloc.free(b);
    return copy;
  }

  ffi.Pointer<ffi.Void> _Block_copy(
    ffi.Pointer<ffi.Void> value,
  ) {
    return __Block_copy(
      value,
    );
  }

  late final __Block_copyPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Void> Function(
              ffi.Pointer<ffi.Void>)>>('_Block_copy');
  late final __Block_copy = __Block_copyPtr
      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();

  void _Block_release(
    ffi.Pointer<ffi.Void> value,
  ) {
    return __Block_release(
      value,
    );
  }

  late final __Block_releasePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
          '_Block_release');
  late final __Block_release =
      __Block_releasePtr.asFunction<void Function(ffi.Pointer<ffi.Void>)>();

  late final _objc_releaseFinalizer11 =
      ffi.NativeFinalizer(__Block_releasePtr.cast());
  late final _sel_enumerateIndexesUsingBlock_1 =
      _registerName1("enumerateIndexesUsingBlock:");
  void _objc_msgSend_91(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_91(
      obj,
      sel,
      block,
    );
  }

  late final __objc_msgSend_91Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_91 = __objc_msgSend_91Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_enumerateIndexesWithOptions_usingBlock_1 =
      _registerName1("enumerateIndexesWithOptions:usingBlock:");
  void _objc_msgSend_92(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_92(
      obj,
      sel,
      opts,
      block,
    );
  }

  late final __objc_msgSend_92Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_92 = __objc_msgSend_92Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_enumerateIndexesInRange_options_usingBlock_1 =
      _registerName1("enumerateIndexesInRange:options:usingBlock:");
  void _objc_msgSend_93(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_93(
      obj,
      sel,
      range,
      opts,
      block,
    );
  }

  late final __objc_msgSend_93Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_93 = __objc_msgSend_93Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexPassingTest_1 = _registerName1("indexPassingTest:");
  int _objc_msgSend_94(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_94(
      obj,
      sel,
      predicate,
    );
  }

  late final __objc_msgSend_94Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_94 = __objc_msgSend_94Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexWithOptions_passingTest_1 =
      _registerName1("indexWithOptions:passingTest:");
  int _objc_msgSend_95(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_95(
      obj,
      sel,
      opts,
      predicate,
    );
  }

  late final __objc_msgSend_95Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_95 = __objc_msgSend_95Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexInRange_options_passingTest_1 =
      _registerName1("indexInRange:options:passingTest:");
  int _objc_msgSend_96(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    int opts,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_96(
      obj,
      sel,
      range,
      opts,
      predicate,
    );
  }

  late final __objc_msgSend_96Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_96 = __objc_msgSend_96Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexesPassingTest_1 = _registerName1("indexesPassingTest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_97(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_97(
      obj,
      sel,
      predicate,
    );
  }

  late final __objc_msgSend_97Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_97 = __objc_msgSend_97Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexesWithOptions_passingTest_1 =
      _registerName1("indexesWithOptions:passingTest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_98(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_98(
      obj,
      sel,
      opts,
      predicate,
    );
  }

  late final __objc_msgSend_98Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_98 = __objc_msgSend_98Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexesInRange_options_passingTest_1 =
      _registerName1("indexesInRange:options:passingTest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_99(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    int opts,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_99(
      obj,
      sel,
      range,
      opts,
      predicate,
    );
  }

  late final __objc_msgSend_99Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_99 = __objc_msgSend_99Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSRange, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_enumerateRangesUsingBlock_1 =
      _registerName1("enumerateRangesUsingBlock:");
  void _objc_msgSend_100(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_100(
      obj,
      sel,
      block,
    );
  }

  late final __objc_msgSend_100Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_100 = __objc_msgSend_100Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_enumerateRangesWithOptions_usingBlock_1 =
      _registerName1("enumerateRangesWithOptions:usingBlock:");
  void _objc_msgSend_101(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_101(
      obj,
      sel,
      opts,
      block,
    );
  }

  late final __objc_msgSend_101Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_101 = __objc_msgSend_101Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_enumerateRangesInRange_options_usingBlock_1 =
      _registerName1("enumerateRangesInRange:options:usingBlock:");
  void _objc_msgSend_102(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_102(
      obj,
      sel,
      range,
      opts,
      block,
    );
  }

  late final __objc_msgSend_102Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_102 = __objc_msgSend_102Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_objectsAtIndexes_1 = _registerName1("objectsAtIndexes:");
  ffi.Pointer<ObjCObject> _objc_msgSend_103(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> indexes,
  ) {
    return __objc_msgSend_103(
      obj,
      sel,
      indexes,
    );
  }

  late final __objc_msgSend_103Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_103 = __objc_msgSend_103Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_objectAtIndexedSubscript_1 =
      _registerName1("objectAtIndexedSubscript:");
  late final _sel_enumerateObjectsUsingBlock_1 =
      _registerName1("enumerateObjectsUsingBlock:");
  void _objc_msgSend_104(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_104(
      obj,
      sel,
      block,
    );
  }

  late final __objc_msgSend_104Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_104 = __objc_msgSend_104Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_enumerateObjectsWithOptions_usingBlock_1 =
      _registerName1("enumerateObjectsWithOptions:usingBlock:");
  void _objc_msgSend_105(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_105(
      obj,
      sel,
      opts,
      block,
    );
  }

  late final __objc_msgSend_105Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_105 = __objc_msgSend_105Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_enumerateObjectsAtIndexes_options_usingBlock_1 =
      _registerName1("enumerateObjectsAtIndexes:options:usingBlock:");
  void _objc_msgSend_106(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> s,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_106(
      obj,
      sel,
      s,
      opts,
      block,
    );
  }

  late final __objc_msgSend_106Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_106 = __objc_msgSend_106Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexOfObjectPassingTest_1 =
      _registerName1("indexOfObjectPassingTest:");
  int _objc_msgSend_107(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_107(
      obj,
      sel,
      predicate,
    );
  }

  late final __objc_msgSend_107Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_107 = __objc_msgSend_107Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexOfObjectWithOptions_passingTest_1 =
      _registerName1("indexOfObjectWithOptions:passingTest:");
  int _objc_msgSend_108(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_108(
      obj,
      sel,
      opts,
      predicate,
    );
  }

  late final __objc_msgSend_108Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_108 = __objc_msgSend_108Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexOfObjectAtIndexes_options_passingTest_1 =
      _registerName1("indexOfObjectAtIndexes:options:passingTest:");
  int _objc_msgSend_109(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> s,
    int opts,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_109(
      obj,
      sel,
      s,
      opts,
      predicate,
    );
  }

  late final __objc_msgSend_109Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_109 = __objc_msgSend_109Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexesOfObjectsPassingTest_1 =
      _registerName1("indexesOfObjectsPassingTest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_110(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_110(
      obj,
      sel,
      predicate,
    );
  }

  late final __objc_msgSend_110Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_110 = __objc_msgSend_110Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexesOfObjectsWithOptions_passingTest_1 =
      _registerName1("indexesOfObjectsWithOptions:passingTest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_111(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_111(
      obj,
      sel,
      opts,
      predicate,
    );
  }

  late final __objc_msgSend_111Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_111 = __objc_msgSend_111Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_indexesOfObjectsAtIndexes_options_passingTest_1 =
      _registerName1("indexesOfObjectsAtIndexes:options:passingTest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_112(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> s,
    int opts,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_112(
      obj,
      sel,
      s,
      opts,
      predicate,
    );
  }

  late final __objc_msgSend_112Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_112 = __objc_msgSend_112Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_sortedArrayUsingComparator_1 =
      _registerName1("sortedArrayUsingComparator:");
  ffi.Pointer<ObjCObject> _objc_msgSend_113(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSComparator cmptr,
  ) {
    return __objc_msgSend_113(
      obj,
      sel,
      cmptr,
    );
  }

  late final __objc_msgSend_113Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSComparator)>>('objc_msgSend');
  late final __objc_msgSend_113 = __objc_msgSend_113Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSComparator)>();

  late final _sel_sortedArrayWithOptions_usingComparator_1 =
      _registerName1("sortedArrayWithOptions:usingComparator:");
  ffi.Pointer<ObjCObject> _objc_msgSend_114(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    NSComparator cmptr,
  ) {
    return __objc_msgSend_114(
      obj,
      sel,
      opts,
      cmptr,
    );
  }

  late final __objc_msgSend_114Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Int32, NSComparator)>>('objc_msgSend');
  late final __objc_msgSend_114 = __objc_msgSend_114Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int, NSComparator)>();

  late final _sel_indexOfObject_inSortedRange_options_usingComparator_1 =
      _registerName1("indexOfObject:inSortedRange:options:usingComparator:");
  int _objc_msgSend_115(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> obj1,
    NSRange r,
    int opts,
    NSComparator cmp,
  ) {
    return __objc_msgSend_115(
      obj,
      sel,
      obj1,
      r,
      opts,
      cmp,
    );
  }

  late final __objc_msgSend_115Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSRange,
              ffi.Int32,
              NSComparator)>>('objc_msgSend');
  late final __objc_msgSend_115 = __objc_msgSend_115Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, NSRange, int, NSComparator)>();

  late final _sel_array1 = _registerName1("array");
  late final _sel_arrayWithObject_1 = _registerName1("arrayWithObject:");
  late final _sel_arrayWithObjects_count_1 =
      _registerName1("arrayWithObjects:count:");
  late final _sel_arrayWithObjects_1 = _registerName1("arrayWithObjects:");
  late final _sel_arrayWithArray_1 = _registerName1("arrayWithArray:");
  late final _sel_initWithObjects_1 = _registerName1("initWithObjects:");
  late final _sel_initWithArray_1 = _registerName1("initWithArray:");
  late final _sel_initWithArray_copyItems_1 =
      _registerName1("initWithArray:copyItems:");
  instancetype _objc_msgSend_116(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> array,
    bool flag,
  ) {
    return __objc_msgSend_116(
      obj,
      sel,
      array,
      flag,
    );
  }

  late final __objc_msgSend_116Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_116 = __objc_msgSend_116Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_initWithContentsOfURL_error_1 =
      _registerName1("initWithContentsOfURL:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_117(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_117(
      obj,
      sel,
      url,
      error,
    );
  }

  late final __objc_msgSend_117Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_117 = __objc_msgSend_117Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_arrayWithContentsOfURL_error_1 =
      _registerName1("arrayWithContentsOfURL:error:");
  late final _sel_getObjects_1 = _registerName1("getObjects:");
  void _objc_msgSend_118(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
  ) {
    return __objc_msgSend_118(
      obj,
      sel,
      objects,
    );
  }

  late final __objc_msgSend_118Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_118 = __objc_msgSend_118Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_arrayWithContentsOfFile_1 =
      _registerName1("arrayWithContentsOfFile:");
  ffi.Pointer<ObjCObject> _objc_msgSend_119(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
  ) {
    return __objc_msgSend_119(
      obj,
      sel,
      path,
    );
  }

  late final __objc_msgSend_119Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_119 = __objc_msgSend_119Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_arrayWithContentsOfURL_1 =
      _registerName1("arrayWithContentsOfURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_120(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
  ) {
    return __objc_msgSend_120(
      obj,
      sel,
      url,
    );
  }

  late final __objc_msgSend_120Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_120 = __objc_msgSend_120Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithContentsOfFile_1 =
      _registerName1("initWithContentsOfFile:");
  late final _sel_initWithContentsOfURL_1 =
      _registerName1("initWithContentsOfURL:");
  late final _sel_writeToURL_atomically_1 =
      _registerName1("writeToURL:atomically:");
  bool _objc_msgSend_121(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    bool atomically,
  ) {
    return __objc_msgSend_121(
      obj,
      sel,
      url,
      atomically,
    );
  }

  late final __objc_msgSend_121Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_121 = __objc_msgSend_121Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_pathsMatchingExtensions_1 =
      _registerName1("pathsMatchingExtensions:");
  late final _sel_valueForKey_1 = _registerName1("valueForKey:");
  late final _sel_setValue_forKey_1 = _registerName1("setValue:forKey:");
  void _objc_msgSend_122(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_122(
      obj,
      sel,
      value,
      key,
    );
  }

  late final __objc_msgSend_122Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_122 = __objc_msgSend_122Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_addObserver_toObjectsAtIndexes_forKeyPath_options_context_1 =
      _registerName1(
          "addObserver:toObjectsAtIndexes:forKeyPath:options:context:");
  void _objc_msgSend_123(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> observer,
    ffi.Pointer<ObjCObject> indexes,
    ffi.Pointer<ObjCObject> keyPath,
    int options,
    ffi.Pointer<ffi.Void> context,
  ) {
    return __objc_msgSend_123(
      obj,
      sel,
      observer,
      indexes,
      keyPath,
      options,
      context,
    );
  }

  late final __objc_msgSend_123Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_123 = __objc_msgSend_123Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_removeObserver_fromObjectsAtIndexes_forKeyPath_context_1 =
      _registerName1("removeObserver:fromObjectsAtIndexes:forKeyPath:context:");
  void _objc_msgSend_124(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> observer,
    ffi.Pointer<ObjCObject> indexes,
    ffi.Pointer<ObjCObject> keyPath,
    ffi.Pointer<ffi.Void> context,
  ) {
    return __objc_msgSend_124(
      obj,
      sel,
      observer,
      indexes,
      keyPath,
      context,
    );
  }

  late final __objc_msgSend_124Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_124 = __objc_msgSend_124Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_removeObserver_fromObjectsAtIndexes_forKeyPath_1 =
      _registerName1("removeObserver:fromObjectsAtIndexes:forKeyPath:");
  void _objc_msgSend_125(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> observer,
    ffi.Pointer<ObjCObject> indexes,
    ffi.Pointer<ObjCObject> keyPath,
  ) {
    return __objc_msgSend_125(
      obj,
      sel,
      observer,
      indexes,
      keyPath,
    );
  }

  late final __objc_msgSend_125Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_125 = __objc_msgSend_125Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_addObserver_forKeyPath_options_context_1 =
      _registerName1("addObserver:forKeyPath:options:context:");
  void _objc_msgSend_126(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> observer,
    ffi.Pointer<ObjCObject> keyPath,
    int options,
    ffi.Pointer<ffi.Void> context,
  ) {
    return __objc_msgSend_126(
      obj,
      sel,
      observer,
      keyPath,
      options,
      context,
    );
  }

  late final __objc_msgSend_126Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_126 = __objc_msgSend_126Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_removeObserver_forKeyPath_context_1 =
      _registerName1("removeObserver:forKeyPath:context:");
  void _objc_msgSend_127(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> observer,
    ffi.Pointer<ObjCObject> keyPath,
    ffi.Pointer<ffi.Void> context,
  ) {
    return __objc_msgSend_127(
      obj,
      sel,
      observer,
      keyPath,
      context,
    );
  }

  late final __objc_msgSend_127Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_127 = __objc_msgSend_127Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_removeObserver_forKeyPath_1 =
      _registerName1("removeObserver:forKeyPath:");
  void _objc_msgSend_128(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> observer,
    ffi.Pointer<ObjCObject> keyPath,
  ) {
    return __objc_msgSend_128(
      obj,
      sel,
      observer,
      keyPath,
    );
  }

  late final __objc_msgSend_128Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_128 = __objc_msgSend_128Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_sortedArrayUsingDescriptors_1 =
      _registerName1("sortedArrayUsingDescriptors:");
  late final _class_NSPredicate1 = _getClass1("NSPredicate");
  late final _sel_predicateWithFormat_argumentArray_1 =
      _registerName1("predicateWithFormat:argumentArray:");
  ffi.Pointer<ObjCObject> _objc_msgSend_129(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> predicateFormat,
    ffi.Pointer<ObjCObject> arguments,
  ) {
    return __objc_msgSend_129(
      obj,
      sel,
      predicateFormat,
      arguments,
    );
  }

  late final __objc_msgSend_129Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_129 = __objc_msgSend_129Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_predicateWithFormat_1 =
      _registerName1("predicateWithFormat:");
  ffi.Pointer<ObjCObject> _objc_msgSend_130(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> predicateFormat,
  ) {
    return __objc_msgSend_130(
      obj,
      sel,
      predicateFormat,
    );
  }

  late final __objc_msgSend_130Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_130 = __objc_msgSend_130Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_predicateWithFormat_arguments_1 =
      _registerName1("predicateWithFormat:arguments:");
  ffi.Pointer<ObjCObject> _objc_msgSend_131(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> predicateFormat,
    ffi.Pointer<__va_list_tag> argList,
  ) {
    return __objc_msgSend_131(
      obj,
      sel,
      predicateFormat,
      argList,
    );
  }

  late final __objc_msgSend_131Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<__va_list_tag>)>>('objc_msgSend');
  late final __objc_msgSend_131 = __objc_msgSend_131Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<__va_list_tag>)>();

  late final _sel_predicateFromMetadataQueryString_1 =
      _registerName1("predicateFromMetadataQueryString:");
  late final _sel_predicateWithValue_1 = _registerName1("predicateWithValue:");
  ffi.Pointer<ObjCObject> _objc_msgSend_132(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool value,
  ) {
    return __objc_msgSend_132(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_132Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_132 = __objc_msgSend_132Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool)>();

  late final _class_NSDictionary1 = _getClass1("NSDictionary");
  late final _sel_objectForKey_1 = _registerName1("objectForKey:");
  late final _sel_keyEnumerator1 = _registerName1("keyEnumerator");
  late final _sel_initWithObjects_forKeys_count_1 =
      _registerName1("initWithObjects:forKeys:count:");
  instancetype _objc_msgSend_133(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
    ffi.Pointer<ffi.Pointer<ObjCObject>> keys,
    int cnt,
  ) {
    return __objc_msgSend_133(
      obj,
      sel,
      objects,
      keys,
      cnt,
    );
  }

  late final __objc_msgSend_133Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_133 = __objc_msgSend_133Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          int)>();

  late final _sel_allKeys1 = _registerName1("allKeys");
  late final _sel_allKeysForObject_1 = _registerName1("allKeysForObject:");
  late final _sel_allValues1 = _registerName1("allValues");
  late final _sel_descriptionInStringsFileFormat1 =
      _registerName1("descriptionInStringsFileFormat");
  late final _sel_isEqualToDictionary_1 =
      _registerName1("isEqualToDictionary:");
  bool _objc_msgSend_134(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> otherDictionary,
  ) {
    return __objc_msgSend_134(
      obj,
      sel,
      otherDictionary,
    );
  }

  late final __objc_msgSend_134Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_134 = __objc_msgSend_134Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_objectsForKeys_notFoundMarker_1 =
      _registerName1("objectsForKeys:notFoundMarker:");
  ffi.Pointer<ObjCObject> _objc_msgSend_135(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> keys,
    ffi.Pointer<ObjCObject> marker,
  ) {
    return __objc_msgSend_135(
      obj,
      sel,
      keys,
      marker,
    );
  }

  late final __objc_msgSend_135Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_135 = __objc_msgSend_135Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_keysSortedByValueUsingSelector_1 =
      _registerName1("keysSortedByValueUsingSelector:");
  late final _sel_getObjects_andKeys_count_1 =
      _registerName1("getObjects:andKeys:count:");
  void _objc_msgSend_136(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
    ffi.Pointer<ffi.Pointer<ObjCObject>> keys,
    int count,
  ) {
    return __objc_msgSend_136(
      obj,
      sel,
      objects,
      keys,
      count,
    );
  }

  late final __objc_msgSend_136Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_136 = __objc_msgSend_136Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          int)>();

  late final _sel_objectForKeyedSubscript_1 =
      _registerName1("objectForKeyedSubscript:");
  late final _sel_enumerateKeysAndObjectsUsingBlock_1 =
      _registerName1("enumerateKeysAndObjectsUsingBlock:");
  void _objc_msgSend_137(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_137(
      obj,
      sel,
      block,
    );
  }

  late final __objc_msgSend_137Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_137 = __objc_msgSend_137Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_enumerateKeysAndObjectsWithOptions_usingBlock_1 =
      _registerName1("enumerateKeysAndObjectsWithOptions:usingBlock:");
  void _objc_msgSend_138(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_138(
      obj,
      sel,
      opts,
      block,
    );
  }

  late final __objc_msgSend_138Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_138 = __objc_msgSend_138Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_keysSortedByValueUsingComparator_1 =
      _registerName1("keysSortedByValueUsingComparator:");
  late final _sel_keysSortedByValueWithOptions_usingComparator_1 =
      _registerName1("keysSortedByValueWithOptions:usingComparator:");
  late final _sel_getObjects_andKeys_1 = _registerName1("getObjects:andKeys:");
  void _objc_msgSend_139(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
    ffi.Pointer<ffi.Pointer<ObjCObject>> keys,
  ) {
    return __objc_msgSend_139(
      obj,
      sel,
      objects,
      keys,
    );
  }

  late final __objc_msgSend_139Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_139 = __objc_msgSend_139Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_dictionaryWithContentsOfFile_1 =
      _registerName1("dictionaryWithContentsOfFile:");
  ffi.Pointer<ObjCObject> _objc_msgSend_140(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
  ) {
    return __objc_msgSend_140(
      obj,
      sel,
      path,
    );
  }

  late final __objc_msgSend_140Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_140 = __objc_msgSend_140Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_dictionaryWithContentsOfURL_1 =
      _registerName1("dictionaryWithContentsOfURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_141(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
  ) {
    return __objc_msgSend_141(
      obj,
      sel,
      url,
    );
  }

  late final __objc_msgSend_141Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_141 = __objc_msgSend_141Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_dictionary1 = _registerName1("dictionary");
  late final _sel_dictionaryWithObject_forKey_1 =
      _registerName1("dictionaryWithObject:forKey:");
  instancetype _objc_msgSend_142(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> object,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_142(
      obj,
      sel,
      object,
      key,
    );
  }

  late final __objc_msgSend_142Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_142 = __objc_msgSend_142Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_dictionaryWithObjects_forKeys_count_1 =
      _registerName1("dictionaryWithObjects:forKeys:count:");
  late final _sel_dictionaryWithObjectsAndKeys_1 =
      _registerName1("dictionaryWithObjectsAndKeys:");
  late final _sel_dictionaryWithDictionary_1 =
      _registerName1("dictionaryWithDictionary:");
  instancetype _objc_msgSend_143(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> dict,
  ) {
    return __objc_msgSend_143(
      obj,
      sel,
      dict,
    );
  }

  late final __objc_msgSend_143Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_143 = __objc_msgSend_143Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_dictionaryWithObjects_forKeys_1 =
      _registerName1("dictionaryWithObjects:forKeys:");
  instancetype _objc_msgSend_144(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> objects,
    ffi.Pointer<ObjCObject> keys,
  ) {
    return __objc_msgSend_144(
      obj,
      sel,
      objects,
      keys,
    );
  }

  late final __objc_msgSend_144Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_144 = __objc_msgSend_144Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithObjectsAndKeys_1 =
      _registerName1("initWithObjectsAndKeys:");
  late final _sel_initWithDictionary_1 = _registerName1("initWithDictionary:");
  late final _sel_initWithDictionary_copyItems_1 =
      _registerName1("initWithDictionary:copyItems:");
  instancetype _objc_msgSend_145(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> otherDictionary,
    bool flag,
  ) {
    return __objc_msgSend_145(
      obj,
      sel,
      otherDictionary,
      flag,
    );
  }

  late final __objc_msgSend_145Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_145 = __objc_msgSend_145Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_initWithObjects_forKeys_1 =
      _registerName1("initWithObjects:forKeys:");
  ffi.Pointer<ObjCObject> _objc_msgSend_146(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_146(
      obj,
      sel,
      url,
      error,
    );
  }

  late final __objc_msgSend_146Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_146 = __objc_msgSend_146Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_dictionaryWithContentsOfURL_error_1 =
      _registerName1("dictionaryWithContentsOfURL:error:");
  late final _sel_sharedKeySetForKeys_1 =
      _registerName1("sharedKeySetForKeys:");
  late final _sel_countByEnumeratingWithState_objects_count_1 =
      _registerName1("countByEnumeratingWithState:objects:count:");
  int _objc_msgSend_147(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSFastEnumerationState> state,
    ffi.Pointer<ffi.Pointer<ObjCObject>> buffer,
    int len,
  ) {
    return __objc_msgSend_147(
      obj,
      sel,
      state,
      buffer,
      len,
    );
  }

  late final __objc_msgSend_147Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSFastEnumerationState>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_147 = __objc_msgSend_147Ptr.asFunction<
      int Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSFastEnumerationState>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          int)>();

  late final _sel_fileSize1 = _registerName1("fileSize");
  int _objc_msgSend_148(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_148(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_148Ptr = _lookup<
      ffi.NativeFunction<
          ffi.UnsignedLongLong Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_148 = __objc_msgSend_148Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _class_NSDate1 = _getClass1("NSDate");
  late final _sel_timeIntervalSinceReferenceDate1 =
      _registerName1("timeIntervalSinceReferenceDate");
  double _objc_msgSend_149(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_149(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_149Ptr = _lookup<
      ffi.NativeFunction<
          NSTimeInterval Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_149 = __objc_msgSend_149Ptr.asFunction<
      double Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_initWithTimeIntervalSinceReferenceDate_1 =
      _registerName1("initWithTimeIntervalSinceReferenceDate:");
  instancetype _objc_msgSend_150(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double ti,
  ) {
    return __objc_msgSend_150(
      obj,
      sel,
      ti,
    );
  }

  late final __objc_msgSend_150Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSTimeInterval)>>('objc_msgSend');
  late final __objc_msgSend_150 = __objc_msgSend_150Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double)>();

  late final _sel_timeIntervalSinceDate_1 =
      _registerName1("timeIntervalSinceDate:");
  double _objc_msgSend_151(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anotherDate,
  ) {
    return __objc_msgSend_151(
      obj,
      sel,
      anotherDate,
    );
  }

  late final __objc_msgSend_151Ptr = _lookup<
      ffi.NativeFunction<
          NSTimeInterval Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_151 = __objc_msgSend_151Ptr.asFunction<
      double Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_timeIntervalSinceNow1 =
      _registerName1("timeIntervalSinceNow");
  late final _sel_timeIntervalSince19701 =
      _registerName1("timeIntervalSince1970");
  late final _sel_addTimeInterval_1 = _registerName1("addTimeInterval:");
  late final _sel_dateByAddingTimeInterval_1 =
      _registerName1("dateByAddingTimeInterval:");
  late final _sel_earlierDate_1 = _registerName1("earlierDate:");
  ffi.Pointer<ObjCObject> _objc_msgSend_152(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anotherDate,
  ) {
    return __objc_msgSend_152(
      obj,
      sel,
      anotherDate,
    );
  }

  late final __objc_msgSend_152Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_152 = __objc_msgSend_152Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_laterDate_1 = _registerName1("laterDate:");
  late final _sel_compare_1 = _registerName1("compare:");
  int _objc_msgSend_153(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> other,
  ) {
    return __objc_msgSend_153(
      obj,
      sel,
      other,
    );
  }

  late final __objc_msgSend_153Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_153 = __objc_msgSend_153Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_isEqualToDate_1 = _registerName1("isEqualToDate:");
  bool _objc_msgSend_154(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> otherDate,
  ) {
    return __objc_msgSend_154(
      obj,
      sel,
      otherDate,
    );
  }

  late final __objc_msgSend_154Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_154 = __objc_msgSend_154Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_date1 = _registerName1("date");
  late final _sel_dateWithTimeIntervalSinceNow_1 =
      _registerName1("dateWithTimeIntervalSinceNow:");
  late final _sel_dateWithTimeIntervalSinceReferenceDate_1 =
      _registerName1("dateWithTimeIntervalSinceReferenceDate:");
  late final _sel_dateWithTimeIntervalSince1970_1 =
      _registerName1("dateWithTimeIntervalSince1970:");
  late final _sel_dateWithTimeInterval_sinceDate_1 =
      _registerName1("dateWithTimeInterval:sinceDate:");
  instancetype _objc_msgSend_155(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double secsToBeAdded,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_155(
      obj,
      sel,
      secsToBeAdded,
      date,
    );
  }

  late final __objc_msgSend_155Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSTimeInterval, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_155 = __objc_msgSend_155Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          double, ffi.Pointer<ObjCObject>)>();

  late final _sel_distantFuture1 = _registerName1("distantFuture");
  ffi.Pointer<ObjCObject> _objc_msgSend_156(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_156(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_156Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_156 = __objc_msgSend_156Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_distantPast1 = _registerName1("distantPast");
  late final _sel_now1 = _registerName1("now");
  late final _sel_initWithTimeIntervalSinceNow_1 =
      _registerName1("initWithTimeIntervalSinceNow:");
  late final _sel_initWithTimeIntervalSince1970_1 =
      _registerName1("initWithTimeIntervalSince1970:");
  late final _sel_initWithTimeInterval_sinceDate_1 =
      _registerName1("initWithTimeInterval:sinceDate:");
  late final _sel_dateWithNaturalLanguageString_locale_1 =
      _registerName1("dateWithNaturalLanguageString:locale:");
  ffi.Pointer<ObjCObject> _objc_msgSend_157(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    ffi.Pointer<ObjCObject> locale,
  ) {
    return __objc_msgSend_157(
      obj,
      sel,
      string,
      locale,
    );
  }

  late final __objc_msgSend_157Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_157 = __objc_msgSend_157Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_dateWithNaturalLanguageString_1 =
      _registerName1("dateWithNaturalLanguageString:");
  late final _sel_dateWithString_1 = _registerName1("dateWithString:");
  late final _class_NSCalendarDate1 = _getClass1("NSCalendarDate");
  late final _sel_calendarDate1 = _registerName1("calendarDate");
  late final _sel_dateWithString_calendarFormat_locale_1 =
      _registerName1("dateWithString:calendarFormat:locale:");
  ffi.Pointer<ObjCObject> _objc_msgSend_158(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> description,
    ffi.Pointer<ObjCObject> format,
    ffi.Pointer<ObjCObject> locale,
  ) {
    return __objc_msgSend_158(
      obj,
      sel,
      description,
      format,
      locale,
    );
  }

  late final __objc_msgSend_158Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_158 = __objc_msgSend_158Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_dateWithString_calendarFormat_1 =
      _registerName1("dateWithString:calendarFormat:");
  ffi.Pointer<ObjCObject> _objc_msgSend_159(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> description,
    ffi.Pointer<ObjCObject> format,
  ) {
    return __objc_msgSend_159(
      obj,
      sel,
      description,
      format,
    );
  }

  late final __objc_msgSend_159Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_159 = __objc_msgSend_159Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _class_NSTimeZone1 = _getClass1("NSTimeZone");
  late final _sel_name1 = _registerName1("name");
  late final _sel_data1 = _registerName1("data");
  late final _sel_secondsFromGMTForDate_1 =
      _registerName1("secondsFromGMTForDate:");
  int _objc_msgSend_160(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aDate,
  ) {
    return __objc_msgSend_160(
      obj,
      sel,
      aDate,
    );
  }

  late final __objc_msgSend_160Ptr = _lookup<
      ffi.NativeFunction<
          NSInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_160 = __objc_msgSend_160Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_abbreviationForDate_1 =
      _registerName1("abbreviationForDate:");
  ffi.Pointer<ObjCObject> _objc_msgSend_161(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aDate,
  ) {
    return __objc_msgSend_161(
      obj,
      sel,
      aDate,
    );
  }

  late final __objc_msgSend_161Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_161 = __objc_msgSend_161Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_isDaylightSavingTimeForDate_1 =
      _registerName1("isDaylightSavingTimeForDate:");
  late final _sel_daylightSavingTimeOffsetForDate_1 =
      _registerName1("daylightSavingTimeOffsetForDate:");
  late final _sel_nextDaylightSavingTimeTransitionAfterDate_1 =
      _registerName1("nextDaylightSavingTimeTransitionAfterDate:");
  late final _sel_systemTimeZone1 = _registerName1("systemTimeZone");
  ffi.Pointer<ObjCObject> _objc_msgSend_162(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_162(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_162Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_162 = __objc_msgSend_162Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_resetSystemTimeZone1 = _registerName1("resetSystemTimeZone");
  late final _sel_defaultTimeZone1 = _registerName1("defaultTimeZone");
  late final _sel_setDefaultTimeZone_1 = _registerName1("setDefaultTimeZone:");
  void _objc_msgSend_163(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_163(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_163Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_163 = __objc_msgSend_163Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_localTimeZone1 = _registerName1("localTimeZone");
  late final _sel_knownTimeZoneNames1 = _registerName1("knownTimeZoneNames");
  late final _sel_abbreviationDictionary1 =
      _registerName1("abbreviationDictionary");
  ffi.Pointer<ObjCObject> _objc_msgSend_164(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_164(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_164Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_164 = __objc_msgSend_164Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setAbbreviationDictionary_1 =
      _registerName1("setAbbreviationDictionary:");
  void _objc_msgSend_165(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_165(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_165Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_165 = __objc_msgSend_165Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_timeZoneDataVersion1 = _registerName1("timeZoneDataVersion");
  late final _sel_secondsFromGMT1 = _registerName1("secondsFromGMT");
  late final _sel_abbreviation1 = _registerName1("abbreviation");
  late final _sel_isDaylightSavingTime1 =
      _registerName1("isDaylightSavingTime");
  late final _sel_daylightSavingTimeOffset1 =
      _registerName1("daylightSavingTimeOffset");
  late final _sel_nextDaylightSavingTimeTransition1 =
      _registerName1("nextDaylightSavingTimeTransition");
  late final _sel_isEqualToTimeZone_1 = _registerName1("isEqualToTimeZone:");
  bool _objc_msgSend_166(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aTimeZone,
  ) {
    return __objc_msgSend_166(
      obj,
      sel,
      aTimeZone,
    );
  }

  late final __objc_msgSend_166Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_166 = __objc_msgSend_166Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _class_NSLocale1 = _getClass1("NSLocale");
  late final _sel_displayNameForKey_value_1 =
      _registerName1("displayNameForKey:value:");
  ffi.Pointer<ObjCObject> _objc_msgSend_167(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSLocaleKey key,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_167(
      obj,
      sel,
      key,
      value,
    );
  }

  late final __objc_msgSend_167Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSLocaleKey,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_167 = __objc_msgSend_167Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSLocaleKey, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithLocaleIdentifier_1 =
      _registerName1("initWithLocaleIdentifier:");
  late final _sel_localeIdentifier1 = _registerName1("localeIdentifier");
  late final _sel_localizedStringForLocaleIdentifier_1 =
      _registerName1("localizedStringForLocaleIdentifier:");
  late final _sel_languageCode1 = _registerName1("languageCode");
  late final _sel_localizedStringForLanguageCode_1 =
      _registerName1("localizedStringForLanguageCode:");
  late final _sel_countryCode1 = _registerName1("countryCode");
  late final _sel_localizedStringForCountryCode_1 =
      _registerName1("localizedStringForCountryCode:");
  late final _sel_scriptCode1 = _registerName1("scriptCode");
  late final _sel_localizedStringForScriptCode_1 =
      _registerName1("localizedStringForScriptCode:");
  late final _sel_variantCode1 = _registerName1("variantCode");
  late final _sel_localizedStringForVariantCode_1 =
      _registerName1("localizedStringForVariantCode:");
  late final _class_NSCharacterSet1 = _getClass1("NSCharacterSet");
  late final _sel_controlCharacterSet1 = _registerName1("controlCharacterSet");
  ffi.Pointer<ObjCObject> _objc_msgSend_168(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_168(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_168Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_168 = __objc_msgSend_168Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_whitespaceCharacterSet1 =
      _registerName1("whitespaceCharacterSet");
  late final _sel_whitespaceAndNewlineCharacterSet1 =
      _registerName1("whitespaceAndNewlineCharacterSet");
  late final _sel_decimalDigitCharacterSet1 =
      _registerName1("decimalDigitCharacterSet");
  late final _sel_letterCharacterSet1 = _registerName1("letterCharacterSet");
  late final _sel_lowercaseLetterCharacterSet1 =
      _registerName1("lowercaseLetterCharacterSet");
  late final _sel_uppercaseLetterCharacterSet1 =
      _registerName1("uppercaseLetterCharacterSet");
  late final _sel_nonBaseCharacterSet1 = _registerName1("nonBaseCharacterSet");
  late final _sel_alphanumericCharacterSet1 =
      _registerName1("alphanumericCharacterSet");
  late final _sel_decomposableCharacterSet1 =
      _registerName1("decomposableCharacterSet");
  late final _sel_illegalCharacterSet1 = _registerName1("illegalCharacterSet");
  late final _sel_punctuationCharacterSet1 =
      _registerName1("punctuationCharacterSet");
  late final _sel_capitalizedLetterCharacterSet1 =
      _registerName1("capitalizedLetterCharacterSet");
  late final _sel_symbolCharacterSet1 = _registerName1("symbolCharacterSet");
  late final _sel_newlineCharacterSet1 = _registerName1("newlineCharacterSet");
  late final _sel_characterSetWithRange_1 =
      _registerName1("characterSetWithRange:");
  ffi.Pointer<ObjCObject> _objc_msgSend_169(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange aRange,
  ) {
    return __objc_msgSend_169(
      obj,
      sel,
      aRange,
    );
  }

  late final __objc_msgSend_169Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_169 = __objc_msgSend_169Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _sel_characterSetWithCharactersInString_1 =
      _registerName1("characterSetWithCharactersInString:");
  ffi.Pointer<ObjCObject> _objc_msgSend_170(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aString,
  ) {
    return __objc_msgSend_170(
      obj,
      sel,
      aString,
    );
  }

  late final __objc_msgSend_170Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_170 = __objc_msgSend_170Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_characterSetWithBitmapRepresentation_1 =
      _registerName1("characterSetWithBitmapRepresentation:");
  ffi.Pointer<ObjCObject> _objc_msgSend_171(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
  ) {
    return __objc_msgSend_171(
      obj,
      sel,
      data,
    );
  }

  late final __objc_msgSend_171Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_171 = __objc_msgSend_171Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_characterSetWithContentsOfFile_1 =
      _registerName1("characterSetWithContentsOfFile:");
  late final _sel_characterIsMember_1 = _registerName1("characterIsMember:");
  bool _objc_msgSend_172(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int aCharacter,
  ) {
    return __objc_msgSend_172(
      obj,
      sel,
      aCharacter,
    );
  }

  late final __objc_msgSend_172Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              unichar)>>('objc_msgSend');
  late final __objc_msgSend_172 = __objc_msgSend_172Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_bitmapRepresentation1 =
      _registerName1("bitmapRepresentation");
  late final _sel_invertedSet1 = _registerName1("invertedSet");
  late final _sel_longCharacterIsMember_1 =
      _registerName1("longCharacterIsMember:");
  bool _objc_msgSend_173(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int theLongChar,
  ) {
    return __objc_msgSend_173(
      obj,
      sel,
      theLongChar,
    );
  }

  late final __objc_msgSend_173Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              UTF32Char)>>('objc_msgSend');
  late final __objc_msgSend_173 = __objc_msgSend_173Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_isSupersetOfSet_1 = _registerName1("isSupersetOfSet:");
  bool _objc_msgSend_174(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> theOtherSet,
  ) {
    return __objc_msgSend_174(
      obj,
      sel,
      theOtherSet,
    );
  }

  late final __objc_msgSend_174Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_174 = __objc_msgSend_174Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_hasMemberInPlane_1 = _registerName1("hasMemberInPlane:");
  bool _objc_msgSend_175(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int thePlane,
  ) {
    return __objc_msgSend_175(
      obj,
      sel,
      thePlane,
    );
  }

  late final __objc_msgSend_175Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Uint8)>>('objc_msgSend');
  late final __objc_msgSend_175 = __objc_msgSend_175Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_URLUserAllowedCharacterSet1 =
      _registerName1("URLUserAllowedCharacterSet");
  late final _sel_URLPasswordAllowedCharacterSet1 =
      _registerName1("URLPasswordAllowedCharacterSet");
  late final _sel_URLHostAllowedCharacterSet1 =
      _registerName1("URLHostAllowedCharacterSet");
  late final _sel_URLPathAllowedCharacterSet1 =
      _registerName1("URLPathAllowedCharacterSet");
  late final _sel_URLQueryAllowedCharacterSet1 =
      _registerName1("URLQueryAllowedCharacterSet");
  late final _sel_URLFragmentAllowedCharacterSet1 =
      _registerName1("URLFragmentAllowedCharacterSet");
  late final _sel_exemplarCharacterSet1 =
      _registerName1("exemplarCharacterSet");
  late final _sel_calendarIdentifier1 = _registerName1("calendarIdentifier");
  late final _sel_localizedStringForCalendarIdentifier_1 =
      _registerName1("localizedStringForCalendarIdentifier:");
  late final _sel_collationIdentifier1 = _registerName1("collationIdentifier");
  late final _sel_localizedStringForCollationIdentifier_1 =
      _registerName1("localizedStringForCollationIdentifier:");
  late final _sel_usesMetricSystem1 = _registerName1("usesMetricSystem");
  late final _sel_decimalSeparator1 = _registerName1("decimalSeparator");
  late final _sel_groupingSeparator1 = _registerName1("groupingSeparator");
  late final _sel_currencySymbol1 = _registerName1("currencySymbol");
  late final _sel_currencyCode1 = _registerName1("currencyCode");
  late final _sel_localizedStringForCurrencyCode_1 =
      _registerName1("localizedStringForCurrencyCode:");
  late final _sel_collatorIdentifier1 = _registerName1("collatorIdentifier");
  late final _sel_localizedStringForCollatorIdentifier_1 =
      _registerName1("localizedStringForCollatorIdentifier:");
  late final _sel_quotationBeginDelimiter1 =
      _registerName1("quotationBeginDelimiter");
  late final _sel_quotationEndDelimiter1 =
      _registerName1("quotationEndDelimiter");
  late final _sel_alternateQuotationBeginDelimiter1 =
      _registerName1("alternateQuotationBeginDelimiter");
  late final _sel_alternateQuotationEndDelimiter1 =
      _registerName1("alternateQuotationEndDelimiter");
  late final _sel_autoupdatingCurrentLocale1 =
      _registerName1("autoupdatingCurrentLocale");
  ffi.Pointer<ObjCObject> _objc_msgSend_176(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_176(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_176Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_176 = __objc_msgSend_176Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_currentLocale1 = _registerName1("currentLocale");
  late final _sel_systemLocale1 = _registerName1("systemLocale");
  late final _sel_localeWithLocaleIdentifier_1 =
      _registerName1("localeWithLocaleIdentifier:");
  late final _sel_availableLocaleIdentifiers1 =
      _registerName1("availableLocaleIdentifiers");
  late final _sel_ISOLanguageCodes1 = _registerName1("ISOLanguageCodes");
  late final _sel_ISOCountryCodes1 = _registerName1("ISOCountryCodes");
  late final _sel_ISOCurrencyCodes1 = _registerName1("ISOCurrencyCodes");
  late final _sel_commonISOCurrencyCodes1 =
      _registerName1("commonISOCurrencyCodes");
  late final _sel_preferredLanguages1 = _registerName1("preferredLanguages");
  late final _sel_componentsFromLocaleIdentifier_1 =
      _registerName1("componentsFromLocaleIdentifier:");
  late final _sel_localeIdentifierFromComponents_1 =
      _registerName1("localeIdentifierFromComponents:");
  ffi.Pointer<ObjCObject> _objc_msgSend_177(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> dict,
  ) {
    return __objc_msgSend_177(
      obj,
      sel,
      dict,
    );
  }

  late final __objc_msgSend_177Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_177 = __objc_msgSend_177Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_canonicalLocaleIdentifierFromString_1 =
      _registerName1("canonicalLocaleIdentifierFromString:");
  late final _sel_canonicalLanguageIdentifierFromString_1 =
      _registerName1("canonicalLanguageIdentifierFromString:");
  late final _sel_localeIdentifierFromWindowsLocaleCode_1 =
      _registerName1("localeIdentifierFromWindowsLocaleCode:");
  ffi.Pointer<ObjCObject> _objc_msgSend_178(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int lcid,
  ) {
    return __objc_msgSend_178(
      obj,
      sel,
      lcid,
    );
  }

  late final __objc_msgSend_178Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Uint32)>>('objc_msgSend');
  late final __objc_msgSend_178 = __objc_msgSend_178Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_windowsLocaleCodeFromLocaleIdentifier_1 =
      _registerName1("windowsLocaleCodeFromLocaleIdentifier:");
  int _objc_msgSend_179(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> localeIdentifier,
  ) {
    return __objc_msgSend_179(
      obj,
      sel,
      localeIdentifier,
    );
  }

  late final __objc_msgSend_179Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Uint32 Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_179 = __objc_msgSend_179Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_characterDirectionForLanguage_1 =
      _registerName1("characterDirectionForLanguage:");
  int _objc_msgSend_180(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> isoLangCode,
  ) {
    return __objc_msgSend_180(
      obj,
      sel,
      isoLangCode,
    );
  }

  late final __objc_msgSend_180Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_180 = __objc_msgSend_180Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_lineDirectionForLanguage_1 =
      _registerName1("lineDirectionForLanguage:");
  late final _sel_localizedName_locale_1 =
      _registerName1("localizedName:locale:");
  ffi.Pointer<ObjCObject> _objc_msgSend_181(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int style,
    ffi.Pointer<ObjCObject> locale,
  ) {
    return __objc_msgSend_181(
      obj,
      sel,
      style,
      locale,
    );
  }

  late final __objc_msgSend_181Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_181 = __objc_msgSend_181Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<ObjCObject>)>();

  late final _sel_timeZoneWithName_1 = _registerName1("timeZoneWithName:");
  late final _sel_timeZoneWithName_data_1 =
      _registerName1("timeZoneWithName:data:");
  instancetype _objc_msgSend_182(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> tzName,
    ffi.Pointer<ObjCObject> aData,
  ) {
    return __objc_msgSend_182(
      obj,
      sel,
      tzName,
      aData,
    );
  }

  late final __objc_msgSend_182Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_182 = __objc_msgSend_182Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithName_1 = _registerName1("initWithName:");
  late final _sel_initWithName_data_1 = _registerName1("initWithName:data:");
  late final _sel_timeZoneForSecondsFromGMT_1 =
      _registerName1("timeZoneForSecondsFromGMT:");
  instancetype _objc_msgSend_183(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int seconds,
  ) {
    return __objc_msgSend_183(
      obj,
      sel,
      seconds,
    );
  }

  late final __objc_msgSend_183Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_183 = __objc_msgSend_183Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_timeZoneWithAbbreviation_1 =
      _registerName1("timeZoneWithAbbreviation:");
  late final _sel_dateWithYear_month_day_hour_minute_second_timeZone_1 =
      _registerName1("dateWithYear:month:day:hour:minute:second:timeZone:");
  ffi.Pointer<ObjCObject> _objc_msgSend_184(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int year,
    int month,
    int day,
    int hour,
    int minute,
    int second,
    ffi.Pointer<ObjCObject> aTimeZone,
  ) {
    return __objc_msgSend_184(
      obj,
      sel,
      year,
      month,
      day,
      hour,
      minute,
      second,
      aTimeZone,
    );
  }

  late final __objc_msgSend_184Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSInteger,
              NSUInteger,
              NSUInteger,
              NSUInteger,
              NSUInteger,
              NSUInteger,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_184 = __objc_msgSend_184Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          int,
          int,
          int,
          int,
          int,
          int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_dateByAddingYears_months_days_hours_minutes_seconds_1 =
      _registerName1("dateByAddingYears:months:days:hours:minutes:seconds:");
  ffi.Pointer<ObjCObject> _objc_msgSend_185(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int year,
    int month,
    int day,
    int hour,
    int minute,
    int second,
  ) {
    return __objc_msgSend_185(
      obj,
      sel,
      year,
      month,
      day,
      hour,
      minute,
      second,
    );
  }

  late final __objc_msgSend_185Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSInteger,
              NSInteger,
              NSInteger,
              NSInteger,
              NSInteger,
              NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_185 = __objc_msgSend_185Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, int, int, int, int, int)>();

  late final _sel_dayOfCommonEra1 = _registerName1("dayOfCommonEra");
  late final _sel_dayOfMonth1 = _registerName1("dayOfMonth");
  late final _sel_dayOfWeek1 = _registerName1("dayOfWeek");
  late final _sel_dayOfYear1 = _registerName1("dayOfYear");
  late final _sel_hourOfDay1 = _registerName1("hourOfDay");
  late final _sel_minuteOfHour1 = _registerName1("minuteOfHour");
  late final _sel_monthOfYear1 = _registerName1("monthOfYear");
  late final _sel_secondOfMinute1 = _registerName1("secondOfMinute");
  late final _sel_yearOfCommonEra1 = _registerName1("yearOfCommonEra");
  late final _sel_calendarFormat1 = _registerName1("calendarFormat");
  late final _sel_descriptionWithCalendarFormat_locale_1 =
      _registerName1("descriptionWithCalendarFormat:locale:");
  late final _sel_descriptionWithCalendarFormat_1 =
      _registerName1("descriptionWithCalendarFormat:");
  late final _sel_timeZone1 = _registerName1("timeZone");
  late final _sel_initWithString_calendarFormat_locale_1 =
      _registerName1("initWithString:calendarFormat:locale:");
  late final _sel_initWithString_calendarFormat_1 =
      _registerName1("initWithString:calendarFormat:");
  late final _sel_initWithYear_month_day_hour_minute_second_timeZone_1 =
      _registerName1("initWithYear:month:day:hour:minute:second:timeZone:");
  late final _sel_setCalendarFormat_1 = _registerName1("setCalendarFormat:");
  void _objc_msgSend_186(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> format,
  ) {
    return __objc_msgSend_186(
      obj,
      sel,
      format,
    );
  }

  late final __objc_msgSend_186Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_186 = __objc_msgSend_186Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_setTimeZone_1 = _registerName1("setTimeZone:");
  void _objc_msgSend_187(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aTimeZone,
  ) {
    return __objc_msgSend_187(
      obj,
      sel,
      aTimeZone,
    );
  }

  late final __objc_msgSend_187Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_187 = __objc_msgSend_187Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_years_months_days_hours_minutes_seconds_sinceDate_1 =
      _registerName1("years:months:days:hours:minutes:seconds:sinceDate:");
  void _objc_msgSend_188(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSInteger> yp,
    ffi.Pointer<NSInteger> mop,
    ffi.Pointer<NSInteger> dp,
    ffi.Pointer<NSInteger> hp,
    ffi.Pointer<NSInteger> mip,
    ffi.Pointer<NSInteger> sp,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_188(
      obj,
      sel,
      yp,
      mop,
      dp,
      hp,
      mip,
      sp,
      date,
    );
  }

  late final __objc_msgSend_188Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSInteger>,
              ffi.Pointer<NSInteger>,
              ffi.Pointer<NSInteger>,
              ffi.Pointer<NSInteger>,
              ffi.Pointer<NSInteger>,
              ffi.Pointer<NSInteger>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_188 = __objc_msgSend_188Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSInteger>,
          ffi.Pointer<NSInteger>,
          ffi.Pointer<NSInteger>,
          ffi.Pointer<NSInteger>,
          ffi.Pointer<NSInteger>,
          ffi.Pointer<NSInteger>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_dateWithCalendarFormat_timeZone_1 =
      _registerName1("dateWithCalendarFormat:timeZone:");
  ffi.Pointer<ObjCObject> _objc_msgSend_189(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> format,
    ffi.Pointer<ObjCObject> aTimeZone,
  ) {
    return __objc_msgSend_189(
      obj,
      sel,
      format,
      aTimeZone,
    );
  }

  late final __objc_msgSend_189Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_189 = __objc_msgSend_189Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_descriptionWithCalendarFormat_timeZone_locale_1 =
      _registerName1("descriptionWithCalendarFormat:timeZone:locale:");
  ffi.Pointer<ObjCObject> _objc_msgSend_190(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> format,
    ffi.Pointer<ObjCObject> aTimeZone,
    ffi.Pointer<ObjCObject> locale,
  ) {
    return __objc_msgSend_190(
      obj,
      sel,
      format,
      aTimeZone,
      locale,
    );
  }

  late final __objc_msgSend_190Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_190 = __objc_msgSend_190Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_fileModificationDate1 =
      _registerName1("fileModificationDate");
  late final _sel_fileType1 = _registerName1("fileType");
  late final _sel_filePosixPermissions1 =
      _registerName1("filePosixPermissions");
  late final _sel_fileOwnerAccountName1 =
      _registerName1("fileOwnerAccountName");
  late final _sel_fileGroupOwnerAccountName1 =
      _registerName1("fileGroupOwnerAccountName");
  late final _sel_fileSystemNumber1 = _registerName1("fileSystemNumber");
  late final _sel_fileSystemFileNumber1 =
      _registerName1("fileSystemFileNumber");
  late final _sel_fileExtensionHidden1 = _registerName1("fileExtensionHidden");
  late final _sel_fileHFSCreatorCode1 = _registerName1("fileHFSCreatorCode");
  int _objc_msgSend_191(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_191(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_191Ptr = _lookup<
      ffi.NativeFunction<
          OSType Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_191 = __objc_msgSend_191Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_fileHFSTypeCode1 = _registerName1("fileHFSTypeCode");
  late final _sel_fileIsImmutable1 = _registerName1("fileIsImmutable");
  late final _sel_fileIsAppendOnly1 = _registerName1("fileIsAppendOnly");
  late final _sel_fileCreationDate1 = _registerName1("fileCreationDate");
  late final _sel_fileOwnerAccountID1 = _registerName1("fileOwnerAccountID");
  ffi.Pointer<ObjCObject> _objc_msgSend_192(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_192(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_192Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_192 = __objc_msgSend_192Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_fileGroupOwnerAccountID1 =
      _registerName1("fileGroupOwnerAccountID");
  late final _sel_predicateWithBlock_1 = _registerName1("predicateWithBlock:");
  ffi.Pointer<ObjCObject> _objc_msgSend_193(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_193(
      obj,
      sel,
      block,
    );
  }

  late final __objc_msgSend_193Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_193 = __objc_msgSend_193Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_predicateFormat1 = _registerName1("predicateFormat");
  late final _sel_predicateWithSubstitutionVariables_1 =
      _registerName1("predicateWithSubstitutionVariables:");
  late final _sel_evaluateWithObject_1 = _registerName1("evaluateWithObject:");
  late final _sel_evaluateWithObject_substitutionVariables_1 =
      _registerName1("evaluateWithObject:substitutionVariables:");
  bool _objc_msgSend_194(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> object,
    ffi.Pointer<ObjCObject> bindings,
  ) {
    return __objc_msgSend_194(
      obj,
      sel,
      object,
      bindings,
    );
  }

  late final __objc_msgSend_194Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_194 = __objc_msgSend_194Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_allowEvaluation1 = _registerName1("allowEvaluation");
  late final _sel_filteredArrayUsingPredicate_1 =
      _registerName1("filteredArrayUsingPredicate:");
  ffi.Pointer<ObjCObject> _objc_msgSend_195(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> predicate,
  ) {
    return __objc_msgSend_195(
      obj,
      sel,
      predicate,
    );
  }

  late final __objc_msgSend_195Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_195 = __objc_msgSend_195Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithChar_1 = _registerName1("initWithChar:");
  ffi.Pointer<ObjCObject> _objc_msgSend_196(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_196(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_196Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Char)>>('objc_msgSend');
  late final __objc_msgSend_196 = __objc_msgSend_196Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithUnsignedChar_1 =
      _registerName1("initWithUnsignedChar:");
  ffi.Pointer<ObjCObject> _objc_msgSend_197(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_197(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_197Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.UnsignedChar)>>('objc_msgSend');
  late final __objc_msgSend_197 = __objc_msgSend_197Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithShort_1 = _registerName1("initWithShort:");
  ffi.Pointer<ObjCObject> _objc_msgSend_198(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_198(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_198Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Short)>>('objc_msgSend');
  late final __objc_msgSend_198 = __objc_msgSend_198Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithUnsignedShort_1 =
      _registerName1("initWithUnsignedShort:");
  ffi.Pointer<ObjCObject> _objc_msgSend_199(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_199(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_199Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.UnsignedShort)>>('objc_msgSend');
  late final __objc_msgSend_199 = __objc_msgSend_199Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithInt_1 = _registerName1("initWithInt:");
  ffi.Pointer<ObjCObject> _objc_msgSend_200(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_200(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_200Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Int)>>('objc_msgSend');
  late final __objc_msgSend_200 = __objc_msgSend_200Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithUnsignedInt_1 =
      _registerName1("initWithUnsignedInt:");
  ffi.Pointer<ObjCObject> _objc_msgSend_201(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_201(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_201Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.UnsignedInt)>>('objc_msgSend');
  late final __objc_msgSend_201 = __objc_msgSend_201Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithLong_1 = _registerName1("initWithLong:");
  ffi.Pointer<ObjCObject> _objc_msgSend_202(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_202(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_202Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Long)>>('objc_msgSend');
  late final __objc_msgSend_202 = __objc_msgSend_202Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithUnsignedLong_1 =
      _registerName1("initWithUnsignedLong:");
  ffi.Pointer<ObjCObject> _objc_msgSend_203(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_203(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_203Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.UnsignedLong)>>('objc_msgSend');
  late final __objc_msgSend_203 = __objc_msgSend_203Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithLongLong_1 = _registerName1("initWithLongLong:");
  ffi.Pointer<ObjCObject> _objc_msgSend_204(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_204(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_204Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.LongLong)>>('objc_msgSend');
  late final __objc_msgSend_204 = __objc_msgSend_204Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithUnsignedLongLong_1 =
      _registerName1("initWithUnsignedLongLong:");
  ffi.Pointer<ObjCObject> _objc_msgSend_205(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_205(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_205Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.UnsignedLongLong)>>('objc_msgSend');
  late final __objc_msgSend_205 = __objc_msgSend_205Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithFloat_1 = _registerName1("initWithFloat:");
  ffi.Pointer<ObjCObject> _objc_msgSend_206(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double value,
  ) {
    return __objc_msgSend_206(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_206Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Float)>>('objc_msgSend');
  late final __objc_msgSend_206 = __objc_msgSend_206Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double)>();

  late final _sel_initWithDouble_1 = _registerName1("initWithDouble:");
  ffi.Pointer<ObjCObject> _objc_msgSend_207(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double value,
  ) {
    return __objc_msgSend_207(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_207Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Double)>>('objc_msgSend');
  late final __objc_msgSend_207 = __objc_msgSend_207Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double)>();

  late final _sel_initWithBool_1 = _registerName1("initWithBool:");
  ffi.Pointer<ObjCObject> _objc_msgSend_208(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool value,
  ) {
    return __objc_msgSend_208(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_208Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_208 = __objc_msgSend_208Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool)>();

  late final _sel_initWithInteger_1 = _registerName1("initWithInteger:");
  late final _sel_initWithUnsignedInteger_1 =
      _registerName1("initWithUnsignedInteger:");
  late final _sel_charValue1 = _registerName1("charValue");
  int _objc_msgSend_209(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_209(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_209Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Char Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_209 = __objc_msgSend_209Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_unsignedCharValue1 = _registerName1("unsignedCharValue");
  int _objc_msgSend_210(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_210(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_210Ptr = _lookup<
      ffi.NativeFunction<
          ffi.UnsignedChar Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_210 = __objc_msgSend_210Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_shortValue1 = _registerName1("shortValue");
  int _objc_msgSend_211(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_211(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_211Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Short Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_211 = __objc_msgSend_211Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_unsignedShortValue1 = _registerName1("unsignedShortValue");
  int _objc_msgSend_212(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_212(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_212Ptr = _lookup<
      ffi.NativeFunction<
          ffi.UnsignedShort Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_212 = __objc_msgSend_212Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_intValue1 = _registerName1("intValue");
  int _objc_msgSend_213(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_213(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_213Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_213 = __objc_msgSend_213Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_unsignedIntValue1 = _registerName1("unsignedIntValue");
  late final _sel_longValue1 = _registerName1("longValue");
  late final _sel_unsignedLongValue1 = _registerName1("unsignedLongValue");
  late final _sel_longLongValue1 = _registerName1("longLongValue");
  int _objc_msgSend_214(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_214(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_214Ptr = _lookup<
      ffi.NativeFunction<
          ffi.LongLong Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_214 = __objc_msgSend_214Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_unsignedLongLongValue1 =
      _registerName1("unsignedLongLongValue");
  late final _sel_floatValue1 = _registerName1("floatValue");
  double _objc_msgSend_215(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_215(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_215Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Float Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_215 = __objc_msgSend_215Ptr.asFunction<
      double Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_doubleValue1 = _registerName1("doubleValue");
  late final _sel_boolValue1 = _registerName1("boolValue");
  late final _sel_integerValue1 = _registerName1("integerValue");
  late final _sel_unsignedIntegerValue1 =
      _registerName1("unsignedIntegerValue");
  late final _sel_stringValue1 = _registerName1("stringValue");
  int _objc_msgSend_216(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> otherNumber,
  ) {
    return __objc_msgSend_216(
      obj,
      sel,
      otherNumber,
    );
  }

  late final __objc_msgSend_216Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_216 = __objc_msgSend_216Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_isEqualToNumber_1 = _registerName1("isEqualToNumber:");
  bool _objc_msgSend_217(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> number,
  ) {
    return __objc_msgSend_217(
      obj,
      sel,
      number,
    );
  }

  late final __objc_msgSend_217Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_217 = __objc_msgSend_217Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_numberWithChar_1 = _registerName1("numberWithChar:");
  late final _sel_numberWithUnsignedChar_1 =
      _registerName1("numberWithUnsignedChar:");
  late final _sel_numberWithShort_1 = _registerName1("numberWithShort:");
  late final _sel_numberWithUnsignedShort_1 =
      _registerName1("numberWithUnsignedShort:");
  late final _sel_numberWithInt_1 = _registerName1("numberWithInt:");
  late final _sel_numberWithUnsignedInt_1 =
      _registerName1("numberWithUnsignedInt:");
  late final _sel_numberWithLong_1 = _registerName1("numberWithLong:");
  late final _sel_numberWithUnsignedLong_1 =
      _registerName1("numberWithUnsignedLong:");
  late final _sel_numberWithLongLong_1 = _registerName1("numberWithLongLong:");
  late final _sel_numberWithUnsignedLongLong_1 =
      _registerName1("numberWithUnsignedLongLong:");
  late final _sel_numberWithFloat_1 = _registerName1("numberWithFloat:");
  late final _sel_numberWithDouble_1 = _registerName1("numberWithDouble:");
  late final _sel_numberWithBool_1 = _registerName1("numberWithBool:");
  late final _sel_numberWithInteger_1 = _registerName1("numberWithInteger:");
  late final _sel_numberWithUnsignedInteger_1 =
      _registerName1("numberWithUnsignedInteger:");
  late final _sel_port1 = _registerName1("port");
  late final _sel_user1 = _registerName1("user");
  late final _sel_password1 = _registerName1("password");
  late final _sel_path1 = _registerName1("path");
  late final _sel_fragment1 = _registerName1("fragment");
  late final _sel_parameterString1 = _registerName1("parameterString");
  late final _sel_query1 = _registerName1("query");
  late final _sel_relativePath1 = _registerName1("relativePath");
  late final _sel_hasDirectoryPath1 = _registerName1("hasDirectoryPath");
  late final _sel_getFileSystemRepresentation_maxLength_1 =
      _registerName1("getFileSystemRepresentation:maxLength:");
  bool _objc_msgSend_218(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> buffer,
    int maxBufferLength,
  ) {
    return __objc_msgSend_218(
      obj,
      sel,
      buffer,
      maxBufferLength,
    );
  }

  late final __objc_msgSend_218Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_218 = __objc_msgSend_218Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>, int)>();

  late final _sel_fileSystemRepresentation1 =
      _registerName1("fileSystemRepresentation");
  late final _sel_isFileURL1 = _registerName1("isFileURL");
  late final _sel_standardizedURL1 = _registerName1("standardizedURL");
  late final _sel_checkResourceIsReachableAndReturnError_1 =
      _registerName1("checkResourceIsReachableAndReturnError:");
  bool _objc_msgSend_219(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_219(
      obj,
      sel,
      error,
    );
  }

  late final __objc_msgSend_219Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_219 = __objc_msgSend_219Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_isFileReferenceURL1 = _registerName1("isFileReferenceURL");
  late final _sel_fileReferenceURL1 = _registerName1("fileReferenceURL");
  late final _sel_filePathURL1 = _registerName1("filePathURL");
  late final _sel_getResourceValue_forKey_error_1 =
      _registerName1("getResourceValue:forKey:error:");
  bool _objc_msgSend_220(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> value,
    NSURLResourceKey key,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_220(
      obj,
      sel,
      value,
      key,
      error,
    );
  }

  late final __objc_msgSend_220Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              NSURLResourceKey,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_220 = __objc_msgSend_220Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          NSURLResourceKey,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_getPromisedItemResourceValue_forKey_error_1 =
      _registerName1("getPromisedItemResourceValue:forKey:error:");
  late final _sel_promisedItemResourceValuesForKeys_error_1 =
      _registerName1("promisedItemResourceValuesForKeys:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_221(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> keys,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_221(
      obj,
      sel,
      keys,
      error,
    );
  }

  late final __objc_msgSend_221Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_221 = __objc_msgSend_221Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_checkPromisedItemIsReachableAndReturnError_1 =
      _registerName1("checkPromisedItemIsReachableAndReturnError:");
  late final _sel_fileURLWithPathComponents_1 =
      _registerName1("fileURLWithPathComponents:");
  ffi.Pointer<ObjCObject> _objc_msgSend_222(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> components,
  ) {
    return __objc_msgSend_222(
      obj,
      sel,
      components,
    );
  }

  late final __objc_msgSend_222Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_222 = __objc_msgSend_222Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_pathComponents1 = _registerName1("pathComponents");
  late final _sel_lastPathComponent1 = _registerName1("lastPathComponent");
  late final _sel_pathExtension1 = _registerName1("pathExtension");
  late final _sel_URLByAppendingPathComponent_1 =
      _registerName1("URLByAppendingPathComponent:");
  late final _sel_URLByAppendingPathComponent_isDirectory_1 =
      _registerName1("URLByAppendingPathComponent:isDirectory:");
  late final _sel_URLByDeletingLastPathComponent1 =
      _registerName1("URLByDeletingLastPathComponent");
  late final _sel_URLByAppendingPathExtension_1 =
      _registerName1("URLByAppendingPathExtension:");
  late final _sel_URLByDeletingPathExtension1 =
      _registerName1("URLByDeletingPathExtension");
  late final _sel_URLByStandardizingPath1 =
      _registerName1("URLByStandardizingPath");
  late final _sel_URLByResolvingSymlinksInPath1 =
      _registerName1("URLByResolvingSymlinksInPath");
  late final _sel_resourceDataUsingCache_1 =
      _registerName1("resourceDataUsingCache:");
  ffi.Pointer<ObjCObject> _objc_msgSend_223(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool shouldUseCache,
  ) {
    return __objc_msgSend_223(
      obj,
      sel,
      shouldUseCache,
    );
  }

  late final __objc_msgSend_223Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_223 = __objc_msgSend_223Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool)>();

  late final _sel_loadResourceDataNotifyingClient_usingCache_1 =
      _registerName1("loadResourceDataNotifyingClient:usingCache:");
  void _objc_msgSend_224(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> client,
    bool shouldUseCache,
  ) {
    return __objc_msgSend_224(
      obj,
      sel,
      client,
      shouldUseCache,
    );
  }

  late final __objc_msgSend_224Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_224 = __objc_msgSend_224Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_propertyForKey_1 = _registerName1("propertyForKey:");
  late final _sel_setResourceData_1 = _registerName1("setResourceData:");
  late final _sel_setProperty_forKey_1 = _registerName1("setProperty:forKey:");
  bool _objc_msgSend_225(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> property,
    ffi.Pointer<ObjCObject> propertyKey,
  ) {
    return __objc_msgSend_225(
      obj,
      sel,
      property,
      propertyKey,
    );
  }

  late final __objc_msgSend_225Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_225 = __objc_msgSend_225Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _class_NSURLHandle1 = _getClass1("NSURLHandle");
  late final _sel_registerURLHandleClass_1 =
      _registerName1("registerURLHandleClass:");
  late final _sel_URLHandleClassForURL_1 =
      _registerName1("URLHandleClassForURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_226(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anURL,
  ) {
    return __objc_msgSend_226(
      obj,
      sel,
      anURL,
    );
  }

  late final __objc_msgSend_226Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_226 = __objc_msgSend_226Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_status1 = _registerName1("status");
  int _objc_msgSend_227(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_227(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_227Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_227 = __objc_msgSend_227Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_failureReason1 = _registerName1("failureReason");
  late final _sel_addClient_1 = _registerName1("addClient:");
  late final _sel_removeClient_1 = _registerName1("removeClient:");
  late final _sel_loadInBackground1 = _registerName1("loadInBackground");
  late final _sel_cancelLoadInBackground1 =
      _registerName1("cancelLoadInBackground");
  late final _sel_resourceData1 = _registerName1("resourceData");
  late final _sel_availableResourceData1 =
      _registerName1("availableResourceData");
  late final _sel_expectedResourceDataSize1 =
      _registerName1("expectedResourceDataSize");
  late final _sel_flushCachedData1 = _registerName1("flushCachedData");
  late final _sel_backgroundLoadDidFailWithReason_1 =
      _registerName1("backgroundLoadDidFailWithReason:");
  late final _sel_didLoadBytes_loadComplete_1 =
      _registerName1("didLoadBytes:loadComplete:");
  void _objc_msgSend_228(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> newBytes,
    bool yorn,
  ) {
    return __objc_msgSend_228(
      obj,
      sel,
      newBytes,
      yorn,
    );
  }

  late final __objc_msgSend_228Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_228 = __objc_msgSend_228Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_canInitWithURL_1 = _registerName1("canInitWithURL:");
  bool _objc_msgSend_229(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anURL,
  ) {
    return __objc_msgSend_229(
      obj,
      sel,
      anURL,
    );
  }

  late final __objc_msgSend_229Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_229 = __objc_msgSend_229Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_cachedHandleForURL_1 = _registerName1("cachedHandleForURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_230(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anURL,
  ) {
    return __objc_msgSend_230(
      obj,
      sel,
      anURL,
    );
  }

  late final __objc_msgSend_230Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_230 = __objc_msgSend_230Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithURL_cached_1 = _registerName1("initWithURL:cached:");
  ffi.Pointer<ObjCObject> _objc_msgSend_231(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anURL,
    bool willCache,
  ) {
    return __objc_msgSend_231(
      obj,
      sel,
      anURL,
      willCache,
    );
  }

  late final __objc_msgSend_231Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_231 = __objc_msgSend_231Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_propertyForKeyIfAvailable_1 =
      _registerName1("propertyForKeyIfAvailable:");
  late final _sel_writeProperty_forKey_1 =
      _registerName1("writeProperty:forKey:");
  late final _sel_writeData_1 = _registerName1("writeData:");
  late final _sel_loadInForeground1 = _registerName1("loadInForeground");
  late final _sel_beginLoadInBackground1 =
      _registerName1("beginLoadInBackground");
  late final _sel_endLoadInBackground1 = _registerName1("endLoadInBackground");
  late final _sel_URLHandleUsingCache_1 =
      _registerName1("URLHandleUsingCache:");
  ffi.Pointer<ObjCObject> _objc_msgSend_232(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool shouldUseCache,
  ) {
    return __objc_msgSend_232(
      obj,
      sel,
      shouldUseCache,
    );
  }

  late final __objc_msgSend_232Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_232 = __objc_msgSend_232Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool)>();

  late final _sel_writeToFile_options_error_1 =
      _registerName1("writeToFile:options:error:");
  bool _objc_msgSend_233(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    int writeOptionsMask,
    ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr,
  ) {
    return __objc_msgSend_233(
      obj,
      sel,
      path,
      writeOptionsMask,
      errorPtr,
    );
  }

  late final __objc_msgSend_233Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_233 = __objc_msgSend_233Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_writeToURL_options_error_1 =
      _registerName1("writeToURL:options:error:");
  bool _objc_msgSend_234(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    int writeOptionsMask,
    ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr,
  ) {
    return __objc_msgSend_234(
      obj,
      sel,
      url,
      writeOptionsMask,
      errorPtr,
    );
  }

  late final __objc_msgSend_234Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_234 = __objc_msgSend_234Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_rangeOfData_options_range_1 =
      _registerName1("rangeOfData:options:range:");
  NSRange _objc_msgSend_235(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> dataToFind,
    int mask,
    NSRange searchRange,
  ) {
    return __objc_msgSend_235(
      obj,
      sel,
      dataToFind,
      mask,
      searchRange,
    );
  }

  late final __objc_msgSend_235Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_235 = __objc_msgSend_235Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, NSRange)>();

  late final _sel_enumerateByteRangesUsingBlock_1 =
      _registerName1("enumerateByteRangesUsingBlock:");
  void _objc_msgSend_236(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_236(
      obj,
      sel,
      block,
    );
  }

  late final __objc_msgSend_236Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_236 = __objc_msgSend_236Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_dataWithBytes_length_1 =
      _registerName1("dataWithBytes:length:");
  instancetype _objc_msgSend_237(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> bytes,
    int length,
  ) {
    return __objc_msgSend_237(
      obj,
      sel,
      bytes,
      length,
    );
  }

  late final __objc_msgSend_237Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_237 = __objc_msgSend_237Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>, int)>();

  late final _sel_dataWithBytesNoCopy_length_1 =
      _registerName1("dataWithBytesNoCopy:length:");
  late final _sel_dataWithBytesNoCopy_length_freeWhenDone_1 =
      _registerName1("dataWithBytesNoCopy:length:freeWhenDone:");
  instancetype _objc_msgSend_238(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> bytes,
    int length,
    bool b,
  ) {
    return __objc_msgSend_238(
      obj,
      sel,
      bytes,
      length,
      b,
    );
  }

  late final __objc_msgSend_238Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>, NSUInteger, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_238 = __objc_msgSend_238Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>, int, bool)>();

  late final _sel_dataWithContentsOfFile_options_error_1 =
      _registerName1("dataWithContentsOfFile:options:error:");
  instancetype _objc_msgSend_239(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    int readOptionsMask,
    ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr,
  ) {
    return __objc_msgSend_239(
      obj,
      sel,
      path,
      readOptionsMask,
      errorPtr,
    );
  }

  late final __objc_msgSend_239Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_239 = __objc_msgSend_239Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_dataWithContentsOfURL_options_error_1 =
      _registerName1("dataWithContentsOfURL:options:error:");
  instancetype _objc_msgSend_240(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    int readOptionsMask,
    ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr,
  ) {
    return __objc_msgSend_240(
      obj,
      sel,
      url,
      readOptionsMask,
      errorPtr,
    );
  }

  late final __objc_msgSend_240Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_240 = __objc_msgSend_240Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_dataWithContentsOfFile_1 =
      _registerName1("dataWithContentsOfFile:");
  late final _sel_dataWithContentsOfURL_1 =
      _registerName1("dataWithContentsOfURL:");
  late final _sel_initWithBytes_length_1 =
      _registerName1("initWithBytes:length:");
  late final _sel_initWithBytesNoCopy_length_1 =
      _registerName1("initWithBytesNoCopy:length:");
  late final _sel_initWithBytesNoCopy_length_freeWhenDone_1 =
      _registerName1("initWithBytesNoCopy:length:freeWhenDone:");
  late final _sel_initWithBytesNoCopy_length_deallocator_1 =
      _registerName1("initWithBytesNoCopy:length:deallocator:");
  instancetype _objc_msgSend_241(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> bytes,
    int length,
    ffi.Pointer<_ObjCBlock> deallocator,
  ) {
    return __objc_msgSend_241(
      obj,
      sel,
      bytes,
      length,
      deallocator,
    );
  }

  late final __objc_msgSend_241Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>,
              NSUInteger,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_241 = __objc_msgSend_241Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_initWithContentsOfFile_options_error_1 =
      _registerName1("initWithContentsOfFile:options:error:");
  late final _sel_initWithContentsOfURL_options_error_1 =
      _registerName1("initWithContentsOfURL:options:error:");
  late final _sel_initWithData_1 = _registerName1("initWithData:");
  instancetype _objc_msgSend_242(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
  ) {
    return __objc_msgSend_242(
      obj,
      sel,
      data,
    );
  }

  late final __objc_msgSend_242Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_242 = __objc_msgSend_242Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_dataWithData_1 = _registerName1("dataWithData:");
  late final _sel_initWithBase64EncodedString_options_1 =
      _registerName1("initWithBase64EncodedString:options:");
  instancetype _objc_msgSend_243(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> base64String,
    int options,
  ) {
    return __objc_msgSend_243(
      obj,
      sel,
      base64String,
      options,
    );
  }

  late final __objc_msgSend_243Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_243 = __objc_msgSend_243Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_base64EncodedStringWithOptions_1 =
      _registerName1("base64EncodedStringWithOptions:");
  ffi.Pointer<ObjCObject> _objc_msgSend_244(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
  ) {
    return __objc_msgSend_244(
      obj,
      sel,
      options,
    );
  }

  late final __objc_msgSend_244Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_244 = __objc_msgSend_244Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithBase64EncodedData_options_1 =
      _registerName1("initWithBase64EncodedData:options:");
  instancetype _objc_msgSend_245(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> base64Data,
    int options,
  ) {
    return __objc_msgSend_245(
      obj,
      sel,
      base64Data,
      options,
    );
  }

  late final __objc_msgSend_245Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_245 = __objc_msgSend_245Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_base64EncodedDataWithOptions_1 =
      _registerName1("base64EncodedDataWithOptions:");
  ffi.Pointer<ObjCObject> _objc_msgSend_246(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
  ) {
    return __objc_msgSend_246(
      obj,
      sel,
      options,
    );
  }

  late final __objc_msgSend_246Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_246 = __objc_msgSend_246Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_decompressedDataUsingAlgorithm_error_1 =
      _registerName1("decompressedDataUsingAlgorithm:error:");
  instancetype _objc_msgSend_247(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int algorithm,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_247(
      obj,
      sel,
      algorithm,
      error,
    );
  }

  late final __objc_msgSend_247Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_247 = __objc_msgSend_247Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_compressedDataUsingAlgorithm_error_1 =
      _registerName1("compressedDataUsingAlgorithm:error:");
  late final _sel_getBytes_1 = _registerName1("getBytes:");
  late final _sel_dataWithContentsOfMappedFile_1 =
      _registerName1("dataWithContentsOfMappedFile:");
  late final _sel_initWithContentsOfMappedFile_1 =
      _registerName1("initWithContentsOfMappedFile:");
  late final _sel_initWithBase64Encoding_1 =
      _registerName1("initWithBase64Encoding:");
  late final _sel_base64Encoding1 = _registerName1("base64Encoding");
  late final _sel_encodeDataObject_1 = _registerName1("encodeDataObject:");
  void _objc_msgSend_248(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
  ) {
    return __objc_msgSend_248(
      obj,
      sel,
      data,
    );
  }

  late final __objc_msgSend_248Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_248 = __objc_msgSend_248Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeDataObject1 = _registerName1("decodeDataObject");
  late final _sel_decodeValueOfObjCType_at_size_1 =
      _registerName1("decodeValueOfObjCType:at:size:");
  void _objc_msgSend_249(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> type,
    ffi.Pointer<ffi.Void> data,
    int size,
  ) {
    return __objc_msgSend_249(
      obj,
      sel,
      type,
      data,
      size,
    );
  }

  late final __objc_msgSend_249Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>,
              ffi.Pointer<ffi.Void>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_249 = __objc_msgSend_249Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Void>, int)>();

  late final _sel_versionForClassName_1 =
      _registerName1("versionForClassName:");
  int _objc_msgSend_250(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> className,
  ) {
    return __objc_msgSend_250(
      obj,
      sel,
      className,
    );
  }

  late final __objc_msgSend_250Ptr = _lookup<
      ffi.NativeFunction<
          NSInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_250 = __objc_msgSend_250Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_encodeObject_1 = _registerName1("encodeObject:");
  late final _sel_encodeRootObject_1 = _registerName1("encodeRootObject:");
  late final _sel_encodeBycopyObject_1 = _registerName1("encodeBycopyObject:");
  late final _sel_encodeByrefObject_1 = _registerName1("encodeByrefObject:");
  late final _sel_encodeConditionalObject_1 =
      _registerName1("encodeConditionalObject:");
  late final _sel_encodeValuesOfObjCTypes_1 =
      _registerName1("encodeValuesOfObjCTypes:");
  void _objc_msgSend_251(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> types,
  ) {
    return __objc_msgSend_251(
      obj,
      sel,
      types,
    );
  }

  late final __objc_msgSend_251Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>)>>('objc_msgSend');
  late final __objc_msgSend_251 = __objc_msgSend_251Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>)>();

  late final _sel_encodeArrayOfObjCType_count_at_1 =
      _registerName1("encodeArrayOfObjCType:count:at:");
  void _objc_msgSend_252(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> type,
    int count,
    ffi.Pointer<ffi.Void> array,
  ) {
    return __objc_msgSend_252(
      obj,
      sel,
      type,
      count,
      array,
    );
  }

  late final __objc_msgSend_252Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>,
              NSUInteger,
              ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_252 = __objc_msgSend_252Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>, int, ffi.Pointer<ffi.Void>)>();

  late final _sel_encodeBytes_length_1 = _registerName1("encodeBytes:length:");
  late final _sel_decodeObject1 = _registerName1("decodeObject");
  late final _sel_decodeTopLevelObjectAndReturnError_1 =
      _registerName1("decodeTopLevelObjectAndReturnError:");
  ffi.Pointer<ObjCObject> _objc_msgSend_253(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_253(
      obj,
      sel,
      error,
    );
  }

  late final __objc_msgSend_253Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_253 = __objc_msgSend_253Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_decodeValuesOfObjCTypes_1 =
      _registerName1("decodeValuesOfObjCTypes:");
  late final _sel_decodeArrayOfObjCType_count_at_1 =
      _registerName1("decodeArrayOfObjCType:count:at:");
  late final _sel_decodeBytesWithReturnedLength_1 =
      _registerName1("decodeBytesWithReturnedLength:");
  ffi.Pointer<ffi.Void> _objc_msgSend_254(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSUInteger> lengthp,
  ) {
    return __objc_msgSend_254(
      obj,
      sel,
      lengthp,
    );
  }

  late final __objc_msgSend_254Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Void> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<NSUInteger>)>>('objc_msgSend');
  late final __objc_msgSend_254 = __objc_msgSend_254Ptr.asFunction<
      ffi.Pointer<ffi.Void> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<NSUInteger>)>();

  late final _sel_encodePropertyList_1 = _registerName1("encodePropertyList:");
  late final _sel_decodePropertyList1 = _registerName1("decodePropertyList");
  late final _sel_setObjectZone_1 = _registerName1("setObjectZone:");
  void _objc_msgSend_255(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSZone> zone,
  ) {
    return __objc_msgSend_255(
      obj,
      sel,
      zone,
    );
  }

  late final __objc_msgSend_255Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSZone>)>>('objc_msgSend');
  late final __objc_msgSend_255 = __objc_msgSend_255Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSZone>)>();

  late final _sel_objectZone1 = _registerName1("objectZone");
  ffi.Pointer<NSZone> _objc_msgSend_256(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_256(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_256Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<NSZone> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_256 = __objc_msgSend_256Ptr.asFunction<
      ffi.Pointer<NSZone> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_systemVersion1 = _registerName1("systemVersion");
  late final _sel_allowsKeyedCoding1 = _registerName1("allowsKeyedCoding");
  late final _sel_encodeObject_forKey_1 =
      _registerName1("encodeObject:forKey:");
  late final _sel_encodeConditionalObject_forKey_1 =
      _registerName1("encodeConditionalObject:forKey:");
  late final _sel_encodeBool_forKey_1 = _registerName1("encodeBool:forKey:");
  void _objc_msgSend_257(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool value,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_257(
      obj,
      sel,
      value,
      key,
    );
  }

  late final __objc_msgSend_257Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Bool, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_257 = __objc_msgSend_257Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_encodeInt_forKey_1 = _registerName1("encodeInt:forKey:");
  void _objc_msgSend_258(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_258(
      obj,
      sel,
      value,
      key,
    );
  }

  late final __objc_msgSend_258Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_258 = __objc_msgSend_258Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_encodeInt32_forKey_1 = _registerName1("encodeInt32:forKey:");
  void _objc_msgSend_259(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_259(
      obj,
      sel,
      value,
      key,
    );
  }

  late final __objc_msgSend_259Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_259 = __objc_msgSend_259Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_encodeInt64_forKey_1 = _registerName1("encodeInt64:forKey:");
  void _objc_msgSend_260(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_260(
      obj,
      sel,
      value,
      key,
    );
  }

  late final __objc_msgSend_260Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int64, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_260 = __objc_msgSend_260Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_encodeFloat_forKey_1 = _registerName1("encodeFloat:forKey:");
  void _objc_msgSend_261(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double value,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_261(
      obj,
      sel,
      value,
      key,
    );
  }

  late final __objc_msgSend_261Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Float, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_261 = __objc_msgSend_261Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_encodeDouble_forKey_1 =
      _registerName1("encodeDouble:forKey:");
  void _objc_msgSend_262(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double value,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_262(
      obj,
      sel,
      value,
      key,
    );
  }

  late final __objc_msgSend_262Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Double, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_262 = __objc_msgSend_262Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_encodeBytes_length_forKey_1 =
      _registerName1("encodeBytes:length:forKey:");
  void _objc_msgSend_263(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Uint8> bytes,
    int length,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_263(
      obj,
      sel,
      bytes,
      length,
      key,
    );
  }

  late final __objc_msgSend_263Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Uint8>,
              NSUInteger,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_263 = __objc_msgSend_263Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Uint8>, int, ffi.Pointer<ObjCObject>)>();

  late final _sel_containsValueForKey_1 =
      _registerName1("containsValueForKey:");
  late final _sel_decodeObjectForKey_1 = _registerName1("decodeObjectForKey:");
  late final _sel_decodeTopLevelObjectForKey_error_1 =
      _registerName1("decodeTopLevelObjectForKey:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_264(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_264(
      obj,
      sel,
      key,
      error,
    );
  }

  late final __objc_msgSend_264Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_264 = __objc_msgSend_264Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_decodeBoolForKey_1 = _registerName1("decodeBoolForKey:");
  late final _sel_decodeIntForKey_1 = _registerName1("decodeIntForKey:");
  int _objc_msgSend_265(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_265(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_265Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_265 = __objc_msgSend_265Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeInt32ForKey_1 = _registerName1("decodeInt32ForKey:");
  int _objc_msgSend_266(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_266(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_266Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_266 = __objc_msgSend_266Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeInt64ForKey_1 = _registerName1("decodeInt64ForKey:");
  int _objc_msgSend_267(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_267(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_267Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int64 Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_267 = __objc_msgSend_267Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeFloatForKey_1 = _registerName1("decodeFloatForKey:");
  double _objc_msgSend_268(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_268(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_268Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Float Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_268 = __objc_msgSend_268Ptr.asFunction<
      double Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeDoubleForKey_1 = _registerName1("decodeDoubleForKey:");
  double _objc_msgSend_269(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_269(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_269Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Double Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_269 = __objc_msgSend_269Ptr.asFunction<
      double Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeBytesForKey_returnedLength_1 =
      _registerName1("decodeBytesForKey:returnedLength:");
  ffi.Pointer<ffi.Uint8> _objc_msgSend_270(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
    ffi.Pointer<NSUInteger> lengthp,
  ) {
    return __objc_msgSend_270(
      obj,
      sel,
      key,
      lengthp,
    );
  }

  late final __objc_msgSend_270Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Uint8> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<NSUInteger>)>>('objc_msgSend');
  late final __objc_msgSend_270 = __objc_msgSend_270Ptr.asFunction<
      ffi.Pointer<ffi.Uint8> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<NSUInteger>)>();

  late final _sel_encodeInteger_forKey_1 =
      _registerName1("encodeInteger:forKey:");
  void _objc_msgSend_271(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_271(
      obj,
      sel,
      value,
      key,
    );
  }

  late final __objc_msgSend_271Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSInteger, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_271 = __objc_msgSend_271Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeIntegerForKey_1 =
      _registerName1("decodeIntegerForKey:");
  late final _sel_requiresSecureCoding1 =
      _registerName1("requiresSecureCoding");
  late final _sel_decodeObjectOfClass_forKey_1 =
      _registerName1("decodeObjectOfClass:forKey:");
  ffi.Pointer<ObjCObject> _objc_msgSend_272(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aClass,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_272(
      obj,
      sel,
      aClass,
      key,
    );
  }

  late final __objc_msgSend_272Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_272 = __objc_msgSend_272Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeTopLevelObjectOfClass_forKey_error_1 =
      _registerName1("decodeTopLevelObjectOfClass:forKey:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_273(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aClass,
    ffi.Pointer<ObjCObject> key,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_273(
      obj,
      sel,
      aClass,
      key,
      error,
    );
  }

  late final __objc_msgSend_273Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_273 = __objc_msgSend_273Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_decodeArrayOfObjectsOfClass_forKey_1 =
      _registerName1("decodeArrayOfObjectsOfClass:forKey:");
  ffi.Pointer<ObjCObject> _objc_msgSend_274(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> cls,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_274(
      obj,
      sel,
      cls,
      key,
    );
  }

  late final __objc_msgSend_274Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_274 = __objc_msgSend_274Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeDictionaryWithKeysOfClass_objectsOfClass_forKey_1 =
      _registerName1("decodeDictionaryWithKeysOfClass:objectsOfClass:forKey:");
  ffi.Pointer<ObjCObject> _objc_msgSend_275(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> keyCls,
    ffi.Pointer<ObjCObject> objectCls,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_275(
      obj,
      sel,
      keyCls,
      objectCls,
      key,
    );
  }

  late final __objc_msgSend_275Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_275 = __objc_msgSend_275Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeObjectOfClasses_forKey_1 =
      _registerName1("decodeObjectOfClasses:forKey:");
  ffi.Pointer<ObjCObject> _objc_msgSend_276(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> classes,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_276(
      obj,
      sel,
      classes,
      key,
    );
  }

  late final __objc_msgSend_276Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_276 = __objc_msgSend_276Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeTopLevelObjectOfClasses_forKey_error_1 =
      _registerName1("decodeTopLevelObjectOfClasses:forKey:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_277(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> classes,
    ffi.Pointer<ObjCObject> key,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_277(
      obj,
      sel,
      classes,
      key,
      error,
    );
  }

  late final __objc_msgSend_277Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_277 = __objc_msgSend_277Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_decodeArrayOfObjectsOfClasses_forKey_1 =
      _registerName1("decodeArrayOfObjectsOfClasses:forKey:");
  ffi.Pointer<ObjCObject> _objc_msgSend_278(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> classes,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_278(
      obj,
      sel,
      classes,
      key,
    );
  }

  late final __objc_msgSend_278Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_278 = __objc_msgSend_278Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeDictionaryWithKeysOfClasses_objectsOfClasses_forKey_1 =
      _registerName1(
          "decodeDictionaryWithKeysOfClasses:objectsOfClasses:forKey:");
  ffi.Pointer<ObjCObject> _objc_msgSend_279(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> keyClasses,
    ffi.Pointer<ObjCObject> objectClasses,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_279(
      obj,
      sel,
      keyClasses,
      objectClasses,
      key,
    );
  }

  late final __objc_msgSend_279Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_279 = __objc_msgSend_279Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodePropertyListForKey_1 =
      _registerName1("decodePropertyListForKey:");
  late final _sel_allowedClasses1 = _registerName1("allowedClasses");
  ffi.Pointer<ObjCObject> _objc_msgSend_280(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_280(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_280Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_280 = __objc_msgSend_280Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_failWithError_1 = _registerName1("failWithError:");
  void _objc_msgSend_281(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> error,
  ) {
    return __objc_msgSend_281(
      obj,
      sel,
      error,
    );
  }

  late final __objc_msgSend_281Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_281 = __objc_msgSend_281Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodingFailurePolicy1 =
      _registerName1("decodingFailurePolicy");
  int _objc_msgSend_282(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_282(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_282Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_282 = __objc_msgSend_282Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_error1 = _registerName1("error");
  ffi.Pointer<ObjCObject> _objc_msgSend_283(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_283(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_283Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_283 = __objc_msgSend_283Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_encodeNXObject_1 = _registerName1("encodeNXObject:");
  late final _sel_decodeNXObject1 = _registerName1("decodeNXObject");
  late final _sel_decodeValueOfObjCType_at_1 =
      _registerName1("decodeValueOfObjCType:at:");
  late final _sel_encodePoint_1 = _registerName1("encodePoint:");
  void _objc_msgSend_284(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSPoint point,
  ) {
    return __objc_msgSend_284(
      obj,
      sel,
      point,
    );
  }

  late final __objc_msgSend_284Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSPoint)>>('objc_msgSend');
  late final __objc_msgSend_284 = __objc_msgSend_284Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSPoint)>();

  late final _sel_decodePoint1 = _registerName1("decodePoint");
  late final _sel_encodeSize_1 = _registerName1("encodeSize:");
  void _objc_msgSend_285(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSSize size,
  ) {
    return __objc_msgSend_285(
      obj,
      sel,
      size,
    );
  }

  late final __objc_msgSend_285Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSSize)>>('objc_msgSend');
  late final __objc_msgSend_285 = __objc_msgSend_285Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSSize)>();

  late final _sel_decodeSize1 = _registerName1("decodeSize");
  late final _sel_encodeRect_1 = _registerName1("encodeRect:");
  void _objc_msgSend_286(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRect rect,
  ) {
    return __objc_msgSend_286(
      obj,
      sel,
      rect,
    );
  }

  late final __objc_msgSend_286Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRect)>>('objc_msgSend');
  late final __objc_msgSend_286 = __objc_msgSend_286Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRect)>();

  late final _sel_decodeRect1 = _registerName1("decodeRect");
  late final _sel_encodePoint_forKey_1 = _registerName1("encodePoint:forKey:");
  void _objc_msgSend_287(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSPoint point,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_287(
      obj,
      sel,
      point,
      key,
    );
  }

  late final __objc_msgSend_287Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSPoint, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_287 = __objc_msgSend_287Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSPoint,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_encodeSize_forKey_1 = _registerName1("encodeSize:forKey:");
  void _objc_msgSend_288(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSSize size,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_288(
      obj,
      sel,
      size,
      key,
    );
  }

  late final __objc_msgSend_288Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSSize, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_288 = __objc_msgSend_288Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSSize,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_encodeRect_forKey_1 = _registerName1("encodeRect:forKey:");
  void _objc_msgSend_289(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRect rect,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_289(
      obj,
      sel,
      rect,
      key,
    );
  }

  late final __objc_msgSend_289Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRect, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_289 = __objc_msgSend_289Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRect,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodePointForKey_1 = _registerName1("decodePointForKey:");
  NSPoint _objc_msgSend_290(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_290(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_290Ptr = _lookup<
      ffi.NativeFunction<
          NSPoint Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_290 = __objc_msgSend_290Ptr.asFunction<
      NSPoint Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeSizeForKey_1 = _registerName1("decodeSizeForKey:");
  NSSize _objc_msgSend_291(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_291(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_291Ptr = _lookup<
      ffi.NativeFunction<
          NSSize Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_291 = __objc_msgSend_291Ptr.asFunction<
      NSSize Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodeRectForKey_1 = _registerName1("decodeRectForKey:");
  NSRect _objc_msgSend_292(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_292(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_292Ptr = _lookup<
      ffi.NativeFunction<
          NSRect Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_292 = __objc_msgSend_292Ptr.asFunction<
      NSRect Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_substringFromIndex_1 = _registerName1("substringFromIndex:");
  ffi.Pointer<ObjCObject> _objc_msgSend_293(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int from,
  ) {
    return __objc_msgSend_293(
      obj,
      sel,
      from,
    );
  }

  late final __objc_msgSend_293Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_293 = __objc_msgSend_293Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_substringToIndex_1 = _registerName1("substringToIndex:");
  late final _sel_substringWithRange_1 = _registerName1("substringWithRange:");
  ffi.Pointer<ObjCObject> _objc_msgSend_294(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
  ) {
    return __objc_msgSend_294(
      obj,
      sel,
      range,
    );
  }

  late final __objc_msgSend_294Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_294 = __objc_msgSend_294Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _sel_getCharacters_range_1 =
      _registerName1("getCharacters:range:");
  void _objc_msgSend_295(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<unichar> buffer,
    NSRange range,
  ) {
    return __objc_msgSend_295(
      obj,
      sel,
      buffer,
      range,
    );
  }

  late final __objc_msgSend_295Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<unichar>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_295 = __objc_msgSend_295Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<unichar>, NSRange)>();

  int _objc_msgSend_296(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
  ) {
    return __objc_msgSend_296(
      obj,
      sel,
      string,
    );
  }

  late final __objc_msgSend_296Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_296 = __objc_msgSend_296Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_compare_options_1 = _registerName1("compare:options:");
  int _objc_msgSend_297(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    int mask,
  ) {
    return __objc_msgSend_297(
      obj,
      sel,
      string,
      mask,
    );
  }

  late final __objc_msgSend_297Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_297 = __objc_msgSend_297Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_compare_options_range_1 =
      _registerName1("compare:options:range:");
  int _objc_msgSend_298(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    int mask,
    NSRange rangeOfReceiverToCompare,
  ) {
    return __objc_msgSend_298(
      obj,
      sel,
      string,
      mask,
      rangeOfReceiverToCompare,
    );
  }

  late final __objc_msgSend_298Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_298 = __objc_msgSend_298Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, NSRange)>();

  late final _sel_compare_options_range_locale_1 =
      _registerName1("compare:options:range:locale:");
  int _objc_msgSend_299(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    int mask,
    NSRange rangeOfReceiverToCompare,
    ffi.Pointer<ObjCObject> locale,
  ) {
    return __objc_msgSend_299(
      obj,
      sel,
      string,
      mask,
      rangeOfReceiverToCompare,
      locale,
    );
  }

  late final __objc_msgSend_299Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              NSRange,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_299 = __objc_msgSend_299Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, NSRange, ffi.Pointer<ObjCObject>)>();

  late final _sel_caseInsensitiveCompare_1 =
      _registerName1("caseInsensitiveCompare:");
  late final _sel_localizedCompare_1 = _registerName1("localizedCompare:");
  late final _sel_localizedCaseInsensitiveCompare_1 =
      _registerName1("localizedCaseInsensitiveCompare:");
  late final _sel_localizedStandardCompare_1 =
      _registerName1("localizedStandardCompare:");
  late final _sel_isEqualToString_1 = _registerName1("isEqualToString:");
  late final _sel_hasPrefix_1 = _registerName1("hasPrefix:");
  late final _sel_hasSuffix_1 = _registerName1("hasSuffix:");
  late final _sel_commonPrefixWithString_options_1 =
      _registerName1("commonPrefixWithString:options:");
  ffi.Pointer<ObjCObject> _objc_msgSend_300(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> str,
    int mask,
  ) {
    return __objc_msgSend_300(
      obj,
      sel,
      str,
      mask,
    );
  }

  late final __objc_msgSend_300Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_300 = __objc_msgSend_300Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, int)>();

  late final _sel_containsString_1 = _registerName1("containsString:");
  late final _sel_localizedCaseInsensitiveContainsString_1 =
      _registerName1("localizedCaseInsensitiveContainsString:");
  late final _sel_localizedStandardContainsString_1 =
      _registerName1("localizedStandardContainsString:");
  late final _sel_localizedStandardRangeOfString_1 =
      _registerName1("localizedStandardRangeOfString:");
  NSRange _objc_msgSend_301(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> str,
  ) {
    return __objc_msgSend_301(
      obj,
      sel,
      str,
    );
  }

  late final __objc_msgSend_301Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_301 = __objc_msgSend_301Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_rangeOfString_1 = _registerName1("rangeOfString:");
  late final _sel_rangeOfString_options_1 =
      _registerName1("rangeOfString:options:");
  NSRange _objc_msgSend_302(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> searchString,
    int mask,
  ) {
    return __objc_msgSend_302(
      obj,
      sel,
      searchString,
      mask,
    );
  }

  late final __objc_msgSend_302Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_302 = __objc_msgSend_302Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_rangeOfString_options_range_1 =
      _registerName1("rangeOfString:options:range:");
  NSRange _objc_msgSend_303(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> searchString,
    int mask,
    NSRange rangeOfReceiverToSearch,
  ) {
    return __objc_msgSend_303(
      obj,
      sel,
      searchString,
      mask,
      rangeOfReceiverToSearch,
    );
  }

  late final __objc_msgSend_303Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_303 = __objc_msgSend_303Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, NSRange)>();

  late final _sel_rangeOfString_options_range_locale_1 =
      _registerName1("rangeOfString:options:range:locale:");
  NSRange _objc_msgSend_304(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> searchString,
    int mask,
    NSRange rangeOfReceiverToSearch,
    ffi.Pointer<ObjCObject> locale,
  ) {
    return __objc_msgSend_304(
      obj,
      sel,
      searchString,
      mask,
      rangeOfReceiverToSearch,
      locale,
    );
  }

  late final __objc_msgSend_304Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              NSRange,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_304 = __objc_msgSend_304Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, NSRange, ffi.Pointer<ObjCObject>)>();

  late final _sel_rangeOfCharacterFromSet_1 =
      _registerName1("rangeOfCharacterFromSet:");
  NSRange _objc_msgSend_305(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> searchSet,
  ) {
    return __objc_msgSend_305(
      obj,
      sel,
      searchSet,
    );
  }

  late final __objc_msgSend_305Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_305 = __objc_msgSend_305Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_rangeOfCharacterFromSet_options_1 =
      _registerName1("rangeOfCharacterFromSet:options:");
  NSRange _objc_msgSend_306(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> searchSet,
    int mask,
  ) {
    return __objc_msgSend_306(
      obj,
      sel,
      searchSet,
      mask,
    );
  }

  late final __objc_msgSend_306Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_306 = __objc_msgSend_306Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_rangeOfCharacterFromSet_options_range_1 =
      _registerName1("rangeOfCharacterFromSet:options:range:");
  NSRange _objc_msgSend_307(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> searchSet,
    int mask,
    NSRange rangeOfReceiverToSearch,
  ) {
    return __objc_msgSend_307(
      obj,
      sel,
      searchSet,
      mask,
      rangeOfReceiverToSearch,
    );
  }

  late final __objc_msgSend_307Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_307 = __objc_msgSend_307Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, NSRange)>();

  late final _sel_rangeOfComposedCharacterSequenceAtIndex_1 =
      _registerName1("rangeOfComposedCharacterSequenceAtIndex:");
  NSRange _objc_msgSend_308(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
  ) {
    return __objc_msgSend_308(
      obj,
      sel,
      index,
    );
  }

  late final __objc_msgSend_308Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_308 = __objc_msgSend_308Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_rangeOfComposedCharacterSequencesForRange_1 =
      _registerName1("rangeOfComposedCharacterSequencesForRange:");
  NSRange _objc_msgSend_309(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
  ) {
    return __objc_msgSend_309(
      obj,
      sel,
      range,
    );
  }

  late final __objc_msgSend_309Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_309 = __objc_msgSend_309Ptr.asFunction<
      NSRange Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _sel_stringByAppendingString_1 =
      _registerName1("stringByAppendingString:");
  late final _sel_stringByAppendingFormat_1 =
      _registerName1("stringByAppendingFormat:");
  late final _sel_uppercaseString1 = _registerName1("uppercaseString");
  late final _sel_lowercaseString1 = _registerName1("lowercaseString");
  late final _sel_capitalizedString1 = _registerName1("capitalizedString");
  late final _sel_localizedUppercaseString1 =
      _registerName1("localizedUppercaseString");
  late final _sel_localizedLowercaseString1 =
      _registerName1("localizedLowercaseString");
  late final _sel_localizedCapitalizedString1 =
      _registerName1("localizedCapitalizedString");
  late final _sel_uppercaseStringWithLocale_1 =
      _registerName1("uppercaseStringWithLocale:");
  ffi.Pointer<ObjCObject> _objc_msgSend_310(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> locale,
  ) {
    return __objc_msgSend_310(
      obj,
      sel,
      locale,
    );
  }

  late final __objc_msgSend_310Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_310 = __objc_msgSend_310Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_lowercaseStringWithLocale_1 =
      _registerName1("lowercaseStringWithLocale:");
  late final _sel_capitalizedStringWithLocale_1 =
      _registerName1("capitalizedStringWithLocale:");
  late final _sel_getLineStart_end_contentsEnd_forRange_1 =
      _registerName1("getLineStart:end:contentsEnd:forRange:");
  void _objc_msgSend_311(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSUInteger> startPtr,
    ffi.Pointer<NSUInteger> lineEndPtr,
    ffi.Pointer<NSUInteger> contentsEndPtr,
    NSRange range,
  ) {
    return __objc_msgSend_311(
      obj,
      sel,
      startPtr,
      lineEndPtr,
      contentsEndPtr,
      range,
    );
  }

  late final __objc_msgSend_311Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSUInteger>,
              ffi.Pointer<NSUInteger>,
              ffi.Pointer<NSUInteger>,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_311 = __objc_msgSend_311Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSUInteger>,
          ffi.Pointer<NSUInteger>,
          ffi.Pointer<NSUInteger>,
          NSRange)>();

  late final _sel_lineRangeForRange_1 = _registerName1("lineRangeForRange:");
  late final _sel_getParagraphStart_end_contentsEnd_forRange_1 =
      _registerName1("getParagraphStart:end:contentsEnd:forRange:");
  late final _sel_paragraphRangeForRange_1 =
      _registerName1("paragraphRangeForRange:");
  late final _sel_enumerateSubstringsInRange_options_usingBlock_1 =
      _registerName1("enumerateSubstringsInRange:options:usingBlock:");
  void _objc_msgSend_312(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_312(
      obj,
      sel,
      range,
      opts,
      block,
    );
  }

  late final __objc_msgSend_312Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_312 = __objc_msgSend_312Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_enumerateLinesUsingBlock_1 =
      _registerName1("enumerateLinesUsingBlock:");
  void _objc_msgSend_313(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_313(
      obj,
      sel,
      block,
    );
  }

  late final __objc_msgSend_313Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_313 = __objc_msgSend_313Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_UTF8String1 = _registerName1("UTF8String");
  late final _sel_fastestEncoding1 = _registerName1("fastestEncoding");
  late final _sel_smallestEncoding1 = _registerName1("smallestEncoding");
  late final _sel_dataUsingEncoding_allowLossyConversion_1 =
      _registerName1("dataUsingEncoding:allowLossyConversion:");
  ffi.Pointer<ObjCObject> _objc_msgSend_314(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int encoding,
    bool lossy,
  ) {
    return __objc_msgSend_314(
      obj,
      sel,
      encoding,
      lossy,
    );
  }

  late final __objc_msgSend_314Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSStringEncoding,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_314 = __objc_msgSend_314Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int, bool)>();

  late final _sel_dataUsingEncoding_1 = _registerName1("dataUsingEncoding:");
  ffi.Pointer<ObjCObject> _objc_msgSend_315(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int encoding,
  ) {
    return __objc_msgSend_315(
      obj,
      sel,
      encoding,
    );
  }

  late final __objc_msgSend_315Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSStringEncoding)>>('objc_msgSend');
  late final __objc_msgSend_315 = __objc_msgSend_315Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_canBeConvertedToEncoding_1 =
      _registerName1("canBeConvertedToEncoding:");
  late final _sel_cStringUsingEncoding_1 =
      _registerName1("cStringUsingEncoding:");
  late final _sel_getCString_maxLength_encoding_1 =
      _registerName1("getCString:maxLength:encoding:");
  bool _objc_msgSend_316(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> buffer,
    int maxBufferCount,
    int encoding,
  ) {
    return __objc_msgSend_316(
      obj,
      sel,
      buffer,
      maxBufferCount,
      encoding,
    );
  }

  late final __objc_msgSend_316Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>,
              NSUInteger,
              NSStringEncoding)>>('objc_msgSend');
  late final __objc_msgSend_316 = __objc_msgSend_316Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>, int, int)>();

  late final _sel_getBytes_maxLength_usedLength_encoding_options_range_remainingRange_1 =
      _registerName1(
          "getBytes:maxLength:usedLength:encoding:options:range:remainingRange:");
  bool _objc_msgSend_317(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> buffer,
    int maxBufferCount,
    ffi.Pointer<NSUInteger> usedBufferCount,
    int encoding,
    int options,
    NSRange range,
    NSRangePointer leftover,
  ) {
    return __objc_msgSend_317(
      obj,
      sel,
      buffer,
      maxBufferCount,
      usedBufferCount,
      encoding,
      options,
      range,
      leftover,
    );
  }

  late final __objc_msgSend_317Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>,
              NSUInteger,
              ffi.Pointer<NSUInteger>,
              NSStringEncoding,
              ffi.Int32,
              NSRange,
              NSRangePointer)>>('objc_msgSend');
  late final __objc_msgSend_317 = __objc_msgSend_317Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>,
          int,
          ffi.Pointer<NSUInteger>,
          int,
          int,
          NSRange,
          NSRangePointer)>();

  late final _sel_maximumLengthOfBytesUsingEncoding_1 =
      _registerName1("maximumLengthOfBytesUsingEncoding:");
  late final _sel_lengthOfBytesUsingEncoding_1 =
      _registerName1("lengthOfBytesUsingEncoding:");
  late final _sel_availableStringEncodings1 =
      _registerName1("availableStringEncodings");
  ffi.Pointer<NSStringEncoding> _objc_msgSend_318(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_318(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_318Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<NSStringEncoding> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_318 = __objc_msgSend_318Ptr.asFunction<
      ffi.Pointer<NSStringEncoding> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_localizedNameOfStringEncoding_1 =
      _registerName1("localizedNameOfStringEncoding:");
  late final _sel_defaultCStringEncoding1 =
      _registerName1("defaultCStringEncoding");
  late final _sel_decomposedStringWithCanonicalMapping1 =
      _registerName1("decomposedStringWithCanonicalMapping");
  late final _sel_precomposedStringWithCanonicalMapping1 =
      _registerName1("precomposedStringWithCanonicalMapping");
  late final _sel_decomposedStringWithCompatibilityMapping1 =
      _registerName1("decomposedStringWithCompatibilityMapping");
  late final _sel_precomposedStringWithCompatibilityMapping1 =
      _registerName1("precomposedStringWithCompatibilityMapping");
  late final _sel_componentsSeparatedByString_1 =
      _registerName1("componentsSeparatedByString:");
  late final _sel_componentsSeparatedByCharactersInSet_1 =
      _registerName1("componentsSeparatedByCharactersInSet:");
  ffi.Pointer<ObjCObject> _objc_msgSend_319(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> separator,
  ) {
    return __objc_msgSend_319(
      obj,
      sel,
      separator,
    );
  }

  late final __objc_msgSend_319Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_319 = __objc_msgSend_319Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_stringByTrimmingCharactersInSet_1 =
      _registerName1("stringByTrimmingCharactersInSet:");
  ffi.Pointer<ObjCObject> _objc_msgSend_320(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> set1,
  ) {
    return __objc_msgSend_320(
      obj,
      sel,
      set1,
    );
  }

  late final __objc_msgSend_320Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_320 = __objc_msgSend_320Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_stringByPaddingToLength_withString_startingAtIndex_1 =
      _registerName1("stringByPaddingToLength:withString:startingAtIndex:");
  ffi.Pointer<ObjCObject> _objc_msgSend_321(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int newLength,
    ffi.Pointer<ObjCObject> padString,
    int padIndex,
  ) {
    return __objc_msgSend_321(
      obj,
      sel,
      newLength,
      padString,
      padIndex,
    );
  }

  late final __objc_msgSend_321Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSUInteger,
              ffi.Pointer<ObjCObject>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_321 = __objc_msgSend_321Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<ObjCObject>, int)>();

  late final _sel_stringByFoldingWithOptions_locale_1 =
      _registerName1("stringByFoldingWithOptions:locale:");
  ffi.Pointer<ObjCObject> _objc_msgSend_322(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
    ffi.Pointer<ObjCObject> locale,
  ) {
    return __objc_msgSend_322(
      obj,
      sel,
      options,
      locale,
    );
  }

  late final __objc_msgSend_322Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_322 = __objc_msgSend_322Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<ObjCObject>)>();

  late final _sel_stringByReplacingOccurrencesOfString_withString_options_range_1 =
      _registerName1(
          "stringByReplacingOccurrencesOfString:withString:options:range:");
  ffi.Pointer<ObjCObject> _objc_msgSend_323(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> target,
    ffi.Pointer<ObjCObject> replacement,
    int options,
    NSRange searchRange,
  ) {
    return __objc_msgSend_323(
      obj,
      sel,
      target,
      replacement,
      options,
      searchRange,
    );
  }

  late final __objc_msgSend_323Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_323 = __objc_msgSend_323Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int,
          NSRange)>();

  late final _sel_stringByReplacingOccurrencesOfString_withString_1 =
      _registerName1("stringByReplacingOccurrencesOfString:withString:");
  ffi.Pointer<ObjCObject> _objc_msgSend_324(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> target,
    ffi.Pointer<ObjCObject> replacement,
  ) {
    return __objc_msgSend_324(
      obj,
      sel,
      target,
      replacement,
    );
  }

  late final __objc_msgSend_324Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_324 = __objc_msgSend_324Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_stringByReplacingCharactersInRange_withString_1 =
      _registerName1("stringByReplacingCharactersInRange:withString:");
  ffi.Pointer<ObjCObject> _objc_msgSend_325(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> replacement,
  ) {
    return __objc_msgSend_325(
      obj,
      sel,
      range,
      replacement,
    );
  }

  late final __objc_msgSend_325Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_325 = __objc_msgSend_325Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSRange, ffi.Pointer<ObjCObject>)>();

  late final _sel_stringByApplyingTransform_reverse_1 =
      _registerName1("stringByApplyingTransform:reverse:");
  ffi.Pointer<ObjCObject> _objc_msgSend_326(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSStringTransform transform,
    bool reverse,
  ) {
    return __objc_msgSend_326(
      obj,
      sel,
      transform,
      reverse,
    );
  }

  late final __objc_msgSend_326Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSStringTransform,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_326 = __objc_msgSend_326Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSStringTransform, bool)>();

  late final _sel_writeToURL_atomically_encoding_error_1 =
      _registerName1("writeToURL:atomically:encoding:error:");
  bool _objc_msgSend_327(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    bool useAuxiliaryFile,
    int enc,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_327(
      obj,
      sel,
      url,
      useAuxiliaryFile,
      enc,
      error,
    );
  }

  late final __objc_msgSend_327Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool,
              NSStringEncoding,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_327 = __objc_msgSend_327Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          bool,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_writeToFile_atomically_encoding_error_1 =
      _registerName1("writeToFile:atomically:encoding:error:");
  bool _objc_msgSend_328(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    bool useAuxiliaryFile,
    int enc,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_328(
      obj,
      sel,
      path,
      useAuxiliaryFile,
      enc,
      error,
    );
  }

  late final __objc_msgSend_328Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool,
              NSStringEncoding,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_328 = __objc_msgSend_328Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          bool,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_hash1 = _registerName1("hash");
  late final _sel_initWithCharactersNoCopy_length_freeWhenDone_1 =
      _registerName1("initWithCharactersNoCopy:length:freeWhenDone:");
  instancetype _objc_msgSend_329(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<unichar> characters,
    int length,
    bool freeBuffer,
  ) {
    return __objc_msgSend_329(
      obj,
      sel,
      characters,
      length,
      freeBuffer,
    );
  }

  late final __objc_msgSend_329Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<unichar>, NSUInteger, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_329 = __objc_msgSend_329Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<unichar>, int, bool)>();

  late final _sel_initWithCharactersNoCopy_length_deallocator_1 =
      _registerName1("initWithCharactersNoCopy:length:deallocator:");
  instancetype _objc_msgSend_330(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<unichar> chars,
    int len,
    ffi.Pointer<_ObjCBlock> deallocator,
  ) {
    return __objc_msgSend_330(
      obj,
      sel,
      chars,
      len,
      deallocator,
    );
  }

  late final __objc_msgSend_330Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<unichar>,
              NSUInteger,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_330 = __objc_msgSend_330Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<unichar>, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_initWithCharacters_length_1 =
      _registerName1("initWithCharacters:length:");
  instancetype _objc_msgSend_331(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<unichar> characters,
    int length,
  ) {
    return __objc_msgSend_331(
      obj,
      sel,
      characters,
      length,
    );
  }

  late final __objc_msgSend_331Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<unichar>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_331 = __objc_msgSend_331Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<unichar>, int)>();

  late final _sel_initWithUTF8String_1 = _registerName1("initWithUTF8String:");
  instancetype _objc_msgSend_332(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> nullTerminatedCString,
  ) {
    return __objc_msgSend_332(
      obj,
      sel,
      nullTerminatedCString,
    );
  }

  late final __objc_msgSend_332Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>)>>('objc_msgSend');
  late final __objc_msgSend_332 = __objc_msgSend_332Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>)>();

  late final _sel_initWithFormat_1 = _registerName1("initWithFormat:");
  late final _sel_initWithFormat_arguments_1 =
      _registerName1("initWithFormat:arguments:");
  instancetype _objc_msgSend_333(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> format,
    ffi.Pointer<__va_list_tag> argList,
  ) {
    return __objc_msgSend_333(
      obj,
      sel,
      format,
      argList,
    );
  }

  late final __objc_msgSend_333Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<__va_list_tag>)>>('objc_msgSend');
  late final __objc_msgSend_333 = __objc_msgSend_333Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<__va_list_tag>)>();

  late final _sel_initWithFormat_locale_1 =
      _registerName1("initWithFormat:locale:");
  late final _sel_initWithFormat_locale_arguments_1 =
      _registerName1("initWithFormat:locale:arguments:");
  instancetype _objc_msgSend_334(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> format,
    ffi.Pointer<ObjCObject> locale,
    ffi.Pointer<__va_list_tag> argList,
  ) {
    return __objc_msgSend_334(
      obj,
      sel,
      format,
      locale,
      argList,
    );
  }

  late final __objc_msgSend_334Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<__va_list_tag>)>>('objc_msgSend');
  late final __objc_msgSend_334 = __objc_msgSend_334Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<__va_list_tag>)>();

  late final _sel_initWithData_encoding_1 =
      _registerName1("initWithData:encoding:");
  instancetype _objc_msgSend_335(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
    int encoding,
  ) {
    return __objc_msgSend_335(
      obj,
      sel,
      data,
      encoding,
    );
  }

  late final __objc_msgSend_335Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSStringEncoding)>>('objc_msgSend');
  late final __objc_msgSend_335 = __objc_msgSend_335Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_initWithBytes_length_encoding_1 =
      _registerName1("initWithBytes:length:encoding:");
  instancetype _objc_msgSend_336(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> bytes,
    int len,
    int encoding,
  ) {
    return __objc_msgSend_336(
      obj,
      sel,
      bytes,
      len,
      encoding,
    );
  }

  late final __objc_msgSend_336Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>,
              NSUInteger,
              NSStringEncoding)>>('objc_msgSend');
  late final __objc_msgSend_336 = __objc_msgSend_336Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>, int, int)>();

  late final _sel_initWithBytesNoCopy_length_encoding_freeWhenDone_1 =
      _registerName1("initWithBytesNoCopy:length:encoding:freeWhenDone:");
  instancetype _objc_msgSend_337(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> bytes,
    int len,
    int encoding,
    bool freeBuffer,
  ) {
    return __objc_msgSend_337(
      obj,
      sel,
      bytes,
      len,
      encoding,
      freeBuffer,
    );
  }

  late final __objc_msgSend_337Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>,
              NSUInteger,
              NSStringEncoding,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_337 = __objc_msgSend_337Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>, int, int, bool)>();

  late final _sel_initWithBytesNoCopy_length_encoding_deallocator_1 =
      _registerName1("initWithBytesNoCopy:length:encoding:deallocator:");
  instancetype _objc_msgSend_338(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> bytes,
    int len,
    int encoding,
    ffi.Pointer<_ObjCBlock> deallocator,
  ) {
    return __objc_msgSend_338(
      obj,
      sel,
      bytes,
      len,
      encoding,
      deallocator,
    );
  }

  late final __objc_msgSend_338Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>,
              NSUInteger,
              NSStringEncoding,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_338 = __objc_msgSend_338Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>, int, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_string1 = _registerName1("string");
  late final _sel_stringWithString_1 = _registerName1("stringWithString:");
  late final _sel_stringWithCharacters_length_1 =
      _registerName1("stringWithCharacters:length:");
  late final _sel_stringWithUTF8String_1 =
      _registerName1("stringWithUTF8String:");
  late final _sel_stringWithFormat_1 = _registerName1("stringWithFormat:");
  late final _sel_localizedStringWithFormat_1 =
      _registerName1("localizedStringWithFormat:");
  late final _sel_initWithCString_encoding_1 =
      _registerName1("initWithCString:encoding:");
  instancetype _objc_msgSend_339(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> nullTerminatedCString,
    int encoding,
  ) {
    return __objc_msgSend_339(
      obj,
      sel,
      nullTerminatedCString,
      encoding,
    );
  }

  late final __objc_msgSend_339Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>, NSStringEncoding)>>('objc_msgSend');
  late final __objc_msgSend_339 = __objc_msgSend_339Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>, int)>();

  late final _sel_stringWithCString_encoding_1 =
      _registerName1("stringWithCString:encoding:");
  late final _sel_initWithContentsOfURL_encoding_error_1 =
      _registerName1("initWithContentsOfURL:encoding:error:");
  instancetype _objc_msgSend_340(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    int enc,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_340(
      obj,
      sel,
      url,
      enc,
      error,
    );
  }

  late final __objc_msgSend_340Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSStringEncoding,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_340 = __objc_msgSend_340Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_initWithContentsOfFile_encoding_error_1 =
      _registerName1("initWithContentsOfFile:encoding:error:");
  instancetype _objc_msgSend_341(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    int enc,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_341(
      obj,
      sel,
      path,
      enc,
      error,
    );
  }

  late final __objc_msgSend_341Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSStringEncoding,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_341 = __objc_msgSend_341Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_stringWithContentsOfURL_encoding_error_1 =
      _registerName1("stringWithContentsOfURL:encoding:error:");
  late final _sel_stringWithContentsOfFile_encoding_error_1 =
      _registerName1("stringWithContentsOfFile:encoding:error:");
  late final _sel_initWithContentsOfURL_usedEncoding_error_1 =
      _registerName1("initWithContentsOfURL:usedEncoding:error:");
  instancetype _objc_msgSend_342(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<NSStringEncoding> enc,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_342(
      obj,
      sel,
      url,
      enc,
      error,
    );
  }

  late final __objc_msgSend_342Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<NSStringEncoding>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_342 = __objc_msgSend_342Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<NSStringEncoding>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_initWithContentsOfFile_usedEncoding_error_1 =
      _registerName1("initWithContentsOfFile:usedEncoding:error:");
  instancetype _objc_msgSend_343(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<NSStringEncoding> enc,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_343(
      obj,
      sel,
      path,
      enc,
      error,
    );
  }

  late final __objc_msgSend_343Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<NSStringEncoding>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_343 = __objc_msgSend_343Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<NSStringEncoding>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_stringWithContentsOfURL_usedEncoding_error_1 =
      _registerName1("stringWithContentsOfURL:usedEncoding:error:");
  late final _sel_stringWithContentsOfFile_usedEncoding_error_1 =
      _registerName1("stringWithContentsOfFile:usedEncoding:error:");
  late final _sel_stringEncodingForData_encodingOptions_convertedString_usedLossyConversion_1 =
      _registerName1(
          "stringEncodingForData:encodingOptions:convertedString:usedLossyConversion:");
  int _objc_msgSend_344(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
    ffi.Pointer<ObjCObject> opts,
    ffi.Pointer<ffi.Pointer<ObjCObject>> string,
    ffi.Pointer<ffi.Bool> usedLossyConversion,
  ) {
    return __objc_msgSend_344(
      obj,
      sel,
      data,
      opts,
      string,
      usedLossyConversion,
    );
  }

  late final __objc_msgSend_344Ptr = _lookup<
      ffi.NativeFunction<
          NSStringEncoding Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ffi.Bool>)>>('objc_msgSend');
  late final __objc_msgSend_344 = __objc_msgSend_344Ptr.asFunction<
      int Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ffi.Bool>)>();

  late final _sel_propertyList1 = _registerName1("propertyList");
  late final _sel_propertyListFromStringsFileFormat1 =
      _registerName1("propertyListFromStringsFileFormat");
  late final _sel_cString1 = _registerName1("cString");
  late final _sel_lossyCString1 = _registerName1("lossyCString");
  late final _sel_cStringLength1 = _registerName1("cStringLength");
  late final _sel_getCString_1 = _registerName1("getCString:");
  late final _sel_getCString_maxLength_1 =
      _registerName1("getCString:maxLength:");
  void _objc_msgSend_345(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> bytes,
    int maxLength,
  ) {
    return __objc_msgSend_345(
      obj,
      sel,
      bytes,
      maxLength,
    );
  }

  late final __objc_msgSend_345Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_345 = __objc_msgSend_345Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>, int)>();

  late final _sel_getCString_maxLength_range_remainingRange_1 =
      _registerName1("getCString:maxLength:range:remainingRange:");
  void _objc_msgSend_346(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> bytes,
    int maxLength,
    NSRange aRange,
    NSRangePointer leftoverRange,
  ) {
    return __objc_msgSend_346(
      obj,
      sel,
      bytes,
      maxLength,
      aRange,
      leftoverRange,
    );
  }

  late final __objc_msgSend_346Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>,
              NSUInteger,
              NSRange,
              NSRangePointer)>>('objc_msgSend');
  late final __objc_msgSend_346 = __objc_msgSend_346Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Char>, int, NSRange, NSRangePointer)>();

  late final _sel_stringWithContentsOfFile_1 =
      _registerName1("stringWithContentsOfFile:");
  late final _sel_stringWithContentsOfURL_1 =
      _registerName1("stringWithContentsOfURL:");
  late final _sel_initWithCStringNoCopy_length_freeWhenDone_1 =
      _registerName1("initWithCStringNoCopy:length:freeWhenDone:");
  ffi.Pointer<ObjCObject> _objc_msgSend_347(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Char> bytes,
    int length,
    bool freeBuffer,
  ) {
    return __objc_msgSend_347(
      obj,
      sel,
      bytes,
      length,
      freeBuffer,
    );
  }

  late final __objc_msgSend_347Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Char>,
              NSUInteger,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_347 = __objc_msgSend_347Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ffi.Char>, int, bool)>();

  late final _sel_initWithCString_length_1 =
      _registerName1("initWithCString:length:");
  late final _sel_initWithCString_1 = _registerName1("initWithCString:");
  late final _sel_stringWithCString_length_1 =
      _registerName1("stringWithCString:length:");
  late final _sel_stringWithCString_1 = _registerName1("stringWithCString:");
  late final _sel_getCharacters_1 = _registerName1("getCharacters:");
  void _objc_msgSend_348(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<unichar> buffer,
  ) {
    return __objc_msgSend_348(
      obj,
      sel,
      buffer,
    );
  }

  late final __objc_msgSend_348Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<unichar>)>>('objc_msgSend');
  late final __objc_msgSend_348 = __objc_msgSend_348Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<unichar>)>();

  late final _sel_variantFittingPresentationWidth_1 =
      _registerName1("variantFittingPresentationWidth:");
  ffi.Pointer<ObjCObject> _objc_msgSend_349(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int width,
  ) {
    return __objc_msgSend_349(
      obj,
      sel,
      width,
    );
  }

  late final __objc_msgSend_349Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_349 = __objc_msgSend_349Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_pathWithComponents_1 = _registerName1("pathWithComponents:");
  ffi.Pointer<ObjCObject> _objc_msgSend_350(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> components,
  ) {
    return __objc_msgSend_350(
      obj,
      sel,
      components,
    );
  }

  late final __objc_msgSend_350Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_350 = __objc_msgSend_350Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_isAbsolutePath1 = _registerName1("isAbsolutePath");
  late final _sel_stringByDeletingLastPathComponent1 =
      _registerName1("stringByDeletingLastPathComponent");
  late final _sel_stringByAppendingPathComponent_1 =
      _registerName1("stringByAppendingPathComponent:");
  late final _sel_stringByDeletingPathExtension1 =
      _registerName1("stringByDeletingPathExtension");
  late final _sel_stringByAppendingPathExtension_1 =
      _registerName1("stringByAppendingPathExtension:");
  late final _sel_stringByAbbreviatingWithTildeInPath1 =
      _registerName1("stringByAbbreviatingWithTildeInPath");
  late final _sel_stringByExpandingTildeInPath1 =
      _registerName1("stringByExpandingTildeInPath");
  late final _sel_stringByStandardizingPath1 =
      _registerName1("stringByStandardizingPath");
  late final _sel_stringByResolvingSymlinksInPath1 =
      _registerName1("stringByResolvingSymlinksInPath");
  late final _sel_stringsByAppendingPaths_1 =
      _registerName1("stringsByAppendingPaths:");
  late final _sel_completePathIntoString_caseSensitive_matchesIntoArray_filterTypes_1 =
      _registerName1(
          "completePathIntoString:caseSensitive:matchesIntoArray:filterTypes:");
  int _objc_msgSend_351(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outputName,
    bool flag,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outputArray,
    ffi.Pointer<ObjCObject> filterTypes,
  ) {
    return __objc_msgSend_351(
      obj,
      sel,
      outputName,
      flag,
      outputArray,
      filterTypes,
    );
  }

  late final __objc_msgSend_351Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Bool,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_351 = __objc_msgSend_351Ptr.asFunction<
      int Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          bool,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_stringByAddingPercentEncodingWithAllowedCharacters_1 =
      _registerName1("stringByAddingPercentEncodingWithAllowedCharacters:");
  late final _sel_stringByRemovingPercentEncoding1 =
      _registerName1("stringByRemovingPercentEncoding");
  late final _sel_stringByAddingPercentEscapesUsingEncoding_1 =
      _registerName1("stringByAddingPercentEscapesUsingEncoding:");
  late final _sel_stringByReplacingPercentEscapesUsingEncoding_1 =
      _registerName1("stringByReplacingPercentEscapesUsingEncoding:");
  late final _class_NSOrthography1 = _getClass1("NSOrthography");
  late final _sel_dominantScript1 = _registerName1("dominantScript");
  late final _sel_languageMap1 = _registerName1("languageMap");
  late final _sel_initWithDominantScript_languageMap_1 =
      _registerName1("initWithDominantScript:languageMap:");
  instancetype _objc_msgSend_352(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> script,
    ffi.Pointer<ObjCObject> map,
  ) {
    return __objc_msgSend_352(
      obj,
      sel,
      script,
      map,
    );
  }

  late final __objc_msgSend_352Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_352 = __objc_msgSend_352Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_languagesForScript_1 = _registerName1("languagesForScript:");
  late final _sel_dominantLanguageForScript_1 =
      _registerName1("dominantLanguageForScript:");
  late final _sel_dominantLanguage1 = _registerName1("dominantLanguage");
  late final _sel_allScripts1 = _registerName1("allScripts");
  late final _sel_allLanguages1 = _registerName1("allLanguages");
  late final _sel_defaultOrthographyForLanguage_1 =
      _registerName1("defaultOrthographyForLanguage:");
  late final _sel_orthographyWithDominantScript_languageMap_1 =
      _registerName1("orthographyWithDominantScript:languageMap:");
  late final _sel_linguisticTagsInRange_scheme_options_orthography_tokenRanges_1 =
      _registerName1(
          "linguisticTagsInRange:scheme:options:orthography:tokenRanges:");
  ffi.Pointer<ObjCObject> _objc_msgSend_353(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    NSLinguisticTagScheme scheme,
    int options,
    ffi.Pointer<ObjCObject> orthography,
    ffi.Pointer<ffi.Pointer<ObjCObject>> tokenRanges,
  ) {
    return __objc_msgSend_353(
      obj,
      sel,
      range,
      scheme,
      options,
      orthography,
      tokenRanges,
    );
  }

  late final __objc_msgSend_353Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              NSLinguisticTagScheme,
              ffi.Int32,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_353 = __objc_msgSend_353Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          NSRange,
          NSLinguisticTagScheme,
          int,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_enumerateLinguisticTagsInRange_scheme_options_orthography_usingBlock_1 =
      _registerName1(
          "enumerateLinguisticTagsInRange:scheme:options:orthography:usingBlock:");
  void _objc_msgSend_354(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    NSLinguisticTagScheme scheme,
    int options,
    ffi.Pointer<ObjCObject> orthography,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_354(
      obj,
      sel,
      range,
      scheme,
      options,
      orthography,
      block,
    );
  }

  late final __objc_msgSend_354Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              NSLinguisticTagScheme,
              ffi.Int32,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_354 = __objc_msgSend_354Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          NSRange,
          NSLinguisticTagScheme,
          int,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_allObjects1 = _registerName1("allObjects");
  late final _sel_anyObject1 = _registerName1("anyObject");
  late final _sel_intersectsSet_1 = _registerName1("intersectsSet:");
  bool _objc_msgSend_355(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> otherSet,
  ) {
    return __objc_msgSend_355(
      obj,
      sel,
      otherSet,
    );
  }

  late final __objc_msgSend_355Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_355 = __objc_msgSend_355Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_isEqualToSet_1 = _registerName1("isEqualToSet:");
  late final _sel_isSubsetOfSet_1 = _registerName1("isSubsetOfSet:");
  late final _sel_setByAddingObject_1 = _registerName1("setByAddingObject:");
  ffi.Pointer<ObjCObject> _objc_msgSend_356(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anObject,
  ) {
    return __objc_msgSend_356(
      obj,
      sel,
      anObject,
    );
  }

  late final __objc_msgSend_356Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_356 = __objc_msgSend_356Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_setByAddingObjectsFromSet_1 =
      _registerName1("setByAddingObjectsFromSet:");
  ffi.Pointer<ObjCObject> _objc_msgSend_357(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> other,
  ) {
    return __objc_msgSend_357(
      obj,
      sel,
      other,
    );
  }

  late final __objc_msgSend_357Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_357 = __objc_msgSend_357Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_setByAddingObjectsFromArray_1 =
      _registerName1("setByAddingObjectsFromArray:");
  ffi.Pointer<ObjCObject> _objc_msgSend_358(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> other,
  ) {
    return __objc_msgSend_358(
      obj,
      sel,
      other,
    );
  }

  late final __objc_msgSend_358Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_358 = __objc_msgSend_358Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  void _objc_msgSend_359(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_359(
      obj,
      sel,
      block,
    );
  }

  late final __objc_msgSend_359Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_359 = __objc_msgSend_359Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  void _objc_msgSend_360(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_360(
      obj,
      sel,
      opts,
      block,
    );
  }

  late final __objc_msgSend_360Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_360 = __objc_msgSend_360Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_objectsPassingTest_1 = _registerName1("objectsPassingTest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_361(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_361(
      obj,
      sel,
      predicate,
    );
  }

  late final __objc_msgSend_361Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_361 = __objc_msgSend_361Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_objectsWithOptions_passingTest_1 =
      _registerName1("objectsWithOptions:passingTest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_362(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    ffi.Pointer<_ObjCBlock> predicate,
  ) {
    return __objc_msgSend_362(
      obj,
      sel,
      opts,
      predicate,
    );
  }

  late final __objc_msgSend_362Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_362 = __objc_msgSend_362Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_set1 = _registerName1("set");
  late final _sel_setWithObject_1 = _registerName1("setWithObject:");
  late final _sel_setWithObjects_count_1 =
      _registerName1("setWithObjects:count:");
  late final _sel_setWithObjects_1 = _registerName1("setWithObjects:");
  late final _sel_setWithSet_1 = _registerName1("setWithSet:");
  instancetype _objc_msgSend_363(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> set1,
  ) {
    return __objc_msgSend_363(
      obj,
      sel,
      set1,
    );
  }

  late final __objc_msgSend_363Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_363 = __objc_msgSend_363Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_setWithArray_1 = _registerName1("setWithArray:");
  late final _sel_initWithSet_1 = _registerName1("initWithSet:");
  late final _sel_initWithSet_copyItems_1 =
      _registerName1("initWithSet:copyItems:");
  instancetype _objc_msgSend_364(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> set1,
    bool flag,
  ) {
    return __objc_msgSend_364(
      obj,
      sel,
      set1,
      flag,
    );
  }

  late final __objc_msgSend_364Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_364 = __objc_msgSend_364Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_filteredSetUsingPredicate_1 =
      _registerName1("filteredSetUsingPredicate:");
  ffi.Pointer<ObjCObject> _objc_msgSend_365(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> predicate,
  ) {
    return __objc_msgSend_365(
      obj,
      sel,
      predicate,
    );
  }

  late final __objc_msgSend_365Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_365 = __objc_msgSend_365Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_invocationWithMethodSignature_1 =
      _registerName1("invocationWithMethodSignature:");
  ffi.Pointer<ObjCObject> _objc_msgSend_366(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> sig,
  ) {
    return __objc_msgSend_366(
      obj,
      sel,
      sig,
    );
  }

  late final __objc_msgSend_366Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_366 = __objc_msgSend_366Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_methodSignature1 = _registerName1("methodSignature");
  ffi.Pointer<ObjCObject> _objc_msgSend_367(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_367(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_367Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_367 = __objc_msgSend_367Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_retainArguments1 = _registerName1("retainArguments");
  late final _sel_argumentsRetained1 = _registerName1("argumentsRetained");
  late final _sel_target1 = _registerName1("target");
  late final _sel_setTarget_1 = _registerName1("setTarget:");
  void _objc_msgSend_368(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_368(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_368Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_368 = __objc_msgSend_368Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_selector1 = _registerName1("selector");
  ffi.Pointer<ObjCSel> _objc_msgSend_369(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_369(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_369Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCSel> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_369 = __objc_msgSend_369Ptr.asFunction<
      ffi.Pointer<ObjCSel> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setSelector_1 = _registerName1("setSelector:");
  void _objc_msgSend_370(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> value,
  ) {
    return __objc_msgSend_370(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_370Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_370 = __objc_msgSend_370Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>)>();

  late final _sel_getReturnValue_1 = _registerName1("getReturnValue:");
  late final _sel_setReturnValue_1 = _registerName1("setReturnValue:");
  late final _sel_getArgument_atIndex_1 =
      _registerName1("getArgument:atIndex:");
  void _objc_msgSend_371(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> argumentLocation,
    int idx,
  ) {
    return __objc_msgSend_371(
      obj,
      sel,
      argumentLocation,
      idx,
    );
  }

  late final __objc_msgSend_371Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>, NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_371 = __objc_msgSend_371Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>, int)>();

  late final _sel_setArgument_atIndex_1 =
      _registerName1("setArgument:atIndex:");
  late final _sel_invoke1 = _registerName1("invoke");
  late final _sel_invokeWithTarget_1 = _registerName1("invokeWithTarget:");
  late final _sel_forwardInvocation_1 = _registerName1("forwardInvocation:");
  void _objc_msgSend_372(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anInvocation,
  ) {
    return __objc_msgSend_372(
      obj,
      sel,
      anInvocation,
    );
  }

  late final __objc_msgSend_372Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_372 = __objc_msgSend_372Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_methodSignatureForSelector_1 =
      _registerName1("methodSignatureForSelector:");
  ffi.Pointer<ObjCObject> _objc_msgSend_373(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
  ) {
    return __objc_msgSend_373(
      obj,
      sel,
      aSelector,
    );
  }

  late final __objc_msgSend_373Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_373 = __objc_msgSend_373Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCSel>)>();

  late final _sel_instanceMethodSignatureForSelector_1 =
      _registerName1("instanceMethodSignatureForSelector:");
  late final _sel_allowsWeakReference1 = _registerName1("allowsWeakReference");
  late final _sel_retainWeakReference1 = _registerName1("retainWeakReference");
  late final _sel_isSubclassOfClass_1 = _registerName1("isSubclassOfClass:");
  late final _sel_resolveClassMethod_1 = _registerName1("resolveClassMethod:");
  late final _sel_resolveInstanceMethod_1 =
      _registerName1("resolveInstanceMethod:");
  late final _sel_superclass1 = _registerName1("superclass");
  late final _sel_class1 = _registerName1("class");
  late final _sel_debugDescription1 = _registerName1("debugDescription");
  late final _sel_version1 = _registerName1("version");
  late final _sel_setVersion_1 = _registerName1("setVersion:");
  void _objc_msgSend_374(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int aVersion,
  ) {
    return __objc_msgSend_374(
      obj,
      sel,
      aVersion,
    );
  }

  late final __objc_msgSend_374Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_374 = __objc_msgSend_374Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_classForCoder1 = _registerName1("classForCoder");
  late final _sel_replacementObjectForCoder_1 =
      _registerName1("replacementObjectForCoder:");
  late final _sel_awakeAfterUsingCoder_1 =
      _registerName1("awakeAfterUsingCoder:");
  late final _sel_poseAsClass_1 = _registerName1("poseAsClass:");
  late final _sel_autoContentAccessingProxy1 =
      _registerName1("autoContentAccessingProxy");
  late final _sel_attemptRecoveryFromError_optionIndex_delegate_didRecoverSelector_contextInfo_1 =
      _registerName1(
          "attemptRecoveryFromError:optionIndex:delegate:didRecoverSelector:contextInfo:");
  void _objc_msgSend_375(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> error,
    int recoveryOptionIndex,
    ffi.Pointer<ObjCObject> delegate,
    ffi.Pointer<ObjCSel> didRecoverSelector,
    ffi.Pointer<ffi.Void> contextInfo,
  ) {
    return __objc_msgSend_375(
      obj,
      sel,
      error,
      recoveryOptionIndex,
      delegate,
      didRecoverSelector,
      contextInfo,
    );
  }

  late final __objc_msgSend_375Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSUInteger,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_375 = __objc_msgSend_375Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_attemptRecoveryFromError_optionIndex_1 =
      _registerName1("attemptRecoveryFromError:optionIndex:");
  bool _objc_msgSend_376(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> error,
    int recoveryOptionIndex,
  ) {
    return __objc_msgSend_376(
      obj,
      sel,
      error,
      recoveryOptionIndex,
    );
  }

  late final __objc_msgSend_376Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_376 = __objc_msgSend_376Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_performSelector_withObject_afterDelay_inModes_1 =
      _registerName1("performSelector:withObject:afterDelay:inModes:");
  void _objc_msgSend_377(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
    ffi.Pointer<ObjCObject> anArgument,
    double delay,
    ffi.Pointer<ObjCObject> modes,
  ) {
    return __objc_msgSend_377(
      obj,
      sel,
      aSelector,
      anArgument,
      delay,
      modes,
    );
  }

  late final __objc_msgSend_377Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSTimeInterval,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_377 = __objc_msgSend_377Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          double,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_performSelector_withObject_afterDelay_1 =
      _registerName1("performSelector:withObject:afterDelay:");
  void _objc_msgSend_378(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
    ffi.Pointer<ObjCObject> anArgument,
    double delay,
  ) {
    return __objc_msgSend_378(
      obj,
      sel,
      aSelector,
      anArgument,
      delay,
    );
  }

  late final __objc_msgSend_378Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSTimeInterval)>>('objc_msgSend');
  late final __objc_msgSend_378 = __objc_msgSend_378Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, double)>();

  late final _sel_URL_resourceDataDidBecomeAvailable_1 =
      _registerName1("URL:resourceDataDidBecomeAvailable:");
  void _objc_msgSend_379(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> sender,
    ffi.Pointer<ObjCObject> newBytes,
  ) {
    return __objc_msgSend_379(
      obj,
      sel,
      sender,
      newBytes,
    );
  }

  late final __objc_msgSend_379Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_379 = __objc_msgSend_379Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_URLResourceDidFinishLoading_1 =
      _registerName1("URLResourceDidFinishLoading:");
  void _objc_msgSend_380(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> sender,
  ) {
    return __objc_msgSend_380(
      obj,
      sel,
      sender,
    );
  }

  late final __objc_msgSend_380Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_380 = __objc_msgSend_380Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_URLResourceDidCancelLoading_1 =
      _registerName1("URLResourceDidCancelLoading:");
  late final _sel_URL_resourceDidFailLoadingWithReason_1 =
      _registerName1("URL:resourceDidFailLoadingWithReason:");
  void _objc_msgSend_381(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> sender,
    ffi.Pointer<ObjCObject> reason,
  ) {
    return __objc_msgSend_381(
      obj,
      sel,
      sender,
      reason,
    );
  }

  late final __objc_msgSend_381Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_381 = __objc_msgSend_381Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _class_NSFileManager1 = _getClass1("NSFileManager");
  late final _sel_defaultManager1 = _registerName1("defaultManager");
  ffi.Pointer<ObjCObject> _objc_msgSend_382(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_382(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_382Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_382 = __objc_msgSend_382Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_mountedVolumeURLsIncludingResourceValuesForKeys_options_1 =
      _registerName1(
          "mountedVolumeURLsIncludingResourceValuesForKeys:options:");
  ffi.Pointer<ObjCObject> _objc_msgSend_383(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> propertyKeys,
    int options,
  ) {
    return __objc_msgSend_383(
      obj,
      sel,
      propertyKeys,
      options,
    );
  }

  late final __objc_msgSend_383Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_383 = __objc_msgSend_383Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, int)>();

  late final _sel_unmountVolumeAtURL_options_completionHandler_1 =
      _registerName1("unmountVolumeAtURL:options:completionHandler:");
  void _objc_msgSend_384(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    int mask,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_384(
      obj,
      sel,
      url,
      mask,
      completionHandler,
    );
  }

  late final __objc_msgSend_384Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_384 = __objc_msgSend_384Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_contentsOfDirectoryAtURL_includingPropertiesForKeys_options_error_1 =
      _registerName1(
          "contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_385(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<ObjCObject> keys,
    int mask,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_385(
      obj,
      sel,
      url,
      keys,
      mask,
      error,
    );
  }

  late final __objc_msgSend_385Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_385 = __objc_msgSend_385Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_URLsForDirectory_inDomains_1 =
      _registerName1("URLsForDirectory:inDomains:");
  ffi.Pointer<ObjCObject> _objc_msgSend_386(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int directory,
    int domainMask,
  ) {
    return __objc_msgSend_386(
      obj,
      sel,
      directory,
      domainMask,
    );
  }

  late final __objc_msgSend_386Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Int32, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_386 = __objc_msgSend_386Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int, int)>();

  late final _sel_URLForDirectory_inDomain_appropriateForURL_create_error_1 =
      _registerName1(
          "URLForDirectory:inDomain:appropriateForURL:create:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_387(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int directory,
    int domain,
    ffi.Pointer<ObjCObject> url,
    bool shouldCreate,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_387(
      obj,
      sel,
      directory,
      domain,
      url,
      shouldCreate,
      error,
    );
  }

  late final __objc_msgSend_387Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Int32,
              ffi.Pointer<ObjCObject>,
              ffi.Bool,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_387 = __objc_msgSend_387Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          int,
          int,
          ffi.Pointer<ObjCObject>,
          bool,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_getRelationship_ofDirectoryAtURL_toItemAtURL_error_1 =
      _registerName1("getRelationship:ofDirectoryAtURL:toItemAtURL:error:");
  bool _objc_msgSend_388(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Int32> outRelationship,
    ffi.Pointer<ObjCObject> directoryURL,
    ffi.Pointer<ObjCObject> otherURL,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_388(
      obj,
      sel,
      outRelationship,
      directoryURL,
      otherURL,
      error,
    );
  }

  late final __objc_msgSend_388Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Int32>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_388 = __objc_msgSend_388Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Int32>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_getRelationship_ofDirectory_inDomain_toItemAtURL_error_1 =
      _registerName1("getRelationship:ofDirectory:inDomain:toItemAtURL:error:");
  bool _objc_msgSend_389(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Int32> outRelationship,
    int directory,
    int domainMask,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_389(
      obj,
      sel,
      outRelationship,
      directory,
      domainMask,
      url,
      error,
    );
  }

  late final __objc_msgSend_389Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Int32>,
              ffi.Int32,
              ffi.Int32,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_389 = __objc_msgSend_389Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Int32>,
          int,
          int,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_createDirectoryAtURL_withIntermediateDirectories_attributes_error_1 =
      _registerName1(
          "createDirectoryAtURL:withIntermediateDirectories:attributes:error:");
  bool _objc_msgSend_390(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    bool createIntermediates,
    ffi.Pointer<ObjCObject> attributes,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_390(
      obj,
      sel,
      url,
      createIntermediates,
      attributes,
      error,
    );
  }

  late final __objc_msgSend_390Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_390 = __objc_msgSend_390Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          bool,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_createSymbolicLinkAtURL_withDestinationURL_error_1 =
      _registerName1("createSymbolicLinkAtURL:withDestinationURL:error:");
  bool _objc_msgSend_391(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<ObjCObject> destURL,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_391(
      obj,
      sel,
      url,
      destURL,
      error,
    );
  }

  late final __objc_msgSend_391Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_391 = __objc_msgSend_391Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_delegate1 = _registerName1("delegate");
  late final _sel_setDelegate_1 = _registerName1("setDelegate:");
  late final _sel_setAttributes_ofItemAtPath_error_1 =
      _registerName1("setAttributes:ofItemAtPath:error:");
  bool _objc_msgSend_392(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> attributes,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_392(
      obj,
      sel,
      attributes,
      path,
      error,
    );
  }

  late final __objc_msgSend_392Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_392 = __objc_msgSend_392Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_createDirectoryAtPath_withIntermediateDirectories_attributes_error_1 =
      _registerName1(
          "createDirectoryAtPath:withIntermediateDirectories:attributes:error:");
  bool _objc_msgSend_393(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    bool createIntermediates,
    ffi.Pointer<ObjCObject> attributes,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_393(
      obj,
      sel,
      path,
      createIntermediates,
      attributes,
      error,
    );
  }

  late final __objc_msgSend_393Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_393 = __objc_msgSend_393Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          bool,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_contentsOfDirectoryAtPath_error_1 =
      _registerName1("contentsOfDirectoryAtPath:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_394(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_394(
      obj,
      sel,
      path,
      error,
    );
  }

  late final __objc_msgSend_394Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_394 = __objc_msgSend_394Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_subpathsOfDirectoryAtPath_error_1 =
      _registerName1("subpathsOfDirectoryAtPath:error:");
  late final _sel_attributesOfItemAtPath_error_1 =
      _registerName1("attributesOfItemAtPath:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_395(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_395(
      obj,
      sel,
      path,
      error,
    );
  }

  late final __objc_msgSend_395Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_395 = __objc_msgSend_395Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_attributesOfFileSystemForPath_error_1 =
      _registerName1("attributesOfFileSystemForPath:error:");
  late final _sel_createSymbolicLinkAtPath_withDestinationPath_error_1 =
      _registerName1("createSymbolicLinkAtPath:withDestinationPath:error:");
  bool _objc_msgSend_396(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ObjCObject> destPath,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_396(
      obj,
      sel,
      path,
      destPath,
      error,
    );
  }

  late final __objc_msgSend_396Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_396 = __objc_msgSend_396Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_destinationOfSymbolicLinkAtPath_error_1 =
      _registerName1("destinationOfSymbolicLinkAtPath:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_397(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_397(
      obj,
      sel,
      path,
      error,
    );
  }

  late final __objc_msgSend_397Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_397 = __objc_msgSend_397Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_copyItemAtPath_toPath_error_1 =
      _registerName1("copyItemAtPath:toPath:error:");
  late final _sel_moveItemAtPath_toPath_error_1 =
      _registerName1("moveItemAtPath:toPath:error:");
  late final _sel_linkItemAtPath_toPath_error_1 =
      _registerName1("linkItemAtPath:toPath:error:");
  late final _sel_removeItemAtPath_error_1 =
      _registerName1("removeItemAtPath:error:");
  bool _objc_msgSend_398(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_398(
      obj,
      sel,
      path,
      error,
    );
  }

  late final __objc_msgSend_398Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_398 = __objc_msgSend_398Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_copyItemAtURL_toURL_error_1 =
      _registerName1("copyItemAtURL:toURL:error:");
  late final _sel_moveItemAtURL_toURL_error_1 =
      _registerName1("moveItemAtURL:toURL:error:");
  late final _sel_linkItemAtURL_toURL_error_1 =
      _registerName1("linkItemAtURL:toURL:error:");
  late final _sel_removeItemAtURL_error_1 =
      _registerName1("removeItemAtURL:error:");
  late final _sel_trashItemAtURL_resultingItemURL_error_1 =
      _registerName1("trashItemAtURL:resultingItemURL:error:");
  bool _objc_msgSend_399(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outResultingURL,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_399(
      obj,
      sel,
      url,
      outResultingURL,
      error,
    );
  }

  late final __objc_msgSend_399Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_399 = __objc_msgSend_399Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_fileAttributesAtPath_traverseLink_1 =
      _registerName1("fileAttributesAtPath:traverseLink:");
  ffi.Pointer<ObjCObject> _objc_msgSend_400(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    bool yorn,
  ) {
    return __objc_msgSend_400(
      obj,
      sel,
      path,
      yorn,
    );
  }

  late final __objc_msgSend_400Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_400 = __objc_msgSend_400Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_changeFileAttributes_atPath_1 =
      _registerName1("changeFileAttributes:atPath:");
  bool _objc_msgSend_401(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> attributes,
    ffi.Pointer<ObjCObject> path,
  ) {
    return __objc_msgSend_401(
      obj,
      sel,
      attributes,
      path,
    );
  }

  late final __objc_msgSend_401Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_401 = __objc_msgSend_401Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_directoryContentsAtPath_1 =
      _registerName1("directoryContentsAtPath:");
  late final _sel_fileSystemAttributesAtPath_1 =
      _registerName1("fileSystemAttributesAtPath:");
  late final _sel_pathContentOfSymbolicLinkAtPath_1 =
      _registerName1("pathContentOfSymbolicLinkAtPath:");
  late final _sel_createSymbolicLinkAtPath_pathContent_1 =
      _registerName1("createSymbolicLinkAtPath:pathContent:");
  bool _objc_msgSend_402(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ObjCObject> otherpath,
  ) {
    return __objc_msgSend_402(
      obj,
      sel,
      path,
      otherpath,
    );
  }

  late final __objc_msgSend_402Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_402 = __objc_msgSend_402Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_createDirectoryAtPath_attributes_1 =
      _registerName1("createDirectoryAtPath:attributes:");
  bool _objc_msgSend_403(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ObjCObject> attributes,
  ) {
    return __objc_msgSend_403(
      obj,
      sel,
      path,
      attributes,
    );
  }

  late final __objc_msgSend_403Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_403 = __objc_msgSend_403Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_linkPath_toPath_handler_1 =
      _registerName1("linkPath:toPath:handler:");
  bool _objc_msgSend_404(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> src,
    ffi.Pointer<ObjCObject> dest,
    ffi.Pointer<ObjCObject> handler,
  ) {
    return __objc_msgSend_404(
      obj,
      sel,
      src,
      dest,
      handler,
    );
  }

  late final __objc_msgSend_404Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_404 = __objc_msgSend_404Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_copyPath_toPath_handler_1 =
      _registerName1("copyPath:toPath:handler:");
  late final _sel_movePath_toPath_handler_1 =
      _registerName1("movePath:toPath:handler:");
  late final _sel_removeFileAtPath_handler_1 =
      _registerName1("removeFileAtPath:handler:");
  bool _objc_msgSend_405(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ObjCObject> handler,
  ) {
    return __objc_msgSend_405(
      obj,
      sel,
      path,
      handler,
    );
  }

  late final __objc_msgSend_405Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_405 = __objc_msgSend_405Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_currentDirectoryPath1 =
      _registerName1("currentDirectoryPath");
  late final _sel_changeCurrentDirectoryPath_1 =
      _registerName1("changeCurrentDirectoryPath:");
  late final _sel_fileExistsAtPath_1 = _registerName1("fileExistsAtPath:");
  late final _sel_fileExistsAtPath_isDirectory_1 =
      _registerName1("fileExistsAtPath:isDirectory:");
  bool _objc_msgSend_406(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ffi.Bool> isDirectory,
  ) {
    return __objc_msgSend_406(
      obj,
      sel,
      path,
      isDirectory,
    );
  }

  late final __objc_msgSend_406Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Bool>)>>('objc_msgSend');
  late final __objc_msgSend_406 = __objc_msgSend_406Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Bool>)>();

  late final _sel_isReadableFileAtPath_1 =
      _registerName1("isReadableFileAtPath:");
  late final _sel_isWritableFileAtPath_1 =
      _registerName1("isWritableFileAtPath:");
  late final _sel_isExecutableFileAtPath_1 =
      _registerName1("isExecutableFileAtPath:");
  late final _sel_isDeletableFileAtPath_1 =
      _registerName1("isDeletableFileAtPath:");
  late final _sel_contentsEqualAtPath_andPath_1 =
      _registerName1("contentsEqualAtPath:andPath:");
  late final _sel_displayNameAtPath_1 = _registerName1("displayNameAtPath:");
  late final _sel_componentsToDisplayForPath_1 =
      _registerName1("componentsToDisplayForPath:");
  late final _sel_homeDirectoryForCurrentUser1 =
      _registerName1("homeDirectoryForCurrentUser");
  late final _sel_temporaryDirectory1 = _registerName1("temporaryDirectory");
  late final _sel_homeDirectoryForUser_1 =
      _registerName1("homeDirectoryForUser:");
  late final _sel_fileManager_shouldProceedAfterError_1 =
      _registerName1("fileManager:shouldProceedAfterError:");
  bool _objc_msgSend_407(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> fm,
    ffi.Pointer<ObjCObject> errorInfo,
  ) {
    return __objc_msgSend_407(
      obj,
      sel,
      fm,
      errorInfo,
    );
  }

  late final __objc_msgSend_407Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_407 = __objc_msgSend_407Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_fileManager_willProcessPath_1 =
      _registerName1("fileManager:willProcessPath:");
  void _objc_msgSend_408(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> fm,
    ffi.Pointer<ObjCObject> path,
  ) {
    return __objc_msgSend_408(
      obj,
      sel,
      fm,
      path,
    );
  }

  late final __objc_msgSend_408Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_408 = __objc_msgSend_408Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_validateValue_forKey_error_1 =
      _registerName1("validateValue:forKey:error:");
  late final _class_NSMutableArray1 = _getClass1("NSMutableArray");
  late final _sel_addObject_1 = _registerName1("addObject:");
  late final _sel_insertObject_atIndex_1 =
      _registerName1("insertObject:atIndex:");
  void _objc_msgSend_409(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anObject,
    int index,
  ) {
    return __objc_msgSend_409(
      obj,
      sel,
      anObject,
      index,
    );
  }

  late final __objc_msgSend_409Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_409 = __objc_msgSend_409Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_removeLastObject1 = _registerName1("removeLastObject");
  late final _sel_removeObjectAtIndex_1 =
      _registerName1("removeObjectAtIndex:");
  void _objc_msgSend_410(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
  ) {
    return __objc_msgSend_410(
      obj,
      sel,
      index,
    );
  }

  late final __objc_msgSend_410Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_410 = __objc_msgSend_410Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_replaceObjectAtIndex_withObject_1 =
      _registerName1("replaceObjectAtIndex:withObject:");
  void _objc_msgSend_411(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
    ffi.Pointer<ObjCObject> anObject,
  ) {
    return __objc_msgSend_411(
      obj,
      sel,
      index,
      anObject,
    );
  }

  late final __objc_msgSend_411Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_411 = __objc_msgSend_411Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithCapacity_1 = _registerName1("initWithCapacity:");
  late final _sel_addObjectsFromArray_1 =
      _registerName1("addObjectsFromArray:");
  void _objc_msgSend_412(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> otherArray,
  ) {
    return __objc_msgSend_412(
      obj,
      sel,
      otherArray,
    );
  }

  late final __objc_msgSend_412Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_412 = __objc_msgSend_412Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_exchangeObjectAtIndex_withObjectAtIndex_1 =
      _registerName1("exchangeObjectAtIndex:withObjectAtIndex:");
  void _objc_msgSend_413(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int idx1,
    int idx2,
  ) {
    return __objc_msgSend_413(
      obj,
      sel,
      idx1,
      idx2,
    );
  }

  late final __objc_msgSend_413Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_413 = __objc_msgSend_413Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int, int)>();

  late final _sel_removeAllObjects1 = _registerName1("removeAllObjects");
  late final _sel_removeObject_inRange_1 =
      _registerName1("removeObject:inRange:");
  void _objc_msgSend_414(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anObject,
    NSRange range,
  ) {
    return __objc_msgSend_414(
      obj,
      sel,
      anObject,
      range,
    );
  }

  late final __objc_msgSend_414Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_414 = __objc_msgSend_414Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, NSRange)>();

  late final _sel_removeObject_1 = _registerName1("removeObject:");
  late final _sel_removeObjectIdenticalTo_inRange_1 =
      _registerName1("removeObjectIdenticalTo:inRange:");
  late final _sel_removeObjectIdenticalTo_1 =
      _registerName1("removeObjectIdenticalTo:");
  late final _sel_removeObjectsFromIndices_numIndices_1 =
      _registerName1("removeObjectsFromIndices:numIndices:");
  void _objc_msgSend_415(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSUInteger> indices,
    int cnt,
  ) {
    return __objc_msgSend_415(
      obj,
      sel,
      indices,
      cnt,
    );
  }

  late final __objc_msgSend_415Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSUInteger>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_415 = __objc_msgSend_415Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSUInteger>, int)>();

  late final _sel_removeObjectsInArray_1 =
      _registerName1("removeObjectsInArray:");
  late final _sel_removeObjectsInRange_1 =
      _registerName1("removeObjectsInRange:");
  void _objc_msgSend_416(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
  ) {
    return __objc_msgSend_416(
      obj,
      sel,
      range,
    );
  }

  late final __objc_msgSend_416Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_416 = __objc_msgSend_416Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _sel_replaceObjectsInRange_withObjectsFromArray_range_1 =
      _registerName1("replaceObjectsInRange:withObjectsFromArray:range:");
  void _objc_msgSend_417(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> otherArray,
    NSRange otherRange,
  ) {
    return __objc_msgSend_417(
      obj,
      sel,
      range,
      otherArray,
      otherRange,
    );
  }

  late final __objc_msgSend_417Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Pointer<ObjCObject>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_417 = __objc_msgSend_417Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange,
          ffi.Pointer<ObjCObject>, NSRange)>();

  late final _sel_replaceObjectsInRange_withObjectsFromArray_1 =
      _registerName1("replaceObjectsInRange:withObjectsFromArray:");
  void _objc_msgSend_418(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> otherArray,
  ) {
    return __objc_msgSend_418(
      obj,
      sel,
      range,
      otherArray,
    );
  }

  late final __objc_msgSend_418Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_418 = __objc_msgSend_418Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_setArray_1 = _registerName1("setArray:");
  late final _sel_sortUsingFunction_context_1 =
      _registerName1("sortUsingFunction:context:");
  void _objc_msgSend_419(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<
            ffi.NativeFunction<
                NSInteger Function(ffi.Pointer<ObjCObject>,
                    ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>
        compare,
    ffi.Pointer<ffi.Void> context,
  ) {
    return __objc_msgSend_419(
      obj,
      sel,
      compare,
      context,
    );
  }

  late final __objc_msgSend_419Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<
                  ffi.NativeFunction<
                      NSInteger Function(ffi.Pointer<ObjCObject>,
                          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>,
              ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_419 = __objc_msgSend_419Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<
              ffi.NativeFunction<
                  NSInteger Function(ffi.Pointer<ObjCObject>,
                      ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_sortUsingSelector_1 = _registerName1("sortUsingSelector:");
  late final _sel_insertObjects_atIndexes_1 =
      _registerName1("insertObjects:atIndexes:");
  void _objc_msgSend_420(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> objects,
    ffi.Pointer<ObjCObject> indexes,
  ) {
    return __objc_msgSend_420(
      obj,
      sel,
      objects,
      indexes,
    );
  }

  late final __objc_msgSend_420Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_420 = __objc_msgSend_420Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_removeObjectsAtIndexes_1 =
      _registerName1("removeObjectsAtIndexes:");
  void _objc_msgSend_421(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> indexes,
  ) {
    return __objc_msgSend_421(
      obj,
      sel,
      indexes,
    );
  }

  late final __objc_msgSend_421Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_421 = __objc_msgSend_421Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_replaceObjectsAtIndexes_withObjects_1 =
      _registerName1("replaceObjectsAtIndexes:withObjects:");
  void _objc_msgSend_422(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> indexes,
    ffi.Pointer<ObjCObject> objects,
  ) {
    return __objc_msgSend_422(
      obj,
      sel,
      indexes,
      objects,
    );
  }

  late final __objc_msgSend_422Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_422 = __objc_msgSend_422Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_setObject_atIndexedSubscript_1 =
      _registerName1("setObject:atIndexedSubscript:");
  late final _sel_sortUsingComparator_1 =
      _registerName1("sortUsingComparator:");
  void _objc_msgSend_423(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSComparator cmptr,
  ) {
    return __objc_msgSend_423(
      obj,
      sel,
      cmptr,
    );
  }

  late final __objc_msgSend_423Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSComparator)>>('objc_msgSend');
  late final __objc_msgSend_423 = __objc_msgSend_423Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSComparator)>();

  late final _sel_sortWithOptions_usingComparator_1 =
      _registerName1("sortWithOptions:usingComparator:");
  void _objc_msgSend_424(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int opts,
    NSComparator cmptr,
  ) {
    return __objc_msgSend_424(
      obj,
      sel,
      opts,
      cmptr,
    );
  }

  late final __objc_msgSend_424Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, NSComparator)>>('objc_msgSend');
  late final __objc_msgSend_424 = __objc_msgSend_424Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int, NSComparator)>();

  late final _sel_arrayWithCapacity_1 = _registerName1("arrayWithCapacity:");
  ffi.Pointer<ObjCObject> _objc_msgSend_425(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
  ) {
    return __objc_msgSend_425(
      obj,
      sel,
      path,
    );
  }

  late final __objc_msgSend_425Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_425 = __objc_msgSend_425Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  ffi.Pointer<ObjCObject> _objc_msgSend_426(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
  ) {
    return __objc_msgSend_426(
      obj,
      sel,
      url,
    );
  }

  late final __objc_msgSend_426Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_426 = __objc_msgSend_426Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_applyDifference_1 = _registerName1("applyDifference:");
  late final _sel_sortUsingDescriptors_1 =
      _registerName1("sortUsingDescriptors:");
  late final _sel_filterUsingPredicate_1 =
      _registerName1("filterUsingPredicate:");
  void _objc_msgSend_427(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> predicate,
  ) {
    return __objc_msgSend_427(
      obj,
      sel,
      predicate,
    );
  }

  late final __objc_msgSend_427Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_427 = __objc_msgSend_427Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_mutableArrayValueForKey_1 =
      _registerName1("mutableArrayValueForKey:");
  late final _class_NSMutableOrderedSet1 = _getClass1("NSMutableOrderedSet");
  late final _class_NSOrderedSet1 = _getClass1("NSOrderedSet");
  late final _sel_isEqualToOrderedSet_1 =
      _registerName1("isEqualToOrderedSet:");
  bool _objc_msgSend_428(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> other,
  ) {
    return __objc_msgSend_428(
      obj,
      sel,
      other,
    );
  }

  late final __objc_msgSend_428Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_428 = __objc_msgSend_428Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_intersectsOrderedSet_1 =
      _registerName1("intersectsOrderedSet:");
  late final _sel_isSubsetOfOrderedSet_1 =
      _registerName1("isSubsetOfOrderedSet:");
  late final _sel_reversedOrderedSet1 = _registerName1("reversedOrderedSet");
  ffi.Pointer<ObjCObject> _objc_msgSend_429(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_429(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_429Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_429 = __objc_msgSend_429Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_orderedSet1 = _registerName1("orderedSet");
  late final _sel_orderedSetWithObject_1 =
      _registerName1("orderedSetWithObject:");
  late final _sel_orderedSetWithObjects_count_1 =
      _registerName1("orderedSetWithObjects:count:");
  late final _sel_orderedSetWithObjects_1 =
      _registerName1("orderedSetWithObjects:");
  late final _sel_orderedSetWithOrderedSet_1 =
      _registerName1("orderedSetWithOrderedSet:");
  instancetype _objc_msgSend_430(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> set1,
  ) {
    return __objc_msgSend_430(
      obj,
      sel,
      set1,
    );
  }

  late final __objc_msgSend_430Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_430 = __objc_msgSend_430Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_orderedSetWithOrderedSet_range_copyItems_1 =
      _registerName1("orderedSetWithOrderedSet:range:copyItems:");
  instancetype _objc_msgSend_431(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> set1,
    NSRange range,
    bool flag,
  ) {
    return __objc_msgSend_431(
      obj,
      sel,
      set1,
      range,
      flag,
    );
  }

  late final __objc_msgSend_431Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSRange, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_431 = __objc_msgSend_431Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, NSRange, bool)>();

  late final _sel_orderedSetWithArray_1 =
      _registerName1("orderedSetWithArray:");
  late final _sel_orderedSetWithArray_range_copyItems_1 =
      _registerName1("orderedSetWithArray:range:copyItems:");
  instancetype _objc_msgSend_432(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> array,
    NSRange range,
    bool flag,
  ) {
    return __objc_msgSend_432(
      obj,
      sel,
      array,
      range,
      flag,
    );
  }

  late final __objc_msgSend_432Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSRange, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_432 = __objc_msgSend_432Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, NSRange, bool)>();

  late final _sel_orderedSetWithSet_1 = _registerName1("orderedSetWithSet:");
  late final _sel_orderedSetWithSet_copyItems_1 =
      _registerName1("orderedSetWithSet:copyItems:");
  late final _sel_initWithObject_1 = _registerName1("initWithObject:");
  late final _sel_initWithOrderedSet_1 = _registerName1("initWithOrderedSet:");
  late final _sel_initWithOrderedSet_copyItems_1 =
      _registerName1("initWithOrderedSet:copyItems:");
  instancetype _objc_msgSend_433(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> set1,
    bool flag,
  ) {
    return __objc_msgSend_433(
      obj,
      sel,
      set1,
      flag,
    );
  }

  late final __objc_msgSend_433Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_433 = __objc_msgSend_433Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_initWithOrderedSet_range_copyItems_1 =
      _registerName1("initWithOrderedSet:range:copyItems:");
  late final _sel_initWithArray_range_copyItems_1 =
      _registerName1("initWithArray:range:copyItems:");
  late final _sel_filteredOrderedSetUsingPredicate_1 =
      _registerName1("filteredOrderedSetUsingPredicate:");
  ffi.Pointer<ObjCObject> _objc_msgSend_434(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> p,
  ) {
    return __objc_msgSend_434(
      obj,
      sel,
      p,
    );
  }

  late final __objc_msgSend_434Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_434 = __objc_msgSend_434Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_addObjects_count_1 = _registerName1("addObjects:count:");
  void _objc_msgSend_435(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
    int count,
  ) {
    return __objc_msgSend_435(
      obj,
      sel,
      objects,
      count,
    );
  }

  late final __objc_msgSend_435Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_435 = __objc_msgSend_435Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>, int)>();

  late final _sel_moveObjectsAtIndexes_toIndex_1 =
      _registerName1("moveObjectsAtIndexes:toIndex:");
  void _objc_msgSend_436(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> indexes,
    int idx,
  ) {
    return __objc_msgSend_436(
      obj,
      sel,
      indexes,
      idx,
    );
  }

  late final __objc_msgSend_436Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_436 = __objc_msgSend_436Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_setObject_atIndex_1 = _registerName1("setObject:atIndex:");
  late final _sel_replaceObjectsInRange_withObjects_count_1 =
      _registerName1("replaceObjectsInRange:withObjects:count:");
  void _objc_msgSend_437(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
    int count,
  ) {
    return __objc_msgSend_437(
      obj,
      sel,
      range,
      objects,
      count,
    );
  }

  late final __objc_msgSend_437Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_437 = __objc_msgSend_437Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange,
          ffi.Pointer<ffi.Pointer<ObjCObject>>, int)>();

  late final _sel_intersectOrderedSet_1 =
      _registerName1("intersectOrderedSet:");
  void _objc_msgSend_438(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> other,
  ) {
    return __objc_msgSend_438(
      obj,
      sel,
      other,
    );
  }

  late final __objc_msgSend_438Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_438 = __objc_msgSend_438Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_minusOrderedSet_1 = _registerName1("minusOrderedSet:");
  late final _sel_unionOrderedSet_1 = _registerName1("unionOrderedSet:");
  late final _sel_intersectSet_1 = _registerName1("intersectSet:");
  void _objc_msgSend_439(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> other,
  ) {
    return __objc_msgSend_439(
      obj,
      sel,
      other,
    );
  }

  late final __objc_msgSend_439Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_439 = __objc_msgSend_439Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_minusSet_1 = _registerName1("minusSet:");
  late final _sel_unionSet_1 = _registerName1("unionSet:");
  late final _sel_sortRange_options_usingComparator_1 =
      _registerName1("sortRange:options:usingComparator:");
  void _objc_msgSend_440(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    int opts,
    NSComparator cmptr,
  ) {
    return __objc_msgSend_440(
      obj,
      sel,
      range,
      opts,
      cmptr,
    );
  }

  late final __objc_msgSend_440Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Int32, NSComparator)>>('objc_msgSend');
  late final __objc_msgSend_440 = __objc_msgSend_440Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange, int,
          NSComparator)>();

  late final _sel_orderedSetWithCapacity_1 =
      _registerName1("orderedSetWithCapacity:");
  late final _sel_mutableOrderedSetValueForKey_1 =
      _registerName1("mutableOrderedSetValueForKey:");
  ffi.Pointer<ObjCObject> _objc_msgSend_441(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_441(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_441Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_441 = __objc_msgSend_441Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _class_NSMutableSet1 = _getClass1("NSMutableSet");
  late final _sel_setSet_1 = _registerName1("setSet:");
  late final _sel_setWithCapacity_1 = _registerName1("setWithCapacity:");
  late final _sel_mutableSetValueForKey_1 =
      _registerName1("mutableSetValueForKey:");
  ffi.Pointer<ObjCObject> _objc_msgSend_442(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_442(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_442Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_442 = __objc_msgSend_442Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_valueForKeyPath_1 = _registerName1("valueForKeyPath:");
  late final _sel_setValue_forKeyPath_1 =
      _registerName1("setValue:forKeyPath:");
  late final _sel_validateValue_forKeyPath_error_1 =
      _registerName1("validateValue:forKeyPath:error:");
  late final _sel_mutableArrayValueForKeyPath_1 =
      _registerName1("mutableArrayValueForKeyPath:");
  late final _sel_mutableOrderedSetValueForKeyPath_1 =
      _registerName1("mutableOrderedSetValueForKeyPath:");
  late final _sel_mutableSetValueForKeyPath_1 =
      _registerName1("mutableSetValueForKeyPath:");
  late final _sel_valueForUndefinedKey_1 =
      _registerName1("valueForUndefinedKey:");
  late final _sel_setValue_forUndefinedKey_1 =
      _registerName1("setValue:forUndefinedKey:");
  late final _sel_setNilValueForKey_1 = _registerName1("setNilValueForKey:");
  late final _sel_dictionaryWithValuesForKeys_1 =
      _registerName1("dictionaryWithValuesForKeys:");
  ffi.Pointer<ObjCObject> _objc_msgSend_443(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> keys,
  ) {
    return __objc_msgSend_443(
      obj,
      sel,
      keys,
    );
  }

  late final __objc_msgSend_443Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_443 = __objc_msgSend_443Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_setValuesForKeysWithDictionary_1 =
      _registerName1("setValuesForKeysWithDictionary:");
  void _objc_msgSend_444(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> keyedValues,
  ) {
    return __objc_msgSend_444(
      obj,
      sel,
      keyedValues,
    );
  }

  late final __objc_msgSend_444Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_444 = __objc_msgSend_444Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_storedValueForKey_1 = _registerName1("storedValueForKey:");
  late final _sel_takeStoredValue_forKey_1 =
      _registerName1("takeStoredValue:forKey:");
  late final _sel_takeValue_forKey_1 = _registerName1("takeValue:forKey:");
  late final _sel_takeValue_forKeyPath_1 =
      _registerName1("takeValue:forKeyPath:");
  late final _sel_handleQueryWithUnboundKey_1 =
      _registerName1("handleQueryWithUnboundKey:");
  late final _sel_handleTakeValue_forUnboundKey_1 =
      _registerName1("handleTakeValue:forUnboundKey:");
  late final _sel_unableToSetNilForKey_1 =
      _registerName1("unableToSetNilForKey:");
  late final _sel_valuesForKeys_1 = _registerName1("valuesForKeys:");
  late final _sel_takeValuesFromDictionary_1 =
      _registerName1("takeValuesFromDictionary:");
  late final _sel_observeValueForKeyPath_ofObject_change_context_1 =
      _registerName1("observeValueForKeyPath:ofObject:change:context:");
  void _objc_msgSend_445(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> keyPath,
    ffi.Pointer<ObjCObject> object,
    ffi.Pointer<ObjCObject> change,
    ffi.Pointer<ffi.Void> context,
  ) {
    return __objc_msgSend_445(
      obj,
      sel,
      keyPath,
      object,
      change,
      context,
    );
  }

  late final __objc_msgSend_445Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_445 = __objc_msgSend_445Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_willChangeValueForKey_1 =
      _registerName1("willChangeValueForKey:");
  late final _sel_didChangeValueForKey_1 =
      _registerName1("didChangeValueForKey:");
  late final _sel_willChange_valuesAtIndexes_forKey_1 =
      _registerName1("willChange:valuesAtIndexes:forKey:");
  void _objc_msgSend_446(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int changeKind,
    ffi.Pointer<ObjCObject> indexes,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_446(
      obj,
      sel,
      changeKind,
      indexes,
      key,
    );
  }

  late final __objc_msgSend_446Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_446 = __objc_msgSend_446Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_didChange_valuesAtIndexes_forKey_1 =
      _registerName1("didChange:valuesAtIndexes:forKey:");
  late final _sel_willChangeValueForKey_withSetMutation_usingObjects_1 =
      _registerName1("willChangeValueForKey:withSetMutation:usingObjects:");
  void _objc_msgSend_447(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
    int mutationKind,
    ffi.Pointer<ObjCObject> objects,
  ) {
    return __objc_msgSend_447(
      obj,
      sel,
      key,
      mutationKind,
      objects,
    );
  }

  late final __objc_msgSend_447Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_447 = __objc_msgSend_447Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, ffi.Pointer<ObjCObject>)>();

  late final _sel_didChangeValueForKey_withSetMutation_usingObjects_1 =
      _registerName1("didChangeValueForKey:withSetMutation:usingObjects:");
  late final _sel_observationInfo1 = _registerName1("observationInfo");
  late final _sel_setObservationInfo_1 = _registerName1("setObservationInfo:");
  void _objc_msgSend_448(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Void> value,
  ) {
    return __objc_msgSend_448(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_448Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_448 = __objc_msgSend_448Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_classForKeyedArchiver1 =
      _registerName1("classForKeyedArchiver");
  late final _class_NSKeyedArchiver1 = _getClass1("NSKeyedArchiver");
  late final _sel_initRequiringSecureCoding_1 =
      _registerName1("initRequiringSecureCoding:");
  instancetype _objc_msgSend_449(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool requiresSecureCoding,
  ) {
    return __objc_msgSend_449(
      obj,
      sel,
      requiresSecureCoding,
    );
  }

  late final __objc_msgSend_449Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_449 = __objc_msgSend_449Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool)>();

  late final _sel_archivedDataWithRootObject_requiringSecureCoding_error_1 =
      _registerName1("archivedDataWithRootObject:requiringSecureCoding:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_450(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> object,
    bool requiresSecureCoding,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_450(
      obj,
      sel,
      object,
      requiresSecureCoding,
      error,
    );
  }

  late final __objc_msgSend_450Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_450 = __objc_msgSend_450Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          bool,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _class_NSMutableData1 = _getClass1("NSMutableData");
  late final _sel_mutableBytes1 = _registerName1("mutableBytes");
  late final _sel_setLength_1 = _registerName1("setLength:");
  void _objc_msgSend_451(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_451(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_451Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_451 = __objc_msgSend_451Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_appendBytes_length_1 = _registerName1("appendBytes:length:");
  late final _sel_appendData_1 = _registerName1("appendData:");
  late final _sel_increaseLengthBy_1 = _registerName1("increaseLengthBy:");
  late final _sel_replaceBytesInRange_withBytes_1 =
      _registerName1("replaceBytesInRange:withBytes:");
  void _objc_msgSend_452(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ffi.Void> bytes,
  ) {
    return __objc_msgSend_452(
      obj,
      sel,
      range,
      bytes,
    );
  }

  late final __objc_msgSend_452Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_452 = __objc_msgSend_452Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_resetBytesInRange_1 = _registerName1("resetBytesInRange:");
  late final _sel_setData_1 = _registerName1("setData:");
  late final _sel_replaceBytesInRange_withBytes_length_1 =
      _registerName1("replaceBytesInRange:withBytes:length:");
  void _objc_msgSend_453(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ffi.Void> replacementBytes,
    int replacementLength,
  ) {
    return __objc_msgSend_453(
      obj,
      sel,
      range,
      replacementBytes,
      replacementLength,
    );
  }

  late final __objc_msgSend_453Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Pointer<ffi.Void>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_453 = __objc_msgSend_453Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange,
          ffi.Pointer<ffi.Void>, int)>();

  late final _sel_dataWithCapacity_1 = _registerName1("dataWithCapacity:");
  late final _sel_dataWithLength_1 = _registerName1("dataWithLength:");
  late final _sel_initWithLength_1 = _registerName1("initWithLength:");
  late final _sel_decompressUsingAlgorithm_error_1 =
      _registerName1("decompressUsingAlgorithm:error:");
  bool _objc_msgSend_454(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int algorithm,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_454(
      obj,
      sel,
      algorithm,
      error,
    );
  }

  late final __objc_msgSend_454Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_454 = __objc_msgSend_454Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_compressUsingAlgorithm_error_1 =
      _registerName1("compressUsingAlgorithm:error:");
  late final _sel_initForWritingWithMutableData_1 =
      _registerName1("initForWritingWithMutableData:");
  instancetype _objc_msgSend_455(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
  ) {
    return __objc_msgSend_455(
      obj,
      sel,
      data,
    );
  }

  late final __objc_msgSend_455Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_455 = __objc_msgSend_455Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_archivedDataWithRootObject_1 =
      _registerName1("archivedDataWithRootObject:");
  ffi.Pointer<ObjCObject> _objc_msgSend_456(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> rootObject,
  ) {
    return __objc_msgSend_456(
      obj,
      sel,
      rootObject,
    );
  }

  late final __objc_msgSend_456Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_456 = __objc_msgSend_456Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_archiveRootObject_toFile_1 =
      _registerName1("archiveRootObject:toFile:");
  late final _sel_outputFormat1 = _registerName1("outputFormat");
  int _objc_msgSend_457(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_457(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_457Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_457 = __objc_msgSend_457Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setOutputFormat_1 = _registerName1("setOutputFormat:");
  void _objc_msgSend_458(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_458(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_458Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_458 = __objc_msgSend_458Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_encodedData1 = _registerName1("encodedData");
  late final _sel_finishEncoding1 = _registerName1("finishEncoding");
  late final _sel_setClassName_forClass_1 =
      _registerName1("setClassName:forClass:");
  void _objc_msgSend_459(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> codedName,
    ffi.Pointer<ObjCObject> cls,
  ) {
    return __objc_msgSend_459(
      obj,
      sel,
      codedName,
      cls,
    );
  }

  late final __objc_msgSend_459Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_459 = __objc_msgSend_459Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_classNameForClass_1 = _registerName1("classNameForClass:");
  late final _sel_setRequiresSecureCoding_1 =
      _registerName1("setRequiresSecureCoding:");
  void _objc_msgSend_460(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool value,
  ) {
    return __objc_msgSend_460(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_460Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_460 = __objc_msgSend_460Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool)>();

  late final _sel_replacementObjectForKeyedArchiver_1 =
      _registerName1("replacementObjectForKeyedArchiver:");
  ffi.Pointer<ObjCObject> _objc_msgSend_461(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> archiver,
  ) {
    return __objc_msgSend_461(
      obj,
      sel,
      archiver,
    );
  }

  late final __objc_msgSend_461Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_461 = __objc_msgSend_461Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_performSelectorOnMainThread_withObject_waitUntilDone_modes_1 =
      _registerName1(
          "performSelectorOnMainThread:withObject:waitUntilDone:modes:");
  void _objc_msgSend_462(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
    ffi.Pointer<ObjCObject> arg,
    bool wait,
    ffi.Pointer<ObjCObject> array,
  ) {
    return __objc_msgSend_462(
      obj,
      sel,
      aSelector,
      arg,
      wait,
      array,
    );
  }

  late final __objc_msgSend_462Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_462 = __objc_msgSend_462Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          bool,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_performSelectorOnMainThread_withObject_waitUntilDone_1 =
      _registerName1("performSelectorOnMainThread:withObject:waitUntilDone:");
  void _objc_msgSend_463(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
    ffi.Pointer<ObjCObject> arg,
    bool wait,
  ) {
    return __objc_msgSend_463(
      obj,
      sel,
      aSelector,
      arg,
      wait,
    );
  }

  late final __objc_msgSend_463Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_463 = __objc_msgSend_463Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, bool)>();

  late final _class_NSThread1 = _getClass1("NSThread");
  late final _sel_currentThread1 = _registerName1("currentThread");
  ffi.Pointer<ObjCObject> _objc_msgSend_464(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_464(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_464Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_464 = __objc_msgSend_464Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_detachNewThreadWithBlock_1 =
      _registerName1("detachNewThreadWithBlock:");
  void _objc_msgSend_465(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_465(
      obj,
      sel,
      block,
    );
  }

  late final __objc_msgSend_465Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_465 = __objc_msgSend_465Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_detachNewThreadSelector_toTarget_withObject_1 =
      _registerName1("detachNewThreadSelector:toTarget:withObject:");
  void _objc_msgSend_466(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> selector,
    ffi.Pointer<ObjCObject> target,
    ffi.Pointer<ObjCObject> argument,
  ) {
    return __objc_msgSend_466(
      obj,
      sel,
      selector,
      target,
      argument,
    );
  }

  late final __objc_msgSend_466Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_466 = __objc_msgSend_466Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_isMultiThreaded1 = _registerName1("isMultiThreaded");
  late final _class_NSMutableDictionary1 = _getClass1("NSMutableDictionary");
  late final _sel_removeObjectForKey_1 = _registerName1("removeObjectForKey:");
  late final _sel_setObject_forKey_1 = _registerName1("setObject:forKey:");
  void _objc_msgSend_467(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anObject,
    ffi.Pointer<ObjCObject> aKey,
  ) {
    return __objc_msgSend_467(
      obj,
      sel,
      anObject,
      aKey,
    );
  }

  late final __objc_msgSend_467Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_467 = __objc_msgSend_467Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_addEntriesFromDictionary_1 =
      _registerName1("addEntriesFromDictionary:");
  late final _sel_removeObjectsForKeys_1 =
      _registerName1("removeObjectsForKeys:");
  late final _sel_setDictionary_1 = _registerName1("setDictionary:");
  late final _sel_setObject_forKeyedSubscript_1 =
      _registerName1("setObject:forKeyedSubscript:");
  late final _sel_dictionaryWithCapacity_1 =
      _registerName1("dictionaryWithCapacity:");
  ffi.Pointer<ObjCObject> _objc_msgSend_468(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
  ) {
    return __objc_msgSend_468(
      obj,
      sel,
      path,
    );
  }

  late final __objc_msgSend_468Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_468 = __objc_msgSend_468Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  ffi.Pointer<ObjCObject> _objc_msgSend_469(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
  ) {
    return __objc_msgSend_469(
      obj,
      sel,
      url,
    );
  }

  late final __objc_msgSend_469Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_469 = __objc_msgSend_469Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_dictionaryWithSharedKeySet_1 =
      _registerName1("dictionaryWithSharedKeySet:");
  ffi.Pointer<ObjCObject> _objc_msgSend_470(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> keyset,
  ) {
    return __objc_msgSend_470(
      obj,
      sel,
      keyset,
    );
  }

  late final __objc_msgSend_470Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_470 = __objc_msgSend_470Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_threadDictionary1 = _registerName1("threadDictionary");
  ffi.Pointer<ObjCObject> _objc_msgSend_471(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_471(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_471Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_471 = __objc_msgSend_471Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_sleepUntilDate_1 = _registerName1("sleepUntilDate:");
  void _objc_msgSend_472(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_472(
      obj,
      sel,
      date,
    );
  }

  late final __objc_msgSend_472Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_472 = __objc_msgSend_472Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_sleepForTimeInterval_1 =
      _registerName1("sleepForTimeInterval:");
  void _objc_msgSend_473(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double ti,
  ) {
    return __objc_msgSend_473(
      obj,
      sel,
      ti,
    );
  }

  late final __objc_msgSend_473Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSTimeInterval)>>('objc_msgSend');
  late final __objc_msgSend_473 = __objc_msgSend_473Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double)>();

  late final _sel_exit1 = _registerName1("exit");
  late final _sel_threadPriority1 = _registerName1("threadPriority");
  late final _sel_setThreadPriority_1 = _registerName1("setThreadPriority:");
  void _objc_msgSend_474(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double value,
  ) {
    return __objc_msgSend_474(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_474Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Double)>>('objc_msgSend');
  late final __objc_msgSend_474 = __objc_msgSend_474Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double)>();

  late final _sel_qualityOfService1 = _registerName1("qualityOfService");
  int _objc_msgSend_475(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_475(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_475Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_475 = __objc_msgSend_475Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setQualityOfService_1 =
      _registerName1("setQualityOfService:");
  void _objc_msgSend_476(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_476(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_476Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_476 = __objc_msgSend_476Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_callStackReturnAddresses1 =
      _registerName1("callStackReturnAddresses");
  late final _sel_callStackSymbols1 = _registerName1("callStackSymbols");
  late final _sel_setName_1 = _registerName1("setName:");
  void _objc_msgSend_477(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_477(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_477Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_477 = __objc_msgSend_477Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_stackSize1 = _registerName1("stackSize");
  late final _sel_setStackSize_1 = _registerName1("setStackSize:");
  late final _sel_isMainThread1 = _registerName1("isMainThread");
  late final _sel_mainThread1 = _registerName1("mainThread");
  late final _sel_initWithTarget_selector_object_1 =
      _registerName1("initWithTarget:selector:object:");
  instancetype _objc_msgSend_478(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> target,
    ffi.Pointer<ObjCSel> selector,
    ffi.Pointer<ObjCObject> argument,
  ) {
    return __objc_msgSend_478(
      obj,
      sel,
      target,
      selector,
      argument,
    );
  }

  late final __objc_msgSend_478Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_478 = __objc_msgSend_478Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithBlock_1 = _registerName1("initWithBlock:");
  instancetype _objc_msgSend_479(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_479(
      obj,
      sel,
      block,
    );
  }

  late final __objc_msgSend_479Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_479 = __objc_msgSend_479Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_isExecuting1 = _registerName1("isExecuting");
  late final _sel_isFinished1 = _registerName1("isFinished");
  late final _sel_isCancelled1 = _registerName1("isCancelled");
  late final _sel_cancel1 = _registerName1("cancel");
  late final _sel_start1 = _registerName1("start");
  late final _sel_main1 = _registerName1("main");
  late final _sel_performSelector_onThread_withObject_waitUntilDone_modes_1 =
      _registerName1(
          "performSelector:onThread:withObject:waitUntilDone:modes:");
  void _objc_msgSend_480(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
    ffi.Pointer<ObjCObject> thr,
    ffi.Pointer<ObjCObject> arg,
    bool wait,
    ffi.Pointer<ObjCObject> array,
  ) {
    return __objc_msgSend_480(
      obj,
      sel,
      aSelector,
      thr,
      arg,
      wait,
      array,
    );
  }

  late final __objc_msgSend_480Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_480 = __objc_msgSend_480Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          bool,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_performSelector_onThread_withObject_waitUntilDone_1 =
      _registerName1("performSelector:onThread:withObject:waitUntilDone:");
  void _objc_msgSend_481(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
    ffi.Pointer<ObjCObject> thr,
    ffi.Pointer<ObjCObject> arg,
    bool wait,
  ) {
    return __objc_msgSend_481(
      obj,
      sel,
      aSelector,
      thr,
      arg,
      wait,
    );
  }

  late final __objc_msgSend_481Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_481 = __objc_msgSend_481Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          bool)>();

  late final _sel_performSelectorInBackground_withObject_1 =
      _registerName1("performSelectorInBackground:withObject:");
  late final _sel_classForArchiver1 = _registerName1("classForArchiver");
  late final _class_NSArchiver1 = _getClass1("NSArchiver");
  late final _sel_archiverData1 = _registerName1("archiverData");
  ffi.Pointer<ObjCObject> _objc_msgSend_482(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_482(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_482Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_482 = __objc_msgSend_482Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_encodeClassName_intoClassName_1 =
      _registerName1("encodeClassName:intoClassName:");
  void _objc_msgSend_483(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> trueName,
    ffi.Pointer<ObjCObject> inArchiveName,
  ) {
    return __objc_msgSend_483(
      obj,
      sel,
      trueName,
      inArchiveName,
    );
  }

  late final __objc_msgSend_483Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_483 = __objc_msgSend_483Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_classNameEncodedForTrueClassName_1 =
      _registerName1("classNameEncodedForTrueClassName:");
  late final _sel_replaceObject_withObject_1 =
      _registerName1("replaceObject:withObject:");
  late final _sel_replacementObjectForArchiver_1 =
      _registerName1("replacementObjectForArchiver:");
  ffi.Pointer<ObjCObject> _objc_msgSend_484(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> archiver,
  ) {
    return __objc_msgSend_484(
      obj,
      sel,
      archiver,
    );
  }

  late final __objc_msgSend_484Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_484 = __objc_msgSend_484Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_classForPortCoder1 = _registerName1("classForPortCoder");
  late final _class_NSPortCoder1 = _getClass1("NSPortCoder");
  late final _sel_isBycopy1 = _registerName1("isBycopy");
  late final _sel_isByref1 = _registerName1("isByref");
  late final _class_NSPort1 = _getClass1("NSPort");
  ffi.Pointer<ObjCObject> _objc_msgSend_485(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_485(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_485Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_485 = __objc_msgSend_485Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_invalidate1 = _registerName1("invalidate");
  late final _sel_isValid1 = _registerName1("isValid");
  late final _class_NSRunLoop1 = _getClass1("NSRunLoop");
  late final _sel_currentRunLoop1 = _registerName1("currentRunLoop");
  ffi.Pointer<ObjCObject> _objc_msgSend_486(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_486(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_486Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_486 = __objc_msgSend_486Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_mainRunLoop1 = _registerName1("mainRunLoop");
  late final _sel_currentMode1 = _registerName1("currentMode");
  late final _sel_getCFRunLoop1 = _registerName1("getCFRunLoop");
  CFRunLoopRef _objc_msgSend_487(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_487(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_487Ptr = _lookup<
      ffi.NativeFunction<
          CFRunLoopRef Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_487 = __objc_msgSend_487Ptr.asFunction<
      CFRunLoopRef Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _class_NSTimer1 = _getClass1("NSTimer");
  late final _sel_timerWithTimeInterval_invocation_repeats_1 =
      _registerName1("timerWithTimeInterval:invocation:repeats:");
  ffi.Pointer<ObjCObject> _objc_msgSend_488(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double ti,
    ffi.Pointer<ObjCObject> invocation,
    bool yesOrNo,
  ) {
    return __objc_msgSend_488(
      obj,
      sel,
      ti,
      invocation,
      yesOrNo,
    );
  }

  late final __objc_msgSend_488Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSTimeInterval,
              ffi.Pointer<ObjCObject>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_488 = __objc_msgSend_488Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, double, ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_scheduledTimerWithTimeInterval_invocation_repeats_1 =
      _registerName1("scheduledTimerWithTimeInterval:invocation:repeats:");
  late final _sel_timerWithTimeInterval_target_selector_userInfo_repeats_1 =
      _registerName1("timerWithTimeInterval:target:selector:userInfo:repeats:");
  ffi.Pointer<ObjCObject> _objc_msgSend_489(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double ti,
    ffi.Pointer<ObjCObject> aTarget,
    ffi.Pointer<ObjCSel> aSelector,
    ffi.Pointer<ObjCObject> userInfo,
    bool yesOrNo,
  ) {
    return __objc_msgSend_489(
      obj,
      sel,
      ti,
      aTarget,
      aSelector,
      userInfo,
      yesOrNo,
    );
  }

  late final __objc_msgSend_489Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSTimeInterval,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_489 = __objc_msgSend_489Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          double,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          bool)>();

  late final _sel_scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_1 =
      _registerName1(
          "scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:");
  late final _sel_timerWithTimeInterval_repeats_block_1 =
      _registerName1("timerWithTimeInterval:repeats:block:");
  ffi.Pointer<ObjCObject> _objc_msgSend_490(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double interval,
    bool repeats,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_490(
      obj,
      sel,
      interval,
      repeats,
      block,
    );
  }

  late final __objc_msgSend_490Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSTimeInterval,
              ffi.Bool,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_490 = __objc_msgSend_490Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, double, bool, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_scheduledTimerWithTimeInterval_repeats_block_1 =
      _registerName1("scheduledTimerWithTimeInterval:repeats:block:");
  late final _sel_initWithFireDate_interval_repeats_block_1 =
      _registerName1("initWithFireDate:interval:repeats:block:");
  instancetype _objc_msgSend_491(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date,
    double interval,
    bool repeats,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_491(
      obj,
      sel,
      date,
      interval,
      repeats,
      block,
    );
  }

  late final __objc_msgSend_491Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSTimeInterval,
              ffi.Bool,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_491 = __objc_msgSend_491Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, double, bool, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_initWithFireDate_interval_target_selector_userInfo_repeats_1 =
      _registerName1(
          "initWithFireDate:interval:target:selector:userInfo:repeats:");
  instancetype _objc_msgSend_492(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date,
    double ti,
    ffi.Pointer<ObjCObject> t,
    ffi.Pointer<ObjCSel> s,
    ffi.Pointer<ObjCObject> ui,
    bool rep,
  ) {
    return __objc_msgSend_492(
      obj,
      sel,
      date,
      ti,
      t,
      s,
      ui,
      rep,
    );
  }

  late final __objc_msgSend_492Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSTimeInterval,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_492 = __objc_msgSend_492Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          double,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          bool)>();

  late final _sel_fire1 = _registerName1("fire");
  late final _sel_fireDate1 = _registerName1("fireDate");
  late final _sel_setFireDate_1 = _registerName1("setFireDate:");
  void _objc_msgSend_493(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_493(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_493Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_493 = __objc_msgSend_493Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_timeInterval1 = _registerName1("timeInterval");
  late final _sel_tolerance1 = _registerName1("tolerance");
  late final _sel_setTolerance_1 = _registerName1("setTolerance:");
  late final _sel_userInfo1 = _registerName1("userInfo");
  late final _sel_addTimer_forMode_1 = _registerName1("addTimer:forMode:");
  void _objc_msgSend_494(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> timer,
    NSRunLoopMode mode,
  ) {
    return __objc_msgSend_494(
      obj,
      sel,
      timer,
      mode,
    );
  }

  late final __objc_msgSend_494Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSRunLoopMode)>>('objc_msgSend');
  late final __objc_msgSend_494 = __objc_msgSend_494Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, NSRunLoopMode)>();

  late final _sel_addPort_forMode_1 = _registerName1("addPort:forMode:");
  void _objc_msgSend_495(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aPort,
    NSRunLoopMode mode,
  ) {
    return __objc_msgSend_495(
      obj,
      sel,
      aPort,
      mode,
    );
  }

  late final __objc_msgSend_495Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSRunLoopMode)>>('objc_msgSend');
  late final __objc_msgSend_495 = __objc_msgSend_495Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, NSRunLoopMode)>();

  late final _sel_removePort_forMode_1 = _registerName1("removePort:forMode:");
  late final _sel_limitDateForMode_1 = _registerName1("limitDateForMode:");
  ffi.Pointer<ObjCObject> _objc_msgSend_496(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRunLoopMode mode,
  ) {
    return __objc_msgSend_496(
      obj,
      sel,
      mode,
    );
  }

  late final __objc_msgSend_496Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSRunLoopMode)>>('objc_msgSend');
  late final __objc_msgSend_496 = __objc_msgSend_496Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRunLoopMode)>();

  late final _sel_acceptInputForMode_beforeDate_1 =
      _registerName1("acceptInputForMode:beforeDate:");
  void _objc_msgSend_497(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRunLoopMode mode,
    ffi.Pointer<ObjCObject> limitDate,
  ) {
    return __objc_msgSend_497(
      obj,
      sel,
      mode,
      limitDate,
    );
  }

  late final __objc_msgSend_497Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRunLoopMode, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_497 = __objc_msgSend_497Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          NSRunLoopMode, ffi.Pointer<ObjCObject>)>();

  late final _sel_run1 = _registerName1("run");
  late final _sel_runUntilDate_1 = _registerName1("runUntilDate:");
  late final _sel_runMode_beforeDate_1 = _registerName1("runMode:beforeDate:");
  bool _objc_msgSend_498(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRunLoopMode mode,
    ffi.Pointer<ObjCObject> limitDate,
  ) {
    return __objc_msgSend_498(
      obj,
      sel,
      mode,
      limitDate,
    );
  }

  late final __objc_msgSend_498Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRunLoopMode, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_498 = __objc_msgSend_498Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          NSRunLoopMode, ffi.Pointer<ObjCObject>)>();

  late final _sel_configureAsServer1 = _registerName1("configureAsServer");
  late final _sel_performInModes_block_1 =
      _registerName1("performInModes:block:");
  void _objc_msgSend_499(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> modes,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_499(
      obj,
      sel,
      modes,
      block,
    );
  }

  late final __objc_msgSend_499Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_499 = __objc_msgSend_499Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_performBlock_1 = _registerName1("performBlock:");
  late final _sel_performSelector_target_argument_order_modes_1 =
      _registerName1("performSelector:target:argument:order:modes:");
  void _objc_msgSend_500(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCSel> aSelector,
    ffi.Pointer<ObjCObject> target,
    ffi.Pointer<ObjCObject> arg,
    int order,
    ffi.Pointer<ObjCObject> modes,
  ) {
    return __objc_msgSend_500(
      obj,
      sel,
      aSelector,
      target,
      arg,
      order,
      modes,
    );
  }

  late final __objc_msgSend_500Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              NSUInteger,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_500 = __objc_msgSend_500Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_cancelPerformSelector_target_argument_1 =
      _registerName1("cancelPerformSelector:target:argument:");
  late final _sel_cancelPerformSelectorsWithTarget_1 =
      _registerName1("cancelPerformSelectorsWithTarget:");
  late final _sel_scheduleInRunLoop_forMode_1 =
      _registerName1("scheduleInRunLoop:forMode:");
  void _objc_msgSend_501(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> runLoop,
    NSRunLoopMode mode,
  ) {
    return __objc_msgSend_501(
      obj,
      sel,
      runLoop,
      mode,
    );
  }

  late final __objc_msgSend_501Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSRunLoopMode)>>('objc_msgSend');
  late final __objc_msgSend_501 = __objc_msgSend_501Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, NSRunLoopMode)>();

  late final _sel_removeFromRunLoop_forMode_1 =
      _registerName1("removeFromRunLoop:forMode:");
  late final _sel_reservedSpaceLength1 = _registerName1("reservedSpaceLength");
  late final _sel_sendBeforeDate_components_from_reserved_1 =
      _registerName1("sendBeforeDate:components:from:reserved:");
  bool _objc_msgSend_502(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> limitDate,
    ffi.Pointer<ObjCObject> components,
    ffi.Pointer<ObjCObject> receivePort,
    int headerSpaceReserved,
  ) {
    return __objc_msgSend_502(
      obj,
      sel,
      limitDate,
      components,
      receivePort,
      headerSpaceReserved,
    );
  }

  late final __objc_msgSend_502Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_502 = __objc_msgSend_502Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int)>();

  late final _sel_sendBeforeDate_msgid_components_from_reserved_1 =
      _registerName1("sendBeforeDate:msgid:components:from:reserved:");
  bool _objc_msgSend_503(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> limitDate,
    int msgID,
    ffi.Pointer<ObjCObject> components,
    ffi.Pointer<ObjCObject> receivePort,
    int headerSpaceReserved,
  ) {
    return __objc_msgSend_503(
      obj,
      sel,
      limitDate,
      msgID,
      components,
      receivePort,
      headerSpaceReserved,
    );
  }

  late final __objc_msgSend_503Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSUInteger,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_503 = __objc_msgSend_503Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int)>();

  late final _class_NSConnection1 = _getClass1("NSConnection");
  late final _sel_statistics1 = _registerName1("statistics");
  late final _sel_allConnections1 = _registerName1("allConnections");
  late final _sel_defaultConnection1 = _registerName1("defaultConnection");
  ffi.Pointer<ObjCObject> _objc_msgSend_504(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_504(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_504Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_504 = __objc_msgSend_504Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_connectionWithRegisteredName_host_1 =
      _registerName1("connectionWithRegisteredName:host:");
  late final _class_NSPortNameServer1 = _getClass1("NSPortNameServer");
  late final _sel_systemDefaultPortNameServer1 =
      _registerName1("systemDefaultPortNameServer");
  ffi.Pointer<ObjCObject> _objc_msgSend_505(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_505(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_505Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_505 = __objc_msgSend_505Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_portForName_1 = _registerName1("portForName:");
  ffi.Pointer<ObjCObject> _objc_msgSend_506(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
  ) {
    return __objc_msgSend_506(
      obj,
      sel,
      name,
    );
  }

  late final __objc_msgSend_506Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_506 = __objc_msgSend_506Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_portForName_host_1 = _registerName1("portForName:host:");
  ffi.Pointer<ObjCObject> _objc_msgSend_507(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> host,
  ) {
    return __objc_msgSend_507(
      obj,
      sel,
      name,
      host,
    );
  }

  late final __objc_msgSend_507Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_507 = __objc_msgSend_507Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_registerPort_name_1 = _registerName1("registerPort:name:");
  bool _objc_msgSend_508(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> port,
    ffi.Pointer<ObjCObject> name,
  ) {
    return __objc_msgSend_508(
      obj,
      sel,
      port,
      name,
    );
  }

  late final __objc_msgSend_508Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_508 = __objc_msgSend_508Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_removePortForName_1 = _registerName1("removePortForName:");
  late final _sel_connectionWithRegisteredName_host_usingNameServer_1 =
      _registerName1("connectionWithRegisteredName:host:usingNameServer:");
  instancetype _objc_msgSend_509(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> hostName,
    ffi.Pointer<ObjCObject> server,
  ) {
    return __objc_msgSend_509(
      obj,
      sel,
      name,
      hostName,
      server,
    );
  }

  late final __objc_msgSend_509Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_509 = __objc_msgSend_509Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _class_NSDistantObject1 = _getClass1("NSDistantObject");
  late final _class_NSProxy1 = _getClass1("NSProxy");
  late final _sel_respondsToSelector_1 = _registerName1("respondsToSelector:");
  late final _sel_proxyWithTarget_connection_1 =
      _registerName1("proxyWithTarget:connection:");
  ffi.Pointer<ObjCObject> _objc_msgSend_510(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> target,
    ffi.Pointer<ObjCObject> connection,
  ) {
    return __objc_msgSend_510(
      obj,
      sel,
      target,
      connection,
    );
  }

  late final __objc_msgSend_510Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_510 = __objc_msgSend_510Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithTarget_connection_1 =
      _registerName1("initWithTarget:connection:");
  late final _sel_proxyWithLocal_connection_1 =
      _registerName1("proxyWithLocal:connection:");
  late final _sel_initWithLocal_connection_1 =
      _registerName1("initWithLocal:connection:");
  late final _sel_setProtocolForProxy_1 =
      _registerName1("setProtocolForProxy:");
  void _objc_msgSend_511(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> proto,
  ) {
    return __objc_msgSend_511(
      obj,
      sel,
      proto,
    );
  }

  late final __objc_msgSend_511Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_511 = __objc_msgSend_511Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_connectionForProxy1 = _registerName1("connectionForProxy");
  late final _sel_rootProxyForConnectionWithRegisteredName_host_1 =
      _registerName1("rootProxyForConnectionWithRegisteredName:host:");
  ffi.Pointer<ObjCObject> _objc_msgSend_512(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> hostName,
  ) {
    return __objc_msgSend_512(
      obj,
      sel,
      name,
      hostName,
    );
  }

  late final __objc_msgSend_512Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_512 = __objc_msgSend_512Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_rootProxyForConnectionWithRegisteredName_host_usingNameServer_1 =
      _registerName1(
          "rootProxyForConnectionWithRegisteredName:host:usingNameServer:");
  ffi.Pointer<ObjCObject> _objc_msgSend_513(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> hostName,
    ffi.Pointer<ObjCObject> server,
  ) {
    return __objc_msgSend_513(
      obj,
      sel,
      name,
      hostName,
      server,
    );
  }

  late final __objc_msgSend_513Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_513 = __objc_msgSend_513Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_serviceConnectionWithName_rootObject_usingNameServer_1 =
      _registerName1("serviceConnectionWithName:rootObject:usingNameServer:");
  instancetype _objc_msgSend_514(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> root,
    ffi.Pointer<ObjCObject> server,
  ) {
    return __objc_msgSend_514(
      obj,
      sel,
      name,
      root,
      server,
    );
  }

  late final __objc_msgSend_514Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_514 = __objc_msgSend_514Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_serviceConnectionWithName_rootObject_1 =
      _registerName1("serviceConnectionWithName:rootObject:");
  late final _sel_requestTimeout1 = _registerName1("requestTimeout");
  late final _sel_setRequestTimeout_1 = _registerName1("setRequestTimeout:");
  late final _sel_replyTimeout1 = _registerName1("replyTimeout");
  late final _sel_setReplyTimeout_1 = _registerName1("setReplyTimeout:");
  late final _sel_rootObject1 = _registerName1("rootObject");
  late final _sel_setRootObject_1 = _registerName1("setRootObject:");
  late final _sel_independentConversationQueueing1 =
      _registerName1("independentConversationQueueing");
  late final _sel_setIndependentConversationQueueing_1 =
      _registerName1("setIndependentConversationQueueing:");
  late final _sel_rootProxy1 = _registerName1("rootProxy");
  ffi.Pointer<ObjCObject> _objc_msgSend_515(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_515(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_515Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_515 = __objc_msgSend_515Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_addRequestMode_1 = _registerName1("addRequestMode:");
  late final _sel_removeRequestMode_1 = _registerName1("removeRequestMode:");
  late final _sel_requestModes1 = _registerName1("requestModes");
  late final _sel_registerName_1 = _registerName1("registerName:");
  late final _sel_registerName_withNameServer_1 =
      _registerName1("registerName:withNameServer:");
  bool _objc_msgSend_516(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> server,
  ) {
    return __objc_msgSend_516(
      obj,
      sel,
      name,
      server,
    );
  }

  late final __objc_msgSend_516Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_516 = __objc_msgSend_516Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_connectionWithReceivePort_sendPort_1 =
      _registerName1("connectionWithReceivePort:sendPort:");
  instancetype _objc_msgSend_517(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> receivePort,
    ffi.Pointer<ObjCObject> sendPort,
  ) {
    return __objc_msgSend_517(
      obj,
      sel,
      receivePort,
      sendPort,
    );
  }

  late final __objc_msgSend_517Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_517 = __objc_msgSend_517Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_currentConversation1 = _registerName1("currentConversation");
  late final _sel_initWithReceivePort_sendPort_1 =
      _registerName1("initWithReceivePort:sendPort:");
  late final _sel_sendPort1 = _registerName1("sendPort");
  late final _sel_receivePort1 = _registerName1("receivePort");
  late final _sel_enableMultipleThreads1 =
      _registerName1("enableMultipleThreads");
  late final _sel_multipleThreadsEnabled1 =
      _registerName1("multipleThreadsEnabled");
  late final _sel_addRunLoop_1 = _registerName1("addRunLoop:");
  void _objc_msgSend_518(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> runloop,
  ) {
    return __objc_msgSend_518(
      obj,
      sel,
      runloop,
    );
  }

  late final __objc_msgSend_518Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_518 = __objc_msgSend_518Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_removeRunLoop_1 = _registerName1("removeRunLoop:");
  late final _sel_runInNewThread1 = _registerName1("runInNewThread");
  late final _sel_remoteObjects1 = _registerName1("remoteObjects");
  late final _sel_localObjects1 = _registerName1("localObjects");
  late final _sel_dispatchWithComponents_1 =
      _registerName1("dispatchWithComponents:");
  late final _sel_addConnection_toRunLoop_forMode_1 =
      _registerName1("addConnection:toRunLoop:forMode:");
  void _objc_msgSend_519(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> conn,
    ffi.Pointer<ObjCObject> runLoop,
    NSRunLoopMode mode,
  ) {
    return __objc_msgSend_519(
      obj,
      sel,
      conn,
      runLoop,
      mode,
    );
  }

  late final __objc_msgSend_519Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              NSRunLoopMode)>>('objc_msgSend');
  late final __objc_msgSend_519 = __objc_msgSend_519Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>, NSRunLoopMode)>();

  late final _sel_removeConnection_fromRunLoop_forMode_1 =
      _registerName1("removeConnection:fromRunLoop:forMode:");
  late final _sel_encodePortObject_1 = _registerName1("encodePortObject:");
  void _objc_msgSend_520(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aport,
  ) {
    return __objc_msgSend_520(
      obj,
      sel,
      aport,
    );
  }

  late final __objc_msgSend_520Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_520 = __objc_msgSend_520Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_decodePortObject1 = _registerName1("decodePortObject");
  late final _sel_connection1 = _registerName1("connection");
  late final _sel_portCoderWithReceivePort_sendPort_components_1 =
      _registerName1("portCoderWithReceivePort:sendPort:components:");
  ffi.Pointer<ObjCObject> _objc_msgSend_521(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> rcvPort,
    ffi.Pointer<ObjCObject> sndPort,
    ffi.Pointer<ObjCObject> comps,
  ) {
    return __objc_msgSend_521(
      obj,
      sel,
      rcvPort,
      sndPort,
      comps,
    );
  }

  late final __objc_msgSend_521Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_521 = __objc_msgSend_521Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithReceivePort_sendPort_components_1 =
      _registerName1("initWithReceivePort:sendPort:components:");
  late final _sel_dispatch1 = _registerName1("dispatch");
  late final _sel_replacementObjectForPortCoder_1 =
      _registerName1("replacementObjectForPortCoder:");
  ffi.Pointer<ObjCObject> _objc_msgSend_522(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> coder,
  ) {
    return __objc_msgSend_522(
      obj,
      sel,
      coder,
    );
  }

  late final __objc_msgSend_522Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_522 = __objc_msgSend_522Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _class_NSClassDescription1 = _getClass1("NSClassDescription");
  late final _sel_registerClassDescription_forClass_1 =
      _registerName1("registerClassDescription:forClass:");
  void _objc_msgSend_523(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> description,
    ffi.Pointer<ObjCObject> aClass,
  ) {
    return __objc_msgSend_523(
      obj,
      sel,
      description,
      aClass,
    );
  }

  late final __objc_msgSend_523Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_523 = __objc_msgSend_523Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_invalidateClassDescriptionCache1 =
      _registerName1("invalidateClassDescriptionCache");
  late final _sel_classDescriptionForClass_1 =
      _registerName1("classDescriptionForClass:");
  ffi.Pointer<ObjCObject> _objc_msgSend_524(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aClass,
  ) {
    return __objc_msgSend_524(
      obj,
      sel,
      aClass,
    );
  }

  late final __objc_msgSend_524Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_524 = __objc_msgSend_524Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_attributeKeys1 = _registerName1("attributeKeys");
  late final _sel_toOneRelationshipKeys1 =
      _registerName1("toOneRelationshipKeys");
  late final _sel_toManyRelationshipKeys1 =
      _registerName1("toManyRelationshipKeys");
  late final _sel_inverseForRelationshipKey_1 =
      _registerName1("inverseForRelationshipKey:");
  late final _sel_classDescription1 = _registerName1("classDescription");
  ffi.Pointer<ObjCObject> _objc_msgSend_525(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_525(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_525Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_525 = __objc_msgSend_525Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _class_NSScriptObjectSpecifier1 =
      _getClass1("NSScriptObjectSpecifier");
  late final _class_NSAppleEventDescriptor1 =
      _getClass1("NSAppleEventDescriptor");
  late final _sel_nullDescriptor1 = _registerName1("nullDescriptor");
  ffi.Pointer<ObjCObject> _objc_msgSend_526(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_526(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_526Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_526 = __objc_msgSend_526Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_descriptorWithDescriptorType_bytes_length_1 =
      _registerName1("descriptorWithDescriptorType:bytes:length:");
  ffi.Pointer<ObjCObject> _objc_msgSend_527(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int descriptorType,
    ffi.Pointer<ffi.Void> bytes,
    int byteCount,
  ) {
    return __objc_msgSend_527(
      obj,
      sel,
      descriptorType,
      bytes,
      byteCount,
    );
  }

  late final __objc_msgSend_527Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              DescType,
              ffi.Pointer<ffi.Void>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_527 = __objc_msgSend_527Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<ffi.Void>, int)>();

  late final _sel_descriptorWithDescriptorType_data_1 =
      _registerName1("descriptorWithDescriptorType:data:");
  ffi.Pointer<ObjCObject> _objc_msgSend_528(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int descriptorType,
    ffi.Pointer<ObjCObject> data,
  ) {
    return __objc_msgSend_528(
      obj,
      sel,
      descriptorType,
      data,
    );
  }

  late final __objc_msgSend_528Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              DescType,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_528 = __objc_msgSend_528Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<ObjCObject>)>();

  late final _sel_descriptorWithBoolean_1 =
      _registerName1("descriptorWithBoolean:");
  ffi.Pointer<ObjCObject> _objc_msgSend_529(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int boolean,
  ) {
    return __objc_msgSend_529(
      obj,
      sel,
      boolean,
    );
  }

  late final __objc_msgSend_529Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, Boolean)>>('objc_msgSend');
  late final __objc_msgSend_529 = __objc_msgSend_529Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_descriptorWithEnumCode_1 =
      _registerName1("descriptorWithEnumCode:");
  ffi.Pointer<ObjCObject> _objc_msgSend_530(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int enumerator,
  ) {
    return __objc_msgSend_530(
      obj,
      sel,
      enumerator,
    );
  }

  late final __objc_msgSend_530Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, OSType)>>('objc_msgSend');
  late final __objc_msgSend_530 = __objc_msgSend_530Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_descriptorWithInt32_1 =
      _registerName1("descriptorWithInt32:");
  ffi.Pointer<ObjCObject> _objc_msgSend_531(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int signedInt,
  ) {
    return __objc_msgSend_531(
      obj,
      sel,
      signedInt,
    );
  }

  late final __objc_msgSend_531Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, SInt32)>>('objc_msgSend');
  late final __objc_msgSend_531 = __objc_msgSend_531Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_descriptorWithDouble_1 =
      _registerName1("descriptorWithDouble:");
  ffi.Pointer<ObjCObject> _objc_msgSend_532(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double doubleValue,
  ) {
    return __objc_msgSend_532(
      obj,
      sel,
      doubleValue,
    );
  }

  late final __objc_msgSend_532Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Double)>>('objc_msgSend');
  late final __objc_msgSend_532 = __objc_msgSend_532Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double)>();

  late final _sel_descriptorWithTypeCode_1 =
      _registerName1("descriptorWithTypeCode:");
  late final _sel_descriptorWithString_1 =
      _registerName1("descriptorWithString:");
  ffi.Pointer<ObjCObject> _objc_msgSend_533(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
  ) {
    return __objc_msgSend_533(
      obj,
      sel,
      string,
    );
  }

  late final __objc_msgSend_533Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_533 = __objc_msgSend_533Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_descriptorWithDate_1 = _registerName1("descriptorWithDate:");
  ffi.Pointer<ObjCObject> _objc_msgSend_534(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_534(
      obj,
      sel,
      date,
    );
  }

  late final __objc_msgSend_534Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_534 = __objc_msgSend_534Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_descriptorWithFileURL_1 =
      _registerName1("descriptorWithFileURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_535(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> fileURL,
  ) {
    return __objc_msgSend_535(
      obj,
      sel,
      fileURL,
    );
  }

  late final __objc_msgSend_535Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_535 = __objc_msgSend_535Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_appleEventWithEventClass_eventID_targetDescriptor_returnID_transactionID_1 =
      _registerName1(
          "appleEventWithEventClass:eventID:targetDescriptor:returnID:transactionID:");
  ffi.Pointer<ObjCObject> _objc_msgSend_536(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int eventClass,
    int eventID,
    ffi.Pointer<ObjCObject> targetDescriptor,
    int returnID,
    int transactionID,
  ) {
    return __objc_msgSend_536(
      obj,
      sel,
      eventClass,
      eventID,
      targetDescriptor,
      returnID,
      transactionID,
    );
  }

  late final __objc_msgSend_536Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              AEEventClass,
              AEEventID,
              ffi.Pointer<ObjCObject>,
              AEReturnID,
              AETransactionID)>>('objc_msgSend');
  late final __objc_msgSend_536 = __objc_msgSend_536Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, int, ffi.Pointer<ObjCObject>, int, int)>();

  late final _sel_listDescriptor1 = _registerName1("listDescriptor");
  late final _sel_recordDescriptor1 = _registerName1("recordDescriptor");
  late final _sel_currentProcessDescriptor1 =
      _registerName1("currentProcessDescriptor");
  late final _sel_descriptorWithProcessIdentifier_1 =
      _registerName1("descriptorWithProcessIdentifier:");
  late final _sel_descriptorWithBundleIdentifier_1 =
      _registerName1("descriptorWithBundleIdentifier:");
  late final _sel_descriptorWithApplicationURL_1 =
      _registerName1("descriptorWithApplicationURL:");
  late final _sel_initWithAEDescNoCopy_1 =
      _registerName1("initWithAEDescNoCopy:");
  instancetype _objc_msgSend_537(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<AEDesc> aeDesc,
  ) {
    return __objc_msgSend_537(
      obj,
      sel,
      aeDesc,
    );
  }

  late final __objc_msgSend_537Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<AEDesc>)>>('objc_msgSend');
  late final __objc_msgSend_537 = __objc_msgSend_537Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<AEDesc>)>();

  late final _sel_initWithDescriptorType_bytes_length_1 =
      _registerName1("initWithDescriptorType:bytes:length:");
  instancetype _objc_msgSend_538(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int descriptorType,
    ffi.Pointer<ffi.Void> bytes,
    int byteCount,
  ) {
    return __objc_msgSend_538(
      obj,
      sel,
      descriptorType,
      bytes,
      byteCount,
    );
  }

  late final __objc_msgSend_538Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              DescType, ffi.Pointer<ffi.Void>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_538 = __objc_msgSend_538Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ffi.Void>, int)>();

  late final _sel_initWithDescriptorType_data_1 =
      _registerName1("initWithDescriptorType:data:");
  instancetype _objc_msgSend_539(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int descriptorType,
    ffi.Pointer<ObjCObject> data,
  ) {
    return __objc_msgSend_539(
      obj,
      sel,
      descriptorType,
      data,
    );
  }

  late final __objc_msgSend_539Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              DescType, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_539 = __objc_msgSend_539Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithEventClass_eventID_targetDescriptor_returnID_transactionID_1 =
      _registerName1(
          "initWithEventClass:eventID:targetDescriptor:returnID:transactionID:");
  instancetype _objc_msgSend_540(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int eventClass,
    int eventID,
    ffi.Pointer<ObjCObject> targetDescriptor,
    int returnID,
    int transactionID,
  ) {
    return __objc_msgSend_540(
      obj,
      sel,
      eventClass,
      eventID,
      targetDescriptor,
      returnID,
      transactionID,
    );
  }

  late final __objc_msgSend_540Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              AEEventClass,
              AEEventID,
              ffi.Pointer<ObjCObject>,
              AEReturnID,
              AETransactionID)>>('objc_msgSend');
  late final __objc_msgSend_540 = __objc_msgSend_540Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          int, ffi.Pointer<ObjCObject>, int, int)>();

  late final _sel_initListDescriptor1 = _registerName1("initListDescriptor");
  late final _sel_initRecordDescriptor1 =
      _registerName1("initRecordDescriptor");
  late final _sel_aeDesc1 = _registerName1("aeDesc");
  ffi.Pointer<AEDesc> _objc_msgSend_541(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_541(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_541Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<AEDesc> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_541 = __objc_msgSend_541Ptr.asFunction<
      ffi.Pointer<AEDesc> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_descriptorType1 = _registerName1("descriptorType");
  late final _sel_booleanValue1 = _registerName1("booleanValue");
  late final _sel_enumCodeValue1 = _registerName1("enumCodeValue");
  late final _sel_int32Value1 = _registerName1("int32Value");
  late final _sel_typeCodeValue1 = _registerName1("typeCodeValue");
  late final _sel_dateValue1 = _registerName1("dateValue");
  late final _sel_fileURLValue1 = _registerName1("fileURLValue");
  late final _sel_eventClass1 = _registerName1("eventClass");
  late final _sel_eventID1 = _registerName1("eventID");
  late final _sel_returnID1 = _registerName1("returnID");
  late final _sel_transactionID1 = _registerName1("transactionID");
  late final _sel_setParamDescriptor_forKeyword_1 =
      _registerName1("setParamDescriptor:forKeyword:");
  void _objc_msgSend_542(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> descriptor,
    int keyword,
  ) {
    return __objc_msgSend_542(
      obj,
      sel,
      descriptor,
      keyword,
    );
  }

  late final __objc_msgSend_542Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, AEKeyword)>>('objc_msgSend');
  late final __objc_msgSend_542 = __objc_msgSend_542Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_paramDescriptorForKeyword_1 =
      _registerName1("paramDescriptorForKeyword:");
  late final _sel_removeParamDescriptorWithKeyword_1 =
      _registerName1("removeParamDescriptorWithKeyword:");
  void _objc_msgSend_543(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int keyword,
  ) {
    return __objc_msgSend_543(
      obj,
      sel,
      keyword,
    );
  }

  late final __objc_msgSend_543Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              AEKeyword)>>('objc_msgSend');
  late final __objc_msgSend_543 = __objc_msgSend_543Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_setAttributeDescriptor_forKeyword_1 =
      _registerName1("setAttributeDescriptor:forKeyword:");
  late final _sel_attributeDescriptorForKeyword_1 =
      _registerName1("attributeDescriptorForKeyword:");
  late final _sel_sendEventWithOptions_timeout_error_1 =
      _registerName1("sendEventWithOptions:timeout:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_544(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int sendOptions,
    double timeoutInSeconds,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_544(
      obj,
      sel,
      sendOptions,
      timeoutInSeconds,
      error,
    );
  }

  late final __objc_msgSend_544Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              NSTimeInterval,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_544 = __objc_msgSend_544Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          int,
          double,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_isRecordDescriptor1 = _registerName1("isRecordDescriptor");
  late final _sel_numberOfItems1 = _registerName1("numberOfItems");
  late final _sel_insertDescriptor_atIndex_1 =
      _registerName1("insertDescriptor:atIndex:");
  void _objc_msgSend_545(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> descriptor,
    int index,
  ) {
    return __objc_msgSend_545(
      obj,
      sel,
      descriptor,
      index,
    );
  }

  late final __objc_msgSend_545Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_545 = __objc_msgSend_545Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_descriptorAtIndex_1 = _registerName1("descriptorAtIndex:");
  ffi.Pointer<ObjCObject> _objc_msgSend_546(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
  ) {
    return __objc_msgSend_546(
      obj,
      sel,
      index,
    );
  }

  late final __objc_msgSend_546Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_546 = __objc_msgSend_546Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_removeDescriptorAtIndex_1 =
      _registerName1("removeDescriptorAtIndex:");
  late final _sel_setDescriptor_forKeyword_1 =
      _registerName1("setDescriptor:forKeyword:");
  late final _sel_descriptorForKeyword_1 =
      _registerName1("descriptorForKeyword:");
  late final _sel_removeDescriptorWithKeyword_1 =
      _registerName1("removeDescriptorWithKeyword:");
  late final _sel_keywordForDescriptorAtIndex_1 =
      _registerName1("keywordForDescriptorAtIndex:");
  int _objc_msgSend_547(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
  ) {
    return __objc_msgSend_547(
      obj,
      sel,
      index,
    );
  }

  late final __objc_msgSend_547Ptr = _lookup<
      ffi.NativeFunction<
          AEKeyword Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_547 = __objc_msgSend_547Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_coerceToDescriptorType_1 =
      _registerName1("coerceToDescriptorType:");
  late final _sel_objectSpecifierWithDescriptor_1 =
      _registerName1("objectSpecifierWithDescriptor:");
  ffi.Pointer<ObjCObject> _objc_msgSend_548(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> descriptor,
  ) {
    return __objc_msgSend_548(
      obj,
      sel,
      descriptor,
    );
  }

  late final __objc_msgSend_548Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_548 = __objc_msgSend_548Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithContainerSpecifier_key_1 =
      _registerName1("initWithContainerSpecifier:key:");
  instancetype _objc_msgSend_549(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> container,
    ffi.Pointer<ObjCObject> property,
  ) {
    return __objc_msgSend_549(
      obj,
      sel,
      container,
      property,
    );
  }

  late final __objc_msgSend_549Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_549 = __objc_msgSend_549Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _class_NSScriptClassDescription1 =
      _getClass1("NSScriptClassDescription");
  ffi.Pointer<ObjCObject> _objc_msgSend_550(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aClass,
  ) {
    return __objc_msgSend_550(
      obj,
      sel,
      aClass,
    );
  }

  late final __objc_msgSend_550Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_550 = __objc_msgSend_550Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithSuiteName_className_dictionary_1 =
      _registerName1("initWithSuiteName:className:dictionary:");
  instancetype _objc_msgSend_551(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> suiteName,
    ffi.Pointer<ObjCObject> className,
    ffi.Pointer<ObjCObject> classDeclaration,
  ) {
    return __objc_msgSend_551(
      obj,
      sel,
      suiteName,
      className,
      classDeclaration,
    );
  }

  late final __objc_msgSend_551Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_551 = __objc_msgSend_551Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_suiteName1 = _registerName1("suiteName");
  late final _sel_className1 = _registerName1("className");
  late final _sel_implementationClassName1 =
      _registerName1("implementationClassName");
  late final _sel_superclassDescription1 =
      _registerName1("superclassDescription");
  ffi.Pointer<ObjCObject> _objc_msgSend_552(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_552(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_552Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_552 = __objc_msgSend_552Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_appleEventCode1 = _registerName1("appleEventCode");
  late final _sel_matchesAppleEventCode_1 =
      _registerName1("matchesAppleEventCode:");
  late final _class_NSScriptCommandDescription1 =
      _getClass1("NSScriptCommandDescription");
  late final _sel_initWithSuiteName_commandName_dictionary_1 =
      _registerName1("initWithSuiteName:commandName:dictionary:");
  late final _sel_commandName1 = _registerName1("commandName");
  late final _sel_appleEventClassCode1 = _registerName1("appleEventClassCode");
  late final _sel_commandClassName1 = _registerName1("commandClassName");
  late final _sel_returnType1 = _registerName1("returnType");
  late final _sel_appleEventCodeForReturnType1 =
      _registerName1("appleEventCodeForReturnType");
  late final _sel_argumentNames1 = _registerName1("argumentNames");
  late final _sel_typeForArgumentWithName_1 =
      _registerName1("typeForArgumentWithName:");
  late final _sel_appleEventCodeForArgumentWithName_1 =
      _registerName1("appleEventCodeForArgumentWithName:");
  int _objc_msgSend_553(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> argumentName,
  ) {
    return __objc_msgSend_553(
      obj,
      sel,
      argumentName,
    );
  }

  late final __objc_msgSend_553Ptr = _lookup<
      ffi.NativeFunction<
          FourCharCode Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_553 = __objc_msgSend_553Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_isOptionalArgumentWithName_1 =
      _registerName1("isOptionalArgumentWithName:");
  late final _class_NSScriptCommand1 = _getClass1("NSScriptCommand");
  late final _sel_initWithCommandDescription_1 =
      _registerName1("initWithCommandDescription:");
  instancetype _objc_msgSend_554(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> commandDef,
  ) {
    return __objc_msgSend_554(
      obj,
      sel,
      commandDef,
    );
  }

  late final __objc_msgSend_554Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_554 = __objc_msgSend_554Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_commandDescription1 = _registerName1("commandDescription");
  ffi.Pointer<ObjCObject> _objc_msgSend_555(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_555(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_555Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_555 = __objc_msgSend_555Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_directParameter1 = _registerName1("directParameter");
  late final _sel_setDirectParameter_1 = _registerName1("setDirectParameter:");
  late final _sel_receiversSpecifier1 = _registerName1("receiversSpecifier");
  ffi.Pointer<ObjCObject> _objc_msgSend_556(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_556(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_556Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_556 = __objc_msgSend_556Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setReceiversSpecifier_1 =
      _registerName1("setReceiversSpecifier:");
  void _objc_msgSend_557(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_557(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_557Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_557 = __objc_msgSend_557Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_evaluatedReceivers1 = _registerName1("evaluatedReceivers");
  late final _sel_arguments1 = _registerName1("arguments");
  late final _sel_setArguments_1 = _registerName1("setArguments:");
  late final _sel_evaluatedArguments1 = _registerName1("evaluatedArguments");
  late final _sel_isWellFormed1 = _registerName1("isWellFormed");
  late final _sel_performDefaultImplementation1 =
      _registerName1("performDefaultImplementation");
  late final _sel_executeCommand1 = _registerName1("executeCommand");
  late final _sel_scriptErrorNumber1 = _registerName1("scriptErrorNumber");
  late final _sel_setScriptErrorNumber_1 =
      _registerName1("setScriptErrorNumber:");
  void _objc_msgSend_558(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_558(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_558Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_558 = __objc_msgSend_558Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_scriptErrorOffendingObjectDescriptor1 =
      _registerName1("scriptErrorOffendingObjectDescriptor");
  late final _sel_setScriptErrorOffendingObjectDescriptor_1 =
      _registerName1("setScriptErrorOffendingObjectDescriptor:");
  void _objc_msgSend_559(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_559(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_559Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_559 = __objc_msgSend_559Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_scriptErrorExpectedTypeDescriptor1 =
      _registerName1("scriptErrorExpectedTypeDescriptor");
  late final _sel_setScriptErrorExpectedTypeDescriptor_1 =
      _registerName1("setScriptErrorExpectedTypeDescriptor:");
  late final _sel_scriptErrorString1 = _registerName1("scriptErrorString");
  late final _sel_setScriptErrorString_1 =
      _registerName1("setScriptErrorString:");
  late final _sel_currentCommand1 = _registerName1("currentCommand");
  ffi.Pointer<ObjCObject> _objc_msgSend_560(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_560(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_560Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_560 = __objc_msgSend_560Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_appleEvent1 = _registerName1("appleEvent");
  late final _sel_suspendExecution1 = _registerName1("suspendExecution");
  late final _sel_resumeExecutionWithResult_1 =
      _registerName1("resumeExecutionWithResult:");
  late final _sel_createCommandInstance1 =
      _registerName1("createCommandInstance");
  late final _sel_createCommandInstanceWithZone_1 =
      _registerName1("createCommandInstanceWithZone:");
  ffi.Pointer<ObjCObject> _objc_msgSend_561(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSZone> zone,
  ) {
    return __objc_msgSend_561(
      obj,
      sel,
      zone,
    );
  }

  late final __objc_msgSend_561Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<NSZone>)>>('objc_msgSend');
  late final __objc_msgSend_561 = __objc_msgSend_561Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<NSZone>)>();

  late final _sel_supportsCommand_1 = _registerName1("supportsCommand:");
  bool _objc_msgSend_562(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> commandDescription,
  ) {
    return __objc_msgSend_562(
      obj,
      sel,
      commandDescription,
    );
  }

  late final __objc_msgSend_562Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_562 = __objc_msgSend_562Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_selectorForCommand_1 = _registerName1("selectorForCommand:");
  ffi.Pointer<ObjCSel> _objc_msgSend_563(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> commandDescription,
  ) {
    return __objc_msgSend_563(
      obj,
      sel,
      commandDescription,
    );
  }

  late final __objc_msgSend_563Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCSel> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_563 = __objc_msgSend_563Ptr.asFunction<
      ffi.Pointer<ObjCSel> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_typeForKey_1 = _registerName1("typeForKey:");
  late final _sel_classDescriptionForKey_1 =
      _registerName1("classDescriptionForKey:");
  ffi.Pointer<ObjCObject> _objc_msgSend_564(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_564(
      obj,
      sel,
      key,
    );
  }

  late final __objc_msgSend_564Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_564 = __objc_msgSend_564Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_appleEventCodeForKey_1 =
      _registerName1("appleEventCodeForKey:");
  late final _sel_keyWithAppleEventCode_1 =
      _registerName1("keyWithAppleEventCode:");
  ffi.Pointer<ObjCObject> _objc_msgSend_565(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int appleEventCode,
  ) {
    return __objc_msgSend_565(
      obj,
      sel,
      appleEventCode,
    );
  }

  late final __objc_msgSend_565Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, FourCharCode)>>('objc_msgSend');
  late final __objc_msgSend_565 = __objc_msgSend_565Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_defaultSubcontainerAttributeKey1 =
      _registerName1("defaultSubcontainerAttributeKey");
  late final _sel_isLocationRequiredToCreateForKey_1 =
      _registerName1("isLocationRequiredToCreateForKey:");
  late final _sel_hasPropertyForKey_1 = _registerName1("hasPropertyForKey:");
  late final _sel_hasOrderedToManyRelationshipForKey_1 =
      _registerName1("hasOrderedToManyRelationshipForKey:");
  late final _sel_hasReadablePropertyForKey_1 =
      _registerName1("hasReadablePropertyForKey:");
  late final _sel_hasWritablePropertyForKey_1 =
      _registerName1("hasWritablePropertyForKey:");
  late final _sel_isReadOnlyKey_1 = _registerName1("isReadOnlyKey:");
  late final _sel_initWithContainerClassDescription_containerSpecifier_key_1 =
      _registerName1(
          "initWithContainerClassDescription:containerSpecifier:key:");
  instancetype _objc_msgSend_566(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> classDesc,
    ffi.Pointer<ObjCObject> container,
    ffi.Pointer<ObjCObject> property,
  ) {
    return __objc_msgSend_566(
      obj,
      sel,
      classDesc,
      container,
      property,
    );
  }

  late final __objc_msgSend_566Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_566 = __objc_msgSend_566Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_childSpecifier1 = _registerName1("childSpecifier");
  late final _sel_setChildSpecifier_1 = _registerName1("setChildSpecifier:");
  late final _sel_containerSpecifier1 = _registerName1("containerSpecifier");
  late final _sel_setContainerSpecifier_1 =
      _registerName1("setContainerSpecifier:");
  late final _sel_containerIsObjectBeingTested1 =
      _registerName1("containerIsObjectBeingTested");
  late final _sel_setContainerIsObjectBeingTested_1 =
      _registerName1("setContainerIsObjectBeingTested:");
  late final _sel_containerIsRangeContainerObject1 =
      _registerName1("containerIsRangeContainerObject");
  late final _sel_setContainerIsRangeContainerObject_1 =
      _registerName1("setContainerIsRangeContainerObject:");
  late final _sel_key1 = _registerName1("key");
  late final _sel_setKey_1 = _registerName1("setKey:");
  late final _sel_containerClassDescription1 =
      _registerName1("containerClassDescription");
  late final _sel_setContainerClassDescription_1 =
      _registerName1("setContainerClassDescription:");
  void _objc_msgSend_567(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_567(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_567Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_567 = __objc_msgSend_567Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_keyClassDescription1 = _registerName1("keyClassDescription");
  late final _sel_indicesOfObjectsByEvaluatingWithContainer_count_1 =
      _registerName1("indicesOfObjectsByEvaluatingWithContainer:count:");
  ffi.Pointer<NSInteger> _objc_msgSend_568(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> container,
    ffi.Pointer<NSInteger> count,
  ) {
    return __objc_msgSend_568(
      obj,
      sel,
      container,
      count,
    );
  }

  late final __objc_msgSend_568Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<NSInteger> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<NSInteger>)>>('objc_msgSend');
  late final __objc_msgSend_568 = __objc_msgSend_568Ptr.asFunction<
      ffi.Pointer<NSInteger> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<NSInteger>)>();

  late final _sel_objectsByEvaluatingWithContainers_1 =
      _registerName1("objectsByEvaluatingWithContainers:");
  late final _sel_objectsByEvaluatingSpecifier1 =
      _registerName1("objectsByEvaluatingSpecifier");
  late final _sel_evaluationErrorNumber1 =
      _registerName1("evaluationErrorNumber");
  late final _sel_setEvaluationErrorNumber_1 =
      _registerName1("setEvaluationErrorNumber:");
  late final _sel_evaluationErrorSpecifier1 =
      _registerName1("evaluationErrorSpecifier");
  late final _sel_descriptor1 = _registerName1("descriptor");
  late final _sel_scriptingValueForSpecifier_1 =
      _registerName1("scriptingValueForSpecifier:");
  ffi.Pointer<ObjCObject> _objc_msgSend_569(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> objectSpecifier,
  ) {
    return __objc_msgSend_569(
      obj,
      sel,
      objectSpecifier,
    );
  }

  late final __objc_msgSend_569Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_569 = __objc_msgSend_569Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_scriptingProperties1 = _registerName1("scriptingProperties");
  late final _sel_setScriptingProperties_1 =
      _registerName1("setScriptingProperties:");
  late final _sel_copyScriptingValue_forKey_withProperties_1 =
      _registerName1("copyScriptingValue:forKey:withProperties:");
  ffi.Pointer<ObjCObject> _objc_msgSend_570(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
    ffi.Pointer<ObjCObject> key,
    ffi.Pointer<ObjCObject> properties,
  ) {
    return __objc_msgSend_570(
      obj,
      sel,
      value,
      key,
      properties,
    );
  }

  late final __objc_msgSend_570Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_570 = __objc_msgSend_570Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_newScriptingObjectOfClass_forValueForKey_withContentsValue_properties_1 =
      _registerName1(
          "newScriptingObjectOfClass:forValueForKey:withContentsValue:properties:");
  ffi.Pointer<ObjCObject> _objc_msgSend_571(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> objectClass,
    ffi.Pointer<ObjCObject> key,
    ffi.Pointer<ObjCObject> contentsValue,
    ffi.Pointer<ObjCObject> properties,
  ) {
    return __objc_msgSend_571(
      obj,
      sel,
      objectClass,
      key,
      contentsValue,
      properties,
    );
  }

  late final __objc_msgSend_571Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_571 = __objc_msgSend_571Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_classCode1 = _registerName1("classCode");
  late final _sel_valueAtIndex_inPropertyWithKey_1 =
      _registerName1("valueAtIndex:inPropertyWithKey:");
  ffi.Pointer<ObjCObject> _objc_msgSend_572(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_572(
      obj,
      sel,
      index,
      key,
    );
  }

  late final __objc_msgSend_572Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSUInteger,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_572 = __objc_msgSend_572Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<ObjCObject>)>();

  late final _sel_valueWithName_inPropertyWithKey_1 =
      _registerName1("valueWithName:inPropertyWithKey:");
  late final _sel_valueWithUniqueID_inPropertyWithKey_1 =
      _registerName1("valueWithUniqueID:inPropertyWithKey:");
  late final _sel_insertValue_atIndex_inPropertyWithKey_1 =
      _registerName1("insertValue:atIndex:inPropertyWithKey:");
  void _objc_msgSend_573(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
    int index,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_573(
      obj,
      sel,
      value,
      index,
      key,
    );
  }

  late final __objc_msgSend_573Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSUInteger,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_573 = __objc_msgSend_573Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, ffi.Pointer<ObjCObject>)>();

  late final _sel_removeValueAtIndex_fromPropertyWithKey_1 =
      _registerName1("removeValueAtIndex:fromPropertyWithKey:");
  void _objc_msgSend_574(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
    ffi.Pointer<ObjCObject> key,
  ) {
    return __objc_msgSend_574(
      obj,
      sel,
      index,
      key,
    );
  }

  late final __objc_msgSend_574Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_574 = __objc_msgSend_574Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_replaceValueAtIndex_inPropertyWithKey_withValue_1 =
      _registerName1("replaceValueAtIndex:inPropertyWithKey:withValue:");
  void _objc_msgSend_575(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
    ffi.Pointer<ObjCObject> key,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_575(
      obj,
      sel,
      index,
      key,
      value,
    );
  }

  late final __objc_msgSend_575Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSUInteger,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_575 = __objc_msgSend_575Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_insertValue_inPropertyWithKey_1 =
      _registerName1("insertValue:inPropertyWithKey:");
  late final _sel_coerceValue_forKey_1 = _registerName1("coerceValue:forKey:");
  late final _sel_objectSpecifier1 = _registerName1("objectSpecifier");
  late final _sel_indicesOfObjectsByEvaluatingObjectSpecifier_1 =
      _registerName1("indicesOfObjectsByEvaluatingObjectSpecifier:");
  ffi.Pointer<ObjCObject> _objc_msgSend_576(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> specifier,
  ) {
    return __objc_msgSend_576(
      obj,
      sel,
      specifier,
    );
  }

  late final __objc_msgSend_576Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_576 = __objc_msgSend_576Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_isEqualTo_1 = _registerName1("isEqualTo:");
  late final _sel_isLessThanOrEqualTo_1 =
      _registerName1("isLessThanOrEqualTo:");
  late final _sel_isLessThan_1 = _registerName1("isLessThan:");
  late final _sel_isGreaterThanOrEqualTo_1 =
      _registerName1("isGreaterThanOrEqualTo:");
  late final _sel_isGreaterThan_1 = _registerName1("isGreaterThan:");
  late final _sel_isNotEqualTo_1 = _registerName1("isNotEqualTo:");
  late final _sel_doesContain_1 = _registerName1("doesContain:");
  late final _sel_isLike_1 = _registerName1("isLike:");
  late final _sel_isCaseInsensitiveLike_1 =
      _registerName1("isCaseInsensitiveLike:");
  late final _sel_scriptingIsEqualTo_1 = _registerName1("scriptingIsEqualTo:");
  late final _sel_scriptingIsLessThanOrEqualTo_1 =
      _registerName1("scriptingIsLessThanOrEqualTo:");
  late final _sel_scriptingIsLessThan_1 =
      _registerName1("scriptingIsLessThan:");
  late final _sel_scriptingIsGreaterThanOrEqualTo_1 =
      _registerName1("scriptingIsGreaterThanOrEqualTo:");
  late final _sel_scriptingIsGreaterThan_1 =
      _registerName1("scriptingIsGreaterThan:");
  late final _sel_scriptingBeginsWith_1 =
      _registerName1("scriptingBeginsWith:");
  late final _sel_scriptingEndsWith_1 = _registerName1("scriptingEndsWith:");
  late final _sel_scriptingContains_1 = _registerName1("scriptingContains:");
  late final _class_NSItemProvider1 = _getClass1("NSItemProvider");
  late final _class_NSProgress1 = _getClass1("NSProgress");
  late final _sel_currentProgress1 = _registerName1("currentProgress");
  ffi.Pointer<ObjCObject> _objc_msgSend_577(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_577(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_577Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_577 = __objc_msgSend_577Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_progressWithTotalUnitCount_1 =
      _registerName1("progressWithTotalUnitCount:");
  ffi.Pointer<ObjCObject> _objc_msgSend_578(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unitCount,
  ) {
    return __objc_msgSend_578(
      obj,
      sel,
      unitCount,
    );
  }

  late final __objc_msgSend_578Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Int64)>>('objc_msgSend');
  late final __objc_msgSend_578 = __objc_msgSend_578Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_discreteProgressWithTotalUnitCount_1 =
      _registerName1("discreteProgressWithTotalUnitCount:");
  late final _sel_progressWithTotalUnitCount_parent_pendingUnitCount_1 =
      _registerName1("progressWithTotalUnitCount:parent:pendingUnitCount:");
  ffi.Pointer<ObjCObject> _objc_msgSend_579(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unitCount,
    ffi.Pointer<ObjCObject> parent,
    int portionOfParentTotalUnitCount,
  ) {
    return __objc_msgSend_579(
      obj,
      sel,
      unitCount,
      parent,
      portionOfParentTotalUnitCount,
    );
  }

  late final __objc_msgSend_579Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int64,
              ffi.Pointer<ObjCObject>,
              ffi.Int64)>>('objc_msgSend');
  late final __objc_msgSend_579 = __objc_msgSend_579Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<ObjCObject>, int)>();

  late final _sel_initWithParent_userInfo_1 =
      _registerName1("initWithParent:userInfo:");
  instancetype _objc_msgSend_580(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> parentProgressOrNil,
  ) {
    return __objc_msgSend_580(
      obj,
      sel,
      parentProgressOrNil,
    );
  }

  late final __objc_msgSend_580Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_580 = __objc_msgSend_580Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_becomeCurrentWithPendingUnitCount_1 =
      _registerName1("becomeCurrentWithPendingUnitCount:");
  void _objc_msgSend_581(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unitCount,
  ) {
    return __objc_msgSend_581(
      obj,
      sel,
      unitCount,
    );
  }

  late final __objc_msgSend_581Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int64)>>('objc_msgSend');
  late final __objc_msgSend_581 = __objc_msgSend_581Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_performAsCurrentWithPendingUnitCount_usingBlock_1 =
      _registerName1("performAsCurrentWithPendingUnitCount:usingBlock:");
  void _objc_msgSend_582(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unitCount,
    ffi.Pointer<_ObjCBlock> work,
  ) {
    return __objc_msgSend_582(
      obj,
      sel,
      unitCount,
      work,
    );
  }

  late final __objc_msgSend_582Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int64, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_582 = __objc_msgSend_582Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_resignCurrent1 = _registerName1("resignCurrent");
  late final _sel_addChild_withPendingUnitCount_1 =
      _registerName1("addChild:withPendingUnitCount:");
  void _objc_msgSend_583(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> child,
    int inUnitCount,
  ) {
    return __objc_msgSend_583(
      obj,
      sel,
      child,
      inUnitCount,
    );
  }

  late final __objc_msgSend_583Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int64)>>('objc_msgSend');
  late final __objc_msgSend_583 = __objc_msgSend_583Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_totalUnitCount1 = _registerName1("totalUnitCount");
  int _objc_msgSend_584(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_584(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_584Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int64 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_584 = __objc_msgSend_584Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setTotalUnitCount_1 = _registerName1("setTotalUnitCount:");
  void _objc_msgSend_585(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_585(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_585Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int64)>>('objc_msgSend');
  late final __objc_msgSend_585 = __objc_msgSend_585Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_completedUnitCount1 = _registerName1("completedUnitCount");
  late final _sel_setCompletedUnitCount_1 =
      _registerName1("setCompletedUnitCount:");
  late final _sel_localizedDescription1 =
      _registerName1("localizedDescription");
  late final _sel_setLocalizedDescription_1 =
      _registerName1("setLocalizedDescription:");
  late final _sel_localizedAdditionalDescription1 =
      _registerName1("localizedAdditionalDescription");
  late final _sel_setLocalizedAdditionalDescription_1 =
      _registerName1("setLocalizedAdditionalDescription:");
  late final _sel_isCancellable1 = _registerName1("isCancellable");
  late final _sel_setCancellable_1 = _registerName1("setCancellable:");
  late final _sel_isPausable1 = _registerName1("isPausable");
  late final _sel_setPausable_1 = _registerName1("setPausable:");
  late final _sel_isPaused1 = _registerName1("isPaused");
  late final _sel_cancellationHandler1 = _registerName1("cancellationHandler");
  ffi.Pointer<_ObjCBlock> _objc_msgSend_586(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_586(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_586Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<_ObjCBlock> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_586 = __objc_msgSend_586Ptr.asFunction<
      ffi.Pointer<_ObjCBlock> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setCancellationHandler_1 =
      _registerName1("setCancellationHandler:");
  void _objc_msgSend_587(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> value,
  ) {
    return __objc_msgSend_587(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_587Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_587 = __objc_msgSend_587Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_pausingHandler1 = _registerName1("pausingHandler");
  late final _sel_setPausingHandler_1 = _registerName1("setPausingHandler:");
  late final _sel_resumingHandler1 = _registerName1("resumingHandler");
  late final _sel_setResumingHandler_1 = _registerName1("setResumingHandler:");
  late final _sel_setUserInfoObject_forKey_1 =
      _registerName1("setUserInfoObject:forKey:");
  late final _sel_isIndeterminate1 = _registerName1("isIndeterminate");
  late final _sel_fractionCompleted1 = _registerName1("fractionCompleted");
  late final _sel_pause1 = _registerName1("pause");
  late final _sel_resume1 = _registerName1("resume");
  late final _sel_registerDataRepresentationForTypeIdentifier_visibility_loadHandler_1 =
      _registerName1(
          "registerDataRepresentationForTypeIdentifier:visibility:loadHandler:");
  void _objc_msgSend_588(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> typeIdentifier,
    int visibility,
    ffi.Pointer<_ObjCBlock> loadHandler,
  ) {
    return __objc_msgSend_588(
      obj,
      sel,
      typeIdentifier,
      visibility,
      loadHandler,
    );
  }

  late final __objc_msgSend_588Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_588 = __objc_msgSend_588Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_registerFileRepresentationForTypeIdentifier_fileOptions_visibility_loadHandler_1 =
      _registerName1(
          "registerFileRepresentationForTypeIdentifier:fileOptions:visibility:loadHandler:");
  void _objc_msgSend_589(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> typeIdentifier,
    int fileOptions,
    int visibility,
    ffi.Pointer<_ObjCBlock> loadHandler,
  ) {
    return __objc_msgSend_589(
      obj,
      sel,
      typeIdentifier,
      fileOptions,
      visibility,
      loadHandler,
    );
  }

  late final __objc_msgSend_589Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_589 = __objc_msgSend_589Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_registeredTypeIdentifiers1 =
      _registerName1("registeredTypeIdentifiers");
  late final _sel_registeredTypeIdentifiersWithFileOptions_1 =
      _registerName1("registeredTypeIdentifiersWithFileOptions:");
  ffi.Pointer<ObjCObject> _objc_msgSend_590(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int fileOptions,
  ) {
    return __objc_msgSend_590(
      obj,
      sel,
      fileOptions,
    );
  }

  late final __objc_msgSend_590Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_590 = __objc_msgSend_590Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_hasItemConformingToTypeIdentifier_1 =
      _registerName1("hasItemConformingToTypeIdentifier:");
  late final _sel_hasRepresentationConformingToTypeIdentifier_fileOptions_1 =
      _registerName1(
          "hasRepresentationConformingToTypeIdentifier:fileOptions:");
  bool _objc_msgSend_591(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> typeIdentifier,
    int fileOptions,
  ) {
    return __objc_msgSend_591(
      obj,
      sel,
      typeIdentifier,
      fileOptions,
    );
  }

  late final __objc_msgSend_591Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_591 = __objc_msgSend_591Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_loadDataRepresentationForTypeIdentifier_completionHandler_1 =
      _registerName1(
          "loadDataRepresentationForTypeIdentifier:completionHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_592(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> typeIdentifier,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_592(
      obj,
      sel,
      typeIdentifier,
      completionHandler,
    );
  }

  late final __objc_msgSend_592Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_592 = __objc_msgSend_592Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_loadFileRepresentationForTypeIdentifier_completionHandler_1 =
      _registerName1(
          "loadFileRepresentationForTypeIdentifier:completionHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_593(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> typeIdentifier,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_593(
      obj,
      sel,
      typeIdentifier,
      completionHandler,
    );
  }

  late final __objc_msgSend_593Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_593 = __objc_msgSend_593Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_loadInPlaceFileRepresentationForTypeIdentifier_completionHandler_1 =
      _registerName1(
          "loadInPlaceFileRepresentationForTypeIdentifier:completionHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_594(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> typeIdentifier,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_594(
      obj,
      sel,
      typeIdentifier,
      completionHandler,
    );
  }

  late final __objc_msgSend_594Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_594 = __objc_msgSend_594Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_suggestedName1 = _registerName1("suggestedName");
  late final _sel_setSuggestedName_1 = _registerName1("setSuggestedName:");
  late final _sel_registerObject_visibility_1 =
      _registerName1("registerObject:visibility:");
  void _objc_msgSend_595(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> object,
    int visibility,
  ) {
    return __objc_msgSend_595(
      obj,
      sel,
      object,
      visibility,
    );
  }

  late final __objc_msgSend_595Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_595 = __objc_msgSend_595Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_registerObjectOfClass_visibility_loadHandler_1 =
      _registerName1("registerObjectOfClass:visibility:loadHandler:");
  void _objc_msgSend_596(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aClass,
    int visibility,
    ffi.Pointer<_ObjCBlock> loadHandler,
  ) {
    return __objc_msgSend_596(
      obj,
      sel,
      aClass,
      visibility,
      loadHandler,
    );
  }

  late final __objc_msgSend_596Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_596 = __objc_msgSend_596Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_canLoadObjectOfClass_1 =
      _registerName1("canLoadObjectOfClass:");
  late final _sel_loadObjectOfClass_completionHandler_1 =
      _registerName1("loadObjectOfClass:completionHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_597(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aClass,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_597(
      obj,
      sel,
      aClass,
      completionHandler,
    );
  }

  late final __objc_msgSend_597Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_597 = __objc_msgSend_597Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_initWithItem_typeIdentifier_1 =
      _registerName1("initWithItem:typeIdentifier:");
  late final _sel_registerItemForTypeIdentifier_loadHandler_1 =
      _registerName1("registerItemForTypeIdentifier:loadHandler:");
  void _objc_msgSend_598(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> typeIdentifier,
    NSItemProviderLoadHandler loadHandler,
  ) {
    return __objc_msgSend_598(
      obj,
      sel,
      typeIdentifier,
      loadHandler,
    );
  }

  late final __objc_msgSend_598Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSItemProviderLoadHandler)>>('objc_msgSend');
  late final __objc_msgSend_598 = __objc_msgSend_598Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, NSItemProviderLoadHandler)>();

  late final _sel_loadItemForTypeIdentifier_options_completionHandler_1 =
      _registerName1("loadItemForTypeIdentifier:options:completionHandler:");
  void _objc_msgSend_599(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> typeIdentifier,
    ffi.Pointer<ObjCObject> options,
    NSItemProviderCompletionHandler completionHandler,
  ) {
    return __objc_msgSend_599(
      obj,
      sel,
      typeIdentifier,
      options,
      completionHandler,
    );
  }

  late final __objc_msgSend_599Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              NSItemProviderCompletionHandler)>>('objc_msgSend');
  late final __objc_msgSend_599 = __objc_msgSend_599Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          NSItemProviderCompletionHandler)>();

  late final _sel_previewImageHandler1 = _registerName1("previewImageHandler");
  NSItemProviderLoadHandler _objc_msgSend_600(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_600(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_600Ptr = _lookup<
      ffi.NativeFunction<
          NSItemProviderLoadHandler Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_600 = __objc_msgSend_600Ptr.asFunction<
      NSItemProviderLoadHandler Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setPreviewImageHandler_1 =
      _registerName1("setPreviewImageHandler:");
  void _objc_msgSend_601(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSItemProviderLoadHandler value,
  ) {
    return __objc_msgSend_601(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_601Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSItemProviderLoadHandler)>>('objc_msgSend');
  late final __objc_msgSend_601 = __objc_msgSend_601Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          NSItemProviderLoadHandler)>();

  late final _sel_loadPreviewImageWithOptions_completionHandler_1 =
      _registerName1("loadPreviewImageWithOptions:completionHandler:");
  void _objc_msgSend_602(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> options,
    NSItemProviderCompletionHandler completionHandler,
  ) {
    return __objc_msgSend_602(
      obj,
      sel,
      options,
      completionHandler,
    );
  }

  late final __objc_msgSend_602Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSItemProviderCompletionHandler)>>('objc_msgSend');
  late final __objc_msgSend_602 = __objc_msgSend_602Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, NSItemProviderCompletionHandler)>();

  late final _class_NSMutableString1 = _getClass1("NSMutableString");
  late final _sel_replaceCharactersInRange_withString_1 =
      _registerName1("replaceCharactersInRange:withString:");
  void _objc_msgSend_603(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> aString,
  ) {
    return __objc_msgSend_603(
      obj,
      sel,
      range,
      aString,
    );
  }

  late final __objc_msgSend_603Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_603 = __objc_msgSend_603Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_insertString_atIndex_1 =
      _registerName1("insertString:atIndex:");
  void _objc_msgSend_604(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aString,
    int loc,
  ) {
    return __objc_msgSend_604(
      obj,
      sel,
      aString,
      loc,
    );
  }

  late final __objc_msgSend_604Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_604 = __objc_msgSend_604Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_deleteCharactersInRange_1 =
      _registerName1("deleteCharactersInRange:");
  late final _sel_appendString_1 = _registerName1("appendString:");
  late final _sel_appendFormat_1 = _registerName1("appendFormat:");
  late final _sel_setString_1 = _registerName1("setString:");
  late final _sel_replaceOccurrencesOfString_withString_options_range_1 =
      _registerName1("replaceOccurrencesOfString:withString:options:range:");
  int _objc_msgSend_605(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> target,
    ffi.Pointer<ObjCObject> replacement,
    int options,
    NSRange searchRange,
  ) {
    return __objc_msgSend_605(
      obj,
      sel,
      target,
      replacement,
      options,
      searchRange,
    );
  }

  late final __objc_msgSend_605Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_605 = __objc_msgSend_605Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>, int, NSRange)>();

  late final _sel_applyTransform_reverse_range_updatedRange_1 =
      _registerName1("applyTransform:reverse:range:updatedRange:");
  bool _objc_msgSend_606(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSStringTransform transform,
    bool reverse,
    NSRange range,
    NSRangePointer resultingRange,
  ) {
    return __objc_msgSend_606(
      obj,
      sel,
      transform,
      reverse,
      range,
      resultingRange,
    );
  }

  late final __objc_msgSend_606Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSStringTransform,
              ffi.Bool,
              NSRange,
              NSRangePointer)>>('objc_msgSend');
  late final __objc_msgSend_606 = __objc_msgSend_606Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          NSStringTransform, bool, NSRange, NSRangePointer)>();

  ffi.Pointer<ObjCObject> _objc_msgSend_607(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int capacity,
  ) {
    return __objc_msgSend_607(
      obj,
      sel,
      capacity,
    );
  }

  late final __objc_msgSend_607Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_607 = __objc_msgSend_607Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_stringWithCapacity_1 = _registerName1("stringWithCapacity:");
  late final _class_NSNotification1 = _getClass1("NSNotification");
  late final _sel_object1 = _registerName1("object");
  late final _sel_initWithName_object_userInfo_1 =
      _registerName1("initWithName:object:userInfo:");
  instancetype _objc_msgSend_608(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSNotificationName name,
    ffi.Pointer<ObjCObject> object,
    ffi.Pointer<ObjCObject> userInfo,
  ) {
    return __objc_msgSend_608(
      obj,
      sel,
      name,
      object,
      userInfo,
    );
  }

  late final __objc_msgSend_608Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSNotificationName,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_608 = __objc_msgSend_608Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          NSNotificationName,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_notificationWithName_object_1 =
      _registerName1("notificationWithName:object:");
  late final _sel_notificationWithName_object_userInfo_1 =
      _registerName1("notificationWithName:object:userInfo:");
  late final _class_NSBundle1 = _getClass1("NSBundle");
  late final _sel_mainBundle1 = _registerName1("mainBundle");
  ffi.Pointer<ObjCObject> _objc_msgSend_609(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_609(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_609Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_609 = __objc_msgSend_609Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_bundleWithPath_1 = _registerName1("bundleWithPath:");
  late final _sel_initWithPath_1 = _registerName1("initWithPath:");
  late final _sel_bundleWithURL_1 = _registerName1("bundleWithURL:");
  late final _sel_initWithURL_1 = _registerName1("initWithURL:");
  late final _sel_bundleForClass_1 = _registerName1("bundleForClass:");
  ffi.Pointer<ObjCObject> _objc_msgSend_610(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aClass,
  ) {
    return __objc_msgSend_610(
      obj,
      sel,
      aClass,
    );
  }

  late final __objc_msgSend_610Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_610 = __objc_msgSend_610Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_bundleWithIdentifier_1 =
      _registerName1("bundleWithIdentifier:");
  ffi.Pointer<ObjCObject> _objc_msgSend_611(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> identifier,
  ) {
    return __objc_msgSend_611(
      obj,
      sel,
      identifier,
    );
  }

  late final __objc_msgSend_611Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_611 = __objc_msgSend_611Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_allBundles1 = _registerName1("allBundles");
  late final _sel_allFrameworks1 = _registerName1("allFrameworks");
  late final _sel_isLoaded1 = _registerName1("isLoaded");
  late final _sel_unload1 = _registerName1("unload");
  late final _sel_preflightAndReturnError_1 =
      _registerName1("preflightAndReturnError:");
  late final _sel_loadAndReturnError_1 = _registerName1("loadAndReturnError:");
  late final _sel_bundleURL1 = _registerName1("bundleURL");
  late final _sel_resourceURL1 = _registerName1("resourceURL");
  late final _sel_executableURL1 = _registerName1("executableURL");
  late final _sel_URLForAuxiliaryExecutable_1 =
      _registerName1("URLForAuxiliaryExecutable:");
  late final _sel_privateFrameworksURL1 =
      _registerName1("privateFrameworksURL");
  late final _sel_sharedFrameworksURL1 = _registerName1("sharedFrameworksURL");
  late final _sel_sharedSupportURL1 = _registerName1("sharedSupportURL");
  late final _sel_builtInPlugInsURL1 = _registerName1("builtInPlugInsURL");
  late final _sel_appStoreReceiptURL1 = _registerName1("appStoreReceiptURL");
  late final _sel_bundlePath1 = _registerName1("bundlePath");
  late final _sel_resourcePath1 = _registerName1("resourcePath");
  late final _sel_executablePath1 = _registerName1("executablePath");
  late final _sel_pathForAuxiliaryExecutable_1 =
      _registerName1("pathForAuxiliaryExecutable:");
  late final _sel_privateFrameworksPath1 =
      _registerName1("privateFrameworksPath");
  late final _sel_sharedFrameworksPath1 =
      _registerName1("sharedFrameworksPath");
  late final _sel_sharedSupportPath1 = _registerName1("sharedSupportPath");
  late final _sel_builtInPlugInsPath1 = _registerName1("builtInPlugInsPath");
  late final _sel_URLForResource_withExtension_subdirectory_inBundleWithURL_1 =
      _registerName1(
          "URLForResource:withExtension:subdirectory:inBundleWithURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_612(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> ext,
    ffi.Pointer<ObjCObject> subpath,
    ffi.Pointer<ObjCObject> bundleURL,
  ) {
    return __objc_msgSend_612(
      obj,
      sel,
      name,
      ext,
      subpath,
      bundleURL,
    );
  }

  late final __objc_msgSend_612Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_612 = __objc_msgSend_612Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_URLsForResourcesWithExtension_subdirectory_inBundleWithURL_1 =
      _registerName1(
          "URLsForResourcesWithExtension:subdirectory:inBundleWithURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_613(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> ext,
    ffi.Pointer<ObjCObject> subpath,
    ffi.Pointer<ObjCObject> bundleURL,
  ) {
    return __objc_msgSend_613(
      obj,
      sel,
      ext,
      subpath,
      bundleURL,
    );
  }

  late final __objc_msgSend_613Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_613 = __objc_msgSend_613Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_URLForResource_withExtension_1 =
      _registerName1("URLForResource:withExtension:");
  ffi.Pointer<ObjCObject> _objc_msgSend_614(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> ext,
  ) {
    return __objc_msgSend_614(
      obj,
      sel,
      name,
      ext,
    );
  }

  late final __objc_msgSend_614Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_614 = __objc_msgSend_614Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_URLForResource_withExtension_subdirectory_1 =
      _registerName1("URLForResource:withExtension:subdirectory:");
  ffi.Pointer<ObjCObject> _objc_msgSend_615(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> ext,
    ffi.Pointer<ObjCObject> subpath,
  ) {
    return __objc_msgSend_615(
      obj,
      sel,
      name,
      ext,
      subpath,
    );
  }

  late final __objc_msgSend_615Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_615 = __objc_msgSend_615Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_URLForResource_withExtension_subdirectory_localization_1 =
      _registerName1("URLForResource:withExtension:subdirectory:localization:");
  ffi.Pointer<ObjCObject> _objc_msgSend_616(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> ext,
    ffi.Pointer<ObjCObject> subpath,
    ffi.Pointer<ObjCObject> localizationName,
  ) {
    return __objc_msgSend_616(
      obj,
      sel,
      name,
      ext,
      subpath,
      localizationName,
    );
  }

  late final __objc_msgSend_616Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_616 = __objc_msgSend_616Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_URLsForResourcesWithExtension_subdirectory_1 =
      _registerName1("URLsForResourcesWithExtension:subdirectory:");
  ffi.Pointer<ObjCObject> _objc_msgSend_617(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> ext,
    ffi.Pointer<ObjCObject> subpath,
  ) {
    return __objc_msgSend_617(
      obj,
      sel,
      ext,
      subpath,
    );
  }

  late final __objc_msgSend_617Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_617 = __objc_msgSend_617Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_URLsForResourcesWithExtension_subdirectory_localization_1 =
      _registerName1(
          "URLsForResourcesWithExtension:subdirectory:localization:");
  ffi.Pointer<ObjCObject> _objc_msgSend_618(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> ext,
    ffi.Pointer<ObjCObject> subpath,
    ffi.Pointer<ObjCObject> localizationName,
  ) {
    return __objc_msgSend_618(
      obj,
      sel,
      ext,
      subpath,
      localizationName,
    );
  }

  late final __objc_msgSend_618Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_618 = __objc_msgSend_618Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_pathForResource_ofType_inDirectory_1 =
      _registerName1("pathForResource:ofType:inDirectory:");
  ffi.Pointer<ObjCObject> _objc_msgSend_619(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> ext,
    ffi.Pointer<ObjCObject> bundlePath,
  ) {
    return __objc_msgSend_619(
      obj,
      sel,
      name,
      ext,
      bundlePath,
    );
  }

  late final __objc_msgSend_619Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_619 = __objc_msgSend_619Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_pathsForResourcesOfType_inDirectory_1 =
      _registerName1("pathsForResourcesOfType:inDirectory:");
  late final _sel_pathForResource_ofType_1 =
      _registerName1("pathForResource:ofType:");
  late final _sel_pathForResource_ofType_inDirectory_forLocalization_1 =
      _registerName1("pathForResource:ofType:inDirectory:forLocalization:");
  ffi.Pointer<ObjCObject> _objc_msgSend_620(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> ext,
    ffi.Pointer<ObjCObject> subpath,
    ffi.Pointer<ObjCObject> localizationName,
  ) {
    return __objc_msgSend_620(
      obj,
      sel,
      name,
      ext,
      subpath,
      localizationName,
    );
  }

  late final __objc_msgSend_620Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_620 = __objc_msgSend_620Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_pathsForResourcesOfType_inDirectory_forLocalization_1 =
      _registerName1("pathsForResourcesOfType:inDirectory:forLocalization:");
  late final _sel_localizedStringForKey_value_table_1 =
      _registerName1("localizedStringForKey:value:table:");
  late final _class_NSAttributedString1 = _getClass1("NSAttributedString");
  late final _sel_attributesAtIndex_effectiveRange_1 =
      _registerName1("attributesAtIndex:effectiveRange:");
  ffi.Pointer<ObjCObject> _objc_msgSend_621(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int location,
    NSRangePointer range,
  ) {
    return __objc_msgSend_621(
      obj,
      sel,
      location,
      range,
    );
  }

  late final __objc_msgSend_621Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSUInteger,
              NSRangePointer)>>('objc_msgSend');
  late final __objc_msgSend_621 = __objc_msgSend_621Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, NSRangePointer)>();

  late final _sel_attribute_atIndex_effectiveRange_1 =
      _registerName1("attribute:atIndex:effectiveRange:");
  ffi.Pointer<ObjCObject> _objc_msgSend_622(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSAttributedStringKey attrName,
    int location,
    NSRangePointer range,
  ) {
    return __objc_msgSend_622(
      obj,
      sel,
      attrName,
      location,
      range,
    );
  }

  late final __objc_msgSend_622Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSAttributedStringKey,
              NSUInteger,
              NSRangePointer)>>('objc_msgSend');
  late final __objc_msgSend_622 = __objc_msgSend_622Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSAttributedStringKey, int, NSRangePointer)>();

  late final _sel_attributedSubstringFromRange_1 =
      _registerName1("attributedSubstringFromRange:");
  ffi.Pointer<ObjCObject> _objc_msgSend_623(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
  ) {
    return __objc_msgSend_623(
      obj,
      sel,
      range,
    );
  }

  late final __objc_msgSend_623Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_623 = __objc_msgSend_623Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _sel_attributesAtIndex_longestEffectiveRange_inRange_1 =
      _registerName1("attributesAtIndex:longestEffectiveRange:inRange:");
  ffi.Pointer<ObjCObject> _objc_msgSend_624(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int location,
    NSRangePointer range,
    NSRange rangeLimit,
  ) {
    return __objc_msgSend_624(
      obj,
      sel,
      location,
      range,
      rangeLimit,
    );
  }

  late final __objc_msgSend_624Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSUInteger,
              NSRangePointer,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_624 = __objc_msgSend_624Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, NSRangePointer, NSRange)>();

  late final _sel_attribute_atIndex_longestEffectiveRange_inRange_1 =
      _registerName1("attribute:atIndex:longestEffectiveRange:inRange:");
  ffi.Pointer<ObjCObject> _objc_msgSend_625(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSAttributedStringKey attrName,
    int location,
    NSRangePointer range,
    NSRange rangeLimit,
  ) {
    return __objc_msgSend_625(
      obj,
      sel,
      attrName,
      location,
      range,
      rangeLimit,
    );
  }

  late final __objc_msgSend_625Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSAttributedStringKey,
              NSUInteger,
              NSRangePointer,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_625 = __objc_msgSend_625Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          NSAttributedStringKey,
          int,
          NSRangePointer,
          NSRange)>();

  late final _sel_isEqualToAttributedString_1 =
      _registerName1("isEqualToAttributedString:");
  bool _objc_msgSend_626(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> other,
  ) {
    return __objc_msgSend_626(
      obj,
      sel,
      other,
    );
  }

  late final __objc_msgSend_626Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_626 = __objc_msgSend_626Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithString_attributes_1 =
      _registerName1("initWithString:attributes:");
  late final _sel_initWithAttributedString_1 =
      _registerName1("initWithAttributedString:");
  instancetype _objc_msgSend_627(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> attrStr,
  ) {
    return __objc_msgSend_627(
      obj,
      sel,
      attrStr,
    );
  }

  late final __objc_msgSend_627Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_627 = __objc_msgSend_627Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_enumerateAttributesInRange_options_usingBlock_1 =
      _registerName1("enumerateAttributesInRange:options:usingBlock:");
  void _objc_msgSend_628(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange enumerationRange,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_628(
      obj,
      sel,
      enumerationRange,
      opts,
      block,
    );
  }

  late final __objc_msgSend_628Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_628 = __objc_msgSend_628Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_enumerateAttribute_inRange_options_usingBlock_1 =
      _registerName1("enumerateAttribute:inRange:options:usingBlock:");
  void _objc_msgSend_629(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSAttributedStringKey attrName,
    NSRange enumerationRange,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_629(
      obj,
      sel,
      attrName,
      enumerationRange,
      opts,
      block,
    );
  }

  late final __objc_msgSend_629Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSAttributedStringKey,
              NSRange,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_629 = __objc_msgSend_629Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          NSAttributedStringKey, NSRange, int, ffi.Pointer<_ObjCBlock>)>();

  late final _class_NSAttributedStringMarkdownParsingOptions1 =
      _getClass1("NSAttributedStringMarkdownParsingOptions");
  late final _sel_allowsExtendedAttributes1 =
      _registerName1("allowsExtendedAttributes");
  late final _sel_setAllowsExtendedAttributes_1 =
      _registerName1("setAllowsExtendedAttributes:");
  late final _sel_interpretedSyntax1 = _registerName1("interpretedSyntax");
  int _objc_msgSend_630(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_630(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_630Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_630 = __objc_msgSend_630Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setInterpretedSyntax_1 =
      _registerName1("setInterpretedSyntax:");
  void _objc_msgSend_631(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_631(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_631Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_631 = __objc_msgSend_631Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_failurePolicy1 = _registerName1("failurePolicy");
  int _objc_msgSend_632(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_632(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_632Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_632 = __objc_msgSend_632Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setFailurePolicy_1 = _registerName1("setFailurePolicy:");
  void _objc_msgSend_633(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_633(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_633Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_633 = __objc_msgSend_633Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_setLanguageCode_1 = _registerName1("setLanguageCode:");
  late final _sel_initWithContentsOfMarkdownFileAtURL_options_baseURL_error_1 =
      _registerName1(
          "initWithContentsOfMarkdownFileAtURL:options:baseURL:error:");
  instancetype _objc_msgSend_634(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> markdownFile,
    ffi.Pointer<ObjCObject> options,
    ffi.Pointer<ObjCObject> baseURL,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_634(
      obj,
      sel,
      markdownFile,
      options,
      baseURL,
      error,
    );
  }

  late final __objc_msgSend_634Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_634 = __objc_msgSend_634Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_initWithMarkdown_options_baseURL_error_1 =
      _registerName1("initWithMarkdown:options:baseURL:error:");
  instancetype _objc_msgSend_635(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> markdown,
    ffi.Pointer<ObjCObject> options,
    ffi.Pointer<ObjCObject> baseURL,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_635(
      obj,
      sel,
      markdown,
      options,
      baseURL,
      error,
    );
  }

  late final __objc_msgSend_635Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_635 = __objc_msgSend_635Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_initWithMarkdownString_options_baseURL_error_1 =
      _registerName1("initWithMarkdownString:options:baseURL:error:");
  instancetype _objc_msgSend_636(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> markdownString,
    ffi.Pointer<ObjCObject> options,
    ffi.Pointer<ObjCObject> baseURL,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_636(
      obj,
      sel,
      markdownString,
      options,
      baseURL,
      error,
    );
  }

  late final __objc_msgSend_636Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_636 = __objc_msgSend_636Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_initWithFormat_options_locale_1 =
      _registerName1("initWithFormat:options:locale:");
  instancetype _objc_msgSend_637(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> format,
    int options,
    ffi.Pointer<ObjCObject> locale,
  ) {
    return __objc_msgSend_637(
      obj,
      sel,
      format,
      options,
      locale,
    );
  }

  late final __objc_msgSend_637Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_637 = __objc_msgSend_637Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithFormat_options_locale_arguments_1 =
      _registerName1("initWithFormat:options:locale:arguments:");
  instancetype _objc_msgSend_638(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> format,
    int options,
    ffi.Pointer<ObjCObject> locale,
    ffi.Pointer<__va_list_tag> arguments,
  ) {
    return __objc_msgSend_638(
      obj,
      sel,
      format,
      options,
      locale,
      arguments,
    );
  }

  late final __objc_msgSend_638Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<__va_list_tag>)>>('objc_msgSend');
  late final __objc_msgSend_638 = __objc_msgSend_638Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<__va_list_tag>)>();

  late final _sel_localizedAttributedStringWithFormat_1 =
      _registerName1("localizedAttributedStringWithFormat:");
  late final _sel_localizedAttributedStringWithFormat_options_1 =
      _registerName1("localizedAttributedStringWithFormat:options:");
  instancetype _objc_msgSend_639(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> format,
    int options,
  ) {
    return __objc_msgSend_639(
      obj,
      sel,
      format,
      options,
    );
  }

  late final __objc_msgSend_639Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_639 = __objc_msgSend_639Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_attributedStringByInflectingString1 =
      _registerName1("attributedStringByInflectingString");
  ffi.Pointer<ObjCObject> _objc_msgSend_640(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_640(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_640Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_640 = __objc_msgSend_640Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_localizedAttributedStringForKey_value_table_1 =
      _registerName1("localizedAttributedStringForKey:value:table:");
  ffi.Pointer<ObjCObject> _objc_msgSend_641(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
    ffi.Pointer<ObjCObject> value,
    ffi.Pointer<ObjCObject> tableName,
  ) {
    return __objc_msgSend_641(
      obj,
      sel,
      key,
      value,
      tableName,
    );
  }

  late final __objc_msgSend_641Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_641 = __objc_msgSend_641Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_bundleIdentifier1 = _registerName1("bundleIdentifier");
  late final _sel_infoDictionary1 = _registerName1("infoDictionary");
  late final _sel_localizedInfoDictionary1 =
      _registerName1("localizedInfoDictionary");
  late final _sel_objectForInfoDictionaryKey_1 =
      _registerName1("objectForInfoDictionaryKey:");
  late final _sel_classNamed_1 = _registerName1("classNamed:");
  late final _sel_principalClass1 = _registerName1("principalClass");
  late final _sel_preferredLocalizations1 =
      _registerName1("preferredLocalizations");
  late final _sel_localizations1 = _registerName1("localizations");
  late final _sel_developmentLocalization1 =
      _registerName1("developmentLocalization");
  late final _sel_preferredLocalizationsFromArray_1 =
      _registerName1("preferredLocalizationsFromArray:");
  late final _sel_preferredLocalizationsFromArray_forPreferences_1 =
      _registerName1("preferredLocalizationsFromArray:forPreferences:");
  ffi.Pointer<ObjCObject> _objc_msgSend_642(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> localizationsArray,
    ffi.Pointer<ObjCObject> preferencesArray,
  ) {
    return __objc_msgSend_642(
      obj,
      sel,
      localizationsArray,
      preferencesArray,
    );
  }

  late final __objc_msgSend_642Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_642 = __objc_msgSend_642Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_executableArchitectures1 =
      _registerName1("executableArchitectures");
  late final _sel_setPreservationPriority_forTags_1 =
      _registerName1("setPreservationPriority:forTags:");
  void _objc_msgSend_643(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double priority,
    ffi.Pointer<ObjCObject> tags,
  ) {
    return __objc_msgSend_643(
      obj,
      sel,
      priority,
      tags,
    );
  }

  late final __objc_msgSend_643Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Double, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_643 = __objc_msgSend_643Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_preservationPriorityForTag_1 =
      _registerName1("preservationPriorityForTag:");
  late final _class_NSMutableAttributedString1 =
      _getClass1("NSMutableAttributedString");
  late final _sel_setAttributes_range_1 =
      _registerName1("setAttributes:range:");
  void _objc_msgSend_644(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> attrs,
    NSRange range,
  ) {
    return __objc_msgSend_644(
      obj,
      sel,
      attrs,
      range,
    );
  }

  late final __objc_msgSend_644Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_644 = __objc_msgSend_644Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, NSRange)>();

  late final _sel_mutableString1 = _registerName1("mutableString");
  ffi.Pointer<ObjCObject> _objc_msgSend_645(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_645(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_645Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_645 = __objc_msgSend_645Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_addAttribute_value_range_1 =
      _registerName1("addAttribute:value:range:");
  void _objc_msgSend_646(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSAttributedStringKey name,
    ffi.Pointer<ObjCObject> value,
    NSRange range,
  ) {
    return __objc_msgSend_646(
      obj,
      sel,
      name,
      value,
      range,
    );
  }

  late final __objc_msgSend_646Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSAttributedStringKey,
              ffi.Pointer<ObjCObject>,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_646 = __objc_msgSend_646Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          NSAttributedStringKey, ffi.Pointer<ObjCObject>, NSRange)>();

  late final _sel_addAttributes_range_1 =
      _registerName1("addAttributes:range:");
  late final _sel_removeAttribute_range_1 =
      _registerName1("removeAttribute:range:");
  void _objc_msgSend_647(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSAttributedStringKey name,
    NSRange range,
  ) {
    return __objc_msgSend_647(
      obj,
      sel,
      name,
      range,
    );
  }

  late final __objc_msgSend_647Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSAttributedStringKey, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_647 = __objc_msgSend_647Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          NSAttributedStringKey, NSRange)>();

  late final _sel_replaceCharactersInRange_withAttributedString_1 =
      _registerName1("replaceCharactersInRange:withAttributedString:");
  void _objc_msgSend_648(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> attrString,
  ) {
    return __objc_msgSend_648(
      obj,
      sel,
      range,
      attrString,
    );
  }

  late final __objc_msgSend_648Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSRange, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_648 = __objc_msgSend_648Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_insertAttributedString_atIndex_1 =
      _registerName1("insertAttributedString:atIndex:");
  void _objc_msgSend_649(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> attrString,
    int loc,
  ) {
    return __objc_msgSend_649(
      obj,
      sel,
      attrString,
      loc,
    );
  }

  late final __objc_msgSend_649Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_649 = __objc_msgSend_649Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_appendAttributedString_1 =
      _registerName1("appendAttributedString:");
  void _objc_msgSend_650(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> attrString,
  ) {
    return __objc_msgSend_650(
      obj,
      sel,
      attrString,
    );
  }

  late final __objc_msgSend_650Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_650 = __objc_msgSend_650Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_setAttributedString_1 =
      _registerName1("setAttributedString:");
  late final _sel_beginEditing1 = _registerName1("beginEditing");
  late final _sel_endEditing1 = _registerName1("endEditing");
  late final _sel_appendLocalizedFormat_1 =
      _registerName1("appendLocalizedFormat:");
  late final _class_NSDateFormatter1 = _getClass1("NSDateFormatter");
  late final _class_NSFormatter1 = _getClass1("NSFormatter");
  late final _sel_stringForObjectValue_1 =
      _registerName1("stringForObjectValue:");
  late final _sel_attributedStringForObjectValue_withDefaultAttributes_1 =
      _registerName1("attributedStringForObjectValue:withDefaultAttributes:");
  ffi.Pointer<ObjCObject> _objc_msgSend_651(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> obj1,
    ffi.Pointer<ObjCObject> attrs,
  ) {
    return __objc_msgSend_651(
      obj,
      sel,
      obj1,
      attrs,
    );
  }

  late final __objc_msgSend_651Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_651 = __objc_msgSend_651Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_editingStringForObjectValue_1 =
      _registerName1("editingStringForObjectValue:");
  late final _sel_getObjectValue_forString_errorDescription_1 =
      _registerName1("getObjectValue:forString:errorDescription:");
  bool _objc_msgSend_652(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> obj1,
    ffi.Pointer<ObjCObject> string,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_652(
      obj,
      sel,
      obj1,
      string,
      error,
    );
  }

  late final __objc_msgSend_652Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_652 = __objc_msgSend_652Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_isPartialStringValid_newEditingString_errorDescription_1 =
      _registerName1("isPartialStringValid:newEditingString:errorDescription:");
  bool _objc_msgSend_653(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> partialString,
    ffi.Pointer<ffi.Pointer<ObjCObject>> newString,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_653(
      obj,
      sel,
      partialString,
      newString,
      error,
    );
  }

  late final __objc_msgSend_653Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_653 = __objc_msgSend_653Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_isPartialStringValid_proposedSelectedRange_originalString_originalSelectedRange_errorDescription_1 =
      _registerName1(
          "isPartialStringValid:proposedSelectedRange:originalString:originalSelectedRange:errorDescription:");
  bool _objc_msgSend_654(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> partialStringPtr,
    NSRangePointer proposedSelRangePtr,
    ffi.Pointer<ObjCObject> origString,
    NSRange origSelRange,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_654(
      obj,
      sel,
      partialStringPtr,
      proposedSelRangePtr,
      origString,
      origSelRange,
      error,
    );
  }

  late final __objc_msgSend_654Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              NSRangePointer,
              ffi.Pointer<ObjCObject>,
              NSRange,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_654 = __objc_msgSend_654Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          NSRangePointer,
          ffi.Pointer<ObjCObject>,
          NSRange,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_formattingContext1 = _registerName1("formattingContext");
  int _objc_msgSend_655(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_655(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_655Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_655 = __objc_msgSend_655Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setFormattingContext_1 =
      _registerName1("setFormattingContext:");
  void _objc_msgSend_656(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_656(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_656Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_656 = __objc_msgSend_656Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_getObjectValue_forString_range_error_1 =
      _registerName1("getObjectValue:forString:range:error:");
  bool _objc_msgSend_657(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> obj1,
    ffi.Pointer<ObjCObject> string,
    ffi.Pointer<NSRange> rangep,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_657(
      obj,
      sel,
      obj1,
      string,
      rangep,
      error,
    );
  }

  late final __objc_msgSend_657Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<NSRange>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_657 = __objc_msgSend_657Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<NSRange>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_stringFromDate_1 = _registerName1("stringFromDate:");
  late final _sel_dateFromString_1 = _registerName1("dateFromString:");
  late final _sel_localizedStringFromDate_dateStyle_timeStyle_1 =
      _registerName1("localizedStringFromDate:dateStyle:timeStyle:");
  ffi.Pointer<ObjCObject> _objc_msgSend_658(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date,
    int dstyle,
    int tstyle,
  ) {
    return __objc_msgSend_658(
      obj,
      sel,
      date,
      dstyle,
      tstyle,
    );
  }

  late final __objc_msgSend_658Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_658 = __objc_msgSend_658Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, int, int)>();

  late final _sel_dateFormatFromTemplate_options_locale_1 =
      _registerName1("dateFormatFromTemplate:options:locale:");
  ffi.Pointer<ObjCObject> _objc_msgSend_659(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> tmplate,
    int opts,
    ffi.Pointer<ObjCObject> locale,
  ) {
    return __objc_msgSend_659(
      obj,
      sel,
      tmplate,
      opts,
      locale,
    );
  }

  late final __objc_msgSend_659Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSUInteger,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_659 = __objc_msgSend_659Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_defaultFormatterBehavior1 =
      _registerName1("defaultFormatterBehavior");
  int _objc_msgSend_660(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_660(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_660Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_660 = __objc_msgSend_660Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setDefaultFormatterBehavior_1 =
      _registerName1("setDefaultFormatterBehavior:");
  void _objc_msgSend_661(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_661(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_661Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_661 = __objc_msgSend_661Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_setLocalizedDateFormatFromTemplate_1 =
      _registerName1("setLocalizedDateFormatFromTemplate:");
  late final _sel_dateFormat1 = _registerName1("dateFormat");
  late final _sel_setDateFormat_1 = _registerName1("setDateFormat:");
  late final _sel_dateStyle1 = _registerName1("dateStyle");
  int _objc_msgSend_662(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_662(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_662Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_662 = __objc_msgSend_662Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setDateStyle_1 = _registerName1("setDateStyle:");
  void _objc_msgSend_663(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_663(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_663Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_663 = __objc_msgSend_663Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_timeStyle1 = _registerName1("timeStyle");
  late final _sel_setTimeStyle_1 = _registerName1("setTimeStyle:");
  late final _sel_locale1 = _registerName1("locale");
  late final _sel_setLocale_1 = _registerName1("setLocale:");
  void _objc_msgSend_664(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_664(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_664Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_664 = __objc_msgSend_664Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_generatesCalendarDates1 =
      _registerName1("generatesCalendarDates");
  late final _sel_setGeneratesCalendarDates_1 =
      _registerName1("setGeneratesCalendarDates:");
  late final _sel_formatterBehavior1 = _registerName1("formatterBehavior");
  late final _sel_setFormatterBehavior_1 =
      _registerName1("setFormatterBehavior:");
  late final _class_NSCalendar1 = _getClass1("NSCalendar");
  late final _sel_currentCalendar1 = _registerName1("currentCalendar");
  ffi.Pointer<ObjCObject> _objc_msgSend_665(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_665(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_665Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_665 = __objc_msgSend_665Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_autoupdatingCurrentCalendar1 =
      _registerName1("autoupdatingCurrentCalendar");
  late final _sel_calendarWithIdentifier_1 =
      _registerName1("calendarWithIdentifier:");
  ffi.Pointer<ObjCObject> _objc_msgSend_666(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSCalendarIdentifier calendarIdentifierConstant,
  ) {
    return __objc_msgSend_666(
      obj,
      sel,
      calendarIdentifierConstant,
    );
  }

  late final __objc_msgSend_666Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSCalendarIdentifier)>>('objc_msgSend');
  late final __objc_msgSend_666 = __objc_msgSend_666Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSCalendarIdentifier)>();

  late final _sel_initWithCalendarIdentifier_1 =
      _registerName1("initWithCalendarIdentifier:");
  late final _sel_firstWeekday1 = _registerName1("firstWeekday");
  late final _sel_setFirstWeekday_1 = _registerName1("setFirstWeekday:");
  late final _sel_minimumDaysInFirstWeek1 =
      _registerName1("minimumDaysInFirstWeek");
  late final _sel_setMinimumDaysInFirstWeek_1 =
      _registerName1("setMinimumDaysInFirstWeek:");
  late final _sel_eraSymbols1 = _registerName1("eraSymbols");
  late final _sel_longEraSymbols1 = _registerName1("longEraSymbols");
  late final _sel_monthSymbols1 = _registerName1("monthSymbols");
  late final _sel_shortMonthSymbols1 = _registerName1("shortMonthSymbols");
  late final _sel_veryShortMonthSymbols1 =
      _registerName1("veryShortMonthSymbols");
  late final _sel_standaloneMonthSymbols1 =
      _registerName1("standaloneMonthSymbols");
  late final _sel_shortStandaloneMonthSymbols1 =
      _registerName1("shortStandaloneMonthSymbols");
  late final _sel_veryShortStandaloneMonthSymbols1 =
      _registerName1("veryShortStandaloneMonthSymbols");
  late final _sel_weekdaySymbols1 = _registerName1("weekdaySymbols");
  late final _sel_shortWeekdaySymbols1 = _registerName1("shortWeekdaySymbols");
  late final _sel_veryShortWeekdaySymbols1 =
      _registerName1("veryShortWeekdaySymbols");
  late final _sel_standaloneWeekdaySymbols1 =
      _registerName1("standaloneWeekdaySymbols");
  late final _sel_shortStandaloneWeekdaySymbols1 =
      _registerName1("shortStandaloneWeekdaySymbols");
  late final _sel_veryShortStandaloneWeekdaySymbols1 =
      _registerName1("veryShortStandaloneWeekdaySymbols");
  late final _sel_quarterSymbols1 = _registerName1("quarterSymbols");
  late final _sel_shortQuarterSymbols1 = _registerName1("shortQuarterSymbols");
  late final _sel_standaloneQuarterSymbols1 =
      _registerName1("standaloneQuarterSymbols");
  late final _sel_shortStandaloneQuarterSymbols1 =
      _registerName1("shortStandaloneQuarterSymbols");
  late final _sel_AMSymbol1 = _registerName1("AMSymbol");
  late final _sel_PMSymbol1 = _registerName1("PMSymbol");
  late final _sel_minimumRangeOfUnit_1 = _registerName1("minimumRangeOfUnit:");
  NSRange _objc_msgSend_667(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unit,
  ) {
    return __objc_msgSend_667(
      obj,
      sel,
      unit,
    );
  }

  late final __objc_msgSend_667Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_667 = __objc_msgSend_667Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_maximumRangeOfUnit_1 = _registerName1("maximumRangeOfUnit:");
  late final _sel_rangeOfUnit_inUnit_forDate_1 =
      _registerName1("rangeOfUnit:inUnit:forDate:");
  NSRange _objc_msgSend_668(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int smaller,
    int larger,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_668(
      obj,
      sel,
      smaller,
      larger,
      date,
    );
  }

  late final __objc_msgSend_668Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Int32, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_668 = __objc_msgSend_668Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int, int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_ordinalityOfUnit_inUnit_forDate_1 =
      _registerName1("ordinalityOfUnit:inUnit:forDate:");
  int _objc_msgSend_669(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int smaller,
    int larger,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_669(
      obj,
      sel,
      smaller,
      larger,
      date,
    );
  }

  late final __objc_msgSend_669Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Int32, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_669 = __objc_msgSend_669Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int, int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_rangeOfUnit_startDate_interval_forDate_1 =
      _registerName1("rangeOfUnit:startDate:interval:forDate:");
  bool _objc_msgSend_670(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unit,
    ffi.Pointer<ffi.Pointer<ObjCObject>> datep,
    ffi.Pointer<NSTimeInterval> tip,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_670(
      obj,
      sel,
      unit,
      datep,
      tip,
      date,
    );
  }

  late final __objc_msgSend_670Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<NSTimeInterval>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_670 = __objc_msgSend_670Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<NSTimeInterval>,
          ffi.Pointer<ObjCObject>)>();

  late final _class_NSDateComponents1 = _getClass1("NSDateComponents");
  late final _sel_calendar1 = _registerName1("calendar");
  late final _sel_setCalendar_1 = _registerName1("setCalendar:");
  void _objc_msgSend_671(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_671(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_671Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_671 = __objc_msgSend_671Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_era1 = _registerName1("era");
  late final _sel_setEra_1 = _registerName1("setEra:");
  late final _sel_year1 = _registerName1("year");
  late final _sel_setYear_1 = _registerName1("setYear:");
  late final _sel_month1 = _registerName1("month");
  late final _sel_setMonth_1 = _registerName1("setMonth:");
  late final _sel_day1 = _registerName1("day");
  late final _sel_setDay_1 = _registerName1("setDay:");
  late final _sel_hour1 = _registerName1("hour");
  late final _sel_setHour_1 = _registerName1("setHour:");
  late final _sel_minute1 = _registerName1("minute");
  late final _sel_setMinute_1 = _registerName1("setMinute:");
  late final _sel_second1 = _registerName1("second");
  late final _sel_setSecond_1 = _registerName1("setSecond:");
  late final _sel_nanosecond1 = _registerName1("nanosecond");
  late final _sel_setNanosecond_1 = _registerName1("setNanosecond:");
  late final _sel_weekday1 = _registerName1("weekday");
  late final _sel_setWeekday_1 = _registerName1("setWeekday:");
  late final _sel_weekdayOrdinal1 = _registerName1("weekdayOrdinal");
  late final _sel_setWeekdayOrdinal_1 = _registerName1("setWeekdayOrdinal:");
  late final _sel_quarter1 = _registerName1("quarter");
  late final _sel_setQuarter_1 = _registerName1("setQuarter:");
  late final _sel_weekOfMonth1 = _registerName1("weekOfMonth");
  late final _sel_setWeekOfMonth_1 = _registerName1("setWeekOfMonth:");
  late final _sel_weekOfYear1 = _registerName1("weekOfYear");
  late final _sel_setWeekOfYear_1 = _registerName1("setWeekOfYear:");
  late final _sel_yearForWeekOfYear1 = _registerName1("yearForWeekOfYear");
  late final _sel_setYearForWeekOfYear_1 =
      _registerName1("setYearForWeekOfYear:");
  late final _sel_isLeapMonth1 = _registerName1("isLeapMonth");
  late final _sel_setLeapMonth_1 = _registerName1("setLeapMonth:");
  late final _sel_week1 = _registerName1("week");
  late final _sel_setWeek_1 = _registerName1("setWeek:");
  late final _sel_setValue_forComponent_1 =
      _registerName1("setValue:forComponent:");
  void _objc_msgSend_672(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
    int unit,
  ) {
    return __objc_msgSend_672(
      obj,
      sel,
      value,
      unit,
    );
  }

  late final __objc_msgSend_672Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSInteger, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_672 = __objc_msgSend_672Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int, int)>();

  late final _sel_valueForComponent_1 = _registerName1("valueForComponent:");
  int _objc_msgSend_673(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unit,
  ) {
    return __objc_msgSend_673(
      obj,
      sel,
      unit,
    );
  }

  late final __objc_msgSend_673Ptr = _lookup<
      ffi.NativeFunction<
          NSInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_673 = __objc_msgSend_673Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_isValidDate1 = _registerName1("isValidDate");
  late final _sel_isValidDateInCalendar_1 =
      _registerName1("isValidDateInCalendar:");
  bool _objc_msgSend_674(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> calendar,
  ) {
    return __objc_msgSend_674(
      obj,
      sel,
      calendar,
    );
  }

  late final __objc_msgSend_674Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_674 = __objc_msgSend_674Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_dateFromComponents_1 = _registerName1("dateFromComponents:");
  ffi.Pointer<ObjCObject> _objc_msgSend_675(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> comps,
  ) {
    return __objc_msgSend_675(
      obj,
      sel,
      comps,
    );
  }

  late final __objc_msgSend_675Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_675 = __objc_msgSend_675Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_components_fromDate_1 =
      _registerName1("components:fromDate:");
  ffi.Pointer<ObjCObject> _objc_msgSend_676(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unitFlags,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_676(
      obj,
      sel,
      unitFlags,
      date,
    );
  }

  late final __objc_msgSend_676Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_676 = __objc_msgSend_676Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<ObjCObject>)>();

  late final _sel_dateByAddingComponents_toDate_options_1 =
      _registerName1("dateByAddingComponents:toDate:options:");
  ffi.Pointer<ObjCObject> _objc_msgSend_677(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> comps,
    ffi.Pointer<ObjCObject> date,
    int opts,
  ) {
    return __objc_msgSend_677(
      obj,
      sel,
      comps,
      date,
      opts,
    );
  }

  late final __objc_msgSend_677Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_677 = __objc_msgSend_677Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int)>();

  late final _sel_components_fromDate_toDate_options_1 =
      _registerName1("components:fromDate:toDate:options:");
  ffi.Pointer<ObjCObject> _objc_msgSend_678(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unitFlags,
    ffi.Pointer<ObjCObject> startingDate,
    ffi.Pointer<ObjCObject> resultDate,
    int opts,
  ) {
    return __objc_msgSend_678(
      obj,
      sel,
      unitFlags,
      startingDate,
      resultDate,
      opts,
    );
  }

  late final __objc_msgSend_678Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_678 = __objc_msgSend_678Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          int,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int)>();

  late final _sel_getEra_year_month_day_fromDate_1 =
      _registerName1("getEra:year:month:day:fromDate:");
  void _objc_msgSend_679(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSInteger> eraValuePointer,
    ffi.Pointer<NSInteger> yearValuePointer,
    ffi.Pointer<NSInteger> monthValuePointer,
    ffi.Pointer<NSInteger> dayValuePointer,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_679(
      obj,
      sel,
      eraValuePointer,
      yearValuePointer,
      monthValuePointer,
      dayValuePointer,
      date,
    );
  }

  late final __objc_msgSend_679Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSInteger>,
              ffi.Pointer<NSInteger>,
              ffi.Pointer<NSInteger>,
              ffi.Pointer<NSInteger>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_679 = __objc_msgSend_679Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSInteger>,
          ffi.Pointer<NSInteger>,
          ffi.Pointer<NSInteger>,
          ffi.Pointer<NSInteger>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_getEra_yearForWeekOfYear_weekOfYear_weekday_fromDate_1 =
      _registerName1("getEra:yearForWeekOfYear:weekOfYear:weekday:fromDate:");
  late final _sel_getHour_minute_second_nanosecond_fromDate_1 =
      _registerName1("getHour:minute:second:nanosecond:fromDate:");
  late final _sel_component_fromDate_1 = _registerName1("component:fromDate:");
  int _objc_msgSend_680(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unit,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_680(
      obj,
      sel,
      unit,
      date,
    );
  }

  late final __objc_msgSend_680Ptr = _lookup<
      ffi.NativeFunction<
          NSInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_680 = __objc_msgSend_680Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_dateWithEra_year_month_day_hour_minute_second_nanosecond_1 =
      _registerName1(
          "dateWithEra:year:month:day:hour:minute:second:nanosecond:");
  ffi.Pointer<ObjCObject> _objc_msgSend_681(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int eraValue,
    int yearValue,
    int monthValue,
    int dayValue,
    int hourValue,
    int minuteValue,
    int secondValue,
    int nanosecondValue,
  ) {
    return __objc_msgSend_681(
      obj,
      sel,
      eraValue,
      yearValue,
      monthValue,
      dayValue,
      hourValue,
      minuteValue,
      secondValue,
      nanosecondValue,
    );
  }

  late final __objc_msgSend_681Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSInteger,
              NSInteger,
              NSInteger,
              NSInteger,
              NSInteger,
              NSInteger,
              NSInteger,
              NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_681 = __objc_msgSend_681Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, int, int, int, int, int, int, int)>();

  late final _sel_dateWithEra_yearForWeekOfYear_weekOfYear_weekday_hour_minute_second_nanosecond_1 =
      _registerName1(
          "dateWithEra:yearForWeekOfYear:weekOfYear:weekday:hour:minute:second:nanosecond:");
  late final _sel_startOfDayForDate_1 = _registerName1("startOfDayForDate:");
  late final _sel_componentsInTimeZone_fromDate_1 =
      _registerName1("componentsInTimeZone:fromDate:");
  ffi.Pointer<ObjCObject> _objc_msgSend_682(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> timezone,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_682(
      obj,
      sel,
      timezone,
      date,
    );
  }

  late final __objc_msgSend_682Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_682 = __objc_msgSend_682Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_compareDate_toDate_toUnitGranularity_1 =
      _registerName1("compareDate:toDate:toUnitGranularity:");
  int _objc_msgSend_683(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date1,
    ffi.Pointer<ObjCObject> date2,
    int unit,
  ) {
    return __objc_msgSend_683(
      obj,
      sel,
      date1,
      date2,
      unit,
    );
  }

  late final __objc_msgSend_683Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_683 = __objc_msgSend_683Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>, int)>();

  late final _sel_isDate_equalToDate_toUnitGranularity_1 =
      _registerName1("isDate:equalToDate:toUnitGranularity:");
  bool _objc_msgSend_684(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date1,
    ffi.Pointer<ObjCObject> date2,
    int unit,
  ) {
    return __objc_msgSend_684(
      obj,
      sel,
      date1,
      date2,
      unit,
    );
  }

  late final __objc_msgSend_684Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_684 = __objc_msgSend_684Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>, int)>();

  late final _sel_isDate_inSameDayAsDate_1 =
      _registerName1("isDate:inSameDayAsDate:");
  bool _objc_msgSend_685(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date1,
    ffi.Pointer<ObjCObject> date2,
  ) {
    return __objc_msgSend_685(
      obj,
      sel,
      date1,
      date2,
    );
  }

  late final __objc_msgSend_685Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_685 = __objc_msgSend_685Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_isDateInToday_1 = _registerName1("isDateInToday:");
  late final _sel_isDateInYesterday_1 = _registerName1("isDateInYesterday:");
  late final _sel_isDateInTomorrow_1 = _registerName1("isDateInTomorrow:");
  late final _sel_isDateInWeekend_1 = _registerName1("isDateInWeekend:");
  late final _sel_rangeOfWeekendStartDate_interval_containingDate_1 =
      _registerName1("rangeOfWeekendStartDate:interval:containingDate:");
  bool _objc_msgSend_686(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> datep,
    ffi.Pointer<NSTimeInterval> tip,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_686(
      obj,
      sel,
      datep,
      tip,
      date,
    );
  }

  late final __objc_msgSend_686Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<NSTimeInterval>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_686 = __objc_msgSend_686Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<NSTimeInterval>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_nextWeekendStartDate_interval_options_afterDate_1 =
      _registerName1("nextWeekendStartDate:interval:options:afterDate:");
  bool _objc_msgSend_687(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> datep,
    ffi.Pointer<NSTimeInterval> tip,
    int options,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_687(
      obj,
      sel,
      datep,
      tip,
      options,
      date,
    );
  }

  late final __objc_msgSend_687Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<NSTimeInterval>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_687 = __objc_msgSend_687Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<NSTimeInterval>,
          int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_components_fromDateComponents_toDateComponents_options_1 =
      _registerName1("components:fromDateComponents:toDateComponents:options:");
  ffi.Pointer<ObjCObject> _objc_msgSend_688(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unitFlags,
    ffi.Pointer<ObjCObject> startingDateComp,
    ffi.Pointer<ObjCObject> resultDateComp,
    int options,
  ) {
    return __objc_msgSend_688(
      obj,
      sel,
      unitFlags,
      startingDateComp,
      resultDateComp,
      options,
    );
  }

  late final __objc_msgSend_688Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_688 = __objc_msgSend_688Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          int,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int)>();

  late final _sel_dateByAddingUnit_value_toDate_options_1 =
      _registerName1("dateByAddingUnit:value:toDate:options:");
  ffi.Pointer<ObjCObject> _objc_msgSend_689(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int unit,
    int value,
    ffi.Pointer<ObjCObject> date,
    int options,
  ) {
    return __objc_msgSend_689(
      obj,
      sel,
      unit,
      value,
      date,
      options,
    );
  }

  late final __objc_msgSend_689Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              NSInteger,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_689 = __objc_msgSend_689Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, int, ffi.Pointer<ObjCObject>, int)>();

  late final _sel_enumerateDatesStartingAfterDate_matchingComponents_options_usingBlock_1 =
      _registerName1(
          "enumerateDatesStartingAfterDate:matchingComponents:options:usingBlock:");
  void _objc_msgSend_690(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> start,
    ffi.Pointer<ObjCObject> comps,
    int opts,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_690(
      obj,
      sel,
      start,
      comps,
      opts,
      block,
    );
  }

  late final __objc_msgSend_690Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_690 = __objc_msgSend_690Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_nextDateAfterDate_matchingComponents_options_1 =
      _registerName1("nextDateAfterDate:matchingComponents:options:");
  ffi.Pointer<ObjCObject> _objc_msgSend_691(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date,
    ffi.Pointer<ObjCObject> comps,
    int options,
  ) {
    return __objc_msgSend_691(
      obj,
      sel,
      date,
      comps,
      options,
    );
  }

  late final __objc_msgSend_691Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_691 = __objc_msgSend_691Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int)>();

  late final _sel_nextDateAfterDate_matchingUnit_value_options_1 =
      _registerName1("nextDateAfterDate:matchingUnit:value:options:");
  ffi.Pointer<ObjCObject> _objc_msgSend_692(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date,
    int unit,
    int value,
    int options,
  ) {
    return __objc_msgSend_692(
      obj,
      sel,
      date,
      unit,
      value,
      options,
    );
  }

  late final __objc_msgSend_692Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              NSInteger,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_692 = __objc_msgSend_692Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, int, int, int)>();

  late final _sel_nextDateAfterDate_matchingHour_minute_second_options_1 =
      _registerName1("nextDateAfterDate:matchingHour:minute:second:options:");
  ffi.Pointer<ObjCObject> _objc_msgSend_693(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date,
    int hourValue,
    int minuteValue,
    int secondValue,
    int options,
  ) {
    return __objc_msgSend_693(
      obj,
      sel,
      date,
      hourValue,
      minuteValue,
      secondValue,
      options,
    );
  }

  late final __objc_msgSend_693Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSInteger,
              NSInteger,
              NSInteger,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_693 = __objc_msgSend_693Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, int, int, int, int)>();

  late final _sel_dateBySettingUnit_value_ofDate_options_1 =
      _registerName1("dateBySettingUnit:value:ofDate:options:");
  late final _sel_dateBySettingHour_minute_second_ofDate_options_1 =
      _registerName1("dateBySettingHour:minute:second:ofDate:options:");
  ffi.Pointer<ObjCObject> _objc_msgSend_694(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int h,
    int m,
    int s,
    ffi.Pointer<ObjCObject> date,
    int opts,
  ) {
    return __objc_msgSend_694(
      obj,
      sel,
      h,
      m,
      s,
      date,
      opts,
    );
  }

  late final __objc_msgSend_694Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSInteger,
              NSInteger,
              NSInteger,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_694 = __objc_msgSend_694Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, int, int, ffi.Pointer<ObjCObject>, int)>();

  late final _sel_date_matchesComponents_1 =
      _registerName1("date:matchesComponents:");
  bool _objc_msgSend_695(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> date,
    ffi.Pointer<ObjCObject> components,
  ) {
    return __objc_msgSend_695(
      obj,
      sel,
      date,
      components,
    );
  }

  late final __objc_msgSend_695Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_695 = __objc_msgSend_695Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_isLenient1 = _registerName1("isLenient");
  late final _sel_setLenient_1 = _registerName1("setLenient:");
  late final _sel_twoDigitStartDate1 = _registerName1("twoDigitStartDate");
  late final _sel_setTwoDigitStartDate_1 =
      _registerName1("setTwoDigitStartDate:");
  late final _sel_defaultDate1 = _registerName1("defaultDate");
  late final _sel_setDefaultDate_1 = _registerName1("setDefaultDate:");
  late final _sel_setEraSymbols_1 = _registerName1("setEraSymbols:");
  void _objc_msgSend_696(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_696(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_696Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_696 = __objc_msgSend_696Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_setMonthSymbols_1 = _registerName1("setMonthSymbols:");
  late final _sel_setShortMonthSymbols_1 =
      _registerName1("setShortMonthSymbols:");
  late final _sel_setWeekdaySymbols_1 = _registerName1("setWeekdaySymbols:");
  late final _sel_setShortWeekdaySymbols_1 =
      _registerName1("setShortWeekdaySymbols:");
  late final _sel_setAMSymbol_1 = _registerName1("setAMSymbol:");
  late final _sel_setPMSymbol_1 = _registerName1("setPMSymbol:");
  late final _sel_setLongEraSymbols_1 = _registerName1("setLongEraSymbols:");
  late final _sel_setVeryShortMonthSymbols_1 =
      _registerName1("setVeryShortMonthSymbols:");
  late final _sel_setStandaloneMonthSymbols_1 =
      _registerName1("setStandaloneMonthSymbols:");
  late final _sel_setShortStandaloneMonthSymbols_1 =
      _registerName1("setShortStandaloneMonthSymbols:");
  late final _sel_setVeryShortStandaloneMonthSymbols_1 =
      _registerName1("setVeryShortStandaloneMonthSymbols:");
  late final _sel_setVeryShortWeekdaySymbols_1 =
      _registerName1("setVeryShortWeekdaySymbols:");
  late final _sel_setStandaloneWeekdaySymbols_1 =
      _registerName1("setStandaloneWeekdaySymbols:");
  late final _sel_setShortStandaloneWeekdaySymbols_1 =
      _registerName1("setShortStandaloneWeekdaySymbols:");
  late final _sel_setVeryShortStandaloneWeekdaySymbols_1 =
      _registerName1("setVeryShortStandaloneWeekdaySymbols:");
  late final _sel_setQuarterSymbols_1 = _registerName1("setQuarterSymbols:");
  late final _sel_setShortQuarterSymbols_1 =
      _registerName1("setShortQuarterSymbols:");
  late final _sel_setStandaloneQuarterSymbols_1 =
      _registerName1("setStandaloneQuarterSymbols:");
  late final _sel_setShortStandaloneQuarterSymbols_1 =
      _registerName1("setShortStandaloneQuarterSymbols:");
  late final _sel_gregorianStartDate1 = _registerName1("gregorianStartDate");
  late final _sel_setGregorianStartDate_1 =
      _registerName1("setGregorianStartDate:");
  late final _sel_doesRelativeDateFormatting1 =
      _registerName1("doesRelativeDateFormatting");
  late final _sel_setDoesRelativeDateFormatting_1 =
      _registerName1("setDoesRelativeDateFormatting:");
  late final _sel_initWithDateFormat_allowNaturalLanguage_1 =
      _registerName1("initWithDateFormat:allowNaturalLanguage:");
  late final _sel_allowsNaturalLanguage1 =
      _registerName1("allowsNaturalLanguage");
  late final _class_NSNumberFormatter1 = _getClass1("NSNumberFormatter");
  late final _sel_stringFromNumber_1 = _registerName1("stringFromNumber:");
  ffi.Pointer<ObjCObject> _objc_msgSend_697(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> number,
  ) {
    return __objc_msgSend_697(
      obj,
      sel,
      number,
    );
  }

  late final __objc_msgSend_697Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_697 = __objc_msgSend_697Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_numberFromString_1 = _registerName1("numberFromString:");
  ffi.Pointer<ObjCObject> _objc_msgSend_698(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
  ) {
    return __objc_msgSend_698(
      obj,
      sel,
      string,
    );
  }

  late final __objc_msgSend_698Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_698 = __objc_msgSend_698Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_localizedStringFromNumber_numberStyle_1 =
      _registerName1("localizedStringFromNumber:numberStyle:");
  ffi.Pointer<ObjCObject> _objc_msgSend_699(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> num,
    int nstyle,
  ) {
    return __objc_msgSend_699(
      obj,
      sel,
      num,
      nstyle,
    );
  }

  late final __objc_msgSend_699Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_699 = __objc_msgSend_699Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, int)>();

  int _objc_msgSend_700(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_700(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_700Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_700 = __objc_msgSend_700Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  void _objc_msgSend_701(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int behavior,
  ) {
    return __objc_msgSend_701(
      obj,
      sel,
      behavior,
    );
  }

  late final __objc_msgSend_701Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_701 = __objc_msgSend_701Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_numberStyle1 = _registerName1("numberStyle");
  int _objc_msgSend_702(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_702(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_702Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_702 = __objc_msgSend_702Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setNumberStyle_1 = _registerName1("setNumberStyle:");
  void _objc_msgSend_703(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_703(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_703Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_703 = __objc_msgSend_703Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_generatesDecimalNumbers1 =
      _registerName1("generatesDecimalNumbers");
  late final _sel_setGeneratesDecimalNumbers_1 =
      _registerName1("setGeneratesDecimalNumbers:");
  void _objc_msgSend_704(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_704(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_704Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_704 = __objc_msgSend_704Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_negativeFormat1 = _registerName1("negativeFormat");
  late final _sel_setNegativeFormat_1 = _registerName1("setNegativeFormat:");
  late final _sel_textAttributesForNegativeValues1 =
      _registerName1("textAttributesForNegativeValues");
  late final _sel_setTextAttributesForNegativeValues_1 =
      _registerName1("setTextAttributesForNegativeValues:");
  late final _sel_positiveFormat1 = _registerName1("positiveFormat");
  late final _sel_setPositiveFormat_1 = _registerName1("setPositiveFormat:");
  late final _sel_textAttributesForPositiveValues1 =
      _registerName1("textAttributesForPositiveValues");
  late final _sel_setTextAttributesForPositiveValues_1 =
      _registerName1("setTextAttributesForPositiveValues:");
  late final _sel_allowsFloats1 = _registerName1("allowsFloats");
  late final _sel_setAllowsFloats_1 = _registerName1("setAllowsFloats:");
  late final _sel_setDecimalSeparator_1 =
      _registerName1("setDecimalSeparator:");
  late final _sel_alwaysShowsDecimalSeparator1 =
      _registerName1("alwaysShowsDecimalSeparator");
  late final _sel_setAlwaysShowsDecimalSeparator_1 =
      _registerName1("setAlwaysShowsDecimalSeparator:");
  late final _sel_currencyDecimalSeparator1 =
      _registerName1("currencyDecimalSeparator");
  late final _sel_setCurrencyDecimalSeparator_1 =
      _registerName1("setCurrencyDecimalSeparator:");
  late final _sel_usesGroupingSeparator1 =
      _registerName1("usesGroupingSeparator");
  late final _sel_setUsesGroupingSeparator_1 =
      _registerName1("setUsesGroupingSeparator:");
  late final _sel_setGroupingSeparator_1 =
      _registerName1("setGroupingSeparator:");
  late final _sel_zeroSymbol1 = _registerName1("zeroSymbol");
  late final _sel_setZeroSymbol_1 = _registerName1("setZeroSymbol:");
  late final _sel_textAttributesForZero1 =
      _registerName1("textAttributesForZero");
  late final _sel_setTextAttributesForZero_1 =
      _registerName1("setTextAttributesForZero:");
  late final _sel_nilSymbol1 = _registerName1("nilSymbol");
  late final _sel_setNilSymbol_1 = _registerName1("setNilSymbol:");
  late final _sel_textAttributesForNil1 =
      _registerName1("textAttributesForNil");
  late final _sel_setTextAttributesForNil_1 =
      _registerName1("setTextAttributesForNil:");
  late final _sel_notANumberSymbol1 = _registerName1("notANumberSymbol");
  late final _sel_setNotANumberSymbol_1 =
      _registerName1("setNotANumberSymbol:");
  late final _sel_textAttributesForNotANumber1 =
      _registerName1("textAttributesForNotANumber");
  late final _sel_setTextAttributesForNotANumber_1 =
      _registerName1("setTextAttributesForNotANumber:");
  late final _sel_positiveInfinitySymbol1 =
      _registerName1("positiveInfinitySymbol");
  late final _sel_setPositiveInfinitySymbol_1 =
      _registerName1("setPositiveInfinitySymbol:");
  late final _sel_textAttributesForPositiveInfinity1 =
      _registerName1("textAttributesForPositiveInfinity");
  late final _sel_setTextAttributesForPositiveInfinity_1 =
      _registerName1("setTextAttributesForPositiveInfinity:");
  late final _sel_negativeInfinitySymbol1 =
      _registerName1("negativeInfinitySymbol");
  late final _sel_setNegativeInfinitySymbol_1 =
      _registerName1("setNegativeInfinitySymbol:");
  late final _sel_textAttributesForNegativeInfinity1 =
      _registerName1("textAttributesForNegativeInfinity");
  late final _sel_setTextAttributesForNegativeInfinity_1 =
      _registerName1("setTextAttributesForNegativeInfinity:");
  late final _sel_positivePrefix1 = _registerName1("positivePrefix");
  late final _sel_setPositivePrefix_1 = _registerName1("setPositivePrefix:");
  late final _sel_positiveSuffix1 = _registerName1("positiveSuffix");
  late final _sel_setPositiveSuffix_1 = _registerName1("setPositiveSuffix:");
  late final _sel_negativePrefix1 = _registerName1("negativePrefix");
  late final _sel_setNegativePrefix_1 = _registerName1("setNegativePrefix:");
  late final _sel_negativeSuffix1 = _registerName1("negativeSuffix");
  late final _sel_setNegativeSuffix_1 = _registerName1("setNegativeSuffix:");
  late final _sel_setCurrencyCode_1 = _registerName1("setCurrencyCode:");
  late final _sel_setCurrencySymbol_1 = _registerName1("setCurrencySymbol:");
  late final _sel_internationalCurrencySymbol1 =
      _registerName1("internationalCurrencySymbol");
  late final _sel_setInternationalCurrencySymbol_1 =
      _registerName1("setInternationalCurrencySymbol:");
  late final _sel_percentSymbol1 = _registerName1("percentSymbol");
  late final _sel_setPercentSymbol_1 = _registerName1("setPercentSymbol:");
  late final _sel_perMillSymbol1 = _registerName1("perMillSymbol");
  late final _sel_setPerMillSymbol_1 = _registerName1("setPerMillSymbol:");
  late final _sel_minusSign1 = _registerName1("minusSign");
  late final _sel_setMinusSign_1 = _registerName1("setMinusSign:");
  late final _sel_plusSign1 = _registerName1("plusSign");
  late final _sel_setPlusSign_1 = _registerName1("setPlusSign:");
  late final _sel_exponentSymbol1 = _registerName1("exponentSymbol");
  late final _sel_setExponentSymbol_1 = _registerName1("setExponentSymbol:");
  late final _sel_groupingSize1 = _registerName1("groupingSize");
  late final _sel_setGroupingSize_1 = _registerName1("setGroupingSize:");
  late final _sel_secondaryGroupingSize1 =
      _registerName1("secondaryGroupingSize");
  late final _sel_setSecondaryGroupingSize_1 =
      _registerName1("setSecondaryGroupingSize:");
  late final _sel_multiplier1 = _registerName1("multiplier");
  late final _sel_setMultiplier_1 = _registerName1("setMultiplier:");
  void _objc_msgSend_705(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_705(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_705Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_705 = __objc_msgSend_705Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_formatWidth1 = _registerName1("formatWidth");
  late final _sel_setFormatWidth_1 = _registerName1("setFormatWidth:");
  late final _sel_paddingCharacter1 = _registerName1("paddingCharacter");
  late final _sel_setPaddingCharacter_1 =
      _registerName1("setPaddingCharacter:");
  late final _sel_paddingPosition1 = _registerName1("paddingPosition");
  int _objc_msgSend_706(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_706(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_706Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_706 = __objc_msgSend_706Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setPaddingPosition_1 = _registerName1("setPaddingPosition:");
  void _objc_msgSend_707(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_707(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_707Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_707 = __objc_msgSend_707Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_roundingMode1 = _registerName1("roundingMode");
  int _objc_msgSend_708(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_708(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_708Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_708 = __objc_msgSend_708Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setRoundingMode_1 = _registerName1("setRoundingMode:");
  void _objc_msgSend_709(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_709(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_709Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_709 = __objc_msgSend_709Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_roundingIncrement1 = _registerName1("roundingIncrement");
  late final _sel_setRoundingIncrement_1 =
      _registerName1("setRoundingIncrement:");
  late final _sel_minimumIntegerDigits1 =
      _registerName1("minimumIntegerDigits");
  late final _sel_setMinimumIntegerDigits_1 =
      _registerName1("setMinimumIntegerDigits:");
  late final _sel_maximumIntegerDigits1 =
      _registerName1("maximumIntegerDigits");
  late final _sel_setMaximumIntegerDigits_1 =
      _registerName1("setMaximumIntegerDigits:");
  late final _sel_minimumFractionDigits1 =
      _registerName1("minimumFractionDigits");
  late final _sel_setMinimumFractionDigits_1 =
      _registerName1("setMinimumFractionDigits:");
  late final _sel_maximumFractionDigits1 =
      _registerName1("maximumFractionDigits");
  late final _sel_setMaximumFractionDigits_1 =
      _registerName1("setMaximumFractionDigits:");
  late final _sel_minimum1 = _registerName1("minimum");
  late final _sel_setMinimum_1 = _registerName1("setMinimum:");
  late final _sel_maximum1 = _registerName1("maximum");
  late final _sel_setMaximum_1 = _registerName1("setMaximum:");
  late final _sel_currencyGroupingSeparator1 =
      _registerName1("currencyGroupingSeparator");
  late final _sel_setCurrencyGroupingSeparator_1 =
      _registerName1("setCurrencyGroupingSeparator:");
  late final _sel_usesSignificantDigits1 =
      _registerName1("usesSignificantDigits");
  late final _sel_setUsesSignificantDigits_1 =
      _registerName1("setUsesSignificantDigits:");
  late final _sel_minimumSignificantDigits1 =
      _registerName1("minimumSignificantDigits");
  late final _sel_setMinimumSignificantDigits_1 =
      _registerName1("setMinimumSignificantDigits:");
  late final _sel_maximumSignificantDigits1 =
      _registerName1("maximumSignificantDigits");
  late final _sel_setMaximumSignificantDigits_1 =
      _registerName1("setMaximumSignificantDigits:");
  late final _sel_isPartialStringValidationEnabled1 =
      _registerName1("isPartialStringValidationEnabled");
  late final _sel_setPartialStringValidationEnabled_1 =
      _registerName1("setPartialStringValidationEnabled:");
  late final _sel_hasThousandSeparators1 =
      _registerName1("hasThousandSeparators");
  late final _sel_setHasThousandSeparators_1 =
      _registerName1("setHasThousandSeparators:");
  late final _sel_thousandSeparator1 = _registerName1("thousandSeparator");
  late final _sel_setThousandSeparator_1 =
      _registerName1("setThousandSeparator:");
  late final _sel_localizesFormat1 = _registerName1("localizesFormat");
  late final _sel_setLocalizesFormat_1 = _registerName1("setLocalizesFormat:");
  late final _sel_format1 = _registerName1("format");
  late final _sel_setFormat_1 = _registerName1("setFormat:");
  late final _sel_attributedStringForZero1 =
      _registerName1("attributedStringForZero");
  late final _sel_setAttributedStringForZero_1 =
      _registerName1("setAttributedStringForZero:");
  void _objc_msgSend_710(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_710(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_710Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_710 = __objc_msgSend_710Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_attributedStringForNil1 =
      _registerName1("attributedStringForNil");
  late final _sel_setAttributedStringForNil_1 =
      _registerName1("setAttributedStringForNil:");
  late final _sel_attributedStringForNotANumber1 =
      _registerName1("attributedStringForNotANumber");
  late final _sel_setAttributedStringForNotANumber_1 =
      _registerName1("setAttributedStringForNotANumber:");
  late final _class_NSDecimalNumberHandler1 =
      _getClass1("NSDecimalNumberHandler");
  late final _sel_defaultDecimalNumberHandler1 =
      _registerName1("defaultDecimalNumberHandler");
  ffi.Pointer<ObjCObject> _objc_msgSend_711(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_711(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_711Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_711 = __objc_msgSend_711Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_initWithRoundingMode_scale_raiseOnExactness_raiseOnOverflow_raiseOnUnderflow_raiseOnDivideByZero_1 =
      _registerName1(
          "initWithRoundingMode:scale:raiseOnExactness:raiseOnOverflow:raiseOnUnderflow:raiseOnDivideByZero:");
  instancetype _objc_msgSend_712(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int roundingMode,
    int scale,
    bool exact,
    bool overflow,
    bool underflow,
    bool divideByZero,
  ) {
    return __objc_msgSend_712(
      obj,
      sel,
      roundingMode,
      scale,
      exact,
      overflow,
      underflow,
      divideByZero,
    );
  }

  late final __objc_msgSend_712Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Short,
              ffi.Bool,
              ffi.Bool,
              ffi.Bool,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_712 = __objc_msgSend_712Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          int, bool, bool, bool, bool)>();

  late final _sel_decimalNumberHandlerWithRoundingMode_scale_raiseOnExactness_raiseOnOverflow_raiseOnUnderflow_raiseOnDivideByZero_1 =
      _registerName1(
          "decimalNumberHandlerWithRoundingMode:scale:raiseOnExactness:raiseOnOverflow:raiseOnUnderflow:raiseOnDivideByZero:");
  late final _sel_roundingBehavior1 = _registerName1("roundingBehavior");
  late final _sel_setRoundingBehavior_1 =
      _registerName1("setRoundingBehavior:");
  void _objc_msgSend_713(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_713(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_713Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_713 = __objc_msgSend_713Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _class_NSScanner1 = _getClass1("NSScanner");
  late final _sel_scanLocation1 = _registerName1("scanLocation");
  late final _sel_setScanLocation_1 = _registerName1("setScanLocation:");
  late final _sel_charactersToBeSkipped1 =
      _registerName1("charactersToBeSkipped");
  late final _sel_setCharactersToBeSkipped_1 =
      _registerName1("setCharactersToBeSkipped:");
  void _objc_msgSend_714(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_714(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_714Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_714 = __objc_msgSend_714Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_caseSensitive1 = _registerName1("caseSensitive");
  late final _sel_setCaseSensitive_1 = _registerName1("setCaseSensitive:");
  late final _sel_scanInt_1 = _registerName1("scanInt:");
  bool _objc_msgSend_715(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Int> result,
  ) {
    return __objc_msgSend_715(
      obj,
      sel,
      result,
    );
  }

  late final __objc_msgSend_715Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Int>)>>('objc_msgSend');
  late final __objc_msgSend_715 = __objc_msgSend_715Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Int>)>();

  late final _sel_scanInteger_1 = _registerName1("scanInteger:");
  bool _objc_msgSend_716(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSInteger> result,
  ) {
    return __objc_msgSend_716(
      obj,
      sel,
      result,
    );
  }

  late final __objc_msgSend_716Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSInteger>)>>('objc_msgSend');
  late final __objc_msgSend_716 = __objc_msgSend_716Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSInteger>)>();

  late final _sel_scanLongLong_1 = _registerName1("scanLongLong:");
  bool _objc_msgSend_717(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.LongLong> result,
  ) {
    return __objc_msgSend_717(
      obj,
      sel,
      result,
    );
  }

  late final __objc_msgSend_717Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.LongLong>)>>('objc_msgSend');
  late final __objc_msgSend_717 = __objc_msgSend_717Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.LongLong>)>();

  late final _sel_scanUnsignedLongLong_1 =
      _registerName1("scanUnsignedLongLong:");
  bool _objc_msgSend_718(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.UnsignedLongLong> result,
  ) {
    return __objc_msgSend_718(
      obj,
      sel,
      result,
    );
  }

  late final __objc_msgSend_718Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.UnsignedLongLong>)>>('objc_msgSend');
  late final __objc_msgSend_718 = __objc_msgSend_718Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.UnsignedLongLong>)>();

  late final _sel_scanFloat_1 = _registerName1("scanFloat:");
  bool _objc_msgSend_719(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Float> result,
  ) {
    return __objc_msgSend_719(
      obj,
      sel,
      result,
    );
  }

  late final __objc_msgSend_719Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Float>)>>('objc_msgSend');
  late final __objc_msgSend_719 = __objc_msgSend_719Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Float>)>();

  late final _sel_scanDouble_1 = _registerName1("scanDouble:");
  bool _objc_msgSend_720(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Double> result,
  ) {
    return __objc_msgSend_720(
      obj,
      sel,
      result,
    );
  }

  late final __objc_msgSend_720Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Double>)>>('objc_msgSend');
  late final __objc_msgSend_720 = __objc_msgSend_720Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Double>)>();

  late final _sel_scanHexInt_1 = _registerName1("scanHexInt:");
  bool _objc_msgSend_721(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.UnsignedInt> result,
  ) {
    return __objc_msgSend_721(
      obj,
      sel,
      result,
    );
  }

  late final __objc_msgSend_721Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.UnsignedInt>)>>('objc_msgSend');
  late final __objc_msgSend_721 = __objc_msgSend_721Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.UnsignedInt>)>();

  late final _sel_scanHexLongLong_1 = _registerName1("scanHexLongLong:");
  late final _sel_scanHexFloat_1 = _registerName1("scanHexFloat:");
  late final _sel_scanHexDouble_1 = _registerName1("scanHexDouble:");
  late final _sel_scanString_intoString_1 =
      _registerName1("scanString:intoString:");
  bool _objc_msgSend_722(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    ffi.Pointer<ffi.Pointer<ObjCObject>> result,
  ) {
    return __objc_msgSend_722(
      obj,
      sel,
      string,
      result,
    );
  }

  late final __objc_msgSend_722Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_722 = __objc_msgSend_722Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_scanCharactersFromSet_intoString_1 =
      _registerName1("scanCharactersFromSet:intoString:");
  bool _objc_msgSend_723(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> set1,
    ffi.Pointer<ffi.Pointer<ObjCObject>> result,
  ) {
    return __objc_msgSend_723(
      obj,
      sel,
      set1,
      result,
    );
  }

  late final __objc_msgSend_723Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_723 = __objc_msgSend_723Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_scanUpToString_intoString_1 =
      _registerName1("scanUpToString:intoString:");
  late final _sel_scanUpToCharactersFromSet_intoString_1 =
      _registerName1("scanUpToCharactersFromSet:intoString:");
  late final _sel_isAtEnd1 = _registerName1("isAtEnd");
  late final _sel_scannerWithString_1 = _registerName1("scannerWithString:");
  late final _sel_localizedScannerWithString_1 =
      _registerName1("localizedScannerWithString:");
  late final _sel_scanDecimal_1 = _registerName1("scanDecimal:");
  bool _objc_msgSend_724(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSDecimal> dcm,
  ) {
    return __objc_msgSend_724(
      obj,
      sel,
      dcm,
    );
  }

  late final __objc_msgSend_724Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSDecimal>)>>('objc_msgSend');
  late final __objc_msgSend_724 = __objc_msgSend_724Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSDecimal>)>();

  late final _class_NSException1 = _getClass1("NSException");
  late final _sel_exceptionWithName_reason_userInfo_1 =
      _registerName1("exceptionWithName:reason:userInfo:");
  ffi.Pointer<ObjCObject> _objc_msgSend_725(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSExceptionName name,
    ffi.Pointer<ObjCObject> reason,
    ffi.Pointer<ObjCObject> userInfo,
  ) {
    return __objc_msgSend_725(
      obj,
      sel,
      name,
      reason,
      userInfo,
    );
  }

  late final __objc_msgSend_725Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSExceptionName,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_725 = __objc_msgSend_725Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          NSExceptionName,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithName_reason_userInfo_1 =
      _registerName1("initWithName:reason:userInfo:");
  late final _sel_reason1 = _registerName1("reason");
  late final _sel_raise1 = _registerName1("raise");
  late final _sel_raise_format_1 = _registerName1("raise:format:");
  late final _sel_raise_format_arguments_1 =
      _registerName1("raise:format:arguments:");
  void _objc_msgSend_726(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSExceptionName name,
    ffi.Pointer<ObjCObject> format,
    ffi.Pointer<__va_list_tag> argList,
  ) {
    return __objc_msgSend_726(
      obj,
      sel,
      name,
      format,
      argList,
    );
  }

  late final __objc_msgSend_726Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSExceptionName,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<__va_list_tag>)>>('objc_msgSend');
  late final __objc_msgSend_726 = __objc_msgSend_726Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          NSExceptionName,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<__va_list_tag>)>();

  late final _class_NSFileHandle1 = _getClass1("NSFileHandle");
  late final _sel_availableData1 = _registerName1("availableData");
  late final _sel_initWithFileDescriptor_closeOnDealloc_1 =
      _registerName1("initWithFileDescriptor:closeOnDealloc:");
  instancetype _objc_msgSend_727(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int fd,
    bool closeopt,
  ) {
    return __objc_msgSend_727(
      obj,
      sel,
      fd,
      closeopt,
    );
  }

  late final __objc_msgSend_727Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_727 = __objc_msgSend_727Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int, bool)>();

  late final _sel_readDataToEndOfFileAndReturnError_1 =
      _registerName1("readDataToEndOfFileAndReturnError:");
  ffi.Pointer<ObjCObject> _objc_msgSend_728(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_728(
      obj,
      sel,
      error,
    );
  }

  late final __objc_msgSend_728Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_728 = __objc_msgSend_728Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_readDataUpToLength_error_1 =
      _registerName1("readDataUpToLength:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_729(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int length,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_729(
      obj,
      sel,
      length,
      error,
    );
  }

  late final __objc_msgSend_729Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSUInteger,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_729 = __objc_msgSend_729Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_writeData_error_1 = _registerName1("writeData:error:");
  bool _objc_msgSend_730(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_730(
      obj,
      sel,
      data,
      error,
    );
  }

  late final __objc_msgSend_730Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_730 = __objc_msgSend_730Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_getOffset_error_1 = _registerName1("getOffset:error:");
  bool _objc_msgSend_731(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.UnsignedLongLong> offsetInFile,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_731(
      obj,
      sel,
      offsetInFile,
      error,
    );
  }

  late final __objc_msgSend_731Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.UnsignedLongLong>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_731 = __objc_msgSend_731Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.UnsignedLongLong>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_seekToEndReturningOffset_error_1 =
      _registerName1("seekToEndReturningOffset:error:");
  late final _sel_seekToOffset_error_1 = _registerName1("seekToOffset:error:");
  bool _objc_msgSend_732(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int offset,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_732(
      obj,
      sel,
      offset,
      error,
    );
  }

  late final __objc_msgSend_732Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.UnsignedLongLong,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_732 = __objc_msgSend_732Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_truncateAtOffset_error_1 =
      _registerName1("truncateAtOffset:error:");
  late final _sel_synchronizeAndReturnError_1 =
      _registerName1("synchronizeAndReturnError:");
  late final _sel_closeAndReturnError_1 =
      _registerName1("closeAndReturnError:");
  late final _sel_fileHandleWithStandardInput1 =
      _registerName1("fileHandleWithStandardInput");
  ffi.Pointer<ObjCObject> _objc_msgSend_733(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_733(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_733Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_733 = __objc_msgSend_733Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_fileHandleWithStandardOutput1 =
      _registerName1("fileHandleWithStandardOutput");
  late final _sel_fileHandleWithStandardError1 =
      _registerName1("fileHandleWithStandardError");
  late final _sel_fileHandleWithNullDevice1 =
      _registerName1("fileHandleWithNullDevice");
  late final _sel_fileHandleForReadingAtPath_1 =
      _registerName1("fileHandleForReadingAtPath:");
  late final _sel_fileHandleForWritingAtPath_1 =
      _registerName1("fileHandleForWritingAtPath:");
  late final _sel_fileHandleForUpdatingAtPath_1 =
      _registerName1("fileHandleForUpdatingAtPath:");
  late final _sel_fileHandleForReadingFromURL_error_1 =
      _registerName1("fileHandleForReadingFromURL:error:");
  instancetype _objc_msgSend_734(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_734(
      obj,
      sel,
      url,
      error,
    );
  }

  late final __objc_msgSend_734Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_734 = __objc_msgSend_734Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_fileHandleForWritingToURL_error_1 =
      _registerName1("fileHandleForWritingToURL:error:");
  late final _sel_fileHandleForUpdatingURL_error_1 =
      _registerName1("fileHandleForUpdatingURL:error:");
  late final _sel_readInBackgroundAndNotifyForModes_1 =
      _registerName1("readInBackgroundAndNotifyForModes:");
  late final _sel_readInBackgroundAndNotify1 =
      _registerName1("readInBackgroundAndNotify");
  late final _sel_readToEndOfFileInBackgroundAndNotifyForModes_1 =
      _registerName1("readToEndOfFileInBackgroundAndNotifyForModes:");
  late final _sel_readToEndOfFileInBackgroundAndNotify1 =
      _registerName1("readToEndOfFileInBackgroundAndNotify");
  late final _sel_acceptConnectionInBackgroundAndNotifyForModes_1 =
      _registerName1("acceptConnectionInBackgroundAndNotifyForModes:");
  late final _sel_acceptConnectionInBackgroundAndNotify1 =
      _registerName1("acceptConnectionInBackgroundAndNotify");
  late final _sel_waitForDataInBackgroundAndNotifyForModes_1 =
      _registerName1("waitForDataInBackgroundAndNotifyForModes:");
  late final _sel_waitForDataInBackgroundAndNotify1 =
      _registerName1("waitForDataInBackgroundAndNotify");
  late final _sel_readabilityHandler1 = _registerName1("readabilityHandler");
  ffi.Pointer<_ObjCBlock> _objc_msgSend_735(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_735(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_735Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<_ObjCBlock> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_735 = __objc_msgSend_735Ptr.asFunction<
      ffi.Pointer<_ObjCBlock> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setReadabilityHandler_1 =
      _registerName1("setReadabilityHandler:");
  void _objc_msgSend_736(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> value,
  ) {
    return __objc_msgSend_736(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_736Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_736 = __objc_msgSend_736Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_writeabilityHandler1 = _registerName1("writeabilityHandler");
  late final _sel_setWriteabilityHandler_1 =
      _registerName1("setWriteabilityHandler:");
  late final _sel_initWithFileDescriptor_1 =
      _registerName1("initWithFileDescriptor:");
  instancetype _objc_msgSend_737(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int fd,
  ) {
    return __objc_msgSend_737(
      obj,
      sel,
      fd,
    );
  }

  late final __objc_msgSend_737Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int)>>('objc_msgSend');
  late final __objc_msgSend_737 = __objc_msgSend_737Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_fileDescriptor1 = _registerName1("fileDescriptor");
  late final _sel_readDataToEndOfFile1 = _registerName1("readDataToEndOfFile");
  late final _sel_readDataOfLength_1 = _registerName1("readDataOfLength:");
  late final _sel_offsetInFile1 = _registerName1("offsetInFile");
  late final _sel_seekToEndOfFile1 = _registerName1("seekToEndOfFile");
  late final _sel_seekToFileOffset_1 = _registerName1("seekToFileOffset:");
  void _objc_msgSend_738(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int offset,
  ) {
    return __objc_msgSend_738(
      obj,
      sel,
      offset,
    );
  }

  late final __objc_msgSend_738Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.UnsignedLongLong)>>('objc_msgSend');
  late final __objc_msgSend_738 = __objc_msgSend_738Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_truncateFileAtOffset_1 =
      _registerName1("truncateFileAtOffset:");
  late final _sel_synchronizeFile1 = _registerName1("synchronizeFile");
  late final _sel_closeFile1 = _registerName1("closeFile");
  late final _class_NSHTTPCookieStorage1 = _getClass1("NSHTTPCookieStorage");
  late final _sel_sharedHTTPCookieStorage1 =
      _registerName1("sharedHTTPCookieStorage");
  ffi.Pointer<ObjCObject> _objc_msgSend_739(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_739(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_739Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_739 = __objc_msgSend_739Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_sharedCookieStorageForGroupContainerIdentifier_1 =
      _registerName1("sharedCookieStorageForGroupContainerIdentifier:");
  ffi.Pointer<ObjCObject> _objc_msgSend_740(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> identifier,
  ) {
    return __objc_msgSend_740(
      obj,
      sel,
      identifier,
    );
  }

  late final __objc_msgSend_740Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_740 = __objc_msgSend_740Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_cookies1 = _registerName1("cookies");
  late final _class_NSHTTPCookie1 = _getClass1("NSHTTPCookie");
  late final _sel_initWithProperties_1 = _registerName1("initWithProperties:");
  late final _sel_cookieWithProperties_1 =
      _registerName1("cookieWithProperties:");
  ffi.Pointer<ObjCObject> _objc_msgSend_741(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> properties,
  ) {
    return __objc_msgSend_741(
      obj,
      sel,
      properties,
    );
  }

  late final __objc_msgSend_741Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_741 = __objc_msgSend_741Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_requestHeaderFieldsWithCookies_1 =
      _registerName1("requestHeaderFieldsWithCookies:");
  late final _sel_cookiesWithResponseHeaderFields_forURL_1 =
      _registerName1("cookiesWithResponseHeaderFields:forURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_742(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> headerFields,
    ffi.Pointer<ObjCObject> URL,
  ) {
    return __objc_msgSend_742(
      obj,
      sel,
      headerFields,
      URL,
    );
  }

  late final __objc_msgSend_742Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_742 = __objc_msgSend_742Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_properties1 = _registerName1("properties");
  late final _sel_value1 = _registerName1("value");
  late final _sel_expiresDate1 = _registerName1("expiresDate");
  late final _sel_isSessionOnly1 = _registerName1("isSessionOnly");
  late final _sel_isSecure1 = _registerName1("isSecure");
  late final _sel_isHTTPOnly1 = _registerName1("isHTTPOnly");
  late final _sel_comment1 = _registerName1("comment");
  late final _sel_commentURL1 = _registerName1("commentURL");
  late final _sel_portList1 = _registerName1("portList");
  late final _sel_sameSitePolicy1 = _registerName1("sameSitePolicy");
  late final _sel_setCookie_1 = _registerName1("setCookie:");
  void _objc_msgSend_743(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> cookie,
  ) {
    return __objc_msgSend_743(
      obj,
      sel,
      cookie,
    );
  }

  late final __objc_msgSend_743Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_743 = __objc_msgSend_743Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_deleteCookie_1 = _registerName1("deleteCookie:");
  late final _sel_removeCookiesSinceDate_1 =
      _registerName1("removeCookiesSinceDate:");
  late final _sel_cookiesForURL_1 = _registerName1("cookiesForURL:");
  late final _sel_setCookies_forURL_mainDocumentURL_1 =
      _registerName1("setCookies:forURL:mainDocumentURL:");
  void _objc_msgSend_744(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> cookies,
    ffi.Pointer<ObjCObject> URL,
    ffi.Pointer<ObjCObject> mainDocumentURL,
  ) {
    return __objc_msgSend_744(
      obj,
      sel,
      cookies,
      URL,
      mainDocumentURL,
    );
  }

  late final __objc_msgSend_744Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_744 = __objc_msgSend_744Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_cookieAcceptPolicy1 = _registerName1("cookieAcceptPolicy");
  int _objc_msgSend_745(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_745(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_745Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_745 = __objc_msgSend_745Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setCookieAcceptPolicy_1 =
      _registerName1("setCookieAcceptPolicy:");
  void _objc_msgSend_746(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_746(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_746Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_746 = __objc_msgSend_746Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_sortedCookiesUsingDescriptors_1 =
      _registerName1("sortedCookiesUsingDescriptors:");
  late final _class_NSURLSessionTask1 = _getClass1("NSURLSessionTask");
  late final _sel_taskIdentifier1 = _registerName1("taskIdentifier");
  late final _class_NSURLRequest1 = _getClass1("NSURLRequest");
  late final _sel_requestWithURL_1 = _registerName1("requestWithURL:");
  late final _sel_supportsSecureCoding1 =
      _registerName1("supportsSecureCoding");
  late final _sel_requestWithURL_cachePolicy_timeoutInterval_1 =
      _registerName1("requestWithURL:cachePolicy:timeoutInterval:");
  instancetype _objc_msgSend_747(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> URL,
    int cachePolicy,
    double timeoutInterval,
  ) {
    return __objc_msgSend_747(
      obj,
      sel,
      URL,
      cachePolicy,
      timeoutInterval,
    );
  }

  late final __objc_msgSend_747Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              NSTimeInterval)>>('objc_msgSend');
  late final __objc_msgSend_747 = __objc_msgSend_747Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, double)>();

  late final _sel_initWithURL_cachePolicy_timeoutInterval_1 =
      _registerName1("initWithURL:cachePolicy:timeoutInterval:");
  late final _sel_URL1 = _registerName1("URL");
  late final _sel_cachePolicy1 = _registerName1("cachePolicy");
  int _objc_msgSend_748(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_748(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_748Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_748 = __objc_msgSend_748Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_timeoutInterval1 = _registerName1("timeoutInterval");
  late final _sel_mainDocumentURL1 = _registerName1("mainDocumentURL");
  late final _sel_networkServiceType1 = _registerName1("networkServiceType");
  int _objc_msgSend_749(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_749(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_749Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_749 = __objc_msgSend_749Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_allowsCellularAccess1 =
      _registerName1("allowsCellularAccess");
  late final _sel_allowsExpensiveNetworkAccess1 =
      _registerName1("allowsExpensiveNetworkAccess");
  late final _sel_allowsConstrainedNetworkAccess1 =
      _registerName1("allowsConstrainedNetworkAccess");
  late final _sel_assumesHTTP3Capable1 = _registerName1("assumesHTTP3Capable");
  late final _sel_attribution1 = _registerName1("attribution");
  int _objc_msgSend_750(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_750(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_750Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_750 = __objc_msgSend_750Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_HTTPMethod1 = _registerName1("HTTPMethod");
  late final _sel_allHTTPHeaderFields1 = _registerName1("allHTTPHeaderFields");
  late final _sel_valueForHTTPHeaderField_1 =
      _registerName1("valueForHTTPHeaderField:");
  late final _sel_HTTPBody1 = _registerName1("HTTPBody");
  late final _class_NSInputStream1 = _getClass1("NSInputStream");
  late final _class_NSStream1 = _getClass1("NSStream");
  late final _sel_open1 = _registerName1("open");
  late final _sel_close1 = _registerName1("close");
  late final _sel_streamStatus1 = _registerName1("streamStatus");
  int _objc_msgSend_751(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_751(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_751Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_751 = __objc_msgSend_751Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_streamError1 = _registerName1("streamError");
  late final _class_NSOutputStream1 = _getClass1("NSOutputStream");
  late final _sel_write_maxLength_1 = _registerName1("write:maxLength:");
  int _objc_msgSend_752(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Uint8> buffer,
    int len,
  ) {
    return __objc_msgSend_752(
      obj,
      sel,
      buffer,
      len,
    );
  }

  late final __objc_msgSend_752Ptr = _lookup<
      ffi.NativeFunction<
          NSInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Uint8>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_752 = __objc_msgSend_752Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Uint8>, int)>();

  late final _sel_hasSpaceAvailable1 = _registerName1("hasSpaceAvailable");
  late final _sel_initToMemory1 = _registerName1("initToMemory");
  late final _sel_initToBuffer_capacity_1 =
      _registerName1("initToBuffer:capacity:");
  instancetype _objc_msgSend_753(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Uint8> buffer,
    int capacity,
  ) {
    return __objc_msgSend_753(
      obj,
      sel,
      buffer,
      capacity,
    );
  }

  late final __objc_msgSend_753Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Uint8>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_753 = __objc_msgSend_753Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Uint8>, int)>();

  late final _sel_initWithURL_append_1 = _registerName1("initWithURL:append:");
  late final _sel_initToFileAtPath_append_1 =
      _registerName1("initToFileAtPath:append:");
  late final _sel_outputStreamToMemory1 =
      _registerName1("outputStreamToMemory");
  late final _sel_outputStreamToBuffer_capacity_1 =
      _registerName1("outputStreamToBuffer:capacity:");
  late final _sel_outputStreamToFileAtPath_append_1 =
      _registerName1("outputStreamToFileAtPath:append:");
  late final _sel_outputStreamWithURL_append_1 =
      _registerName1("outputStreamWithURL:append:");
  late final _sel_getStreamsToHostWithName_port_inputStream_outputStream_1 =
      _registerName1("getStreamsToHostWithName:port:inputStream:outputStream:");
  void _objc_msgSend_754(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> hostname,
    int port,
    ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream,
  ) {
    return __objc_msgSend_754(
      obj,
      sel,
      hostname,
      port,
      inputStream,
      outputStream,
    );
  }

  late final __objc_msgSend_754Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSInteger,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_754 = __objc_msgSend_754Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _class_NSHost1 = _getClass1("NSHost");
  late final _sel_currentHost1 = _registerName1("currentHost");
  late final _sel_hostWithName_1 = _registerName1("hostWithName:");
  late final _sel_hostWithAddress_1 = _registerName1("hostWithAddress:");
  late final _sel_isEqualToHost_1 = _registerName1("isEqualToHost:");
  bool _objc_msgSend_755(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> aHost,
  ) {
    return __objc_msgSend_755(
      obj,
      sel,
      aHost,
    );
  }

  late final __objc_msgSend_755Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_755 = __objc_msgSend_755Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_names1 = _registerName1("names");
  late final _sel_address1 = _registerName1("address");
  late final _sel_addresses1 = _registerName1("addresses");
  late final _sel_localizedName1 = _registerName1("localizedName");
  late final _sel_setHostCacheEnabled_1 =
      _registerName1("setHostCacheEnabled:");
  void _objc_msgSend_756(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool flag,
  ) {
    return __objc_msgSend_756(
      obj,
      sel,
      flag,
    );
  }

  late final __objc_msgSend_756Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_756 = __objc_msgSend_756Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool)>();

  late final _sel_isHostCacheEnabled1 = _registerName1("isHostCacheEnabled");
  late final _sel_flushHostCache1 = _registerName1("flushHostCache");
  late final _sel_getStreamsToHost_port_inputStream_outputStream_1 =
      _registerName1("getStreamsToHost:port:inputStream:outputStream:");
  void _objc_msgSend_757(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> host,
    int port,
    ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream,
  ) {
    return __objc_msgSend_757(
      obj,
      sel,
      host,
      port,
      inputStream,
      outputStream,
    );
  }

  late final __objc_msgSend_757Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSInteger,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_757 = __objc_msgSend_757Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_getBoundStreamsWithBufferSize_inputStream_outputStream_1 =
      _registerName1("getBoundStreamsWithBufferSize:inputStream:outputStream:");
  void _objc_msgSend_758(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int bufferSize,
    ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream,
  ) {
    return __objc_msgSend_758(
      obj,
      sel,
      bufferSize,
      inputStream,
      outputStream,
    );
  }

  late final __objc_msgSend_758Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSUInteger,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_758 = __objc_msgSend_758Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_read_maxLength_1 = _registerName1("read:maxLength:");
  late final _sel_getBuffer_length_1 = _registerName1("getBuffer:length:");
  bool _objc_msgSend_759(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ffi.Uint8>> buffer,
    ffi.Pointer<NSUInteger> len,
  ) {
    return __objc_msgSend_759(
      obj,
      sel,
      buffer,
      len,
    );
  }

  late final __objc_msgSend_759Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ffi.Uint8>>,
              ffi.Pointer<NSUInteger>)>>('objc_msgSend');
  late final __objc_msgSend_759 = __objc_msgSend_759Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ffi.Uint8>>, ffi.Pointer<NSUInteger>)>();

  late final _sel_hasBytesAvailable1 = _registerName1("hasBytesAvailable");
  late final _sel_initWithFileAtPath_1 = _registerName1("initWithFileAtPath:");
  late final _sel_inputStreamWithData_1 =
      _registerName1("inputStreamWithData:");
  late final _sel_inputStreamWithFileAtPath_1 =
      _registerName1("inputStreamWithFileAtPath:");
  late final _sel_inputStreamWithURL_1 = _registerName1("inputStreamWithURL:");
  late final _sel_HTTPBodyStream1 = _registerName1("HTTPBodyStream");
  ffi.Pointer<ObjCObject> _objc_msgSend_760(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_760(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_760Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_760 = __objc_msgSend_760Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_HTTPShouldHandleCookies1 =
      _registerName1("HTTPShouldHandleCookies");
  late final _sel_HTTPShouldUsePipelining1 =
      _registerName1("HTTPShouldUsePipelining");
  late final _sel_originalRequest1 = _registerName1("originalRequest");
  ffi.Pointer<ObjCObject> _objc_msgSend_761(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_761(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_761Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_761 = __objc_msgSend_761Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_currentRequest1 = _registerName1("currentRequest");
  late final _class_NSURLResponse1 = _getClass1("NSURLResponse");
  late final _sel_initWithURL_MIMEType_expectedContentLength_textEncodingName_1 =
      _registerName1(
          "initWithURL:MIMEType:expectedContentLength:textEncodingName:");
  instancetype _objc_msgSend_762(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> URL,
    ffi.Pointer<ObjCObject> MIMEType,
    int length,
    ffi.Pointer<ObjCObject> name,
  ) {
    return __objc_msgSend_762(
      obj,
      sel,
      URL,
      MIMEType,
      length,
      name,
    );
  }

  late final __objc_msgSend_762Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              NSInteger,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_762 = __objc_msgSend_762Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_MIMEType1 = _registerName1("MIMEType");
  late final _sel_expectedContentLength1 =
      _registerName1("expectedContentLength");
  late final _sel_textEncodingName1 = _registerName1("textEncodingName");
  late final _sel_suggestedFilename1 = _registerName1("suggestedFilename");
  late final _sel_response1 = _registerName1("response");
  ffi.Pointer<ObjCObject> _objc_msgSend_763(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_763(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_763Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_763 = __objc_msgSend_763Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_progress1 = _registerName1("progress");
  late final _sel_earliestBeginDate1 = _registerName1("earliestBeginDate");
  late final _sel_setEarliestBeginDate_1 =
      _registerName1("setEarliestBeginDate:");
  late final _sel_countOfBytesClientExpectsToSend1 =
      _registerName1("countOfBytesClientExpectsToSend");
  late final _sel_setCountOfBytesClientExpectsToSend_1 =
      _registerName1("setCountOfBytesClientExpectsToSend:");
  late final _sel_countOfBytesClientExpectsToReceive1 =
      _registerName1("countOfBytesClientExpectsToReceive");
  late final _sel_setCountOfBytesClientExpectsToReceive_1 =
      _registerName1("setCountOfBytesClientExpectsToReceive:");
  late final _sel_countOfBytesSent1 = _registerName1("countOfBytesSent");
  late final _sel_countOfBytesReceived1 =
      _registerName1("countOfBytesReceived");
  late final _sel_countOfBytesExpectedToSend1 =
      _registerName1("countOfBytesExpectedToSend");
  late final _sel_countOfBytesExpectedToReceive1 =
      _registerName1("countOfBytesExpectedToReceive");
  late final _sel_taskDescription1 = _registerName1("taskDescription");
  late final _sel_setTaskDescription_1 = _registerName1("setTaskDescription:");
  late final _sel_state1 = _registerName1("state");
  int _objc_msgSend_764(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_764(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_764Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_764 = __objc_msgSend_764Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_suspend1 = _registerName1("suspend");
  late final _sel_priority1 = _registerName1("priority");
  late final _sel_setPriority_1 = _registerName1("setPriority:");
  void _objc_msgSend_765(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double value,
  ) {
    return __objc_msgSend_765(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_765Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Float)>>('objc_msgSend');
  late final __objc_msgSend_765 = __objc_msgSend_765Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double)>();

  late final _sel_prefersIncrementalDelivery1 =
      _registerName1("prefersIncrementalDelivery");
  late final _sel_setPrefersIncrementalDelivery_1 =
      _registerName1("setPrefersIncrementalDelivery:");
  late final _sel_storeCookies_forTask_1 =
      _registerName1("storeCookies:forTask:");
  void _objc_msgSend_766(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> cookies,
    ffi.Pointer<ObjCObject> task,
  ) {
    return __objc_msgSend_766(
      obj,
      sel,
      cookies,
      task,
    );
  }

  late final __objc_msgSend_766Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_766 = __objc_msgSend_766Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_getCookiesForTask_completionHandler_1 =
      _registerName1("getCookiesForTask:completionHandler:");
  void _objc_msgSend_767(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> task,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_767(
      obj,
      sel,
      task,
      completionHandler,
    );
  }

  late final __objc_msgSend_767Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_767 = __objc_msgSend_767Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<_ObjCBlock>)>();

  late final _class_NSIndexPath1 = _getClass1("NSIndexPath");
  late final _sel_indexPathWithIndex_1 = _registerName1("indexPathWithIndex:");
  late final _sel_indexPathWithIndexes_length_1 =
      _registerName1("indexPathWithIndexes:length:");
  instancetype _objc_msgSend_768(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSUInteger> indexes,
    int length,
  ) {
    return __objc_msgSend_768(
      obj,
      sel,
      indexes,
      length,
    );
  }

  late final __objc_msgSend_768Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSUInteger>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_768 = __objc_msgSend_768Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSUInteger>, int)>();

  late final _sel_initWithIndexes_length_1 =
      _registerName1("initWithIndexes:length:");
  late final _sel_indexPathByAddingIndex_1 =
      _registerName1("indexPathByAddingIndex:");
  ffi.Pointer<ObjCObject> _objc_msgSend_769(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
  ) {
    return __objc_msgSend_769(
      obj,
      sel,
      index,
    );
  }

  late final __objc_msgSend_769Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_769 = __objc_msgSend_769Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_indexPathByRemovingLastIndex1 =
      _registerName1("indexPathByRemovingLastIndex");
  ffi.Pointer<ObjCObject> _objc_msgSend_770(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_770(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_770Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_770 = __objc_msgSend_770Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_indexAtPosition_1 = _registerName1("indexAtPosition:");
  late final _sel_getIndexes_range_1 = _registerName1("getIndexes:range:");
  void _objc_msgSend_771(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSUInteger> indexes,
    NSRange positionRange,
  ) {
    return __objc_msgSend_771(
      obj,
      sel,
      indexes,
      positionRange,
    );
  }

  late final __objc_msgSend_771Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSUInteger>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_771 = __objc_msgSend_771Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSUInteger>, NSRange)>();

  int _objc_msgSend_772(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> otherObject,
  ) {
    return __objc_msgSend_772(
      obj,
      sel,
      otherObject,
    );
  }

  late final __objc_msgSend_772Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_772 = __objc_msgSend_772Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_getIndexes_1 = _registerName1("getIndexes:");
  void _objc_msgSend_773(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<NSUInteger> indexes,
  ) {
    return __objc_msgSend_773(
      obj,
      sel,
      indexes,
    );
  }

  late final __objc_msgSend_773Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<NSUInteger>)>>('objc_msgSend');
  late final __objc_msgSend_773 = __objc_msgSend_773Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<NSUInteger>)>();

  late final _class_NSInflectionRule1 = _getClass1("NSInflectionRule");
  late final _sel_automaticRule1 = _registerName1("automaticRule");
  ffi.Pointer<ObjCObject> _objc_msgSend_774(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_774(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_774Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_774 = __objc_msgSend_774Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_canInflectLanguage_1 = _registerName1("canInflectLanguage:");
  late final _sel_canInflectPreferredLocalization1 =
      _registerName1("canInflectPreferredLocalization");
  late final _class_NSMorphology1 = _getClass1("NSMorphology");
  late final _sel_grammaticalGender1 = _registerName1("grammaticalGender");
  int _objc_msgSend_775(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_775(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_775Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_775 = __objc_msgSend_775Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setGrammaticalGender_1 =
      _registerName1("setGrammaticalGender:");
  void _objc_msgSend_776(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_776(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_776Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_776 = __objc_msgSend_776Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_partOfSpeech1 = _registerName1("partOfSpeech");
  int _objc_msgSend_777(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_777(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_777Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_777 = __objc_msgSend_777Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setPartOfSpeech_1 = _registerName1("setPartOfSpeech:");
  void _objc_msgSend_778(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_778(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_778Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_778 = __objc_msgSend_778Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_number1 = _registerName1("number");
  int _objc_msgSend_779(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_779(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_779Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_779 = __objc_msgSend_779Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setNumber_1 = _registerName1("setNumber:");
  void _objc_msgSend_780(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_780(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_780Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_780 = __objc_msgSend_780Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _class_NSMorphologyCustomPronoun1 =
      _getClass1("NSMorphologyCustomPronoun");
  late final _sel_isSupportedForLanguage_1 =
      _registerName1("isSupportedForLanguage:");
  late final _sel_requiredKeysForLanguage_1 =
      _registerName1("requiredKeysForLanguage:");
  late final _sel_subjectForm1 = _registerName1("subjectForm");
  late final _sel_setSubjectForm_1 = _registerName1("setSubjectForm:");
  late final _sel_objectForm1 = _registerName1("objectForm");
  late final _sel_setObjectForm_1 = _registerName1("setObjectForm:");
  late final _sel_possessiveForm1 = _registerName1("possessiveForm");
  late final _sel_setPossessiveForm_1 = _registerName1("setPossessiveForm:");
  late final _sel_possessiveAdjectiveForm1 =
      _registerName1("possessiveAdjectiveForm");
  late final _sel_setPossessiveAdjectiveForm_1 =
      _registerName1("setPossessiveAdjectiveForm:");
  late final _sel_reflexiveForm1 = _registerName1("reflexiveForm");
  late final _sel_setReflexiveForm_1 = _registerName1("setReflexiveForm:");
  late final _sel_customPronounForLanguage_1 =
      _registerName1("customPronounForLanguage:");
  ffi.Pointer<ObjCObject> _objc_msgSend_781(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> language,
  ) {
    return __objc_msgSend_781(
      obj,
      sel,
      language,
    );
  }

  late final __objc_msgSend_781Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_781 = __objc_msgSend_781Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_setCustomPronoun_forLanguage_error_1 =
      _registerName1("setCustomPronoun:forLanguage:error:");
  bool _objc_msgSend_782(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> features,
    ffi.Pointer<ObjCObject> language,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_782(
      obj,
      sel,
      features,
      language,
      error,
    );
  }

  late final __objc_msgSend_782Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_782 = __objc_msgSend_782Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_isUnspecified1 = _registerName1("isUnspecified");
  late final _sel_userMorphology1 = _registerName1("userMorphology");
  ffi.Pointer<ObjCObject> _objc_msgSend_783(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_783(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_783Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_783 = __objc_msgSend_783Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _class_NSOperationQueue1 = _getClass1("NSOperationQueue");
  late final _class_NSOperation1 = _getClass1("NSOperation");
  late final _sel_isConcurrent1 = _registerName1("isConcurrent");
  late final _sel_isAsynchronous1 = _registerName1("isAsynchronous");
  late final _sel_isReady1 = _registerName1("isReady");
  late final _sel_addDependency_1 = _registerName1("addDependency:");
  void _objc_msgSend_784(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> op,
  ) {
    return __objc_msgSend_784(
      obj,
      sel,
      op,
    );
  }

  late final __objc_msgSend_784Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_784 = __objc_msgSend_784Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_removeDependency_1 = _registerName1("removeDependency:");
  late final _sel_dependencies1 = _registerName1("dependencies");
  late final _sel_queuePriority1 = _registerName1("queuePriority");
  int _objc_msgSend_785(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_785(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_785Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_785 = __objc_msgSend_785Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setQueuePriority_1 = _registerName1("setQueuePriority:");
  void _objc_msgSend_786(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_786(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_786Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_786 = __objc_msgSend_786Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_completionBlock1 = _registerName1("completionBlock");
  late final _sel_setCompletionBlock_1 = _registerName1("setCompletionBlock:");
  late final _sel_waitUntilFinished1 = _registerName1("waitUntilFinished");
  late final _sel_addOperation_1 = _registerName1("addOperation:");
  late final _sel_addOperations_waitUntilFinished_1 =
      _registerName1("addOperations:waitUntilFinished:");
  void _objc_msgSend_787(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> ops,
    bool wait,
  ) {
    return __objc_msgSend_787(
      obj,
      sel,
      ops,
      wait,
    );
  }

  late final __objc_msgSend_787Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_787 = __objc_msgSend_787Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_addOperationWithBlock_1 =
      _registerName1("addOperationWithBlock:");
  late final _sel_addBarrierBlock_1 = _registerName1("addBarrierBlock:");
  late final _sel_maxConcurrentOperationCount1 =
      _registerName1("maxConcurrentOperationCount");
  late final _sel_setMaxConcurrentOperationCount_1 =
      _registerName1("setMaxConcurrentOperationCount:");
  late final _sel_isSuspended1 = _registerName1("isSuspended");
  late final _sel_setSuspended_1 = _registerName1("setSuspended:");
  late final _sel_underlyingQueue1 = _registerName1("underlyingQueue");
  dispatch_queue_t _objc_msgSend_788(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_788(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_788Ptr = _lookup<
      ffi.NativeFunction<
          dispatch_queue_t Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_788 = __objc_msgSend_788Ptr.asFunction<
      dispatch_queue_t Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setUnderlyingQueue_1 = _registerName1("setUnderlyingQueue:");
  void _objc_msgSend_789(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    dispatch_queue_t value,
  ) {
    return __objc_msgSend_789(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_789Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              dispatch_queue_t)>>('objc_msgSend');
  late final __objc_msgSend_789 = __objc_msgSend_789Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, dispatch_queue_t)>();

  late final _sel_cancelAllOperations1 = _registerName1("cancelAllOperations");
  late final _sel_waitUntilAllOperationsAreFinished1 =
      _registerName1("waitUntilAllOperationsAreFinished");
  late final _sel_currentQueue1 = _registerName1("currentQueue");
  ffi.Pointer<ObjCObject> _objc_msgSend_790(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_790(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_790Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_790 = __objc_msgSend_790Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_mainQueue1 = _registerName1("mainQueue");
  late final _sel_operations1 = _registerName1("operations");
  late final _sel_operationCount1 = _registerName1("operationCount");
  late final _class_NSPointerArray1 = _getClass1("NSPointerArray");
  late final _sel_initWithOptions_1 = _registerName1("initWithOptions:");
  instancetype _objc_msgSend_791(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
  ) {
    return __objc_msgSend_791(
      obj,
      sel,
      options,
    );
  }

  late final __objc_msgSend_791Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_791 = __objc_msgSend_791Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _class_NSPointerFunctions1 = _getClass1("NSPointerFunctions");
  late final _sel_pointerFunctionsWithOptions_1 =
      _registerName1("pointerFunctionsWithOptions:");
  ffi.Pointer<ObjCObject> _objc_msgSend_792(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
  ) {
    return __objc_msgSend_792(
      obj,
      sel,
      options,
    );
  }

  late final __objc_msgSend_792Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_792 = __objc_msgSend_792Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_hashFunction1 = _registerName1("hashFunction");
  ffi.Pointer<
          ffi.NativeFunction<
              NSUInteger Function(
                  ffi.Pointer<ffi.Void>,
                  ffi.Pointer<
                      ffi.NativeFunction<
                          NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
      _objc_msgSend_793(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_793(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_793Ptr = _lookup<
          ffi.NativeFunction<
              ffi.Pointer<
                      ffi.NativeFunction<
                          NSUInteger Function(
                              ffi.Pointer<ffi.Void>,
                              ffi.Pointer<
                                  ffi.NativeFunction<
                                      NSUInteger Function(
                                          ffi.Pointer<ffi.Void>)>>)>>
                  Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>(
      'objc_msgSend');
  late final __objc_msgSend_793 = __objc_msgSend_793Ptr.asFunction<
      ffi.Pointer<
              ffi.NativeFunction<
                  NSUInteger Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
          Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setHashFunction_1 = _registerName1("setHashFunction:");
  void _objc_msgSend_794(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<
            ffi.NativeFunction<
                NSUInteger Function(
                    ffi.Pointer<ffi.Void>,
                    ffi.Pointer<
                        ffi.NativeFunction<
                            NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
        value,
  ) {
    return __objc_msgSend_794(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_794Ptr = _lookup<
          ffi.NativeFunction<
              ffi.Void Function(
                  ffi.Pointer<ObjCObject>,
                  ffi.Pointer<ObjCSel>,
                  ffi.Pointer<
                      ffi.NativeFunction<
                          NSUInteger Function(
                              ffi.Pointer<ffi.Void>,
                              ffi.Pointer<
                                  ffi.NativeFunction<
                                      NSUInteger Function(
                                          ffi.Pointer<ffi.Void>)>>)>>)>>(
      'objc_msgSend');
  late final __objc_msgSend_794 = __objc_msgSend_794Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<
              ffi.NativeFunction<
                  NSUInteger Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(
                                  ffi.Pointer<ffi.Void>)>>)>>)>();

  late final _sel_isEqualFunction1 = _registerName1("isEqualFunction");
  ffi.Pointer<
          ffi.NativeFunction<
              ffi.Bool Function(
                  ffi.Pointer<ffi.Void>,
                  ffi.Pointer<ffi.Void>,
                  ffi.Pointer<
                      ffi.NativeFunction<
                          NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
      _objc_msgSend_795(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_795(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_795Ptr = _lookup<
          ffi.NativeFunction<
              ffi.Pointer<
                      ffi.NativeFunction<
                          ffi.Bool Function(
                              ffi.Pointer<ffi.Void>,
                              ffi.Pointer<ffi.Void>,
                              ffi.Pointer<
                                  ffi.NativeFunction<
                                      NSUInteger Function(
                                          ffi.Pointer<ffi.Void>)>>)>>
                  Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>(
      'objc_msgSend');
  late final __objc_msgSend_795 = __objc_msgSend_795Ptr.asFunction<
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Bool Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
          Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setIsEqualFunction_1 = _registerName1("setIsEqualFunction:");
  void _objc_msgSend_796(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<
            ffi.NativeFunction<
                ffi.Bool Function(
                    ffi.Pointer<ffi.Void>,
                    ffi.Pointer<ffi.Void>,
                    ffi.Pointer<
                        ffi.NativeFunction<
                            NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
        value,
  ) {
    return __objc_msgSend_796(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_796Ptr = _lookup<
          ffi.NativeFunction<
              ffi.Void Function(
                  ffi.Pointer<ObjCObject>,
                  ffi.Pointer<ObjCSel>,
                  ffi.Pointer<
                      ffi.NativeFunction<
                          ffi.Bool Function(
                              ffi.Pointer<ffi.Void>,
                              ffi.Pointer<ffi.Void>,
                              ffi.Pointer<
                                  ffi.NativeFunction<
                                      NSUInteger Function(
                                          ffi.Pointer<ffi.Void>)>>)>>)>>(
      'objc_msgSend');
  late final __objc_msgSend_796 = __objc_msgSend_796Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Bool Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(
                                  ffi.Pointer<ffi.Void>)>>)>>)>();

  late final _sel_sizeFunction1 = _registerName1("sizeFunction");
  ffi.Pointer<ffi.NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>
      _objc_msgSend_797(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_797(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_797Ptr = _lookup<
          ffi.NativeFunction<
              ffi.Pointer<
                      ffi.NativeFunction<
                          NSUInteger Function(ffi.Pointer<ffi.Void>)>>
                  Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>(
      'objc_msgSend');
  late final __objc_msgSend_797 = __objc_msgSend_797Ptr.asFunction<
      ffi.Pointer<
              ffi.NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>
          Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setSizeFunction_1 = _registerName1("setSizeFunction:");
  void _objc_msgSend_798(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>
        value,
  ) {
    return __objc_msgSend_798(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_798Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<
                  ffi.NativeFunction<
                      NSUInteger Function(
                          ffi.Pointer<ffi.Void>)>>)>>('objc_msgSend');
  late final __objc_msgSend_798 = __objc_msgSend_798Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<
              ffi
              .NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>();

  late final _sel_descriptionFunction1 = _registerName1("descriptionFunction");
  ffi.Pointer<
          ffi.NativeFunction<
              ffi.Pointer<ObjCObject> Function(ffi.Pointer<ffi.Void>)>>
      _objc_msgSend_799(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_799(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_799Ptr =
      _lookup<
              ffi.NativeFunction<
                  ffi.Pointer<
                          ffi.NativeFunction<
                              ffi.Pointer<ObjCObject> Function(
                                  ffi.Pointer<ffi.Void>)>>
                      Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>(
          'objc_msgSend');
  late final __objc_msgSend_799 = __objc_msgSend_799Ptr.asFunction<
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Pointer<ObjCObject> Function(ffi.Pointer<ffi.Void>)>>
          Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setDescriptionFunction_1 =
      _registerName1("setDescriptionFunction:");
  void _objc_msgSend_800(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<
            ffi.NativeFunction<
                ffi.Pointer<ObjCObject> Function(ffi.Pointer<ffi.Void>)>>
        value,
  ) {
    return __objc_msgSend_800(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_800Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<
                  ffi.NativeFunction<
                      ffi.Pointer<ObjCObject> Function(
                          ffi.Pointer<ffi.Void>)>>)>>('objc_msgSend');
  late final __objc_msgSend_800 = __objc_msgSend_800Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Pointer<ObjCObject> Function(ffi.Pointer<ffi.Void>)>>)>();

  late final _sel_relinquishFunction1 = _registerName1("relinquishFunction");
  ffi.Pointer<
          ffi.NativeFunction<
              ffi.Void Function(
                  ffi.Pointer<ffi.Void>,
                  ffi.Pointer<
                      ffi.NativeFunction<
                          NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
      _objc_msgSend_801(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_801(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_801Ptr = _lookup<
          ffi.NativeFunction<
              ffi.Pointer<
                      ffi.NativeFunction<
                          ffi.Void Function(
                              ffi.Pointer<ffi.Void>,
                              ffi.Pointer<
                                  ffi.NativeFunction<
                                      NSUInteger Function(
                                          ffi.Pointer<ffi.Void>)>>)>>
                  Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>(
      'objc_msgSend');
  late final __objc_msgSend_801 = __objc_msgSend_801Ptr.asFunction<
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
          Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setRelinquishFunction_1 =
      _registerName1("setRelinquishFunction:");
  void _objc_msgSend_802(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<ffi.Void>,
                    ffi.Pointer<
                        ffi.NativeFunction<
                            NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
        value,
  ) {
    return __objc_msgSend_802(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_802Ptr = _lookup<
          ffi.NativeFunction<
              ffi.Void Function(
                  ffi.Pointer<ObjCObject>,
                  ffi.Pointer<ObjCSel>,
                  ffi.Pointer<
                      ffi.NativeFunction<
                          ffi.Void Function(
                              ffi.Pointer<ffi.Void>,
                              ffi.Pointer<
                                  ffi.NativeFunction<
                                      NSUInteger Function(
                                          ffi.Pointer<ffi.Void>)>>)>>)>>(
      'objc_msgSend');
  late final __objc_msgSend_802 = __objc_msgSend_802Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(
                                  ffi.Pointer<ffi.Void>)>>)>>)>();

  late final _sel_acquireFunction1 = _registerName1("acquireFunction");
  ffi.Pointer<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Void> Function(
              ffi.Pointer<ffi.Void>,
              ffi.Pointer<
                  ffi
                  .NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
              ffi.Bool)>> _objc_msgSend_803(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_803(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_803Ptr =
      _lookup<
              ffi.NativeFunction<
                  ffi.Pointer<
                          ffi.NativeFunction<
                              ffi.Pointer<ffi.Void> Function(
                                  ffi.Pointer<ffi.Void>,
                                  ffi.Pointer<
                                      ffi.NativeFunction<
                                          NSUInteger Function(
                                              ffi.Pointer<ffi.Void>)>>,
                                  ffi.Bool)>>
                      Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>(
          'objc_msgSend');
  late final __objc_msgSend_803 = __objc_msgSend_803Ptr.asFunction<
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Pointer<ffi.Void> Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
                      ffi.Bool)>>
          Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setAcquireFunction_1 = _registerName1("setAcquireFunction:");
  void _objc_msgSend_804(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<
            ffi.NativeFunction<
                ffi.Pointer<ffi.Void> Function(
                    ffi.Pointer<ffi.Void>,
                    ffi.Pointer<
                        ffi.NativeFunction<
                            NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
                    ffi.Bool)>>
        value,
  ) {
    return __objc_msgSend_804(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_804Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<
                  ffi.NativeFunction<
                      ffi.Pointer<ffi.Void> Function(
                          ffi.Pointer<ffi.Void>,
                          ffi.Pointer<
                              ffi.NativeFunction<
                                  NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
                          ffi.Bool)>>)>>('objc_msgSend');
  late final __objc_msgSend_804 = __objc_msgSend_804Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Pointer<ffi.Void> Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
                      ffi.Bool)>>)>();

  late final _sel_usesStrongWriteBarrier1 =
      _registerName1("usesStrongWriteBarrier");
  late final _sel_setUsesStrongWriteBarrier_1 =
      _registerName1("setUsesStrongWriteBarrier:");
  late final _sel_usesWeakReadAndWriteBarriers1 =
      _registerName1("usesWeakReadAndWriteBarriers");
  late final _sel_setUsesWeakReadAndWriteBarriers_1 =
      _registerName1("setUsesWeakReadAndWriteBarriers:");
  late final _sel_initWithPointerFunctions_1 =
      _registerName1("initWithPointerFunctions:");
  instancetype _objc_msgSend_805(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> functions,
  ) {
    return __objc_msgSend_805(
      obj,
      sel,
      functions,
    );
  }

  late final __objc_msgSend_805Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_805 = __objc_msgSend_805Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_pointerArrayWithOptions_1 =
      _registerName1("pointerArrayWithOptions:");
  ffi.Pointer<ObjCObject> _objc_msgSend_806(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
  ) {
    return __objc_msgSend_806(
      obj,
      sel,
      options,
    );
  }

  late final __objc_msgSend_806Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_806 = __objc_msgSend_806Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_pointerArrayWithPointerFunctions_1 =
      _registerName1("pointerArrayWithPointerFunctions:");
  ffi.Pointer<ObjCObject> _objc_msgSend_807(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> functions,
  ) {
    return __objc_msgSend_807(
      obj,
      sel,
      functions,
    );
  }

  late final __objc_msgSend_807Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_807 = __objc_msgSend_807Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_pointerFunctions1 = _registerName1("pointerFunctions");
  ffi.Pointer<ObjCObject> _objc_msgSend_808(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_808(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_808Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_808 = __objc_msgSend_808Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_pointerAtIndex_1 = _registerName1("pointerAtIndex:");
  ffi.Pointer<ffi.Void> _objc_msgSend_809(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
  ) {
    return __objc_msgSend_809(
      obj,
      sel,
      index,
    );
  }

  late final __objc_msgSend_809Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Void> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_809 = __objc_msgSend_809Ptr.asFunction<
      ffi.Pointer<ffi.Void> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_addPointer_1 = _registerName1("addPointer:");
  late final _sel_removePointerAtIndex_1 =
      _registerName1("removePointerAtIndex:");
  late final _sel_insertPointer_atIndex_1 =
      _registerName1("insertPointer:atIndex:");
  late final _sel_replacePointerAtIndex_withPointer_1 =
      _registerName1("replacePointerAtIndex:withPointer:");
  void _objc_msgSend_810(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
    ffi.Pointer<ffi.Void> item,
  ) {
    return __objc_msgSend_810(
      obj,
      sel,
      index,
      item,
    );
  }

  late final __objc_msgSend_810Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger, ffi.Pointer<ffi.Void>)>>('objc_msgSend');
  late final __objc_msgSend_810 = __objc_msgSend_810Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ffi.Void>)>();

  late final _sel_compact1 = _registerName1("compact");
  late final _sel_setCount_1 = _registerName1("setCount:");
  late final _sel_pointerArrayWithStrongObjects1 =
      _registerName1("pointerArrayWithStrongObjects");
  late final _sel_pointerArrayWithWeakObjects1 =
      _registerName1("pointerArrayWithWeakObjects");
  late final _sel_strongObjectsPointerArray1 =
      _registerName1("strongObjectsPointerArray");
  ffi.Pointer<ObjCObject> _objc_msgSend_811(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_811(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_811Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_811 = __objc_msgSend_811Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_weakObjectsPointerArray1 =
      _registerName1("weakObjectsPointerArray");
  late final _class_NSProcessInfo1 = _getClass1("NSProcessInfo");
  late final _sel_processInfo1 = _registerName1("processInfo");
  ffi.Pointer<ObjCObject> _objc_msgSend_812(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_812(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_812Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_812 = __objc_msgSend_812Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_environment1 = _registerName1("environment");
  late final _sel_hostName1 = _registerName1("hostName");
  late final _sel_processName1 = _registerName1("processName");
  late final _sel_setProcessName_1 = _registerName1("setProcessName:");
  late final _sel_processIdentifier1 = _registerName1("processIdentifier");
  late final _sel_globallyUniqueString1 =
      _registerName1("globallyUniqueString");
  late final _sel_operatingSystem1 = _registerName1("operatingSystem");
  late final _sel_operatingSystemName1 = _registerName1("operatingSystemName");
  late final _sel_operatingSystemVersionString1 =
      _registerName1("operatingSystemVersionString");
  late final _sel_operatingSystemVersion1 =
      _registerName1("operatingSystemVersion");
  NSOperatingSystemVersion _objc_msgSend_813(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_813(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_813Ptr = _lookup<
      ffi.NativeFunction<
          NSOperatingSystemVersion Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_813 = __objc_msgSend_813Ptr.asFunction<
      NSOperatingSystemVersion Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_processorCount1 = _registerName1("processorCount");
  late final _sel_activeProcessorCount1 =
      _registerName1("activeProcessorCount");
  late final _sel_physicalMemory1 = _registerName1("physicalMemory");
  late final _sel_isOperatingSystemAtLeastVersion_1 =
      _registerName1("isOperatingSystemAtLeastVersion:");
  bool _objc_msgSend_814(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSOperatingSystemVersion version,
  ) {
    return __objc_msgSend_814(
      obj,
      sel,
      version,
    );
  }

  late final __objc_msgSend_814Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSOperatingSystemVersion)>>('objc_msgSend');
  late final __objc_msgSend_814 = __objc_msgSend_814Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          NSOperatingSystemVersion)>();

  late final _sel_systemUptime1 = _registerName1("systemUptime");
  late final _sel_disableSuddenTermination1 =
      _registerName1("disableSuddenTermination");
  late final _sel_enableSuddenTermination1 =
      _registerName1("enableSuddenTermination");
  late final _sel_disableAutomaticTermination_1 =
      _registerName1("disableAutomaticTermination:");
  late final _sel_enableAutomaticTermination_1 =
      _registerName1("enableAutomaticTermination:");
  late final _sel_automaticTerminationSupportEnabled1 =
      _registerName1("automaticTerminationSupportEnabled");
  late final _sel_setAutomaticTerminationSupportEnabled_1 =
      _registerName1("setAutomaticTerminationSupportEnabled:");
  late final _sel_beginActivityWithOptions_reason_1 =
      _registerName1("beginActivityWithOptions:reason:");
  ffi.Pointer<ObjCObject> _objc_msgSend_815(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
    ffi.Pointer<ObjCObject> reason,
  ) {
    return __objc_msgSend_815(
      obj,
      sel,
      options,
      reason,
    );
  }

  late final __objc_msgSend_815Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_815 = __objc_msgSend_815Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, int, ffi.Pointer<ObjCObject>)>();

  late final _sel_endActivity_1 = _registerName1("endActivity:");
  late final _sel_performActivityWithOptions_reason_usingBlock_1 =
      _registerName1("performActivityWithOptions:reason:usingBlock:");
  void _objc_msgSend_816(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
    ffi.Pointer<ObjCObject> reason,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_816(
      obj,
      sel,
      options,
      reason,
      block,
    );
  }

  late final __objc_msgSend_816Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_816 = __objc_msgSend_816Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_performExpiringActivityWithReason_usingBlock_1 =
      _registerName1("performExpiringActivityWithReason:usingBlock:");
  void _objc_msgSend_817(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> reason,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_817(
      obj,
      sel,
      reason,
      block,
    );
  }

  late final __objc_msgSend_817Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_817 = __objc_msgSend_817Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_userName1 = _registerName1("userName");
  late final _sel_fullUserName1 = _registerName1("fullUserName");
  late final _sel_thermalState1 = _registerName1("thermalState");
  int _objc_msgSend_818(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_818(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_818Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_818 = __objc_msgSend_818Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_isLowPowerModeEnabled1 =
      _registerName1("isLowPowerModeEnabled");
  late final _sel_isMacCatalystApp1 = _registerName1("isMacCatalystApp");
  late final _sel_isiOSAppOnMac1 = _registerName1("isiOSAppOnMac");
  late final _class_NSTextCheckingResult1 = _getClass1("NSTextCheckingResult");
  late final _sel_resultType1 = _registerName1("resultType");
  int _objc_msgSend_819(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_819(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_819Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_819 = __objc_msgSend_819Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_range1 = _registerName1("range");
  late final _sel_orthography1 = _registerName1("orthography");
  ffi.Pointer<ObjCObject> _objc_msgSend_820(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_820(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_820Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_820 = __objc_msgSend_820Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_grammarDetails1 = _registerName1("grammarDetails");
  late final _sel_duration1 = _registerName1("duration");
  late final _sel_components1 = _registerName1("components");
  late final _sel_replacementString1 = _registerName1("replacementString");
  late final _sel_alternativeStrings1 = _registerName1("alternativeStrings");
  late final _class_NSRegularExpression1 = _getClass1("NSRegularExpression");
  late final _sel_regularExpressionWithPattern_options_error_1 =
      _registerName1("regularExpressionWithPattern:options:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_821(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> pattern,
    int options,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_821(
      obj,
      sel,
      pattern,
      options,
      error,
    );
  }

  late final __objc_msgSend_821Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_821 = __objc_msgSend_821Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_initWithPattern_options_error_1 =
      _registerName1("initWithPattern:options:error:");
  instancetype _objc_msgSend_822(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> pattern,
    int options,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_822(
      obj,
      sel,
      pattern,
      options,
      error,
    );
  }

  late final __objc_msgSend_822Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_822 = __objc_msgSend_822Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_pattern1 = _registerName1("pattern");
  late final _sel_options1 = _registerName1("options");
  int _objc_msgSend_823(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_823(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_823Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_823 = __objc_msgSend_823Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_numberOfCaptureGroups1 =
      _registerName1("numberOfCaptureGroups");
  late final _sel_escapedPatternForString_1 =
      _registerName1("escapedPatternForString:");
  late final _sel_enumerateMatchesInString_options_range_usingBlock_1 =
      _registerName1("enumerateMatchesInString:options:range:usingBlock:");
  void _objc_msgSend_824(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    int options,
    NSRange range,
    ffi.Pointer<_ObjCBlock> block,
  ) {
    return __objc_msgSend_824(
      obj,
      sel,
      string,
      options,
      range,
      block,
    );
  }

  late final __objc_msgSend_824Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              NSRange,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_824 = __objc_msgSend_824Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, NSRange, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_matchesInString_options_range_1 =
      _registerName1("matchesInString:options:range:");
  ffi.Pointer<ObjCObject> _objc_msgSend_825(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    int options,
    NSRange range,
  ) {
    return __objc_msgSend_825(
      obj,
      sel,
      string,
      options,
      range,
    );
  }

  late final __objc_msgSend_825Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_825 = __objc_msgSend_825Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, int, NSRange)>();

  late final _sel_numberOfMatchesInString_options_range_1 =
      _registerName1("numberOfMatchesInString:options:range:");
  int _objc_msgSend_826(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    int options,
    NSRange range,
  ) {
    return __objc_msgSend_826(
      obj,
      sel,
      string,
      options,
      range,
    );
  }

  late final __objc_msgSend_826Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_826 = __objc_msgSend_826Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, NSRange)>();

  late final _sel_firstMatchInString_options_range_1 =
      _registerName1("firstMatchInString:options:range:");
  ffi.Pointer<ObjCObject> _objc_msgSend_827(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    int options,
    NSRange range,
  ) {
    return __objc_msgSend_827(
      obj,
      sel,
      string,
      options,
      range,
    );
  }

  late final __objc_msgSend_827Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              NSRange)>>('objc_msgSend');
  late final __objc_msgSend_827 = __objc_msgSend_827Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, int, NSRange)>();

  late final _sel_rangeOfFirstMatchInString_options_range_1 =
      _registerName1("rangeOfFirstMatchInString:options:range:");
  NSRange _objc_msgSend_828(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    int options,
    NSRange range,
  ) {
    return __objc_msgSend_828(
      obj,
      sel,
      string,
      options,
      range,
    );
  }

  late final __objc_msgSend_828Ptr = _lookup<
      ffi.NativeFunction<
          NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Int32, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_828 = __objc_msgSend_828Ptr.asFunction<
      NSRange Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, NSRange)>();

  late final _sel_stringByReplacingMatchesInString_options_range_withTemplate_1 =
      _registerName1(
          "stringByReplacingMatchesInString:options:range:withTemplate:");
  ffi.Pointer<ObjCObject> _objc_msgSend_829(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    int options,
    NSRange range,
    ffi.Pointer<ObjCObject> templ,
  ) {
    return __objc_msgSend_829(
      obj,
      sel,
      string,
      options,
      range,
      templ,
    );
  }

  late final __objc_msgSend_829Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              NSRange,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_829 = __objc_msgSend_829Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          NSRange,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_replaceMatchesInString_options_range_withTemplate_1 =
      _registerName1("replaceMatchesInString:options:range:withTemplate:");
  int _objc_msgSend_830(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    int options,
    NSRange range,
    ffi.Pointer<ObjCObject> templ,
  ) {
    return __objc_msgSend_830(
      obj,
      sel,
      string,
      options,
      range,
      templ,
    );
  }

  late final __objc_msgSend_830Ptr = _lookup<
      ffi.NativeFunction<
          NSUInteger Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              NSRange,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_830 = __objc_msgSend_830Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int, NSRange, ffi.Pointer<ObjCObject>)>();

  late final _sel_replacementStringForResult_inString_offset_template_1 =
      _registerName1("replacementStringForResult:inString:offset:template:");
  ffi.Pointer<ObjCObject> _objc_msgSend_831(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> result,
    ffi.Pointer<ObjCObject> string,
    int offset,
    ffi.Pointer<ObjCObject> templ,
  ) {
    return __objc_msgSend_831(
      obj,
      sel,
      result,
      string,
      offset,
      templ,
    );
  }

  late final __objc_msgSend_831Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              NSInteger,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_831 = __objc_msgSend_831Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_escapedTemplateForString_1 =
      _registerName1("escapedTemplateForString:");
  late final _sel_regularExpression1 = _registerName1("regularExpression");
  ffi.Pointer<ObjCObject> _objc_msgSend_832(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_832(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_832Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_832 = __objc_msgSend_832Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_phoneNumber1 = _registerName1("phoneNumber");
  late final _sel_numberOfRanges1 = _registerName1("numberOfRanges");
  late final _sel_rangeAtIndex_1 = _registerName1("rangeAtIndex:");
  late final _sel_rangeWithName_1 = _registerName1("rangeWithName:");
  late final _sel_resultByAdjustingRangesWithOffset_1 =
      _registerName1("resultByAdjustingRangesWithOffset:");
  ffi.Pointer<ObjCObject> _objc_msgSend_833(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int offset,
  ) {
    return __objc_msgSend_833(
      obj,
      sel,
      offset,
    );
  }

  late final __objc_msgSend_833Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_833 = __objc_msgSend_833Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_addressComponents1 = _registerName1("addressComponents");
  late final _sel_orthographyCheckingResultWithRange_orthography_1 =
      _registerName1("orthographyCheckingResultWithRange:orthography:");
  ffi.Pointer<ObjCObject> _objc_msgSend_834(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> orthography,
  ) {
    return __objc_msgSend_834(
      obj,
      sel,
      range,
      orthography,
    );
  }

  late final __objc_msgSend_834Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_834 = __objc_msgSend_834Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSRange, ffi.Pointer<ObjCObject>)>();

  late final _sel_spellCheckingResultWithRange_1 =
      _registerName1("spellCheckingResultWithRange:");
  ffi.Pointer<ObjCObject> _objc_msgSend_835(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
  ) {
    return __objc_msgSend_835(
      obj,
      sel,
      range,
    );
  }

  late final __objc_msgSend_835Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSRange)>>('objc_msgSend');
  late final __objc_msgSend_835 = __objc_msgSend_835Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, NSRange)>();

  late final _sel_grammarCheckingResultWithRange_details_1 =
      _registerName1("grammarCheckingResultWithRange:details:");
  ffi.Pointer<ObjCObject> _objc_msgSend_836(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> details,
  ) {
    return __objc_msgSend_836(
      obj,
      sel,
      range,
      details,
    );
  }

  late final __objc_msgSend_836Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_836 = __objc_msgSend_836Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSRange, ffi.Pointer<ObjCObject>)>();

  late final _sel_dateCheckingResultWithRange_date_1 =
      _registerName1("dateCheckingResultWithRange:date:");
  ffi.Pointer<ObjCObject> _objc_msgSend_837(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> date,
  ) {
    return __objc_msgSend_837(
      obj,
      sel,
      range,
      date,
    );
  }

  late final __objc_msgSend_837Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_837 = __objc_msgSend_837Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSRange, ffi.Pointer<ObjCObject>)>();

  late final _sel_dateCheckingResultWithRange_date_timeZone_duration_1 =
      _registerName1("dateCheckingResultWithRange:date:timeZone:duration:");
  ffi.Pointer<ObjCObject> _objc_msgSend_838(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> date,
    ffi.Pointer<ObjCObject> timeZone,
    double duration,
  ) {
    return __objc_msgSend_838(
      obj,
      sel,
      range,
      date,
      timeZone,
      duration,
    );
  }

  late final __objc_msgSend_838Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              NSTimeInterval)>>('objc_msgSend');
  late final __objc_msgSend_838 = __objc_msgSend_838Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          NSRange,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          double)>();

  late final _sel_addressCheckingResultWithRange_components_1 =
      _registerName1("addressCheckingResultWithRange:components:");
  ffi.Pointer<ObjCObject> _objc_msgSend_839(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> components,
  ) {
    return __objc_msgSend_839(
      obj,
      sel,
      range,
      components,
    );
  }

  late final __objc_msgSend_839Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_839 = __objc_msgSend_839Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSRange, ffi.Pointer<ObjCObject>)>();

  late final _sel_linkCheckingResultWithRange_URL_1 =
      _registerName1("linkCheckingResultWithRange:URL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_840(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> url,
  ) {
    return __objc_msgSend_840(
      obj,
      sel,
      range,
      url,
    );
  }

  late final __objc_msgSend_840Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_840 = __objc_msgSend_840Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSRange, ffi.Pointer<ObjCObject>)>();

  late final _sel_quoteCheckingResultWithRange_replacementString_1 =
      _registerName1("quoteCheckingResultWithRange:replacementString:");
  ffi.Pointer<ObjCObject> _objc_msgSend_841(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> replacementString,
  ) {
    return __objc_msgSend_841(
      obj,
      sel,
      range,
      replacementString,
    );
  }

  late final __objc_msgSend_841Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_841 = __objc_msgSend_841Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, NSRange, ffi.Pointer<ObjCObject>)>();

  late final _sel_dashCheckingResultWithRange_replacementString_1 =
      _registerName1("dashCheckingResultWithRange:replacementString:");
  late final _sel_replacementCheckingResultWithRange_replacementString_1 =
      _registerName1("replacementCheckingResultWithRange:replacementString:");
  late final _sel_correctionCheckingResultWithRange_replacementString_1 =
      _registerName1("correctionCheckingResultWithRange:replacementString:");
  late final _sel_correctionCheckingResultWithRange_replacementString_alternativeStrings_1 =
      _registerName1(
          "correctionCheckingResultWithRange:replacementString:alternativeStrings:");
  ffi.Pointer<ObjCObject> _objc_msgSend_842(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRange range,
    ffi.Pointer<ObjCObject> replacementString,
    ffi.Pointer<ObjCObject> alternativeStrings,
  ) {
    return __objc_msgSend_842(
      obj,
      sel,
      range,
      replacementString,
      alternativeStrings,
    );
  }

  late final __objc_msgSend_842Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRange,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_842 = __objc_msgSend_842Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          NSRange,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_regularExpressionCheckingResultWithRanges_count_regularExpression_1 =
      _registerName1(
          "regularExpressionCheckingResultWithRanges:count:regularExpression:");
  ffi.Pointer<ObjCObject> _objc_msgSend_843(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    NSRangePointer ranges,
    int count,
    ffi.Pointer<ObjCObject> regularExpression,
  ) {
    return __objc_msgSend_843(
      obj,
      sel,
      ranges,
      count,
      regularExpression,
    );
  }

  late final __objc_msgSend_843Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSRangePointer,
              NSUInteger,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_843 = __objc_msgSend_843Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          NSRangePointer,
          int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_phoneNumberCheckingResultWithRange_phoneNumber_1 =
      _registerName1("phoneNumberCheckingResultWithRange:phoneNumber:");
  late final _sel_transitInformationCheckingResultWithRange_components_1 =
      _registerName1("transitInformationCheckingResultWithRange:components:");
  late final _class_NSURLCache1 = _getClass1("NSURLCache");
  late final _sel_sharedURLCache1 = _registerName1("sharedURLCache");
  ffi.Pointer<ObjCObject> _objc_msgSend_844(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_844(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_844Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_844 = __objc_msgSend_844Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setSharedURLCache_1 = _registerName1("setSharedURLCache:");
  void _objc_msgSend_845(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_845(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_845Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_845 = __objc_msgSend_845Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithMemoryCapacity_diskCapacity_diskPath_1 =
      _registerName1("initWithMemoryCapacity:diskCapacity:diskPath:");
  instancetype _objc_msgSend_846(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int memoryCapacity,
    int diskCapacity,
    ffi.Pointer<ObjCObject> path,
  ) {
    return __objc_msgSend_846(
      obj,
      sel,
      memoryCapacity,
      diskCapacity,
      path,
    );
  }

  late final __objc_msgSend_846Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSUInteger,
              NSUInteger,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_846 = __objc_msgSend_846Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          int, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithMemoryCapacity_diskCapacity_directoryURL_1 =
      _registerName1("initWithMemoryCapacity:diskCapacity:directoryURL:");
  instancetype _objc_msgSend_847(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int memoryCapacity,
    int diskCapacity,
    ffi.Pointer<ObjCObject> directoryURL,
  ) {
    return __objc_msgSend_847(
      obj,
      sel,
      memoryCapacity,
      diskCapacity,
      directoryURL,
    );
  }

  late final __objc_msgSend_847Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSUInteger,
              NSUInteger,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_847 = __objc_msgSend_847Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          int, ffi.Pointer<ObjCObject>)>();

  late final _class_NSCachedURLResponse1 = _getClass1("NSCachedURLResponse");
  late final _sel_initWithResponse_data_1 =
      _registerName1("initWithResponse:data:");
  instancetype _objc_msgSend_848(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> response,
    ffi.Pointer<ObjCObject> data,
  ) {
    return __objc_msgSend_848(
      obj,
      sel,
      response,
      data,
    );
  }

  late final __objc_msgSend_848Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_848 = __objc_msgSend_848Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithResponse_data_userInfo_storagePolicy_1 =
      _registerName1("initWithResponse:data:userInfo:storagePolicy:");
  instancetype _objc_msgSend_849(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> response,
    ffi.Pointer<ObjCObject> data,
    ffi.Pointer<ObjCObject> userInfo,
    int storagePolicy,
  ) {
    return __objc_msgSend_849(
      obj,
      sel,
      response,
      data,
      userInfo,
      storagePolicy,
    );
  }

  late final __objc_msgSend_849Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_849 = __objc_msgSend_849Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int)>();

  late final _sel_storagePolicy1 = _registerName1("storagePolicy");
  int _objc_msgSend_850(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_850(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_850Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_850 = __objc_msgSend_850Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_cachedResponseForRequest_1 =
      _registerName1("cachedResponseForRequest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_851(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_851(
      obj,
      sel,
      request,
    );
  }

  late final __objc_msgSend_851Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_851 = __objc_msgSend_851Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_storeCachedResponse_forRequest_1 =
      _registerName1("storeCachedResponse:forRequest:");
  void _objc_msgSend_852(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> cachedResponse,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_852(
      obj,
      sel,
      cachedResponse,
      request,
    );
  }

  late final __objc_msgSend_852Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_852 = __objc_msgSend_852Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_removeCachedResponseForRequest_1 =
      _registerName1("removeCachedResponseForRequest:");
  void _objc_msgSend_853(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_853(
      obj,
      sel,
      request,
    );
  }

  late final __objc_msgSend_853Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_853 = __objc_msgSend_853Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_removeAllCachedResponses1 =
      _registerName1("removeAllCachedResponses");
  late final _sel_removeCachedResponsesSinceDate_1 =
      _registerName1("removeCachedResponsesSinceDate:");
  late final _sel_memoryCapacity1 = _registerName1("memoryCapacity");
  late final _sel_setMemoryCapacity_1 = _registerName1("setMemoryCapacity:");
  late final _sel_diskCapacity1 = _registerName1("diskCapacity");
  late final _sel_setDiskCapacity_1 = _registerName1("setDiskCapacity:");
  late final _sel_currentMemoryUsage1 = _registerName1("currentMemoryUsage");
  late final _sel_currentDiskUsage1 = _registerName1("currentDiskUsage");
  late final _class_NSURLSessionDataTask1 = _getClass1("NSURLSessionDataTask");
  late final _sel_storeCachedResponse_forDataTask_1 =
      _registerName1("storeCachedResponse:forDataTask:");
  void _objc_msgSend_854(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> cachedResponse,
    ffi.Pointer<ObjCObject> dataTask,
  ) {
    return __objc_msgSend_854(
      obj,
      sel,
      cachedResponse,
      dataTask,
    );
  }

  late final __objc_msgSend_854Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_854 = __objc_msgSend_854Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_getCachedResponseForDataTask_completionHandler_1 =
      _registerName1("getCachedResponseForDataTask:completionHandler:");
  void _objc_msgSend_855(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> dataTask,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_855(
      obj,
      sel,
      dataTask,
      completionHandler,
    );
  }

  late final __objc_msgSend_855Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_855 = __objc_msgSend_855Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_removeCachedResponseForDataTask_1 =
      _registerName1("removeCachedResponseForDataTask:");
  void _objc_msgSend_856(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> dataTask,
  ) {
    return __objc_msgSend_856(
      obj,
      sel,
      dataTask,
    );
  }

  late final __objc_msgSend_856Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_856 = __objc_msgSend_856Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _class_NSURLConnection1 = _getClass1("NSURLConnection");
  late final _sel_initWithRequest_delegate_startImmediately_1 =
      _registerName1("initWithRequest:delegate:startImmediately:");
  instancetype _objc_msgSend_857(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<ObjCObject> delegate,
    bool startImmediately,
  ) {
    return __objc_msgSend_857(
      obj,
      sel,
      request,
      delegate,
      startImmediately,
    );
  }

  late final __objc_msgSend_857Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_857 = __objc_msgSend_857Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_initWithRequest_delegate_1 =
      _registerName1("initWithRequest:delegate:");
  instancetype _objc_msgSend_858(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<ObjCObject> delegate,
  ) {
    return __objc_msgSend_858(
      obj,
      sel,
      request,
      delegate,
    );
  }

  late final __objc_msgSend_858Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_858 = __objc_msgSend_858Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_connectionWithRequest_delegate_1 =
      _registerName1("connectionWithRequest:delegate:");
  ffi.Pointer<ObjCObject> _objc_msgSend_859(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<ObjCObject> delegate,
  ) {
    return __objc_msgSend_859(
      obj,
      sel,
      request,
      delegate,
    );
  }

  late final __objc_msgSend_859Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_859 = __objc_msgSend_859Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_unscheduleFromRunLoop_forMode_1 =
      _registerName1("unscheduleFromRunLoop:forMode:");
  late final _sel_setDelegateQueue_1 = _registerName1("setDelegateQueue:");
  void _objc_msgSend_860(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> queue,
  ) {
    return __objc_msgSend_860(
      obj,
      sel,
      queue,
    );
  }

  late final __objc_msgSend_860Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_860 = __objc_msgSend_860Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_canHandleRequest_1 = _registerName1("canHandleRequest:");
  bool _objc_msgSend_861(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_861(
      obj,
      sel,
      request,
    );
  }

  late final __objc_msgSend_861Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_861 = __objc_msgSend_861Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_sendSynchronousRequest_returningResponse_error_1 =
      _registerName1("sendSynchronousRequest:returningResponse:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_862(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<ffi.Pointer<ObjCObject>> response,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_862(
      obj,
      sel,
      request,
      response,
      error,
    );
  }

  late final __objc_msgSend_862Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_862 = __objc_msgSend_862Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_sendAsynchronousRequest_queue_completionHandler_1 =
      _registerName1("sendAsynchronousRequest:queue:completionHandler:");
  void _objc_msgSend_863(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<ObjCObject> queue,
    ffi.Pointer<_ObjCBlock> handler,
  ) {
    return __objc_msgSend_863(
      obj,
      sel,
      request,
      queue,
      handler,
    );
  }

  late final __objc_msgSend_863Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_863 = __objc_msgSend_863Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _class_NSURLCredential1 = _getClass1("NSURLCredential");
  late final _sel_persistence1 = _registerName1("persistence");
  int _objc_msgSend_864(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_864(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_864Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_864 = __objc_msgSend_864Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_initWithUser_password_persistence_1 =
      _registerName1("initWithUser:password:persistence:");
  instancetype _objc_msgSend_865(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> user,
    ffi.Pointer<ObjCObject> password,
    int persistence,
  ) {
    return __objc_msgSend_865(
      obj,
      sel,
      user,
      password,
      persistence,
    );
  }

  late final __objc_msgSend_865Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_865 = __objc_msgSend_865Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>, int)>();

  late final _sel_credentialWithUser_password_persistence_1 =
      _registerName1("credentialWithUser:password:persistence:");
  ffi.Pointer<ObjCObject> _objc_msgSend_866(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> user,
    ffi.Pointer<ObjCObject> password,
    int persistence,
  ) {
    return __objc_msgSend_866(
      obj,
      sel,
      user,
      password,
      persistence,
    );
  }

  late final __objc_msgSend_866Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_866 = __objc_msgSend_866Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int)>();

  late final _sel_hasPassword1 = _registerName1("hasPassword");
  late final _sel_initWithIdentity_certificates_persistence_1 =
      _registerName1("initWithIdentity:certificates:persistence:");
  instancetype _objc_msgSend_867(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    SecIdentityRef identity,
    ffi.Pointer<ObjCObject> certArray,
    int persistence,
  ) {
    return __objc_msgSend_867(
      obj,
      sel,
      identity,
      certArray,
      persistence,
    );
  }

  late final __objc_msgSend_867Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              SecIdentityRef,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_867 = __objc_msgSend_867Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          SecIdentityRef, ffi.Pointer<ObjCObject>, int)>();

  late final _sel_credentialWithIdentity_certificates_persistence_1 =
      _registerName1("credentialWithIdentity:certificates:persistence:");
  ffi.Pointer<ObjCObject> _objc_msgSend_868(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    SecIdentityRef identity,
    ffi.Pointer<ObjCObject> certArray,
    int persistence,
  ) {
    return __objc_msgSend_868(
      obj,
      sel,
      identity,
      certArray,
      persistence,
    );
  }

  late final __objc_msgSend_868Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              SecIdentityRef,
              ffi.Pointer<ObjCObject>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_868 = __objc_msgSend_868Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          SecIdentityRef,
          ffi.Pointer<ObjCObject>,
          int)>();

  late final _sel_identity1 = _registerName1("identity");
  SecIdentityRef _objc_msgSend_869(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_869(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_869Ptr = _lookup<
      ffi.NativeFunction<
          SecIdentityRef Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_869 = __objc_msgSend_869Ptr.asFunction<
      SecIdentityRef Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_certificates1 = _registerName1("certificates");
  late final _sel_initWithTrust_1 = _registerName1("initWithTrust:");
  instancetype _objc_msgSend_870(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    SecTrustRef trust,
  ) {
    return __objc_msgSend_870(
      obj,
      sel,
      trust,
    );
  }

  late final __objc_msgSend_870Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              SecTrustRef)>>('objc_msgSend');
  late final __objc_msgSend_870 = __objc_msgSend_870Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, SecTrustRef)>();

  late final _sel_credentialForTrust_1 = _registerName1("credentialForTrust:");
  ffi.Pointer<ObjCObject> _objc_msgSend_871(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    SecTrustRef trust,
  ) {
    return __objc_msgSend_871(
      obj,
      sel,
      trust,
    );
  }

  late final __objc_msgSend_871Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, SecTrustRef)>>('objc_msgSend');
  late final __objc_msgSend_871 = __objc_msgSend_871Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, SecTrustRef)>();

  late final _class_NSURLProtectionSpace1 = _getClass1("NSURLProtectionSpace");
  late final _sel_initWithHost_port_protocol_realm_authenticationMethod_1 =
      _registerName1("initWithHost:port:protocol:realm:authenticationMethod:");
  instancetype _objc_msgSend_872(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> host,
    int port,
    ffi.Pointer<ObjCObject> protocol,
    ffi.Pointer<ObjCObject> realm,
    ffi.Pointer<ObjCObject> authenticationMethod,
  ) {
    return __objc_msgSend_872(
      obj,
      sel,
      host,
      port,
      protocol,
      realm,
      authenticationMethod,
    );
  }

  late final __objc_msgSend_872Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSInteger,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_872 = __objc_msgSend_872Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithProxyHost_port_type_realm_authenticationMethod_1 =
      _registerName1("initWithProxyHost:port:type:realm:authenticationMethod:");
  late final _sel_realm1 = _registerName1("realm");
  late final _sel_receivesCredentialSecurely1 =
      _registerName1("receivesCredentialSecurely");
  late final _sel_isProxy1 = _registerName1("isProxy");
  late final _sel_proxyType1 = _registerName1("proxyType");
  late final _sel_protocol1 = _registerName1("protocol");
  late final _sel_authenticationMethod1 =
      _registerName1("authenticationMethod");
  late final _sel_distinguishedNames1 = _registerName1("distinguishedNames");
  late final _sel_serverTrust1 = _registerName1("serverTrust");
  SecTrustRef _objc_msgSend_873(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_873(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_873Ptr = _lookup<
      ffi.NativeFunction<
          SecTrustRef Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_873 = __objc_msgSend_873Ptr.asFunction<
      SecTrustRef Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _class_NSURLCredentialStorage1 =
      _getClass1("NSURLCredentialStorage");
  late final _sel_sharedCredentialStorage1 =
      _registerName1("sharedCredentialStorage");
  ffi.Pointer<ObjCObject> _objc_msgSend_874(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_874(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_874Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_874 = __objc_msgSend_874Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_credentialsForProtectionSpace_1 =
      _registerName1("credentialsForProtectionSpace:");
  ffi.Pointer<ObjCObject> _objc_msgSend_875(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> space,
  ) {
    return __objc_msgSend_875(
      obj,
      sel,
      space,
    );
  }

  late final __objc_msgSend_875Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_875 = __objc_msgSend_875Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_allCredentials1 = _registerName1("allCredentials");
  late final _sel_setCredential_forProtectionSpace_1 =
      _registerName1("setCredential:forProtectionSpace:");
  void _objc_msgSend_876(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> credential,
    ffi.Pointer<ObjCObject> space,
  ) {
    return __objc_msgSend_876(
      obj,
      sel,
      credential,
      space,
    );
  }

  late final __objc_msgSend_876Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_876 = __objc_msgSend_876Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_removeCredential_forProtectionSpace_1 =
      _registerName1("removeCredential:forProtectionSpace:");
  late final _sel_removeCredential_forProtectionSpace_options_1 =
      _registerName1("removeCredential:forProtectionSpace:options:");
  void _objc_msgSend_877(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> credential,
    ffi.Pointer<ObjCObject> space,
    ffi.Pointer<ObjCObject> options,
  ) {
    return __objc_msgSend_877(
      obj,
      sel,
      credential,
      space,
      options,
    );
  }

  late final __objc_msgSend_877Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_877 = __objc_msgSend_877Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_defaultCredentialForProtectionSpace_1 =
      _registerName1("defaultCredentialForProtectionSpace:");
  ffi.Pointer<ObjCObject> _objc_msgSend_878(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> space,
  ) {
    return __objc_msgSend_878(
      obj,
      sel,
      space,
    );
  }

  late final __objc_msgSend_878Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_878 = __objc_msgSend_878Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_setDefaultCredential_forProtectionSpace_1 =
      _registerName1("setDefaultCredential:forProtectionSpace:");
  late final _sel_getCredentialsForProtectionSpace_task_completionHandler_1 =
      _registerName1(
          "getCredentialsForProtectionSpace:task:completionHandler:");
  void _objc_msgSend_879(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> protectionSpace,
    ffi.Pointer<ObjCObject> task,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_879(
      obj,
      sel,
      protectionSpace,
      task,
      completionHandler,
    );
  }

  late final __objc_msgSend_879Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_879 = __objc_msgSend_879Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_setCredential_forProtectionSpace_task_1 =
      _registerName1("setCredential:forProtectionSpace:task:");
  void _objc_msgSend_880(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> credential,
    ffi.Pointer<ObjCObject> protectionSpace,
    ffi.Pointer<ObjCObject> task,
  ) {
    return __objc_msgSend_880(
      obj,
      sel,
      credential,
      protectionSpace,
      task,
    );
  }

  late final __objc_msgSend_880Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_880 = __objc_msgSend_880Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_removeCredential_forProtectionSpace_options_task_1 =
      _registerName1("removeCredential:forProtectionSpace:options:task:");
  void _objc_msgSend_881(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> credential,
    ffi.Pointer<ObjCObject> protectionSpace,
    ffi.Pointer<ObjCObject> options,
    ffi.Pointer<ObjCObject> task,
  ) {
    return __objc_msgSend_881(
      obj,
      sel,
      credential,
      protectionSpace,
      options,
      task,
    );
  }

  late final __objc_msgSend_881Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_881 = __objc_msgSend_881Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_getDefaultCredentialForProtectionSpace_task_completionHandler_1 =
      _registerName1(
          "getDefaultCredentialForProtectionSpace:task:completionHandler:");
  void _objc_msgSend_882(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> space,
    ffi.Pointer<ObjCObject> task,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_882(
      obj,
      sel,
      space,
      task,
      completionHandler,
    );
  }

  late final __objc_msgSend_882Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_882 = __objc_msgSend_882Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_setDefaultCredential_forProtectionSpace_task_1 =
      _registerName1("setDefaultCredential:forProtectionSpace:task:");
  late final _class_NSURLProtocol1 = _getClass1("NSURLProtocol");
  late final _sel_initWithRequest_cachedResponse_client_1 =
      _registerName1("initWithRequest:cachedResponse:client:");
  instancetype _objc_msgSend_883(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<ObjCObject> cachedResponse,
    ffi.Pointer<ObjCObject> client,
  ) {
    return __objc_msgSend_883(
      obj,
      sel,
      request,
      cachedResponse,
      client,
    );
  }

  late final __objc_msgSend_883Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_883 = __objc_msgSend_883Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_client1 = _registerName1("client");
  late final _sel_request1 = _registerName1("request");
  late final _sel_cachedResponse1 = _registerName1("cachedResponse");
  ffi.Pointer<ObjCObject> _objc_msgSend_884(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_884(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_884Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_884 = __objc_msgSend_884Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_canInitWithRequest_1 = _registerName1("canInitWithRequest:");
  late final _sel_canonicalRequestForRequest_1 =
      _registerName1("canonicalRequestForRequest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_885(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_885(
      obj,
      sel,
      request,
    );
  }

  late final __objc_msgSend_885Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_885 = __objc_msgSend_885Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_requestIsCacheEquivalent_toRequest_1 =
      _registerName1("requestIsCacheEquivalent:toRequest:");
  bool _objc_msgSend_886(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> a,
    ffi.Pointer<ObjCObject> b,
  ) {
    return __objc_msgSend_886(
      obj,
      sel,
      a,
      b,
    );
  }

  late final __objc_msgSend_886Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_886 = __objc_msgSend_886Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_startLoading1 = _registerName1("startLoading");
  late final _sel_stopLoading1 = _registerName1("stopLoading");
  late final _sel_propertyForKey_inRequest_1 =
      _registerName1("propertyForKey:inRequest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_887(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_887(
      obj,
      sel,
      key,
      request,
    );
  }

  late final __objc_msgSend_887Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_887 = __objc_msgSend_887Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _class_NSMutableURLRequest1 = _getClass1("NSMutableURLRequest");
  late final _sel_setURL_1 = _registerName1("setURL:");
  void _objc_msgSend_888(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_888(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_888Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_888 = __objc_msgSend_888Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_setCachePolicy_1 = _registerName1("setCachePolicy:");
  void _objc_msgSend_889(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_889(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_889Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_889 = __objc_msgSend_889Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_setTimeoutInterval_1 = _registerName1("setTimeoutInterval:");
  late final _sel_setMainDocumentURL_1 = _registerName1("setMainDocumentURL:");
  late final _sel_setNetworkServiceType_1 =
      _registerName1("setNetworkServiceType:");
  void _objc_msgSend_890(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_890(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_890Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_890 = __objc_msgSend_890Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_setAllowsCellularAccess_1 =
      _registerName1("setAllowsCellularAccess:");
  late final _sel_setAllowsExpensiveNetworkAccess_1 =
      _registerName1("setAllowsExpensiveNetworkAccess:");
  late final _sel_setAllowsConstrainedNetworkAccess_1 =
      _registerName1("setAllowsConstrainedNetworkAccess:");
  late final _sel_setAssumesHTTP3Capable_1 =
      _registerName1("setAssumesHTTP3Capable:");
  late final _sel_setAttribution_1 = _registerName1("setAttribution:");
  void _objc_msgSend_891(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_891(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_891Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_891 = __objc_msgSend_891Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_setHTTPMethod_1 = _registerName1("setHTTPMethod:");
  late final _sel_setAllHTTPHeaderFields_1 =
      _registerName1("setAllHTTPHeaderFields:");
  late final _sel_setValue_forHTTPHeaderField_1 =
      _registerName1("setValue:forHTTPHeaderField:");
  late final _sel_addValue_forHTTPHeaderField_1 =
      _registerName1("addValue:forHTTPHeaderField:");
  late final _sel_setHTTPBody_1 = _registerName1("setHTTPBody:");
  void _objc_msgSend_892(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_892(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_892Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_892 = __objc_msgSend_892Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_setHTTPBodyStream_1 = _registerName1("setHTTPBodyStream:");
  void _objc_msgSend_893(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_893(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_893Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_893 = __objc_msgSend_893Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_setHTTPShouldHandleCookies_1 =
      _registerName1("setHTTPShouldHandleCookies:");
  late final _sel_setHTTPShouldUsePipelining_1 =
      _registerName1("setHTTPShouldUsePipelining:");
  late final _sel_setProperty_forKey_inRequest_1 =
      _registerName1("setProperty:forKey:inRequest:");
  void _objc_msgSend_894(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
    ffi.Pointer<ObjCObject> key,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_894(
      obj,
      sel,
      value,
      key,
      request,
    );
  }

  late final __objc_msgSend_894Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_894 = __objc_msgSend_894Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_removePropertyForKey_inRequest_1 =
      _registerName1("removePropertyForKey:inRequest:");
  void _objc_msgSend_895(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> key,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_895(
      obj,
      sel,
      key,
      request,
    );
  }

  late final __objc_msgSend_895Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_895 = __objc_msgSend_895Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_registerClass_1 = _registerName1("registerClass:");
  late final _sel_unregisterClass_1 = _registerName1("unregisterClass:");
  late final _sel_canInitWithTask_1 = _registerName1("canInitWithTask:");
  bool _objc_msgSend_896(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> task,
  ) {
    return __objc_msgSend_896(
      obj,
      sel,
      task,
    );
  }

  late final __objc_msgSend_896Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_896 = __objc_msgSend_896Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithTask_cachedResponse_client_1 =
      _registerName1("initWithTask:cachedResponse:client:");
  instancetype _objc_msgSend_897(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> task,
    ffi.Pointer<ObjCObject> cachedResponse,
    ffi.Pointer<ObjCObject> client,
  ) {
    return __objc_msgSend_897(
      obj,
      sel,
      task,
      cachedResponse,
      client,
    );
  }

  late final __objc_msgSend_897Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_897 = __objc_msgSend_897Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_task1 = _registerName1("task");
  ffi.Pointer<ObjCObject> _objc_msgSend_898(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_898(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_898Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_898 = __objc_msgSend_898Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _class_NSXMLParser1 = _getClass1("NSXMLParser");
  late final _sel_initWithStream_1 = _registerName1("initWithStream:");
  instancetype _objc_msgSend_899(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> stream,
  ) {
    return __objc_msgSend_899(
      obj,
      sel,
      stream,
    );
  }

  late final __objc_msgSend_899Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_899 = __objc_msgSend_899Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_shouldProcessNamespaces1 =
      _registerName1("shouldProcessNamespaces");
  late final _sel_setShouldProcessNamespaces_1 =
      _registerName1("setShouldProcessNamespaces:");
  late final _sel_shouldReportNamespacePrefixes1 =
      _registerName1("shouldReportNamespacePrefixes");
  late final _sel_setShouldReportNamespacePrefixes_1 =
      _registerName1("setShouldReportNamespacePrefixes:");
  late final _sel_externalEntityResolvingPolicy1 =
      _registerName1("externalEntityResolvingPolicy");
  int _objc_msgSend_900(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_900(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_900Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_900 = __objc_msgSend_900Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setExternalEntityResolvingPolicy_1 =
      _registerName1("setExternalEntityResolvingPolicy:");
  void _objc_msgSend_901(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_901(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_901Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_901 = __objc_msgSend_901Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_allowedExternalEntityURLs1 =
      _registerName1("allowedExternalEntityURLs");
  late final _sel_setAllowedExternalEntityURLs_1 =
      _registerName1("setAllowedExternalEntityURLs:");
  void _objc_msgSend_902(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_902(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_902Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_902 = __objc_msgSend_902Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_parse1 = _registerName1("parse");
  late final _sel_abortParsing1 = _registerName1("abortParsing");
  late final _sel_parserError1 = _registerName1("parserError");
  late final _sel_shouldResolveExternalEntities1 =
      _registerName1("shouldResolveExternalEntities");
  late final _sel_setShouldResolveExternalEntities_1 =
      _registerName1("setShouldResolveExternalEntities:");
  late final _sel_publicID1 = _registerName1("publicID");
  late final _sel_systemID1 = _registerName1("systemID");
  late final _sel_lineNumber1 = _registerName1("lineNumber");
  late final _sel_columnNumber1 = _registerName1("columnNumber");
  late final _class_NSFileWrapper1 = _getClass1("NSFileWrapper");
  late final _sel_initWithURL_options_error_1 =
      _registerName1("initWithURL:options:error:");
  instancetype _objc_msgSend_903(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    int options,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_903(
      obj,
      sel,
      url,
      options,
      outError,
    );
  }

  late final __objc_msgSend_903Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_903 = __objc_msgSend_903Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_initDirectoryWithFileWrappers_1 =
      _registerName1("initDirectoryWithFileWrappers:");
  late final _sel_initRegularFileWithContents_1 =
      _registerName1("initRegularFileWithContents:");
  late final _sel_initSymbolicLinkWithDestinationURL_1 =
      _registerName1("initSymbolicLinkWithDestinationURL:");
  late final _sel_initWithSerializedRepresentation_1 =
      _registerName1("initWithSerializedRepresentation:");
  late final _sel_isDirectory1 = _registerName1("isDirectory");
  late final _sel_isRegularFile1 = _registerName1("isRegularFile");
  late final _sel_isSymbolicLink1 = _registerName1("isSymbolicLink");
  late final _sel_preferredFilename1 = _registerName1("preferredFilename");
  late final _sel_setPreferredFilename_1 =
      _registerName1("setPreferredFilename:");
  late final _sel_filename1 = _registerName1("filename");
  late final _sel_setFilename_1 = _registerName1("setFilename:");
  late final _sel_fileAttributes1 = _registerName1("fileAttributes");
  late final _sel_setFileAttributes_1 = _registerName1("setFileAttributes:");
  late final _sel_matchesContentsOfURL_1 =
      _registerName1("matchesContentsOfURL:");
  late final _sel_readFromURL_options_error_1 =
      _registerName1("readFromURL:options:error:");
  bool _objc_msgSend_904(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    int options,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_904(
      obj,
      sel,
      url,
      options,
      outError,
    );
  }

  late final __objc_msgSend_904Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_904 = __objc_msgSend_904Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_writeToURL_options_originalContentsURL_error_1 =
      _registerName1("writeToURL:options:originalContentsURL:error:");
  bool _objc_msgSend_905(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    int options,
    ffi.Pointer<ObjCObject> originalContentsURL,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_905(
      obj,
      sel,
      url,
      options,
      originalContentsURL,
      outError,
    );
  }

  late final __objc_msgSend_905Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_905 = __objc_msgSend_905Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_serializedRepresentation1 =
      _registerName1("serializedRepresentation");
  late final _sel_addFileWrapper_1 = _registerName1("addFileWrapper:");
  ffi.Pointer<ObjCObject> _objc_msgSend_906(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> child,
  ) {
    return __objc_msgSend_906(
      obj,
      sel,
      child,
    );
  }

  late final __objc_msgSend_906Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_906 = __objc_msgSend_906Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_addRegularFileWithContents_preferredFilename_1 =
      _registerName1("addRegularFileWithContents:preferredFilename:");
  ffi.Pointer<ObjCObject> _objc_msgSend_907(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
    ffi.Pointer<ObjCObject> fileName,
  ) {
    return __objc_msgSend_907(
      obj,
      sel,
      data,
      fileName,
    );
  }

  late final __objc_msgSend_907Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_907 = __objc_msgSend_907Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_removeFileWrapper_1 = _registerName1("removeFileWrapper:");
  void _objc_msgSend_908(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> child,
  ) {
    return __objc_msgSend_908(
      obj,
      sel,
      child,
    );
  }

  late final __objc_msgSend_908Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_908 = __objc_msgSend_908Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_fileWrappers1 = _registerName1("fileWrappers");
  late final _sel_keyForFileWrapper_1 = _registerName1("keyForFileWrapper:");
  late final _sel_regularFileContents1 = _registerName1("regularFileContents");
  late final _sel_symbolicLinkDestinationURL1 =
      _registerName1("symbolicLinkDestinationURL");
  late final _sel_initSymbolicLinkWithDestination_1 =
      _registerName1("initSymbolicLinkWithDestination:");
  late final _sel_needsToBeUpdatedFromPath_1 =
      _registerName1("needsToBeUpdatedFromPath:");
  late final _sel_updateFromPath_1 = _registerName1("updateFromPath:");
  late final _sel_writeToFile_atomically_updateFilenames_1 =
      _registerName1("writeToFile:atomically:updateFilenames:");
  bool _objc_msgSend_909(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    bool atomicFlag,
    bool updateFilenamesFlag,
  ) {
    return __objc_msgSend_909(
      obj,
      sel,
      path,
      atomicFlag,
      updateFilenamesFlag,
    );
  }

  late final __objc_msgSend_909Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_909 = __objc_msgSend_909Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool, bool)>();

  late final _sel_addFileWithPath_1 = _registerName1("addFileWithPath:");
  late final _sel_addSymbolicLinkWithDestination_preferredFilename_1 =
      _registerName1("addSymbolicLinkWithDestination:preferredFilename:");
  late final _sel_symbolicLinkDestination1 =
      _registerName1("symbolicLinkDestination");
  late final _class_NSURLSession1 = _getClass1("NSURLSession");
  late final _sel_sharedSession1 = _registerName1("sharedSession");
  ffi.Pointer<ObjCObject> _objc_msgSend_910(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_910(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_910Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_910 = __objc_msgSend_910Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _class_NSURLSessionConfiguration1 =
      _getClass1("NSURLSessionConfiguration");
  late final _sel_defaultSessionConfiguration1 =
      _registerName1("defaultSessionConfiguration");
  ffi.Pointer<ObjCObject> _objc_msgSend_911(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_911(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_911Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_911 = __objc_msgSend_911Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_ephemeralSessionConfiguration1 =
      _registerName1("ephemeralSessionConfiguration");
  late final _sel_backgroundSessionConfigurationWithIdentifier_1 =
      _registerName1("backgroundSessionConfigurationWithIdentifier:");
  ffi.Pointer<ObjCObject> _objc_msgSend_912(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> identifier,
  ) {
    return __objc_msgSend_912(
      obj,
      sel,
      identifier,
    );
  }

  late final __objc_msgSend_912Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_912 = __objc_msgSend_912Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_identifier1 = _registerName1("identifier");
  late final _sel_requestCachePolicy1 = _registerName1("requestCachePolicy");
  late final _sel_setRequestCachePolicy_1 =
      _registerName1("setRequestCachePolicy:");
  late final _sel_timeoutIntervalForRequest1 =
      _registerName1("timeoutIntervalForRequest");
  late final _sel_setTimeoutIntervalForRequest_1 =
      _registerName1("setTimeoutIntervalForRequest:");
  late final _sel_timeoutIntervalForResource1 =
      _registerName1("timeoutIntervalForResource");
  late final _sel_setTimeoutIntervalForResource_1 =
      _registerName1("setTimeoutIntervalForResource:");
  late final _sel_waitsForConnectivity1 =
      _registerName1("waitsForConnectivity");
  late final _sel_setWaitsForConnectivity_1 =
      _registerName1("setWaitsForConnectivity:");
  late final _sel_isDiscretionary1 = _registerName1("isDiscretionary");
  late final _sel_setDiscretionary_1 = _registerName1("setDiscretionary:");
  late final _sel_sharedContainerIdentifier1 =
      _registerName1("sharedContainerIdentifier");
  late final _sel_setSharedContainerIdentifier_1 =
      _registerName1("setSharedContainerIdentifier:");
  late final _sel_sessionSendsLaunchEvents1 =
      _registerName1("sessionSendsLaunchEvents");
  late final _sel_setSessionSendsLaunchEvents_1 =
      _registerName1("setSessionSendsLaunchEvents:");
  late final _sel_connectionProxyDictionary1 =
      _registerName1("connectionProxyDictionary");
  late final _sel_setConnectionProxyDictionary_1 =
      _registerName1("setConnectionProxyDictionary:");
  late final _sel_TLSMinimumSupportedProtocol1 =
      _registerName1("TLSMinimumSupportedProtocol");
  int _objc_msgSend_913(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_913(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_913Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_913 = __objc_msgSend_913Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setTLSMinimumSupportedProtocol_1 =
      _registerName1("setTLSMinimumSupportedProtocol:");
  void _objc_msgSend_914(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_914(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_914Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_914 = __objc_msgSend_914Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_TLSMaximumSupportedProtocol1 =
      _registerName1("TLSMaximumSupportedProtocol");
  late final _sel_setTLSMaximumSupportedProtocol_1 =
      _registerName1("setTLSMaximumSupportedProtocol:");
  late final _sel_TLSMinimumSupportedProtocolVersion1 =
      _registerName1("TLSMinimumSupportedProtocolVersion");
  int _objc_msgSend_915(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_915(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_915Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_915 = __objc_msgSend_915Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setTLSMinimumSupportedProtocolVersion_1 =
      _registerName1("setTLSMinimumSupportedProtocolVersion:");
  void _objc_msgSend_916(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_916(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_916Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_916 = __objc_msgSend_916Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_TLSMaximumSupportedProtocolVersion1 =
      _registerName1("TLSMaximumSupportedProtocolVersion");
  late final _sel_setTLSMaximumSupportedProtocolVersion_1 =
      _registerName1("setTLSMaximumSupportedProtocolVersion:");
  late final _sel_HTTPShouldSetCookies1 =
      _registerName1("HTTPShouldSetCookies");
  late final _sel_setHTTPShouldSetCookies_1 =
      _registerName1("setHTTPShouldSetCookies:");
  late final _sel_HTTPCookieAcceptPolicy1 =
      _registerName1("HTTPCookieAcceptPolicy");
  late final _sel_setHTTPCookieAcceptPolicy_1 =
      _registerName1("setHTTPCookieAcceptPolicy:");
  late final _sel_HTTPAdditionalHeaders1 =
      _registerName1("HTTPAdditionalHeaders");
  late final _sel_setHTTPAdditionalHeaders_1 =
      _registerName1("setHTTPAdditionalHeaders:");
  late final _sel_HTTPMaximumConnectionsPerHost1 =
      _registerName1("HTTPMaximumConnectionsPerHost");
  late final _sel_setHTTPMaximumConnectionsPerHost_1 =
      _registerName1("setHTTPMaximumConnectionsPerHost:");
  late final _sel_HTTPCookieStorage1 = _registerName1("HTTPCookieStorage");
  late final _sel_setHTTPCookieStorage_1 =
      _registerName1("setHTTPCookieStorage:");
  void _objc_msgSend_917(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_917(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_917Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_917 = __objc_msgSend_917Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_URLCredentialStorage1 =
      _registerName1("URLCredentialStorage");
  late final _sel_setURLCredentialStorage_1 =
      _registerName1("setURLCredentialStorage:");
  void _objc_msgSend_918(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_918(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_918Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_918 = __objc_msgSend_918Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_URLCache1 = _registerName1("URLCache");
  late final _sel_setURLCache_1 = _registerName1("setURLCache:");
  late final _sel_shouldUseExtendedBackgroundIdleMode1 =
      _registerName1("shouldUseExtendedBackgroundIdleMode");
  late final _sel_setShouldUseExtendedBackgroundIdleMode_1 =
      _registerName1("setShouldUseExtendedBackgroundIdleMode:");
  late final _sel_protocolClasses1 = _registerName1("protocolClasses");
  late final _sel_setProtocolClasses_1 = _registerName1("setProtocolClasses:");
  late final _sel_multipathServiceType1 =
      _registerName1("multipathServiceType");
  int _objc_msgSend_919(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_919(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_919Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_919 = __objc_msgSend_919Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setMultipathServiceType_1 =
      _registerName1("setMultipathServiceType:");
  void _objc_msgSend_920(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_920(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_920Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_920 = __objc_msgSend_920Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_backgroundSessionConfiguration_1 =
      _registerName1("backgroundSessionConfiguration:");
  late final _sel_sessionWithConfiguration_1 =
      _registerName1("sessionWithConfiguration:");
  ffi.Pointer<ObjCObject> _objc_msgSend_921(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> configuration,
  ) {
    return __objc_msgSend_921(
      obj,
      sel,
      configuration,
    );
  }

  late final __objc_msgSend_921Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_921 = __objc_msgSend_921Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_sessionWithConfiguration_delegate_delegateQueue_1 =
      _registerName1("sessionWithConfiguration:delegate:delegateQueue:");
  ffi.Pointer<ObjCObject> _objc_msgSend_922(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> configuration,
    ffi.Pointer<ObjCObject> delegate,
    ffi.Pointer<ObjCObject> queue,
  ) {
    return __objc_msgSend_922(
      obj,
      sel,
      configuration,
      delegate,
      queue,
    );
  }

  late final __objc_msgSend_922Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_922 = __objc_msgSend_922Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_delegateQueue1 = _registerName1("delegateQueue");
  late final _sel_configuration1 = _registerName1("configuration");
  late final _sel_sessionDescription1 = _registerName1("sessionDescription");
  late final _sel_setSessionDescription_1 =
      _registerName1("setSessionDescription:");
  late final _sel_finishTasksAndInvalidate1 =
      _registerName1("finishTasksAndInvalidate");
  late final _sel_invalidateAndCancel1 = _registerName1("invalidateAndCancel");
  late final _sel_resetWithCompletionHandler_1 =
      _registerName1("resetWithCompletionHandler:");
  late final _sel_flushWithCompletionHandler_1 =
      _registerName1("flushWithCompletionHandler:");
  late final _sel_getTasksWithCompletionHandler_1 =
      _registerName1("getTasksWithCompletionHandler:");
  void _objc_msgSend_923(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_923(
      obj,
      sel,
      completionHandler,
    );
  }

  late final __objc_msgSend_923Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_923 = __objc_msgSend_923Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_getAllTasksWithCompletionHandler_1 =
      _registerName1("getAllTasksWithCompletionHandler:");
  void _objc_msgSend_924(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_924(
      obj,
      sel,
      completionHandler,
    );
  }

  late final __objc_msgSend_924Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_924 = __objc_msgSend_924Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_dataTaskWithRequest_1 =
      _registerName1("dataTaskWithRequest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_925(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_925(
      obj,
      sel,
      request,
    );
  }

  late final __objc_msgSend_925Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_925 = __objc_msgSend_925Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_dataTaskWithURL_1 = _registerName1("dataTaskWithURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_926(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
  ) {
    return __objc_msgSend_926(
      obj,
      sel,
      url,
    );
  }

  late final __objc_msgSend_926Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_926 = __objc_msgSend_926Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _class_NSURLSessionUploadTask1 =
      _getClass1("NSURLSessionUploadTask");
  late final _sel_uploadTaskWithRequest_fromFile_1 =
      _registerName1("uploadTaskWithRequest:fromFile:");
  ffi.Pointer<ObjCObject> _objc_msgSend_927(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<ObjCObject> fileURL,
  ) {
    return __objc_msgSend_927(
      obj,
      sel,
      request,
      fileURL,
    );
  }

  late final __objc_msgSend_927Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_927 = __objc_msgSend_927Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_uploadTaskWithRequest_fromData_1 =
      _registerName1("uploadTaskWithRequest:fromData:");
  ffi.Pointer<ObjCObject> _objc_msgSend_928(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<ObjCObject> bodyData,
  ) {
    return __objc_msgSend_928(
      obj,
      sel,
      request,
      bodyData,
    );
  }

  late final __objc_msgSend_928Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_928 = __objc_msgSend_928Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_uploadTaskWithStreamedRequest_1 =
      _registerName1("uploadTaskWithStreamedRequest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_929(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_929(
      obj,
      sel,
      request,
    );
  }

  late final __objc_msgSend_929Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_929 = __objc_msgSend_929Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _class_NSURLSessionDownloadTask1 =
      _getClass1("NSURLSessionDownloadTask");
  late final _sel_cancelByProducingResumeData_1 =
      _registerName1("cancelByProducingResumeData:");
  void _objc_msgSend_930(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_930(
      obj,
      sel,
      completionHandler,
    );
  }

  late final __objc_msgSend_930Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_930 = __objc_msgSend_930Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_downloadTaskWithRequest_1 =
      _registerName1("downloadTaskWithRequest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_931(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_931(
      obj,
      sel,
      request,
    );
  }

  late final __objc_msgSend_931Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_931 = __objc_msgSend_931Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_downloadTaskWithURL_1 =
      _registerName1("downloadTaskWithURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_932(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
  ) {
    return __objc_msgSend_932(
      obj,
      sel,
      url,
    );
  }

  late final __objc_msgSend_932Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_932 = __objc_msgSend_932Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_downloadTaskWithResumeData_1 =
      _registerName1("downloadTaskWithResumeData:");
  ffi.Pointer<ObjCObject> _objc_msgSend_933(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> resumeData,
  ) {
    return __objc_msgSend_933(
      obj,
      sel,
      resumeData,
    );
  }

  late final __objc_msgSend_933Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_933 = __objc_msgSend_933Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _class_NSURLSessionStreamTask1 =
      _getClass1("NSURLSessionStreamTask");
  late final _sel_readDataOfMinLength_maxLength_timeout_completionHandler_1 =
      _registerName1(
          "readDataOfMinLength:maxLength:timeout:completionHandler:");
  void _objc_msgSend_934(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int minBytes,
    int maxBytes,
    double timeout,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_934(
      obj,
      sel,
      minBytes,
      maxBytes,
      timeout,
      completionHandler,
    );
  }

  late final __objc_msgSend_934Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSUInteger,
              NSUInteger,
              NSTimeInterval,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_934 = __objc_msgSend_934Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int, int,
          double, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_writeData_timeout_completionHandler_1 =
      _registerName1("writeData:timeout:completionHandler:");
  void _objc_msgSend_935(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
    double timeout,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_935(
      obj,
      sel,
      data,
      timeout,
      completionHandler,
    );
  }

  late final __objc_msgSend_935Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSTimeInterval,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_935 = __objc_msgSend_935Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, double, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_captureStreams1 = _registerName1("captureStreams");
  late final _sel_closeWrite1 = _registerName1("closeWrite");
  late final _sel_closeRead1 = _registerName1("closeRead");
  late final _sel_startSecureConnection1 =
      _registerName1("startSecureConnection");
  late final _sel_stopSecureConnection1 =
      _registerName1("stopSecureConnection");
  late final _sel_streamTaskWithHostName_port_1 =
      _registerName1("streamTaskWithHostName:port:");
  ffi.Pointer<ObjCObject> _objc_msgSend_936(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> hostname,
    int port,
  ) {
    return __objc_msgSend_936(
      obj,
      sel,
      hostname,
      port,
    );
  }

  late final __objc_msgSend_936Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              NSInteger)>>('objc_msgSend');
  late final __objc_msgSend_936 = __objc_msgSend_936Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>, int)>();

  late final _class_NSNetService1 = _getClass1("NSNetService");
  late final _sel_initWithDomain_type_name_port_1 =
      _registerName1("initWithDomain:type:name:port:");
  instancetype _objc_msgSend_937(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> domain,
    ffi.Pointer<ObjCObject> type,
    ffi.Pointer<ObjCObject> name,
    int port,
  ) {
    return __objc_msgSend_937(
      obj,
      sel,
      domain,
      type,
      name,
      port,
    );
  }

  late final __objc_msgSend_937Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Int)>>('objc_msgSend');
  late final __objc_msgSend_937 = __objc_msgSend_937Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          int)>();

  late final _sel_initWithDomain_type_name_1 =
      _registerName1("initWithDomain:type:name:");
  late final _sel_includesPeerToPeer1 = _registerName1("includesPeerToPeer");
  late final _sel_setIncludesPeerToPeer_1 =
      _registerName1("setIncludesPeerToPeer:");
  late final _sel_type1 = _registerName1("type");
  late final _sel_publish1 = _registerName1("publish");
  late final _sel_publishWithOptions_1 = _registerName1("publishWithOptions:");
  void _objc_msgSend_938(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
  ) {
    return __objc_msgSend_938(
      obj,
      sel,
      options,
    );
  }

  late final __objc_msgSend_938Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_938 = __objc_msgSend_938Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_resolve1 = _registerName1("resolve");
  late final _sel_stop1 = _registerName1("stop");
  late final _sel_dictionaryFromTXTRecordData_1 =
      _registerName1("dictionaryFromTXTRecordData:");
  ffi.Pointer<ObjCObject> _objc_msgSend_939(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> txtData,
  ) {
    return __objc_msgSend_939(
      obj,
      sel,
      txtData,
    );
  }

  late final __objc_msgSend_939Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_939 = __objc_msgSend_939Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_dataFromTXTRecordDictionary_1 =
      _registerName1("dataFromTXTRecordDictionary:");
  ffi.Pointer<ObjCObject> _objc_msgSend_940(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> txtDictionary,
  ) {
    return __objc_msgSend_940(
      obj,
      sel,
      txtDictionary,
    );
  }

  late final __objc_msgSend_940Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_940 = __objc_msgSend_940Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_resolveWithTimeout_1 = _registerName1("resolveWithTimeout:");
  late final _sel_getInputStream_outputStream_1 =
      _registerName1("getInputStream:outputStream:");
  bool _objc_msgSend_941(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream,
  ) {
    return __objc_msgSend_941(
      obj,
      sel,
      inputStream,
      outputStream,
    );
  }

  late final __objc_msgSend_941Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_941 = __objc_msgSend_941Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_setTXTRecordData_1 = _registerName1("setTXTRecordData:");
  late final _sel_TXTRecordData1 = _registerName1("TXTRecordData");
  late final _sel_startMonitoring1 = _registerName1("startMonitoring");
  late final _sel_stopMonitoring1 = _registerName1("stopMonitoring");
  late final _sel_streamTaskWithNetService_1 =
      _registerName1("streamTaskWithNetService:");
  ffi.Pointer<ObjCObject> _objc_msgSend_942(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> service,
  ) {
    return __objc_msgSend_942(
      obj,
      sel,
      service,
    );
  }

  late final __objc_msgSend_942Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_942 = __objc_msgSend_942Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _class_NSURLSessionWebSocketTask1 =
      _getClass1("NSURLSessionWebSocketTask");
  late final _class_NSURLSessionWebSocketMessage1 =
      _getClass1("NSURLSessionWebSocketMessage");
  int _objc_msgSend_943(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_943(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_943Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_943 = __objc_msgSend_943Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_sendMessage_completionHandler_1 =
      _registerName1("sendMessage:completionHandler:");
  void _objc_msgSend_944(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> message,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_944(
      obj,
      sel,
      message,
      completionHandler,
    );
  }

  late final __objc_msgSend_944Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_944 = __objc_msgSend_944Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<_ObjCBlock>)>();

  late final _sel_receiveMessageWithCompletionHandler_1 =
      _registerName1("receiveMessageWithCompletionHandler:");
  void _objc_msgSend_945(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_945(
      obj,
      sel,
      completionHandler,
    );
  }

  late final __objc_msgSend_945Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_945 = __objc_msgSend_945Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_sendPingWithPongReceiveHandler_1 =
      _registerName1("sendPingWithPongReceiveHandler:");
  void _objc_msgSend_946(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> pongReceiveHandler,
  ) {
    return __objc_msgSend_946(
      obj,
      sel,
      pongReceiveHandler,
    );
  }

  late final __objc_msgSend_946Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_946 = __objc_msgSend_946Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_cancelWithCloseCode_reason_1 =
      _registerName1("cancelWithCloseCode:reason:");
  void _objc_msgSend_947(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int closeCode,
    ffi.Pointer<ObjCObject> reason,
  ) {
    return __objc_msgSend_947(
      obj,
      sel,
      closeCode,
      reason,
    );
  }

  late final __objc_msgSend_947Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_947 = __objc_msgSend_947Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_maximumMessageSize1 = _registerName1("maximumMessageSize");
  late final _sel_setMaximumMessageSize_1 =
      _registerName1("setMaximumMessageSize:");
  late final _sel_closeCode1 = _registerName1("closeCode");
  int _objc_msgSend_948(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_948(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_948Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_948 = __objc_msgSend_948Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_closeReason1 = _registerName1("closeReason");
  late final _sel_webSocketTaskWithURL_1 =
      _registerName1("webSocketTaskWithURL:");
  ffi.Pointer<ObjCObject> _objc_msgSend_949(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
  ) {
    return __objc_msgSend_949(
      obj,
      sel,
      url,
    );
  }

  late final __objc_msgSend_949Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_949 = __objc_msgSend_949Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_webSocketTaskWithURL_protocols_1 =
      _registerName1("webSocketTaskWithURL:protocols:");
  ffi.Pointer<ObjCObject> _objc_msgSend_950(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<ObjCObject> protocols,
  ) {
    return __objc_msgSend_950(
      obj,
      sel,
      url,
      protocols,
    );
  }

  late final __objc_msgSend_950Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_950 = __objc_msgSend_950Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_webSocketTaskWithRequest_1 =
      _registerName1("webSocketTaskWithRequest:");
  ffi.Pointer<ObjCObject> _objc_msgSend_951(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
  ) {
    return __objc_msgSend_951(
      obj,
      sel,
      request,
    );
  }

  late final __objc_msgSend_951Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_951 = __objc_msgSend_951Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_dataTaskWithRequest_completionHandler_1 =
      _registerName1("dataTaskWithRequest:completionHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_952(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_952(
      obj,
      sel,
      request,
      completionHandler,
    );
  }

  late final __objc_msgSend_952Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_952 = __objc_msgSend_952Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_dataTaskWithURL_completionHandler_1 =
      _registerName1("dataTaskWithURL:completionHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_953(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_953(
      obj,
      sel,
      url,
      completionHandler,
    );
  }

  late final __objc_msgSend_953Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_953 = __objc_msgSend_953Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_uploadTaskWithRequest_fromFile_completionHandler_1 =
      _registerName1("uploadTaskWithRequest:fromFile:completionHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_954(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<ObjCObject> fileURL,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_954(
      obj,
      sel,
      request,
      fileURL,
      completionHandler,
    );
  }

  late final __objc_msgSend_954Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_954 = __objc_msgSend_954Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_uploadTaskWithRequest_fromData_completionHandler_1 =
      _registerName1("uploadTaskWithRequest:fromData:completionHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_955(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<ObjCObject> bodyData,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_955(
      obj,
      sel,
      request,
      bodyData,
      completionHandler,
    );
  }

  late final __objc_msgSend_955Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_955 = __objc_msgSend_955Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_downloadTaskWithRequest_completionHandler_1 =
      _registerName1("downloadTaskWithRequest:completionHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_956(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> request,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_956(
      obj,
      sel,
      request,
      completionHandler,
    );
  }

  late final __objc_msgSend_956Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_956 = __objc_msgSend_956Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_downloadTaskWithURL_completionHandler_1 =
      _registerName1("downloadTaskWithURL:completionHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_957(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_957(
      obj,
      sel,
      url,
      completionHandler,
    );
  }

  late final __objc_msgSend_957Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_957 = __objc_msgSend_957Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_downloadTaskWithResumeData_completionHandler_1 =
      _registerName1("downloadTaskWithResumeData:completionHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_958(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> resumeData,
    ffi.Pointer<_ObjCBlock> completionHandler,
  ) {
    return __objc_msgSend_958(
      obj,
      sel,
      resumeData,
      completionHandler,
    );
  }

  late final __objc_msgSend_958Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_958 = __objc_msgSend_958Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _class_NSProtocolChecker1 = _getClass1("NSProtocolChecker");
  ffi.Pointer<ObjCObject> _objc_msgSend_959(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_959(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_959Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_959 = __objc_msgSend_959Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_protocolCheckerWithTarget_protocol_1 =
      _registerName1("protocolCheckerWithTarget:protocol:");
  instancetype _objc_msgSend_960(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> anObject,
    ffi.Pointer<ObjCObject> aProtocol,
  ) {
    return __objc_msgSend_960(
      obj,
      sel,
      anObject,
      aProtocol,
    );
  }

  late final __objc_msgSend_960Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_960 = __objc_msgSend_960Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithTarget_protocol_1 =
      _registerName1("initWithTarget:protocol:");
  late final _class_NSTask1 = _getClass1("NSTask");
  late final _sel_setExecutableURL_1 = _registerName1("setExecutableURL:");
  late final _sel_setEnvironment_1 = _registerName1("setEnvironment:");
  late final _sel_currentDirectoryURL1 = _registerName1("currentDirectoryURL");
  late final _sel_setCurrentDirectoryURL_1 =
      _registerName1("setCurrentDirectoryURL:");
  late final _sel_standardInput1 = _registerName1("standardInput");
  late final _sel_setStandardInput_1 = _registerName1("setStandardInput:");
  late final _sel_standardOutput1 = _registerName1("standardOutput");
  late final _sel_setStandardOutput_1 = _registerName1("setStandardOutput:");
  late final _sel_standardError1 = _registerName1("standardError");
  late final _sel_setStandardError_1 = _registerName1("setStandardError:");
  late final _sel_launchAndReturnError_1 =
      _registerName1("launchAndReturnError:");
  late final _sel_interrupt1 = _registerName1("interrupt");
  late final _sel_terminate1 = _registerName1("terminate");
  late final _sel_isRunning1 = _registerName1("isRunning");
  late final _sel_terminationStatus1 = _registerName1("terminationStatus");
  late final _sel_terminationReason1 = _registerName1("terminationReason");
  int _objc_msgSend_961(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_961(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_961Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_961 = __objc_msgSend_961Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_terminationHandler1 = _registerName1("terminationHandler");
  ffi.Pointer<_ObjCBlock> _objc_msgSend_962(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_962(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_962Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<_ObjCBlock> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_962 = __objc_msgSend_962Ptr.asFunction<
      ffi.Pointer<_ObjCBlock> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setTerminationHandler_1 =
      _registerName1("setTerminationHandler:");
  void _objc_msgSend_963(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> value,
  ) {
    return __objc_msgSend_963(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_963Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_963 = __objc_msgSend_963Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_launchedTaskWithExecutableURL_arguments_error_terminationHandler_1 =
      _registerName1(
          "launchedTaskWithExecutableURL:arguments:error:terminationHandler:");
  ffi.Pointer<ObjCObject> _objc_msgSend_964(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<ObjCObject> arguments,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
    ffi.Pointer<_ObjCBlock> terminationHandler,
  ) {
    return __objc_msgSend_964(
      obj,
      sel,
      url,
      arguments,
      error,
      terminationHandler,
    );
  }

  late final __objc_msgSend_964Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_964 = __objc_msgSend_964Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_waitUntilExit1 = _registerName1("waitUntilExit");
  late final _sel_launchPath1 = _registerName1("launchPath");
  late final _sel_setLaunchPath_1 = _registerName1("setLaunchPath:");
  late final _sel_setCurrentDirectoryPath_1 =
      _registerName1("setCurrentDirectoryPath:");
  late final _sel_launch1 = _registerName1("launch");
  late final _sel_launchedTaskWithLaunchPath_arguments_1 =
      _registerName1("launchedTaskWithLaunchPath:arguments:");
  ffi.Pointer<ObjCObject> _objc_msgSend_965(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> path,
    ffi.Pointer<ObjCObject> arguments,
  ) {
    return __objc_msgSend_965(
      obj,
      sel,
      path,
      arguments,
    );
  }

  late final __objc_msgSend_965Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_965 = __objc_msgSend_965Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _class_NSXMLElement1 = _getClass1("NSXMLElement");
  late final _class_NSXMLNode1 = _getClass1("NSXMLNode");
  late final _sel_initWithKind_1 = _registerName1("initWithKind:");
  instancetype _objc_msgSend_966(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int kind,
  ) {
    return __objc_msgSend_966(
      obj,
      sel,
      kind,
    );
  }

  late final __objc_msgSend_966Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_966 = __objc_msgSend_966Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithKind_options_1 =
      _registerName1("initWithKind:options:");
  instancetype _objc_msgSend_967(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int kind,
    int options,
  ) {
    return __objc_msgSend_967(
      obj,
      sel,
      kind,
      options,
    );
  }

  late final __objc_msgSend_967Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_967 = __objc_msgSend_967Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int, int)>();

  late final _sel_document1 = _registerName1("document");
  late final _sel_documentWithRootElement_1 =
      _registerName1("documentWithRootElement:");
  ffi.Pointer<ObjCObject> _objc_msgSend_968(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> element,
  ) {
    return __objc_msgSend_968(
      obj,
      sel,
      element,
    );
  }

  late final __objc_msgSend_968Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_968 = __objc_msgSend_968Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_elementWithName_1 = _registerName1("elementWithName:");
  late final _sel_elementWithName_URI_1 =
      _registerName1("elementWithName:URI:");
  late final _sel_elementWithName_stringValue_1 =
      _registerName1("elementWithName:stringValue:");
  late final _sel_elementWithName_children_attributes_1 =
      _registerName1("elementWithName:children:attributes:");
  ffi.Pointer<ObjCObject> _objc_msgSend_969(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> children,
    ffi.Pointer<ObjCObject> attributes,
  ) {
    return __objc_msgSend_969(
      obj,
      sel,
      name,
      children,
      attributes,
    );
  }

  late final __objc_msgSend_969Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_969 = __objc_msgSend_969Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_attributeWithName_stringValue_1 =
      _registerName1("attributeWithName:stringValue:");
  late final _sel_attributeWithName_URI_stringValue_1 =
      _registerName1("attributeWithName:URI:stringValue:");
  late final _sel_namespaceWithName_stringValue_1 =
      _registerName1("namespaceWithName:stringValue:");
  late final _sel_processingInstructionWithName_stringValue_1 =
      _registerName1("processingInstructionWithName:stringValue:");
  late final _sel_commentWithStringValue_1 =
      _registerName1("commentWithStringValue:");
  late final _sel_textWithStringValue_1 =
      _registerName1("textWithStringValue:");
  late final _sel_DTDNodeWithXMLString_1 =
      _registerName1("DTDNodeWithXMLString:");
  late final _sel_kind1 = _registerName1("kind");
  int _objc_msgSend_970(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_970(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_970Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_970 = __objc_msgSend_970Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_objectValue1 = _registerName1("objectValue");
  late final _sel_setObjectValue_1 = _registerName1("setObjectValue:");
  late final _sel_setStringValue_1 = _registerName1("setStringValue:");
  late final _sel_setStringValue_resolvingEntities_1 =
      _registerName1("setStringValue:resolvingEntities:");
  void _objc_msgSend_971(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    bool resolve,
  ) {
    return __objc_msgSend_971(
      obj,
      sel,
      string,
      resolve,
    );
  }

  late final __objc_msgSend_971Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_971 = __objc_msgSend_971Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, bool)>();

  late final _sel_index1 = _registerName1("index");
  late final _sel_level1 = _registerName1("level");
  late final _class_NSXMLDocument1 = _getClass1("NSXMLDocument");
  late final _sel_initWithXMLString_options_error_1 =
      _registerName1("initWithXMLString:options:error:");
  instancetype _objc_msgSend_972(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> string,
    int mask,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_972(
      obj,
      sel,
      string,
      mask,
      error,
    );
  }

  late final __objc_msgSend_972Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_972 = __objc_msgSend_972Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  instancetype _objc_msgSend_973(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    int mask,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_973(
      obj,
      sel,
      url,
      mask,
      error,
    );
  }

  late final __objc_msgSend_973Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_973 = __objc_msgSend_973Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_initWithData_options_error_1 =
      _registerName1("initWithData:options:error:");
  instancetype _objc_msgSend_974(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
    int mask,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_974(
      obj,
      sel,
      data,
      mask,
      error,
    );
  }

  late final __objc_msgSend_974Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_974 = __objc_msgSend_974Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_initWithRootElement_1 =
      _registerName1("initWithRootElement:");
  late final _sel_replacementClassForClass_1 =
      _registerName1("replacementClassForClass:");
  late final _sel_characterEncoding1 = _registerName1("characterEncoding");
  late final _sel_setCharacterEncoding_1 =
      _registerName1("setCharacterEncoding:");
  late final _sel_isStandalone1 = _registerName1("isStandalone");
  late final _sel_setStandalone_1 = _registerName1("setStandalone:");
  late final _sel_documentContentKind1 = _registerName1("documentContentKind");
  int _objc_msgSend_975(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_975(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_975Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_975 = __objc_msgSend_975Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setDocumentContentKind_1 =
      _registerName1("setDocumentContentKind:");
  void _objc_msgSend_976(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_976(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_976Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_976 = __objc_msgSend_976Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_setMIMEType_1 = _registerName1("setMIMEType:");
  late final _class_NSXMLDTD1 = _getClass1("NSXMLDTD");
  late final _sel_setPublicID_1 = _registerName1("setPublicID:");
  late final _sel_setSystemID_1 = _registerName1("setSystemID:");
  late final _sel_insertChild_atIndex_1 =
      _registerName1("insertChild:atIndex:");
  void _objc_msgSend_977(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> child,
    int index,
  ) {
    return __objc_msgSend_977(
      obj,
      sel,
      child,
      index,
    );
  }

  late final __objc_msgSend_977Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_977 = __objc_msgSend_977Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_insertChildren_atIndex_1 =
      _registerName1("insertChildren:atIndex:");
  void _objc_msgSend_978(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> children,
    int index,
  ) {
    return __objc_msgSend_978(
      obj,
      sel,
      children,
      index,
    );
  }

  late final __objc_msgSend_978Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_978 = __objc_msgSend_978Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, int)>();

  late final _sel_removeChildAtIndex_1 = _registerName1("removeChildAtIndex:");
  late final _sel_setChildren_1 = _registerName1("setChildren:");
  late final _sel_addChild_1 = _registerName1("addChild:");
  void _objc_msgSend_979(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> child,
  ) {
    return __objc_msgSend_979(
      obj,
      sel,
      child,
    );
  }

  late final __objc_msgSend_979Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_979 = __objc_msgSend_979Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_replaceChildAtIndex_withNode_1 =
      _registerName1("replaceChildAtIndex:withNode:");
  void _objc_msgSend_980(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
    ffi.Pointer<ObjCObject> node,
  ) {
    return __objc_msgSend_980(
      obj,
      sel,
      index,
      node,
    );
  }

  late final __objc_msgSend_980Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_980 = __objc_msgSend_980Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ObjCObject>)>();

  late final _class_NSXMLDTDNode1 = _getClass1("NSXMLDTDNode");
  late final _sel_initWithXMLString_1 = _registerName1("initWithXMLString:");
  late final _sel_DTDKind1 = _registerName1("DTDKind");
  int _objc_msgSend_981(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_981(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_981Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_981 = __objc_msgSend_981Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setDTDKind_1 = _registerName1("setDTDKind:");
  void _objc_msgSend_982(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int value,
  ) {
    return __objc_msgSend_982(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_982Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_982 = __objc_msgSend_982Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_isExternal1 = _registerName1("isExternal");
  late final _sel_notationName1 = _registerName1("notationName");
  late final _sel_setNotationName_1 = _registerName1("setNotationName:");
  late final _sel_localNameForName_1 = _registerName1("localNameForName:");
  late final _sel_prefixForName_1 = _registerName1("prefixForName:");
  late final _sel_predefinedNamespaceForPrefix_1 =
      _registerName1("predefinedNamespaceForPrefix:");
  ffi.Pointer<ObjCObject> _objc_msgSend_983(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
  ) {
    return __objc_msgSend_983(
      obj,
      sel,
      name,
    );
  }

  late final __objc_msgSend_983Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_983 = __objc_msgSend_983Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_entityDeclarationForName_1 =
      _registerName1("entityDeclarationForName:");
  ffi.Pointer<ObjCObject> _objc_msgSend_984(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
  ) {
    return __objc_msgSend_984(
      obj,
      sel,
      name,
    );
  }

  late final __objc_msgSend_984Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_984 = __objc_msgSend_984Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>, ffi.Pointer<ObjCObject>)>();

  late final _sel_notationDeclarationForName_1 =
      _registerName1("notationDeclarationForName:");
  late final _sel_elementDeclarationForName_1 =
      _registerName1("elementDeclarationForName:");
  late final _sel_attributeDeclarationForName_elementName_1 =
      _registerName1("attributeDeclarationForName:elementName:");
  ffi.Pointer<ObjCObject> _objc_msgSend_985(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> name,
    ffi.Pointer<ObjCObject> elementName,
  ) {
    return __objc_msgSend_985(
      obj,
      sel,
      name,
      elementName,
    );
  }

  late final __objc_msgSend_985Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_985 = __objc_msgSend_985Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_predefinedEntityDeclarationForName_1 =
      _registerName1("predefinedEntityDeclarationForName:");
  late final _sel_DTD1 = _registerName1("DTD");
  ffi.Pointer<ObjCObject> _objc_msgSend_986(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_986(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_986Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_986 = __objc_msgSend_986Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setDTD_1 = _registerName1("setDTD:");
  void _objc_msgSend_987(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> value,
  ) {
    return __objc_msgSend_987(
      obj,
      sel,
      value,
    );
  }

  late final __objc_msgSend_987Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_987 = __objc_msgSend_987Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_setRootElement_1 = _registerName1("setRootElement:");
  void _objc_msgSend_988(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> root,
  ) {
    return __objc_msgSend_988(
      obj,
      sel,
      root,
    );
  }

  late final __objc_msgSend_988Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_988 = __objc_msgSend_988Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_rootElement1 = _registerName1("rootElement");
  ffi.Pointer<ObjCObject> _objc_msgSend_989(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_989(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_989Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_989 = __objc_msgSend_989Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_XMLData1 = _registerName1("XMLData");
  late final _sel_XMLDataWithOptions_1 = _registerName1("XMLDataWithOptions:");
  ffi.Pointer<ObjCObject> _objc_msgSend_990(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
  ) {
    return __objc_msgSend_990(
      obj,
      sel,
      options,
    );
  }

  late final __objc_msgSend_990Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_990 = __objc_msgSend_990Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_objectByApplyingXSLT_arguments_error_1 =
      _registerName1("objectByApplyingXSLT:arguments:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_991(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> xslt,
    ffi.Pointer<ObjCObject> arguments,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_991(
      obj,
      sel,
      xslt,
      arguments,
      error,
    );
  }

  late final __objc_msgSend_991Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_991 = __objc_msgSend_991Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_objectByApplyingXSLTString_arguments_error_1 =
      _registerName1("objectByApplyingXSLTString:arguments:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_992(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> xslt,
    ffi.Pointer<ObjCObject> arguments,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_992(
      obj,
      sel,
      xslt,
      arguments,
      error,
    );
  }

  late final __objc_msgSend_992Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_992 = __objc_msgSend_992Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_objectByApplyingXSLTAtURL_arguments_error_1 =
      _registerName1("objectByApplyingXSLTAtURL:arguments:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_993(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> xsltURL,
    ffi.Pointer<ObjCObject> argument,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_993(
      obj,
      sel,
      xsltURL,
      argument,
      error,
    );
  }

  late final __objc_msgSend_993Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_993 = __objc_msgSend_993Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_validateAndReturnError_1 =
      _registerName1("validateAndReturnError:");
  late final _sel_rootDocument1 = _registerName1("rootDocument");
  ffi.Pointer<ObjCObject> _objc_msgSend_994(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_994(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_994Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_994 = __objc_msgSend_994Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_parent1 = _registerName1("parent");
  ffi.Pointer<ObjCObject> _objc_msgSend_995(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_995(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_995Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_995 = __objc_msgSend_995Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_childCount1 = _registerName1("childCount");
  late final _sel_children1 = _registerName1("children");
  late final _sel_childAtIndex_1 = _registerName1("childAtIndex:");
  ffi.Pointer<ObjCObject> _objc_msgSend_996(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int index,
  ) {
    return __objc_msgSend_996(
      obj,
      sel,
      index,
    );
  }

  late final __objc_msgSend_996Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_996 = __objc_msgSend_996Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_previousSibling1 = _registerName1("previousSibling");
  late final _sel_nextSibling1 = _registerName1("nextSibling");
  late final _sel_previousNode1 = _registerName1("previousNode");
  late final _sel_nextNode1 = _registerName1("nextNode");
  late final _sel_detach1 = _registerName1("detach");
  late final _sel_XPath1 = _registerName1("XPath");
  late final _sel_localName1 = _registerName1("localName");
  late final _sel_prefix1 = _registerName1("prefix");
  late final _sel_URI1 = _registerName1("URI");
  late final _sel_setURI_1 = _registerName1("setURI:");
  late final _sel_XMLString1 = _registerName1("XMLString");
  late final _sel_XMLStringWithOptions_1 =
      _registerName1("XMLStringWithOptions:");
  ffi.Pointer<ObjCObject> _objc_msgSend_997(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
  ) {
    return __objc_msgSend_997(
      obj,
      sel,
      options,
    );
  }

  late final __objc_msgSend_997Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Int32)>>('objc_msgSend');
  late final __objc_msgSend_997 = __objc_msgSend_997Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_canonicalXMLStringPreservingComments_1 =
      _registerName1("canonicalXMLStringPreservingComments:");
  ffi.Pointer<ObjCObject> _objc_msgSend_998(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool comments,
  ) {
    return __objc_msgSend_998(
      obj,
      sel,
      comments,
    );
  }

  late final __objc_msgSend_998Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>, ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_998 = __objc_msgSend_998Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool)>();

  late final _sel_nodesForXPath_error_1 =
      _registerName1("nodesForXPath:error:");
  late final _sel_objectsForXQuery_constants_error_1 =
      _registerName1("objectsForXQuery:constants:error:");
  ffi.Pointer<ObjCObject> _objc_msgSend_999(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> xquery,
    ffi.Pointer<ObjCObject> constants,
    ffi.Pointer<ffi.Pointer<ObjCObject>> error,
  ) {
    return __objc_msgSend_999(
      obj,
      sel,
      xquery,
      constants,
      error,
    );
  }

  late final __objc_msgSend_999Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_999 = __objc_msgSend_999Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_objectsForXQuery_error_1 =
      _registerName1("objectsForXQuery:error:");
  late final _sel_initWithName_URI_1 = _registerName1("initWithName:URI:");
  late final _sel_initWithName_stringValue_1 =
      _registerName1("initWithName:stringValue:");
  late final _sel_initWithXMLString_error_1 =
      _registerName1("initWithXMLString:error:");
  late final _sel_elementsForName_1 = _registerName1("elementsForName:");
  late final _sel_elementsForLocalName_URI_1 =
      _registerName1("elementsForLocalName:URI:");
  late final _sel_addAttribute_1 = _registerName1("addAttribute:");
  late final _sel_removeAttributeForName_1 =
      _registerName1("removeAttributeForName:");
  late final _sel_attributes1 = _registerName1("attributes");
  late final _sel_setAttributes_1 = _registerName1("setAttributes:");
  late final _sel_setAttributesWithDictionary_1 =
      _registerName1("setAttributesWithDictionary:");
  late final _sel_attributeForName_1 = _registerName1("attributeForName:");
  late final _sel_attributeForLocalName_URI_1 =
      _registerName1("attributeForLocalName:URI:");
  ffi.Pointer<ObjCObject> _objc_msgSend_1000(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> localName,
    ffi.Pointer<ObjCObject> URI,
  ) {
    return __objc_msgSend_1000(
      obj,
      sel,
      localName,
      URI,
    );
  }

  late final __objc_msgSend_1000Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_1000 = __objc_msgSend_1000Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>)>();

  late final _sel_addNamespace_1 = _registerName1("addNamespace:");
  late final _sel_removeNamespaceForPrefix_1 =
      _registerName1("removeNamespaceForPrefix:");
  late final _sel_namespaces1 = _registerName1("namespaces");
  late final _sel_setNamespaces_1 = _registerName1("setNamespaces:");
  late final _sel_namespaceForPrefix_1 = _registerName1("namespaceForPrefix:");
  late final _sel_resolveNamespaceForName_1 =
      _registerName1("resolveNamespaceForName:");
  late final _sel_resolvePrefixForNamespaceURI_1 =
      _registerName1("resolvePrefixForNamespaceURI:");
  late final _sel_normalizeAdjacentTextNodesPreservingCDATA_1 =
      _registerName1("normalizeAdjacentTextNodesPreservingCDATA:");
  late final _sel_setAttributesAsDictionary_1 =
      _registerName1("setAttributesAsDictionary:");
  late final _class_AVAudioSession1 = _getClass1("AVAudioSession");
  late final _sel_sharedInstance1 = _registerName1("sharedInstance");
  ffi.Pointer<ObjCObject> _objc_msgSend_1001(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1001(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1001Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1001 = __objc_msgSend_1001Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_availableCategories1 = _registerName1("availableCategories");
  late final _sel_setCategory_error_1 = _registerName1("setCategory:error:");
  late final _sel_setCategory_withOptions_error_1 =
      _registerName1("setCategory:withOptions:error:");
  bool _objc_msgSend_1002(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    AVAudioSessionCategory category,
    int options,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1002(
      obj,
      sel,
      category,
      options,
      outError,
    );
  }

  late final __objc_msgSend_1002Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              AVAudioSessionCategory,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1002 = __objc_msgSend_1002Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          AVAudioSessionCategory, int, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_setCategory_mode_options_error_1 =
      _registerName1("setCategory:mode:options:error:");
  bool _objc_msgSend_1003(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    AVAudioSessionCategory category,
    AVAudioSessionMode mode,
    int options,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1003(
      obj,
      sel,
      category,
      mode,
      options,
      outError,
    );
  }

  late final __objc_msgSend_1003Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              AVAudioSessionCategory,
              AVAudioSessionMode,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1003 = __objc_msgSend_1003Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          AVAudioSessionCategory,
          AVAudioSessionMode,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_setCategory_mode_routeSharingPolicy_options_error_1 =
      _registerName1("setCategory:mode:routeSharingPolicy:options:error:");
  bool _objc_msgSend_1004(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    AVAudioSessionCategory category,
    AVAudioSessionMode mode,
    int policy,
    int options,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1004(
      obj,
      sel,
      category,
      mode,
      policy,
      options,
      outError,
    );
  }

  late final __objc_msgSend_1004Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              AVAudioSessionCategory,
              AVAudioSessionMode,
              ffi.Int32,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1004 = __objc_msgSend_1004Ptr.asFunction<
      bool Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          AVAudioSessionCategory,
          AVAudioSessionMode,
          int,
          int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_category1 = _registerName1("category");
  late final _sel_categoryOptions1 = _registerName1("categoryOptions");
  int _objc_msgSend_1005(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1005(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1005Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1005 = __objc_msgSend_1005Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_routeSharingPolicy1 = _registerName1("routeSharingPolicy");
  int _objc_msgSend_1006(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1006(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1006Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1006 = __objc_msgSend_1006Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_availableModes1 = _registerName1("availableModes");
  late final _sel_setMode_error_1 = _registerName1("setMode:error:");
  late final _sel_mode1 = _registerName1("mode");
  late final _sel_setAllowHapticsAndSystemSoundsDuringRecording_error_1 =
      _registerName1("setAllowHapticsAndSystemSoundsDuringRecording:error:");
  bool _objc_msgSend_1007(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool inValue,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1007(
      obj,
      sel,
      inValue,
      outError,
    );
  }

  late final __objc_msgSend_1007Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Bool, ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1007 = __objc_msgSend_1007Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_allowHapticsAndSystemSoundsDuringRecording1 =
      _registerName1("allowHapticsAndSystemSoundsDuringRecording");
  late final _sel_recordPermission1 = _registerName1("recordPermission");
  int _objc_msgSend_1008(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1008(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1008Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1008 = __objc_msgSend_1008Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_requestRecordPermission_1 =
      _registerName1("requestRecordPermission:");
  void _objc_msgSend_1009(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<_ObjCBlock> response,
  ) {
    return __objc_msgSend_1009(
      obj,
      sel,
      response,
    );
  }

  late final __objc_msgSend_1009Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_1009 = __objc_msgSend_1009Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_overrideOutputAudioPort_error_1 =
      _registerName1("overrideOutputAudioPort:error:");
  bool _objc_msgSend_1010(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int portOverride,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1010(
      obj,
      sel,
      portOverride,
      outError,
    );
  }

  late final __objc_msgSend_1010Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1010 = __objc_msgSend_1010Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _class_AVAudioSessionPortDescription1 =
      _getClass1("AVAudioSessionPortDescription");
  late final _sel_portType1 = _registerName1("portType");
  late final _sel_portName1 = _registerName1("portName");
  late final _sel_UID1 = _registerName1("UID");
  late final _sel_hasHardwareVoiceCallProcessing1 =
      _registerName1("hasHardwareVoiceCallProcessing");
  late final _sel_isSpatialAudioEnabled1 =
      _registerName1("isSpatialAudioEnabled");
  late final _sel_channels1 = _registerName1("channels");
  late final _sel_dataSources1 = _registerName1("dataSources");
  late final _class_AVAudioSessionDataSourceDescription1 =
      _getClass1("AVAudioSessionDataSourceDescription");
  late final _sel_dataSourceID1 = _registerName1("dataSourceID");
  late final _sel_dataSourceName1 = _registerName1("dataSourceName");
  late final _sel_location1 = _registerName1("location");
  late final _sel_orientation1 = _registerName1("orientation");
  late final _sel_supportedPolarPatterns1 =
      _registerName1("supportedPolarPatterns");
  late final _sel_selectedPolarPattern1 =
      _registerName1("selectedPolarPattern");
  late final _sel_preferredPolarPattern1 =
      _registerName1("preferredPolarPattern");
  late final _sel_setPreferredPolarPattern_error_1 =
      _registerName1("setPreferredPolarPattern:error:");
  late final _sel_selectedDataSource1 = _registerName1("selectedDataSource");
  ffi.Pointer<ObjCObject> _objc_msgSend_1011(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1011(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1011Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1011 = __objc_msgSend_1011Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_preferredDataSource1 = _registerName1("preferredDataSource");
  late final _sel_setPreferredDataSource_error_1 =
      _registerName1("setPreferredDataSource:error:");
  bool _objc_msgSend_1012(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> dataSource,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1012(
      obj,
      sel,
      dataSource,
      outError,
    );
  }

  late final __objc_msgSend_1012Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1012 = __objc_msgSend_1012Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_setPreferredInput_error_1 =
      _registerName1("setPreferredInput:error:");
  bool _objc_msgSend_1013(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> inPort,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1013(
      obj,
      sel,
      inPort,
      outError,
    );
  }

  late final __objc_msgSend_1013Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1013 = __objc_msgSend_1013Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_preferredInput1 = _registerName1("preferredInput");
  ffi.Pointer<ObjCObject> _objc_msgSend_1014(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1014(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1014Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1014 = __objc_msgSend_1014Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setPrefersNoInterruptionsFromSystemAlerts_error_1 =
      _registerName1("setPrefersNoInterruptionsFromSystemAlerts:error:");
  late final _sel_prefersNoInterruptionsFromSystemAlerts1 =
      _registerName1("prefersNoInterruptionsFromSystemAlerts");
  late final _sel_setActive_error_1 = _registerName1("setActive:error:");
  late final _sel_setActive_withOptions_error_1 =
      _registerName1("setActive:withOptions:error:");
  bool _objc_msgSend_1015(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool active,
    int options,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1015(
      obj,
      sel,
      active,
      options,
      outError,
    );
  }

  late final __objc_msgSend_1015Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Bool,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1015 = __objc_msgSend_1015Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool, int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_activateWithOptions_completionHandler_1 =
      _registerName1("activateWithOptions:completionHandler:");
  void _objc_msgSend_1016(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int options,
    ffi.Pointer<_ObjCBlock> handler,
  ) {
    return __objc_msgSend_1016(
      obj,
      sel,
      options,
      handler,
    );
  }

  late final __objc_msgSend_1016Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Int32, ffi.Pointer<_ObjCBlock>)>>('objc_msgSend');
  late final __objc_msgSend_1016 = __objc_msgSend_1016Ptr.asFunction<
      void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<_ObjCBlock>)>();

  late final _sel_setPreferredSampleRate_error_1 =
      _registerName1("setPreferredSampleRate:error:");
  bool _objc_msgSend_1017(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double sampleRate,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1017(
      obj,
      sel,
      sampleRate,
      outError,
    );
  }

  late final __objc_msgSend_1017Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Double,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1017 = __objc_msgSend_1017Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_preferredSampleRate1 = _registerName1("preferredSampleRate");
  late final _sel_setPreferredIOBufferDuration_error_1 =
      _registerName1("setPreferredIOBufferDuration:error:");
  late final _sel_preferredIOBufferDuration1 =
      _registerName1("preferredIOBufferDuration");
  late final _sel_setPreferredInputNumberOfChannels_error_1 =
      _registerName1("setPreferredInputNumberOfChannels:error:");
  bool _objc_msgSend_1018(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int count,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1018(
      obj,
      sel,
      count,
      outError,
    );
  }

  late final __objc_msgSend_1018Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              NSInteger,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1018 = __objc_msgSend_1018Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_preferredInputNumberOfChannels1 =
      _registerName1("preferredInputNumberOfChannels");
  late final _sel_setPreferredOutputNumberOfChannels_error_1 =
      _registerName1("setPreferredOutputNumberOfChannels:error:");
  late final _sel_preferredOutputNumberOfChannels1 =
      _registerName1("preferredOutputNumberOfChannels");
  late final _sel_setPreferredInputOrientation_error_1 =
      _registerName1("setPreferredInputOrientation:error:");
  bool _objc_msgSend_1019(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int orientation,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1019(
      obj,
      sel,
      orientation,
      outError,
    );
  }

  late final __objc_msgSend_1019Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1019 = __objc_msgSend_1019Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_preferredInputOrientation1 =
      _registerName1("preferredInputOrientation");
  int _objc_msgSend_1020(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1020(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1020Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1020 = __objc_msgSend_1020Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_inputOrientation1 = _registerName1("inputOrientation");
  late final _sel_maximumInputNumberOfChannels1 =
      _registerName1("maximumInputNumberOfChannels");
  late final _sel_maximumOutputNumberOfChannels1 =
      _registerName1("maximumOutputNumberOfChannels");
  late final _sel_setInputGain_error_1 = _registerName1("setInputGain:error:");
  bool _objc_msgSend_1021(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double gain,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1021(
      obj,
      sel,
      gain,
      outError,
    );
  }

  late final __objc_msgSend_1021Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Float,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1021 = __objc_msgSend_1021Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_inputGain1 = _registerName1("inputGain");
  late final _sel_isInputGainSettable1 = _registerName1("isInputGainSettable");
  late final _sel_isInputAvailable1 = _registerName1("isInputAvailable");
  late final _sel_inputDataSources1 = _registerName1("inputDataSources");
  late final _sel_inputDataSource1 = _registerName1("inputDataSource");
  late final _sel_setInputDataSource_error_1 =
      _registerName1("setInputDataSource:error:");
  late final _sel_outputDataSources1 = _registerName1("outputDataSources");
  late final _sel_outputDataSource1 = _registerName1("outputDataSource");
  late final _sel_setOutputDataSource_error_1 =
      _registerName1("setOutputDataSource:error:");
  late final _sel_sampleRate1 = _registerName1("sampleRate");
  late final _sel_inputNumberOfChannels1 =
      _registerName1("inputNumberOfChannels");
  late final _sel_outputNumberOfChannels1 =
      _registerName1("outputNumberOfChannels");
  late final _sel_inputLatency1 = _registerName1("inputLatency");
  late final _sel_outputLatency1 = _registerName1("outputLatency");
  late final _sel_IOBufferDuration1 = _registerName1("IOBufferDuration");
  late final _sel_isOtherAudioPlaying1 = _registerName1("isOtherAudioPlaying");
  late final _sel_secondaryAudioShouldBeSilencedHint1 =
      _registerName1("secondaryAudioShouldBeSilencedHint");
  late final _sel_outputVolume1 = _registerName1("outputVolume");
  late final _sel_promptStyle1 = _registerName1("promptStyle");
  int _objc_msgSend_1022(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1022(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1022Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1022 = __objc_msgSend_1022Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_availableInputs1 = _registerName1("availableInputs");
  late final _class_AVAudioSessionRouteDescription1 =
      _getClass1("AVAudioSessionRouteDescription");
  late final _sel_inputs1 = _registerName1("inputs");
  late final _sel_outputs1 = _registerName1("outputs");
  late final _sel_currentRoute1 = _registerName1("currentRoute");
  ffi.Pointer<ObjCObject> _objc_msgSend_1023(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1023(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1023Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1023 = __objc_msgSend_1023Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_setAggregatedIOPreference_error_1 =
      _registerName1("setAggregatedIOPreference:error:");
  bool _objc_msgSend_1024(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int inIOType,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1024(
      obj,
      sel,
      inIOType,
      outError,
    );
  }

  late final __objc_msgSend_1024Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1024 = __objc_msgSend_1024Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_setSupportsMultichannelContent_error_1 =
      _registerName1("setSupportsMultichannelContent:error:");
  late final _sel_supportsMultichannelContent1 =
      _registerName1("supportsMultichannelContent");
  late final _sel_setActive_withFlags_error_1 =
      _registerName1("setActive:withFlags:error:");
  bool _objc_msgSend_1025(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    bool active,
    int flags,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1025(
      obj,
      sel,
      active,
      flags,
      outError,
    );
  }

  late final __objc_msgSend_1025Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Bool,
              NSInteger,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1025 = __objc_msgSend_1025Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, bool, int,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_inputIsAvailable1 = _registerName1("inputIsAvailable");
  late final _sel_currentHardwareSampleRate1 =
      _registerName1("currentHardwareSampleRate");
  late final _sel_currentHardwareInputNumberOfChannels1 =
      _registerName1("currentHardwareInputNumberOfChannels");
  late final _sel_currentHardwareOutputNumberOfChannels1 =
      _registerName1("currentHardwareOutputNumberOfChannels");
  late final _sel_setPreferredHardwareSampleRate_error_1 =
      _registerName1("setPreferredHardwareSampleRate:error:");
  late final _sel_preferredHardwareSampleRate1 =
      _registerName1("preferredHardwareSampleRate");
  late final _class_AVAudioPlayer1 = _getClass1("AVAudioPlayer");
  late final _sel_initWithData_error_1 = _registerName1("initWithData:error:");
  instancetype _objc_msgSend_1026(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1026(
      obj,
      sel,
      data,
      outError,
    );
  }

  late final __objc_msgSend_1026Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1026 = __objc_msgSend_1026Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_initWithContentsOfURL_fileTypeHint_error_1 =
      _registerName1("initWithContentsOfURL:fileTypeHint:error:");
  instancetype _objc_msgSend_1027(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> url,
    ffi.Pointer<ObjCObject> utiString,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1027(
      obj,
      sel,
      url,
      utiString,
      outError,
    );
  }

  late final __objc_msgSend_1027Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1027 = __objc_msgSend_1027Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_initWithData_fileTypeHint_error_1 =
      _registerName1("initWithData:fileTypeHint:error:");
  instancetype _objc_msgSend_1028(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<ObjCObject> data,
    ffi.Pointer<ObjCObject> utiString,
    ffi.Pointer<ffi.Pointer<ObjCObject>> outError,
  ) {
    return __objc_msgSend_1028(
      obj,
      sel,
      data,
      utiString,
      outError,
    );
  }

  late final __objc_msgSend_1028Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ffi.Pointer<ObjCObject>>)>>('objc_msgSend');
  late final __objc_msgSend_1028 = __objc_msgSend_1028Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCSel>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ObjCObject>,
          ffi.Pointer<ffi.Pointer<ObjCObject>>)>();

  late final _sel_prepareToPlay1 = _registerName1("prepareToPlay");
  late final _sel_play1 = _registerName1("play");
  late final _sel_playAtTime_1 = _registerName1("playAtTime:");
  bool _objc_msgSend_1029(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double time,
  ) {
    return __objc_msgSend_1029(
      obj,
      sel,
      time,
    );
  }

  late final __objc_msgSend_1029Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSTimeInterval)>>('objc_msgSend');
  late final __objc_msgSend_1029 = __objc_msgSend_1029Ptr.asFunction<
      bool Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double)>();

  late final _sel_isPlaying1 = _registerName1("isPlaying");
  late final _sel_numberOfChannels1 = _registerName1("numberOfChannels");
  late final _sel_currentDevice1 = _registerName1("currentDevice");
  late final _sel_setCurrentDevice_1 = _registerName1("setCurrentDevice:");
  late final _sel_url1 = _registerName1("url");
  late final _sel_pan1 = _registerName1("pan");
  late final _sel_setPan_1 = _registerName1("setPan:");
  late final _sel_volume1 = _registerName1("volume");
  late final _sel_setVolume_1 = _registerName1("setVolume:");
  late final _sel_setVolume_fadeDuration_1 =
      _registerName1("setVolume:fadeDuration:");
  void _objc_msgSend_1030(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double volume,
    double duration,
  ) {
    return __objc_msgSend_1030(
      obj,
      sel,
      volume,
      duration,
    );
  }

  late final __objc_msgSend_1030Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Float, NSTimeInterval)>>('objc_msgSend');
  late final __objc_msgSend_1030 = __objc_msgSend_1030Ptr.asFunction<
      void Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double, double)>();

  late final _sel_enableRate1 = _registerName1("enableRate");
  late final _sel_setEnableRate_1 = _registerName1("setEnableRate:");
  late final _sel_rate1 = _registerName1("rate");
  late final _sel_setRate_1 = _registerName1("setRate:");
  late final _sel_currentTime1 = _registerName1("currentTime");
  late final _sel_setCurrentTime_1 = _registerName1("setCurrentTime:");
  late final _sel_deviceCurrentTime1 = _registerName1("deviceCurrentTime");
  late final _sel_numberOfLoops1 = _registerName1("numberOfLoops");
  late final _sel_setNumberOfLoops_1 = _registerName1("setNumberOfLoops:");
  late final _sel_settings1 = _registerName1("settings");
  late final _class_AVAudioFormat1 = _getClass1("AVAudioFormat");
  late final _sel_initWithStreamDescription_1 =
      _registerName1("initWithStreamDescription:");
  instancetype _objc_msgSend_1031(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<AudioStreamBasicDescription> asbd,
  ) {
    return __objc_msgSend_1031(
      obj,
      sel,
      asbd,
    );
  }

  late final __objc_msgSend_1031Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<AudioStreamBasicDescription>)>>('objc_msgSend');
  late final __objc_msgSend_1031 = __objc_msgSend_1031Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<AudioStreamBasicDescription>)>();

  late final _class_AVAudioChannelLayout1 = _getClass1("AVAudioChannelLayout");
  late final _sel_initWithLayoutTag_1 = _registerName1("initWithLayoutTag:");
  instancetype _objc_msgSend_1032(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int layoutTag,
  ) {
    return __objc_msgSend_1032(
      obj,
      sel,
      layoutTag,
    );
  }

  late final __objc_msgSend_1032Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              AudioChannelLayoutTag)>>('objc_msgSend');
  late final __objc_msgSend_1032 = __objc_msgSend_1032Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_initWithLayout_1 = _registerName1("initWithLayout:");
  instancetype _objc_msgSend_1033(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<AudioChannelLayout> layout,
  ) {
    return __objc_msgSend_1033(
      obj,
      sel,
      layout,
    );
  }

  late final __objc_msgSend_1033Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Pointer<AudioChannelLayout>)>>('objc_msgSend');
  late final __objc_msgSend_1033 = __objc_msgSend_1033Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<AudioChannelLayout>)>();

  late final _sel_isEqual_1 = _registerName1("isEqual:");
  late final _sel_layoutWithLayoutTag_1 =
      _registerName1("layoutWithLayoutTag:");
  late final _sel_layoutWithLayout_1 = _registerName1("layoutWithLayout:");
  late final _sel_layoutTag1 = _registerName1("layoutTag");
  late final _sel_layout1 = _registerName1("layout");
  ffi.Pointer<AudioChannelLayout> _objc_msgSend_1034(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1034(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1034Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<AudioChannelLayout> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1034 = __objc_msgSend_1034Ptr.asFunction<
      ffi.Pointer<AudioChannelLayout> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_channelCount1 = _registerName1("channelCount");
  int _objc_msgSend_1035(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1035(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1035Ptr = _lookup<
      ffi.NativeFunction<
          AVAudioChannelCount Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1035 = __objc_msgSend_1035Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_initWithStreamDescription_channelLayout_1 =
      _registerName1("initWithStreamDescription:channelLayout:");
  instancetype _objc_msgSend_1036(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    ffi.Pointer<AudioStreamBasicDescription> asbd,
    ffi.Pointer<ObjCObject> layout,
  ) {
    return __objc_msgSend_1036(
      obj,
      sel,
      asbd,
      layout,
    );
  }

  late final __objc_msgSend_1036Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Pointer<AudioStreamBasicDescription>,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_1036 = __objc_msgSend_1036Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          ffi.Pointer<AudioStreamBasicDescription>, ffi.Pointer<ObjCObject>)>();

  late final _sel_initStandardFormatWithSampleRate_channels_1 =
      _registerName1("initStandardFormatWithSampleRate:channels:");
  instancetype _objc_msgSend_1037(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double sampleRate,
    int channels,
  ) {
    return __objc_msgSend_1037(
      obj,
      sel,
      sampleRate,
      channels,
    );
  }

  late final __objc_msgSend_1037Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Double, AVAudioChannelCount)>>('objc_msgSend');
  late final __objc_msgSend_1037 = __objc_msgSend_1037Ptr.asFunction<
      instancetype Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, double, int)>();

  late final _sel_initStandardFormatWithSampleRate_channelLayout_1 =
      _registerName1("initStandardFormatWithSampleRate:channelLayout:");
  instancetype _objc_msgSend_1038(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    double sampleRate,
    ffi.Pointer<ObjCObject> layout,
  ) {
    return __objc_msgSend_1038(
      obj,
      sel,
      sampleRate,
      layout,
    );
  }

  late final __objc_msgSend_1038Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              ffi.Double, ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_1038 = __objc_msgSend_1038Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          double, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithCommonFormat_sampleRate_channels_interleaved_1 =
      _registerName1("initWithCommonFormat:sampleRate:channels:interleaved:");
  instancetype _objc_msgSend_1039(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int format,
    double sampleRate,
    int channels,
    bool interleaved,
  ) {
    return __objc_msgSend_1039(
      obj,
      sel,
      format,
      sampleRate,
      channels,
      interleaved,
    );
  }

  late final __objc_msgSend_1039Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Double,
              AVAudioChannelCount,
              ffi.Bool)>>('objc_msgSend');
  late final __objc_msgSend_1039 = __objc_msgSend_1039Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          double, int, bool)>();

  late final _sel_initWithCommonFormat_sampleRate_interleaved_channelLayout_1 =
      _registerName1(
          "initWithCommonFormat:sampleRate:interleaved:channelLayout:");
  instancetype _objc_msgSend_1040(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int format,
    double sampleRate,
    bool interleaved,
    ffi.Pointer<ObjCObject> layout,
  ) {
    return __objc_msgSend_1040(
      obj,
      sel,
      format,
      sampleRate,
      interleaved,
      layout,
    );
  }

  late final __objc_msgSend_1040Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(
              ffi.Pointer<ObjCObject>,
              ffi.Pointer<ObjCSel>,
              ffi.Int32,
              ffi.Double,
              ffi.Bool,
              ffi.Pointer<ObjCObject>)>>('objc_msgSend');
  late final __objc_msgSend_1040 = __objc_msgSend_1040Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int,
          double, bool, ffi.Pointer<ObjCObject>)>();

  late final _sel_initWithSettings_1 = _registerName1("initWithSettings:");
  late final _sel_initWithCMAudioFormatDescription_1 =
      _registerName1("initWithCMAudioFormatDescription:");
  instancetype _objc_msgSend_1041(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    CMAudioFormatDescriptionRef formatDescription,
  ) {
    return __objc_msgSend_1041(
      obj,
      sel,
      formatDescription,
    );
  }

  late final __objc_msgSend_1041Ptr = _lookup<
      ffi.NativeFunction<
          instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              CMAudioFormatDescriptionRef)>>('objc_msgSend');
  late final __objc_msgSend_1041 = __objc_msgSend_1041Ptr.asFunction<
      instancetype Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
          CMAudioFormatDescriptionRef)>();

  late final _sel_isStandard1 = _registerName1("isStandard");
  late final _sel_commonFormat1 = _registerName1("commonFormat");
  int _objc_msgSend_1042(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1042(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1042Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Int32 Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1042 = __objc_msgSend_1042Ptr.asFunction<
      int Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_isInterleaved1 = _registerName1("isInterleaved");
  late final _sel_streamDescription1 = _registerName1("streamDescription");
  ffi.Pointer<AudioStreamBasicDescription> _objc_msgSend_1043(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1043(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1043Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<AudioStreamBasicDescription> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1043 = __objc_msgSend_1043Ptr.asFunction<
      ffi.Pointer<AudioStreamBasicDescription> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_channelLayout1 = _registerName1("channelLayout");
  ffi.Pointer<ObjCObject> _objc_msgSend_1044(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1044(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1044Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1044 = __objc_msgSend_1044Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_magicCookie1 = _registerName1("magicCookie");
  late final _sel_setMagicCookie_1 = _registerName1("setMagicCookie:");
  late final _sel_formatDescription1 = _registerName1("formatDescription");
  CMAudioFormatDescriptionRef _objc_msgSend_1045(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1045(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1045Ptr = _lookup<
      ffi.NativeFunction<
          CMAudioFormatDescriptionRef Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1045 = __objc_msgSend_1045Ptr.asFunction<
      CMAudioFormatDescriptionRef Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  ffi.Pointer<ObjCObject> _objc_msgSend_1046(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
  ) {
    return __objc_msgSend_1046(
      obj,
      sel,
    );
  }

  late final __objc_msgSend_1046Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>('objc_msgSend');
  late final __objc_msgSend_1046 = __objc_msgSend_1046Ptr.asFunction<
      ffi.Pointer<ObjCObject> Function(
          ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>();

  late final _sel_isMeteringEnabled1 = _registerName1("isMeteringEnabled");
  late final _sel_setMeteringEnabled_1 = _registerName1("setMeteringEnabled:");
  late final _sel_updateMeters1 = _registerName1("updateMeters");
  late final _sel_peakPowerForChannel_1 =
      _registerName1("peakPowerForChannel:");
  double _objc_msgSend_1047(
    ffi.Pointer<ObjCObject> obj,
    ffi.Pointer<ObjCSel> sel,
    int channelNumber,
  ) {
    return __objc_msgSend_1047(
      obj,
      sel,
      channelNumber,
    );
  }

  late final __objc_msgSend_1047Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Float Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>,
              NSUInteger)>>('objc_msgSend');
  late final __objc_msgSend_1047 = __objc_msgSend_1047Ptr.asFunction<
      double Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>, int)>();

  late final _sel_averagePowerForChannel_1 =
      _registerName1("averagePowerForChannel:");
  late final _sel_channelAssignments1 = _registerName1("channelAssignments");
  late final _sel_setChannelAssignments_1 =
      _registerName1("setChannelAssignments:");
}

class _ObjCWrapper implements ffi.Finalizable {
  final ffi.Pointer<ObjCObject> _id;
  final AVFAudio _lib;
  bool _pendingRelease;

  _ObjCWrapper._(this._id, this._lib,
      {bool retain = false, bool release = false})
      : _pendingRelease = release {
    if (retain) {
      _lib._objc_retain(_id.cast());
    }
    if (release) {
      _lib._objc_releaseFinalizer2.attach(this, _id.cast(), detach: this);
    }
  }

  /// Releases the reference to the underlying ObjC object held by this wrapper.
  /// Throws a StateError if this wrapper doesn't currently hold a reference.
  void release() {
    if (_pendingRelease) {
      _pendingRelease = false;
      _lib._objc_release(_id.cast());
      _lib._objc_releaseFinalizer2.detach(this);
    } else {
      throw StateError(
          'Released an ObjC object that was unowned or already released.');
    }
  }

  @override
  bool operator ==(Object other) {
    return other is _ObjCWrapper && _id == other._id;
  }

  @override
  int get hashCode => _id.hashCode;
}

class NSObject extends _ObjCWrapper {
  NSObject._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSObject] that points to the same underlying object as [other].
  static NSObject castFrom<T extends _ObjCWrapper>(T other) {
    return NSObject._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSObject] that wraps the given raw object pointer.
  static NSObject castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSObject._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSObject].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSObject1);
  }

  static void load(AVFAudio _lib) {
    return _lib._objc_msgSend_1(_lib._class_NSObject1, _lib._sel_load1);
  }

  static void initialize(AVFAudio _lib) {
    return _lib._objc_msgSend_1(_lib._class_NSObject1, _lib._sel_initialize1);
  }

  NSObject init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSObject1, _lib._sel_new1);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  static NSObject allocWithZone_(AVFAudio _lib, ffi.Pointer<_NSZone> zone) {
    final _ret = _lib._objc_msgSend_3(
        _lib._class_NSObject1, _lib._sel_allocWithZone_1, zone);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  static NSObject alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSObject1, _lib._sel_alloc1);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  void dealloc() {
    return _lib._objc_msgSend_1(_id, _lib._sel_dealloc1);
  }

  void finalize() {
    return _lib._objc_msgSend_1(_id, _lib._sel_finalize1);
  }

  NSObject copy() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_copy1);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  NSObject mutableCopy() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_mutableCopy1);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  static NSObject copyWithZone_(AVFAudio _lib, ffi.Pointer<_NSZone> zone) {
    final _ret = _lib._objc_msgSend_3(
        _lib._class_NSObject1, _lib._sel_copyWithZone_1, zone);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  static NSObject mutableCopyWithZone_(
      AVFAudio _lib, ffi.Pointer<_NSZone> zone) {
    final _ret = _lib._objc_msgSend_3(
        _lib._class_NSObject1, _lib._sel_mutableCopyWithZone_1, zone);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  static bool instancesRespondToSelector_(
      AVFAudio _lib, ffi.Pointer<ObjCSel> aSelector) {
    return _lib._objc_msgSend_4(_lib._class_NSObject1,
        _lib._sel_instancesRespondToSelector_1, aSelector);
  }

  static bool conformsToProtocol_(AVFAudio _lib, Protocol? protocol) {
    return _lib._objc_msgSend_5(_lib._class_NSObject1,
        _lib._sel_conformsToProtocol_1, protocol?._id ?? ffi.nullptr);
  }

  IMP methodForSelector_(ffi.Pointer<ObjCSel> aSelector) {
    return _lib._objc_msgSend_6(_id, _lib._sel_methodForSelector_1, aSelector);
  }

  static IMP instanceMethodForSelector_(
      AVFAudio _lib, ffi.Pointer<ObjCSel> aSelector) {
    return _lib._objc_msgSend_6(_lib._class_NSObject1,
        _lib._sel_instanceMethodForSelector_1, aSelector);
  }

  void doesNotRecognizeSelector_(ffi.Pointer<ObjCSel> aSelector) {
    return _lib._objc_msgSend_7(
        _id, _lib._sel_doesNotRecognizeSelector_1, aSelector);
  }

  NSObject forwardingTargetForSelector_(ffi.Pointer<ObjCSel> aSelector) {
    final _ret = _lib._objc_msgSend_8(
        _id, _lib._sel_forwardingTargetForSelector_1, aSelector);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void forwardInvocation_(NSInvocation? anInvocation) {
    return _lib._objc_msgSend_372(
        _id, _lib._sel_forwardInvocation_1, anInvocation?._id ?? ffi.nullptr);
  }

  NSMethodSignature methodSignatureForSelector_(
      ffi.Pointer<ObjCSel> aSelector) {
    final _ret = _lib._objc_msgSend_373(
        _id, _lib._sel_methodSignatureForSelector_1, aSelector);
    return NSMethodSignature._(_ret, _lib, retain: true, release: true);
  }

  static NSMethodSignature instanceMethodSignatureForSelector_(
      AVFAudio _lib, ffi.Pointer<ObjCSel> aSelector) {
    final _ret = _lib._objc_msgSend_373(_lib._class_NSObject1,
        _lib._sel_instanceMethodSignatureForSelector_1, aSelector);
    return NSMethodSignature._(_ret, _lib, retain: true, release: true);
  }

  bool allowsWeakReference() {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsWeakReference1);
  }

  bool retainWeakReference() {
    return _lib._objc_msgSend_12(_id, _lib._sel_retainWeakReference1);
  }

  static bool isSubclassOfClass_(AVFAudio _lib, NSObject aClass) {
    return _lib._objc_msgSend_0(
        _lib._class_NSObject1, _lib._sel_isSubclassOfClass_1, aClass._id);
  }

  static bool resolveClassMethod_(AVFAudio _lib, ffi.Pointer<ObjCSel> sel) {
    return _lib._objc_msgSend_4(
        _lib._class_NSObject1, _lib._sel_resolveClassMethod_1, sel);
  }

  static bool resolveInstanceMethod_(AVFAudio _lib, ffi.Pointer<ObjCSel> sel) {
    return _lib._objc_msgSend_4(
        _lib._class_NSObject1, _lib._sel_resolveInstanceMethod_1, sel);
  }

  static int hash(AVFAudio _lib) {
    return _lib._objc_msgSend_10(_lib._class_NSObject1, _lib._sel_hash1);
  }

  static NSObject superclass(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSObject1, _lib._sel_superclass1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject class1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSObject1, _lib._sel_class1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSString description(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_20(_lib._class_NSObject1, _lib._sel_description1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString debugDescription(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_20(
        _lib._class_NSObject1, _lib._sel_debugDescription1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static int version(AVFAudio _lib) {
    return _lib._objc_msgSend_78(_lib._class_NSObject1, _lib._sel_version1);
  }

  static void setVersion_(AVFAudio _lib, int aVersion) {
    return _lib._objc_msgSend_374(
        _lib._class_NSObject1, _lib._sel_setVersion_1, aVersion);
  }

  NSObject get classForCoder {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_classForCoder1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject replacementObjectForCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_replacementObjectForCoder_1, coder?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject awakeAfterUsingCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_awakeAfterUsingCoder_1, coder?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  static void poseAsClass_(AVFAudio _lib, NSObject aClass) {
    return _lib._objc_msgSend_15(
        _lib._class_NSObject1, _lib._sel_poseAsClass_1, aClass._id);
  }

  NSObject get autoContentAccessingProxy {
    final _ret =
        _lib._objc_msgSend_2(_id, _lib._sel_autoContentAccessingProxy1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void
      attemptRecoveryFromError_optionIndex_delegate_didRecoverSelector_contextInfo_(
          NSError? error,
          int recoveryOptionIndex,
          NSObject delegate,
          ffi.Pointer<ObjCSel> didRecoverSelector,
          ffi.Pointer<ffi.Void> contextInfo) {
    return _lib._objc_msgSend_375(
        _id,
        _lib._sel_attemptRecoveryFromError_optionIndex_delegate_didRecoverSelector_contextInfo_1,
        error?._id ?? ffi.nullptr,
        recoveryOptionIndex,
        delegate._id,
        didRecoverSelector,
        contextInfo);
  }

  bool attemptRecoveryFromError_optionIndex_(
      NSError? error, int recoveryOptionIndex) {
    return _lib._objc_msgSend_376(
        _id,
        _lib._sel_attemptRecoveryFromError_optionIndex_1,
        error?._id ?? ffi.nullptr,
        recoveryOptionIndex);
  }

  void performSelector_withObject_afterDelay_inModes_(
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument,
      double delay,
      NSArray? modes) {
    return _lib._objc_msgSend_377(
        _id,
        _lib._sel_performSelector_withObject_afterDelay_inModes_1,
        aSelector,
        anArgument._id,
        delay,
        modes?._id ?? ffi.nullptr);
  }

  void performSelector_withObject_afterDelay_(
      ffi.Pointer<ObjCSel> aSelector, NSObject anArgument, double delay) {
    return _lib._objc_msgSend_378(
        _id,
        _lib._sel_performSelector_withObject_afterDelay_1,
        aSelector,
        anArgument._id,
        delay);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSObject1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSObject1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  void URL_resourceDataDidBecomeAvailable_(NSURL? sender, NSData? newBytes) {
    return _lib._objc_msgSend_379(
        _id,
        _lib._sel_URL_resourceDataDidBecomeAvailable_1,
        sender?._id ?? ffi.nullptr,
        newBytes?._id ?? ffi.nullptr);
  }

  void URLResourceDidFinishLoading_(NSURL? sender) {
    return _lib._objc_msgSend_380(_id, _lib._sel_URLResourceDidFinishLoading_1,
        sender?._id ?? ffi.nullptr);
  }

  void URLResourceDidCancelLoading_(NSURL? sender) {
    return _lib._objc_msgSend_380(_id, _lib._sel_URLResourceDidCancelLoading_1,
        sender?._id ?? ffi.nullptr);
  }

  void URL_resourceDidFailLoadingWithReason_(NSURL? sender, NSString? reason) {
    return _lib._objc_msgSend_381(
        _id,
        _lib._sel_URL_resourceDidFailLoadingWithReason_1,
        sender?._id ?? ffi.nullptr,
        reason?._id ?? ffi.nullptr);
  }

  bool fileManager_shouldProceedAfterError_(
      NSFileManager? fm, NSDictionary? errorInfo) {
    return _lib._objc_msgSend_407(
        _id,
        _lib._sel_fileManager_shouldProceedAfterError_1,
        fm?._id ?? ffi.nullptr,
        errorInfo?._id ?? ffi.nullptr);
  }

  void fileManager_willProcessPath_(NSFileManager? fm, NSString? path) {
    return _lib._objc_msgSend_408(_id, _lib._sel_fileManager_willProcessPath_1,
        fm?._id ?? ffi.nullptr, path?._id ?? ffi.nullptr);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSObject1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  NSObject valueForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_valueForKey_1, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void setValue_forKey_(NSObject value, NSString? key) {
    return _lib._objc_msgSend_122(
        _id, _lib._sel_setValue_forKey_1, value._id, key?._id ?? ffi.nullptr);
  }

  bool validateValue_forKey_error_(ffi.Pointer<ffi.Pointer<ObjCObject>> ioValue,
      NSString? inKey, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_220(_id, _lib._sel_validateValue_forKey_error_1,
        ioValue, inKey?._id ?? ffi.nullptr, outError);
  }

  NSMutableArray mutableArrayValueForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_425(
        _id, _lib._sel_mutableArrayValueForKey_1, key?._id ?? ffi.nullptr);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  NSMutableOrderedSet mutableOrderedSetValueForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_441(
        _id, _lib._sel_mutableOrderedSetValueForKey_1, key?._id ?? ffi.nullptr);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  NSMutableSet mutableSetValueForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_442(
        _id, _lib._sel_mutableSetValueForKey_1, key?._id ?? ffi.nullptr);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  NSObject valueForKeyPath_(NSString? keyPath) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_valueForKeyPath_1, keyPath?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void setValue_forKeyPath_(NSObject value, NSString? keyPath) {
    return _lib._objc_msgSend_122(_id, _lib._sel_setValue_forKeyPath_1,
        value._id, keyPath?._id ?? ffi.nullptr);
  }

  bool validateValue_forKeyPath_error_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> ioValue,
      NSString? inKeyPath,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_220(
        _id,
        _lib._sel_validateValue_forKeyPath_error_1,
        ioValue,
        inKeyPath?._id ?? ffi.nullptr,
        outError);
  }

  NSMutableArray mutableArrayValueForKeyPath_(NSString? keyPath) {
    final _ret = _lib._objc_msgSend_425(_id,
        _lib._sel_mutableArrayValueForKeyPath_1, keyPath?._id ?? ffi.nullptr);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  NSMutableOrderedSet mutableOrderedSetValueForKeyPath_(NSString? keyPath) {
    final _ret = _lib._objc_msgSend_441(
        _id,
        _lib._sel_mutableOrderedSetValueForKeyPath_1,
        keyPath?._id ?? ffi.nullptr);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  NSMutableSet mutableSetValueForKeyPath_(NSString? keyPath) {
    final _ret = _lib._objc_msgSend_442(_id,
        _lib._sel_mutableSetValueForKeyPath_1, keyPath?._id ?? ffi.nullptr);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  NSObject valueForUndefinedKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_valueForUndefinedKey_1, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void setValue_forUndefinedKey_(NSObject value, NSString? key) {
    return _lib._objc_msgSend_122(_id, _lib._sel_setValue_forUndefinedKey_1,
        value._id, key?._id ?? ffi.nullptr);
  }

  void setNilValueForKey_(NSString? key) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_setNilValueForKey_1, key?._id ?? ffi.nullptr);
  }

  NSDictionary dictionaryWithValuesForKeys_(NSArray? keys) {
    final _ret = _lib._objc_msgSend_443(
        _id, _lib._sel_dictionaryWithValuesForKeys_1, keys?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  void setValuesForKeysWithDictionary_(NSDictionary? keyedValues) {
    return _lib._objc_msgSend_444(
        _id,
        _lib._sel_setValuesForKeysWithDictionary_1,
        keyedValues?._id ?? ffi.nullptr);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSObject1, _lib._sel_useStoredAccessor1);
  }

  NSObject storedValueForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_storedValueForKey_1, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void takeStoredValue_forKey_(NSObject value, NSString? key) {
    return _lib._objc_msgSend_122(_id, _lib._sel_takeStoredValue_forKey_1,
        value._id, key?._id ?? ffi.nullptr);
  }

  void takeValue_forKey_(NSObject value, NSString? key) {
    return _lib._objc_msgSend_122(
        _id, _lib._sel_takeValue_forKey_1, value._id, key?._id ?? ffi.nullptr);
  }

  void takeValue_forKeyPath_(NSObject value, NSString? keyPath) {
    return _lib._objc_msgSend_122(_id, _lib._sel_takeValue_forKeyPath_1,
        value._id, keyPath?._id ?? ffi.nullptr);
  }

  NSObject handleQueryWithUnboundKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_handleQueryWithUnboundKey_1, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void handleTakeValue_forUnboundKey_(NSObject value, NSString? key) {
    return _lib._objc_msgSend_122(
        _id,
        _lib._sel_handleTakeValue_forUnboundKey_1,
        value._id,
        key?._id ?? ffi.nullptr);
  }

  void unableToSetNilForKey_(NSString? key) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_unableToSetNilForKey_1, key?._id ?? ffi.nullptr);
  }

  NSDictionary valuesForKeys_(NSArray? keys) {
    final _ret = _lib._objc_msgSend_443(
        _id, _lib._sel_valuesForKeys_1, keys?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  void takeValuesFromDictionary_(NSDictionary? properties) {
    return _lib._objc_msgSend_444(_id, _lib._sel_takeValuesFromDictionary_1,
        properties?._id ?? ffi.nullptr);
  }

  void observeValueForKeyPath_ofObject_change_context_(NSString? keyPath,
      NSObject object, NSDictionary? change, ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_445(
        _id,
        _lib._sel_observeValueForKeyPath_ofObject_change_context_1,
        keyPath?._id ?? ffi.nullptr,
        object._id,
        change?._id ?? ffi.nullptr,
        context);
  }

  void addObserver_forKeyPath_options_context_(NSObject? observer,
      NSString? keyPath, int options, ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_126(
        _id,
        _lib._sel_addObserver_forKeyPath_options_context_1,
        observer?._id ?? ffi.nullptr,
        keyPath?._id ?? ffi.nullptr,
        options,
        context);
  }

  void removeObserver_forKeyPath_context_(
      NSObject? observer, NSString? keyPath, ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_127(
        _id,
        _lib._sel_removeObserver_forKeyPath_context_1,
        observer?._id ?? ffi.nullptr,
        keyPath?._id ?? ffi.nullptr,
        context);
  }

  void removeObserver_forKeyPath_(NSObject? observer, NSString? keyPath) {
    return _lib._objc_msgSend_128(_id, _lib._sel_removeObserver_forKeyPath_1,
        observer?._id ?? ffi.nullptr, keyPath?._id ?? ffi.nullptr);
  }

  void willChangeValueForKey_(NSString? key) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_willChangeValueForKey_1, key?._id ?? ffi.nullptr);
  }

  void didChangeValueForKey_(NSString? key) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_didChangeValueForKey_1, key?._id ?? ffi.nullptr);
  }

  void willChange_valuesAtIndexes_forKey_(
      int changeKind, NSIndexSet? indexes, NSString? key) {
    return _lib._objc_msgSend_446(
        _id,
        _lib._sel_willChange_valuesAtIndexes_forKey_1,
        changeKind,
        indexes?._id ?? ffi.nullptr,
        key?._id ?? ffi.nullptr);
  }

  void didChange_valuesAtIndexes_forKey_(
      int changeKind, NSIndexSet? indexes, NSString? key) {
    return _lib._objc_msgSend_446(
        _id,
        _lib._sel_didChange_valuesAtIndexes_forKey_1,
        changeKind,
        indexes?._id ?? ffi.nullptr,
        key?._id ?? ffi.nullptr);
  }

  void willChangeValueForKey_withSetMutation_usingObjects_(
      NSString? key, int mutationKind, NSSet? objects) {
    return _lib._objc_msgSend_447(
        _id,
        _lib._sel_willChangeValueForKey_withSetMutation_usingObjects_1,
        key?._id ?? ffi.nullptr,
        mutationKind,
        objects?._id ?? ffi.nullptr);
  }

  void didChangeValueForKey_withSetMutation_usingObjects_(
      NSString? key, int mutationKind, NSSet? objects) {
    return _lib._objc_msgSend_447(
        _id,
        _lib._sel_didChangeValueForKey_withSetMutation_usingObjects_1,
        key?._id ?? ffi.nullptr,
        mutationKind,
        objects?._id ?? ffi.nullptr);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSObject1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSObject1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  ffi.Pointer<ffi.Void> get observationInfo {
    return _lib._objc_msgSend_19(_id, _lib._sel_observationInfo1);
  }

  set observationInfo(ffi.Pointer<ffi.Void> value) {
    _lib._objc_msgSend_448(_id, _lib._sel_setObservationInfo_1, value);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSObject1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  NSObject get classForKeyedArchiver {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_classForKeyedArchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject replacementObjectForKeyedArchiver_(NSKeyedArchiver? archiver) {
    final _ret = _lib._objc_msgSend_461(
        _id,
        _lib._sel_replacementObjectForKeyedArchiver_1,
        archiver?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSObject1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSObject1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void performSelectorOnMainThread_withObject_waitUntilDone_modes_(
      ffi.Pointer<ObjCSel> aSelector, NSObject arg, bool wait, NSArray? array) {
    return _lib._objc_msgSend_462(
        _id,
        _lib._sel_performSelectorOnMainThread_withObject_waitUntilDone_modes_1,
        aSelector,
        arg._id,
        wait,
        array?._id ?? ffi.nullptr);
  }

  void performSelectorOnMainThread_withObject_waitUntilDone_(
      ffi.Pointer<ObjCSel> aSelector, NSObject arg, bool wait) {
    return _lib._objc_msgSend_463(
        _id,
        _lib._sel_performSelectorOnMainThread_withObject_waitUntilDone_1,
        aSelector,
        arg._id,
        wait);
  }

  void performSelector_onThread_withObject_waitUntilDone_modes_(
      ffi.Pointer<ObjCSel> aSelector,
      NSThread? thr,
      NSObject arg,
      bool wait,
      NSArray? array) {
    return _lib._objc_msgSend_480(
        _id,
        _lib._sel_performSelector_onThread_withObject_waitUntilDone_modes_1,
        aSelector,
        thr?._id ?? ffi.nullptr,
        arg._id,
        wait,
        array?._id ?? ffi.nullptr);
  }

  void performSelector_onThread_withObject_waitUntilDone_(
      ffi.Pointer<ObjCSel> aSelector, NSThread? thr, NSObject arg, bool wait) {
    return _lib._objc_msgSend_481(
        _id,
        _lib._sel_performSelector_onThread_withObject_waitUntilDone_1,
        aSelector,
        thr?._id ?? ffi.nullptr,
        arg._id,
        wait);
  }

  void performSelectorInBackground_withObject_(
      ffi.Pointer<ObjCSel> aSelector, NSObject arg) {
    return _lib._objc_msgSend_82(_id,
        _lib._sel_performSelectorInBackground_withObject_1, aSelector, arg._id);
  }

  NSObject get classForArchiver {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_classForArchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject replacementObjectForArchiver_(NSArchiver? archiver) {
    final _ret = _lib._objc_msgSend_484(_id,
        _lib._sel_replacementObjectForArchiver_1, archiver?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject get classForPortCoder {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_classForPortCoder1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject replacementObjectForPortCoder_(NSPortCoder? coder) {
    final _ret = _lib._objc_msgSend_522(_id,
        _lib._sel_replacementObjectForPortCoder_1, coder?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSClassDescription? get classDescription {
    final _ret = _lib._objc_msgSend_525(_id, _lib._sel_classDescription1);
    return _ret.address == 0
        ? null
        : NSClassDescription._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get attributeKeys {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_attributeKeys1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get toOneRelationshipKeys {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_toOneRelationshipKeys1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get toManyRelationshipKeys {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_toManyRelationshipKeys1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString inverseForRelationshipKey_(NSString? relationshipKey) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_inverseForRelationshipKey_1,
        relationshipKey?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSObject scriptingValueForSpecifier_(
      NSScriptObjectSpecifier? objectSpecifier) {
    final _ret = _lib._objc_msgSend_569(
        _id,
        _lib._sel_scriptingValueForSpecifier_1,
        objectSpecifier?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get scriptingProperties {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_scriptingProperties1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set scriptingProperties(NSDictionary? value) {
    _lib._objc_msgSend_165(
        _id, _lib._sel_setScriptingProperties_1, value?._id ?? ffi.nullptr);
  }

  NSObject copyScriptingValue_forKey_withProperties_(
      NSObject value, NSString? key, NSDictionary? properties) {
    final _ret = _lib._objc_msgSend_570(
        _id,
        _lib._sel_copyScriptingValue_forKey_withProperties_1,
        value._id,
        key?._id ?? ffi.nullptr,
        properties?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  NSObject
      newScriptingObjectOfClass_forValueForKey_withContentsValue_properties_(
          NSObject objectClass,
          NSString? key,
          NSObject contentsValue,
          NSDictionary? properties) {
    final _ret = _lib._objc_msgSend_571(
        _id,
        _lib._sel_newScriptingObjectOfClass_forValueForKey_withContentsValue_properties_1,
        objectClass._id,
        key?._id ?? ffi.nullptr,
        contentsValue._id,
        properties?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  int get classCode {
    return _lib._objc_msgSend_191(_id, _lib._sel_classCode1);
  }

  NSString? get className {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_className1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSObject valueAtIndex_inPropertyWithKey_(int index, NSString? key) {
    final _ret = _lib._objc_msgSend_572(
        _id,
        _lib._sel_valueAtIndex_inPropertyWithKey_1,
        index,
        key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject valueWithName_inPropertyWithKey_(NSString? name, NSString? key) {
    final _ret = _lib._objc_msgSend_159(
        _id,
        _lib._sel_valueWithName_inPropertyWithKey_1,
        name?._id ?? ffi.nullptr,
        key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject valueWithUniqueID_inPropertyWithKey_(
      NSObject uniqueID, NSString? key) {
    final _ret = _lib._objc_msgSend_272(
        _id,
        _lib._sel_valueWithUniqueID_inPropertyWithKey_1,
        uniqueID._id,
        key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void insertValue_atIndex_inPropertyWithKey_(
      NSObject value, int index, NSString? key) {
    return _lib._objc_msgSend_573(
        _id,
        _lib._sel_insertValue_atIndex_inPropertyWithKey_1,
        value._id,
        index,
        key?._id ?? ffi.nullptr);
  }

  void removeValueAtIndex_fromPropertyWithKey_(int index, NSString? key) {
    return _lib._objc_msgSend_574(
        _id,
        _lib._sel_removeValueAtIndex_fromPropertyWithKey_1,
        index,
        key?._id ?? ffi.nullptr);
  }

  void replaceValueAtIndex_inPropertyWithKey_withValue_(
      int index, NSString? key, NSObject value) {
    return _lib._objc_msgSend_575(
        _id,
        _lib._sel_replaceValueAtIndex_inPropertyWithKey_withValue_1,
        index,
        key?._id ?? ffi.nullptr,
        value._id);
  }

  void insertValue_inPropertyWithKey_(NSObject value, NSString? key) {
    return _lib._objc_msgSend_122(
        _id,
        _lib._sel_insertValue_inPropertyWithKey_1,
        value._id,
        key?._id ?? ffi.nullptr);
  }

  NSObject coerceValue_forKey_(NSObject value, NSString? key) {
    final _ret = _lib._objc_msgSend_272(_id, _lib._sel_coerceValue_forKey_1,
        value._id, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSScriptObjectSpecifier? get objectSpecifier {
    final _ret = _lib._objc_msgSend_556(_id, _lib._sel_objectSpecifier1);
    return _ret.address == 0
        ? null
        : NSScriptObjectSpecifier._(_ret, _lib, retain: true, release: true);
  }

  NSArray indicesOfObjectsByEvaluatingObjectSpecifier_(
      NSScriptObjectSpecifier? specifier) {
    final _ret = _lib._objc_msgSend_576(
        _id,
        _lib._sel_indicesOfObjectsByEvaluatingObjectSpecifier_1,
        specifier?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  bool isEqualTo_(NSObject object) {
    return _lib._objc_msgSend_0(_id, _lib._sel_isEqualTo_1, object._id);
  }

  bool isLessThanOrEqualTo_(NSObject object) {
    return _lib._objc_msgSend_0(
        _id, _lib._sel_isLessThanOrEqualTo_1, object._id);
  }

  bool isLessThan_(NSObject object) {
    return _lib._objc_msgSend_0(_id, _lib._sel_isLessThan_1, object._id);
  }

  bool isGreaterThanOrEqualTo_(NSObject object) {
    return _lib._objc_msgSend_0(
        _id, _lib._sel_isGreaterThanOrEqualTo_1, object._id);
  }

  bool isGreaterThan_(NSObject object) {
    return _lib._objc_msgSend_0(_id, _lib._sel_isGreaterThan_1, object._id);
  }

  bool isNotEqualTo_(NSObject object) {
    return _lib._objc_msgSend_0(_id, _lib._sel_isNotEqualTo_1, object._id);
  }

  bool doesContain_(NSObject object) {
    return _lib._objc_msgSend_0(_id, _lib._sel_doesContain_1, object._id);
  }

  bool isLike_(NSString? object) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_isLike_1, object?._id ?? ffi.nullptr);
  }

  bool isCaseInsensitiveLike_(NSString? object) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_isCaseInsensitiveLike_1, object?._id ?? ffi.nullptr);
  }

  bool scriptingIsEqualTo_(NSObject object) {
    return _lib._objc_msgSend_0(
        _id, _lib._sel_scriptingIsEqualTo_1, object._id);
  }

  bool scriptingIsLessThanOrEqualTo_(NSObject object) {
    return _lib._objc_msgSend_0(
        _id, _lib._sel_scriptingIsLessThanOrEqualTo_1, object._id);
  }

  bool scriptingIsLessThan_(NSObject object) {
    return _lib._objc_msgSend_0(
        _id, _lib._sel_scriptingIsLessThan_1, object._id);
  }

  bool scriptingIsGreaterThanOrEqualTo_(NSObject object) {
    return _lib._objc_msgSend_0(
        _id, _lib._sel_scriptingIsGreaterThanOrEqualTo_1, object._id);
  }

  bool scriptingIsGreaterThan_(NSObject object) {
    return _lib._objc_msgSend_0(
        _id, _lib._sel_scriptingIsGreaterThan_1, object._id);
  }

  bool scriptingBeginsWith_(NSObject object) {
    return _lib._objc_msgSend_0(
        _id, _lib._sel_scriptingBeginsWith_1, object._id);
  }

  bool scriptingEndsWith_(NSObject object) {
    return _lib._objc_msgSend_0(_id, _lib._sel_scriptingEndsWith_1, object._id);
  }

  bool scriptingContains_(NSObject object) {
    return _lib._objc_msgSend_0(_id, _lib._sel_scriptingContains_1, object._id);
  }
}

final class ObjCSel extends ffi.Opaque {}

final class ObjCObject extends ffi.Opaque {}

typedef instancetype = ffi.Pointer<ObjCObject>;

final class _NSZone extends ffi.Opaque {}

class Protocol extends _ObjCWrapper {
  Protocol._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [Protocol] that points to the same underlying object as [other].
  static Protocol castFrom<T extends _ObjCWrapper>(T other) {
    return Protocol._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [Protocol] that wraps the given raw object pointer.
  static Protocol castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return Protocol._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [Protocol].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_Protocol1);
  }
}

typedef IMP = ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>;

class NSInvocation extends NSObject {
  NSInvocation._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSInvocation] that points to the same underlying object as [other].
  static NSInvocation castFrom<T extends _ObjCWrapper>(T other) {
    return NSInvocation._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSInvocation] that wraps the given raw object pointer.
  static NSInvocation castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSInvocation._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSInvocation].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSInvocation1);
  }

  static NSInvocation invocationWithMethodSignature_(
      AVFAudio _lib, NSMethodSignature? sig) {
    final _ret = _lib._objc_msgSend_366(_lib._class_NSInvocation1,
        _lib._sel_invocationWithMethodSignature_1, sig?._id ?? ffi.nullptr);
    return NSInvocation._(_ret, _lib, retain: true, release: true);
  }

  NSMethodSignature? get methodSignature {
    final _ret = _lib._objc_msgSend_367(_id, _lib._sel_methodSignature1);
    return _ret.address == 0
        ? null
        : NSMethodSignature._(_ret, _lib, retain: true, release: true);
  }

  void retainArguments() {
    return _lib._objc_msgSend_1(_id, _lib._sel_retainArguments1);
  }

  bool get argumentsRetained {
    return _lib._objc_msgSend_12(_id, _lib._sel_argumentsRetained1);
  }

  NSObject get target {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_target1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  set target(NSObject value) {
    _lib._objc_msgSend_368(_id, _lib._sel_setTarget_1, value._id);
  }

  ffi.Pointer<ObjCSel> get selector {
    return _lib._objc_msgSend_369(_id, _lib._sel_selector1);
  }

  set selector(ffi.Pointer<ObjCSel> value) {
    _lib._objc_msgSend_370(_id, _lib._sel_setSelector_1, value);
  }

  void getReturnValue_(ffi.Pointer<ffi.Void> retLoc) {
    return _lib._objc_msgSend_47(_id, _lib._sel_getReturnValue_1, retLoc);
  }

  void setReturnValue_(ffi.Pointer<ffi.Void> retLoc) {
    return _lib._objc_msgSend_47(_id, _lib._sel_setReturnValue_1, retLoc);
  }

  void getArgument_atIndex_(ffi.Pointer<ffi.Void> argumentLocation, int idx) {
    return _lib._objc_msgSend_371(
        _id, _lib._sel_getArgument_atIndex_1, argumentLocation, idx);
  }

  void setArgument_atIndex_(ffi.Pointer<ffi.Void> argumentLocation, int idx) {
    return _lib._objc_msgSend_371(
        _id, _lib._sel_setArgument_atIndex_1, argumentLocation, idx);
  }

  void invoke() {
    return _lib._objc_msgSend_1(_id, _lib._sel_invoke1);
  }

  void invokeWithTarget_(NSObject target) {
    return _lib._objc_msgSend_15(_id, _lib._sel_invokeWithTarget_1, target._id);
  }

  static NSInvocation new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSInvocation1, _lib._sel_new1);
    return NSInvocation._(_ret, _lib, retain: false, release: true);
  }

  static NSInvocation alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSInvocation1, _lib._sel_alloc1);
    return NSInvocation._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSInvocation1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSInvocation1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSInvocation1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSInvocation1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSInvocation1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSInvocation1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSInvocation1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSInvocation1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSInvocation1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSMethodSignature extends NSObject {
  NSMethodSignature._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSMethodSignature] that points to the same underlying object as [other].
  static NSMethodSignature castFrom<T extends _ObjCWrapper>(T other) {
    return NSMethodSignature._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSMethodSignature] that wraps the given raw object pointer.
  static NSMethodSignature castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSMethodSignature._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSMethodSignature].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSMethodSignature1);
  }

  static NSMethodSignature signatureWithObjCTypes_(
      AVFAudio _lib, ffi.Pointer<ffi.Char> types) {
    final _ret = _lib._objc_msgSend_9(_lib._class_NSMethodSignature1,
        _lib._sel_signatureWithObjCTypes_1, types);
    return NSMethodSignature._(_ret, _lib, retain: true, release: true);
  }

  int get numberOfArguments {
    return _lib._objc_msgSend_10(_id, _lib._sel_numberOfArguments1);
  }

  ffi.Pointer<ffi.Char> getArgumentTypeAtIndex_(int idx) {
    return _lib._objc_msgSend_11(_id, _lib._sel_getArgumentTypeAtIndex_1, idx);
  }

  int get frameLength {
    return _lib._objc_msgSend_10(_id, _lib._sel_frameLength1);
  }

  bool isOneway() {
    return _lib._objc_msgSend_12(_id, _lib._sel_isOneway1);
  }

  ffi.Pointer<ffi.Char> get methodReturnType {
    return _lib._objc_msgSend_13(_id, _lib._sel_methodReturnType1);
  }

  int get methodReturnLength {
    return _lib._objc_msgSend_10(_id, _lib._sel_methodReturnLength1);
  }

  static NSMethodSignature new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMethodSignature1, _lib._sel_new1);
    return NSMethodSignature._(_ret, _lib, retain: false, release: true);
  }

  static NSMethodSignature alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMethodSignature1, _lib._sel_alloc1);
    return NSMethodSignature._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSMethodSignature1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSMethodSignature1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSMethodSignature1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMethodSignature1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSMethodSignature1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSMethodSignature1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSMethodSignature1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSMethodSignature1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMethodSignature1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSUInteger = ffi.UnsignedLong;

class NSSet extends NSObject {
  NSSet._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSSet] that points to the same underlying object as [other].
  static NSSet castFrom<T extends _ObjCWrapper>(T other) {
    return NSSet._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSSet] that wraps the given raw object pointer.
  static NSSet castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSSet._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSSet].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSSet1);
  }

  int get count {
    return _lib._objc_msgSend_10(_id, _lib._sel_count1);
  }

  NSObject member_(NSObject object) {
    final _ret = _lib._objc_msgSend_16(_id, _lib._sel_member_1, object._id);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSEnumerator objectEnumerator() {
    final _ret = _lib._objc_msgSend_72(_id, _lib._sel_objectEnumerator1);
    return NSEnumerator._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSSet init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  NSSet initWithObjects_count_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> objects, int cnt) {
    final _ret = _lib._objc_msgSend_61(
        _id, _lib._sel_initWithObjects_count_1, objects, cnt);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  NSSet initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get allObjects {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_allObjects1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSObject anyObject() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_anyObject1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  bool containsObject_(NSObject anObject) {
    return _lib._objc_msgSend_0(_id, _lib._sel_containsObject_1, anObject._id);
  }

  NSString? get description {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_description1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString descriptionWithLocale_(NSObject locale) {
    final _ret = _lib._objc_msgSend_65(
        _id, _lib._sel_descriptionWithLocale_1, locale._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  bool intersectsSet_(NSSet? otherSet) {
    return _lib._objc_msgSend_355(
        _id, _lib._sel_intersectsSet_1, otherSet?._id ?? ffi.nullptr);
  }

  bool isEqualToSet_(NSSet? otherSet) {
    return _lib._objc_msgSend_355(
        _id, _lib._sel_isEqualToSet_1, otherSet?._id ?? ffi.nullptr);
  }

  bool isSubsetOfSet_(NSSet? otherSet) {
    return _lib._objc_msgSend_355(
        _id, _lib._sel_isSubsetOfSet_1, otherSet?._id ?? ffi.nullptr);
  }

  void makeObjectsPerformSelector_(ffi.Pointer<ObjCSel> aSelector) {
    return _lib._objc_msgSend_7(
        _id, _lib._sel_makeObjectsPerformSelector_1, aSelector);
  }

  void makeObjectsPerformSelector_withObject_(
      ffi.Pointer<ObjCSel> aSelector, NSObject argument) {
    return _lib._objc_msgSend_82(
        _id,
        _lib._sel_makeObjectsPerformSelector_withObject_1,
        aSelector,
        argument._id);
  }

  NSSet setByAddingObject_(NSObject anObject) {
    final _ret = _lib._objc_msgSend_356(
        _id, _lib._sel_setByAddingObject_1, anObject._id);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  NSSet setByAddingObjectsFromSet_(NSSet? other) {
    final _ret = _lib._objc_msgSend_357(
        _id, _lib._sel_setByAddingObjectsFromSet_1, other?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  NSSet setByAddingObjectsFromArray_(NSArray? other) {
    final _ret = _lib._objc_msgSend_358(_id,
        _lib._sel_setByAddingObjectsFromArray_1, other?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  void enumerateObjectsUsingBlock_(ObjCBlock13 block) {
    return _lib._objc_msgSend_359(
        _id, _lib._sel_enumerateObjectsUsingBlock_1, block._id);
  }

  void enumerateObjectsWithOptions_usingBlock_(int opts, ObjCBlock13 block) {
    return _lib._objc_msgSend_360(_id,
        _lib._sel_enumerateObjectsWithOptions_usingBlock_1, opts, block._id);
  }

  NSSet objectsPassingTest_(ObjCBlock14 predicate) {
    final _ret = _lib._objc_msgSend_361(
        _id, _lib._sel_objectsPassingTest_1, predicate._id);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  NSSet objectsWithOptions_passingTest_(int opts, ObjCBlock14 predicate) {
    final _ret = _lib._objc_msgSend_362(
        _id, _lib._sel_objectsWithOptions_passingTest_1, opts, predicate._id);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static NSSet set1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSSet1, _lib._sel_set1);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static NSSet setWithObject_(AVFAudio _lib, NSObject object) {
    final _ret = _lib._objc_msgSend_16(
        _lib._class_NSSet1, _lib._sel_setWithObject_1, object._id);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static NSSet setWithObjects_count_(
      AVFAudio _lib, ffi.Pointer<ffi.Pointer<ObjCObject>> objects, int cnt) {
    final _ret = _lib._objc_msgSend_61(
        _lib._class_NSSet1, _lib._sel_setWithObjects_count_1, objects, cnt);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static NSSet setWithObjects_(AVFAudio _lib, NSObject firstObj) {
    final _ret = _lib._objc_msgSend_16(
        _lib._class_NSSet1, _lib._sel_setWithObjects_1, firstObj._id);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static NSSet setWithSet_(AVFAudio _lib, NSSet? set) {
    final _ret = _lib._objc_msgSend_363(
        _lib._class_NSSet1, _lib._sel_setWithSet_1, set?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static NSSet setWithArray_(AVFAudio _lib, NSArray? array) {
    final _ret = _lib._objc_msgSend_67(_lib._class_NSSet1,
        _lib._sel_setWithArray_1, array?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  NSSet initWithObjects_(NSObject firstObj) {
    final _ret =
        _lib._objc_msgSend_16(_id, _lib._sel_initWithObjects_1, firstObj._id);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  NSSet initWithSet_(NSSet? set) {
    final _ret = _lib._objc_msgSend_363(
        _id, _lib._sel_initWithSet_1, set?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  NSSet initWithSet_copyItems_(NSSet? set, bool flag) {
    final _ret = _lib._objc_msgSend_364(
        _id, _lib._sel_initWithSet_copyItems_1, set?._id ?? ffi.nullptr, flag);
    return NSSet._(_ret, _lib, retain: false, release: true);
  }

  NSSet initWithArray_(NSArray? array) {
    final _ret = _lib._objc_msgSend_67(
        _id, _lib._sel_initWithArray_1, array?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSObject valueForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_valueForKey_1, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  @override
  void setValue_forKey_(NSObject value, NSString? key) {
    return _lib._objc_msgSend_122(
        _id, _lib._sel_setValue_forKey_1, value._id, key?._id ?? ffi.nullptr);
  }

  @override
  void addObserver_forKeyPath_options_context_(NSObject? observer,
      NSString? keyPath, int options, ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_126(
        _id,
        _lib._sel_addObserver_forKeyPath_options_context_1,
        observer?._id ?? ffi.nullptr,
        keyPath?._id ?? ffi.nullptr,
        options,
        context);
  }

  @override
  void removeObserver_forKeyPath_context_(
      NSObject? observer, NSString? keyPath, ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_127(
        _id,
        _lib._sel_removeObserver_forKeyPath_context_1,
        observer?._id ?? ffi.nullptr,
        keyPath?._id ?? ffi.nullptr,
        context);
  }

  @override
  void removeObserver_forKeyPath_(NSObject? observer, NSString? keyPath) {
    return _lib._objc_msgSend_128(_id, _lib._sel_removeObserver_forKeyPath_1,
        observer?._id ?? ffi.nullptr, keyPath?._id ?? ffi.nullptr);
  }

  NSArray sortedArrayUsingDescriptors_(NSArray? sortDescriptors) {
    final _ret = _lib._objc_msgSend_63(
        _id,
        _lib._sel_sortedArrayUsingDescriptors_1,
        sortDescriptors?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSSet filteredSetUsingPredicate_(NSPredicate? predicate) {
    final _ret = _lib._objc_msgSend_365(_id,
        _lib._sel_filteredSetUsingPredicate_1, predicate?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static NSSet new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSSet1, _lib._sel_new1);
    return NSSet._(_ret, _lib, retain: false, release: true);
  }

  static NSSet alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSSet1, _lib._sel_alloc1);
    return NSSet._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSSet1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSSet1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSSet1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSSet1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSSet1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSSet1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSSet1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSEnumerator extends NSObject {
  NSEnumerator._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSEnumerator] that points to the same underlying object as [other].
  static NSEnumerator castFrom<T extends _ObjCWrapper>(T other) {
    return NSEnumerator._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSEnumerator] that wraps the given raw object pointer.
  static NSEnumerator castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSEnumerator._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSEnumerator].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSEnumerator1);
  }

  NSObject nextObject() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_nextObject1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSEnumerator new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSEnumerator1, _lib._sel_new1);
    return NSEnumerator._(_ret, _lib, retain: false, release: true);
  }

  static NSEnumerator alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSEnumerator1, _lib._sel_alloc1);
    return NSEnumerator._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSEnumerator1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSEnumerator1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSEnumerator1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSEnumerator1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSEnumerator1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSEnumerator1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSEnumerator1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSEnumerator1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSEnumerator1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSString extends NSObject {
  NSString._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSString] that points to the same underlying object as [other].
  static NSString castFrom<T extends _ObjCWrapper>(T other) {
    return NSString._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSString] that wraps the given raw object pointer.
  static NSString castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSString._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSString].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSString1);
  }

  factory NSString(AVFAudio _lib, String str) {
    final cstr = str.toNativeUtf8();
    final nsstr = stringWithCString_encoding_(_lib, cstr.cast(), 4 /* UTF8 */);
    pkg_ffi.calloc.free(cstr);
    return nsstr;
  }

  @override
  String toString() => (UTF8String).cast<pkg_ffi.Utf8>().toDartString();
  int get length {
    return _lib._objc_msgSend_10(_id, _lib._sel_length1);
  }

  int characterAtIndex_(int index) {
    return _lib._objc_msgSend_17(_id, _lib._sel_characterAtIndex_1, index);
  }

  @override
  NSString init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString substringFromIndex_(int from) {
    final _ret =
        _lib._objc_msgSend_293(_id, _lib._sel_substringFromIndex_1, from);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString substringToIndex_(int to) {
    final _ret = _lib._objc_msgSend_293(_id, _lib._sel_substringToIndex_1, to);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString substringWithRange_(NSRange range) {
    final _ret =
        _lib._objc_msgSend_294(_id, _lib._sel_substringWithRange_1, range);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  void getCharacters_range_(ffi.Pointer<unichar> buffer, NSRange range) {
    return _lib._objc_msgSend_295(
        _id, _lib._sel_getCharacters_range_1, buffer, range);
  }

  int compare_(NSString? string) {
    return _lib._objc_msgSend_296(
        _id, _lib._sel_compare_1, string?._id ?? ffi.nullptr);
  }

  int compare_options_(NSString? string, int mask) {
    return _lib._objc_msgSend_297(
        _id, _lib._sel_compare_options_1, string?._id ?? ffi.nullptr, mask);
  }

  int compare_options_range_(
      NSString? string, int mask, NSRange rangeOfReceiverToCompare) {
    return _lib._objc_msgSend_298(_id, _lib._sel_compare_options_range_1,
        string?._id ?? ffi.nullptr, mask, rangeOfReceiverToCompare);
  }

  int compare_options_range_locale_(NSString? string, int mask,
      NSRange rangeOfReceiverToCompare, NSObject locale) {
    return _lib._objc_msgSend_299(_id, _lib._sel_compare_options_range_locale_1,
        string?._id ?? ffi.nullptr, mask, rangeOfReceiverToCompare, locale._id);
  }

  int caseInsensitiveCompare_(NSString? string) {
    return _lib._objc_msgSend_296(
        _id, _lib._sel_caseInsensitiveCompare_1, string?._id ?? ffi.nullptr);
  }

  int localizedCompare_(NSString? string) {
    return _lib._objc_msgSend_296(
        _id, _lib._sel_localizedCompare_1, string?._id ?? ffi.nullptr);
  }

  int localizedCaseInsensitiveCompare_(NSString? string) {
    return _lib._objc_msgSend_296(
        _id,
        _lib._sel_localizedCaseInsensitiveCompare_1,
        string?._id ?? ffi.nullptr);
  }

  int localizedStandardCompare_(NSString? string) {
    return _lib._objc_msgSend_296(
        _id, _lib._sel_localizedStandardCompare_1, string?._id ?? ffi.nullptr);
  }

  bool isEqualToString_(NSString? aString) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_isEqualToString_1, aString?._id ?? ffi.nullptr);
  }

  bool hasPrefix_(NSString? str) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_hasPrefix_1, str?._id ?? ffi.nullptr);
  }

  bool hasSuffix_(NSString? str) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_hasSuffix_1, str?._id ?? ffi.nullptr);
  }

  NSString commonPrefixWithString_options_(NSString? str, int mask) {
    final _ret = _lib._objc_msgSend_300(
        _id,
        _lib._sel_commonPrefixWithString_options_1,
        str?._id ?? ffi.nullptr,
        mask);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  bool containsString_(NSString? str) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_containsString_1, str?._id ?? ffi.nullptr);
  }

  bool localizedCaseInsensitiveContainsString_(NSString? str) {
    return _lib._objc_msgSend_59(
        _id,
        _lib._sel_localizedCaseInsensitiveContainsString_1,
        str?._id ?? ffi.nullptr);
  }

  bool localizedStandardContainsString_(NSString? str) {
    return _lib._objc_msgSend_59(_id,
        _lib._sel_localizedStandardContainsString_1, str?._id ?? ffi.nullptr);
  }

  NSRange localizedStandardRangeOfString_(NSString? str) {
    return _lib._objc_msgSend_301(_id,
        _lib._sel_localizedStandardRangeOfString_1, str?._id ?? ffi.nullptr);
  }

  NSRange rangeOfString_(NSString? searchString) {
    return _lib._objc_msgSend_301(
        _id, _lib._sel_rangeOfString_1, searchString?._id ?? ffi.nullptr);
  }

  NSRange rangeOfString_options_(NSString? searchString, int mask) {
    return _lib._objc_msgSend_302(_id, _lib._sel_rangeOfString_options_1,
        searchString?._id ?? ffi.nullptr, mask);
  }

  NSRange rangeOfString_options_range_(
      NSString? searchString, int mask, NSRange rangeOfReceiverToSearch) {
    return _lib._objc_msgSend_303(_id, _lib._sel_rangeOfString_options_range_1,
        searchString?._id ?? ffi.nullptr, mask, rangeOfReceiverToSearch);
  }

  NSRange rangeOfString_options_range_locale_(NSString? searchString, int mask,
      NSRange rangeOfReceiverToSearch, NSLocale? locale) {
    return _lib._objc_msgSend_304(
        _id,
        _lib._sel_rangeOfString_options_range_locale_1,
        searchString?._id ?? ffi.nullptr,
        mask,
        rangeOfReceiverToSearch,
        locale?._id ?? ffi.nullptr);
  }

  NSRange rangeOfCharacterFromSet_(NSCharacterSet? searchSet) {
    return _lib._objc_msgSend_305(_id, _lib._sel_rangeOfCharacterFromSet_1,
        searchSet?._id ?? ffi.nullptr);
  }

  NSRange rangeOfCharacterFromSet_options_(
      NSCharacterSet? searchSet, int mask) {
    return _lib._objc_msgSend_306(
        _id,
        _lib._sel_rangeOfCharacterFromSet_options_1,
        searchSet?._id ?? ffi.nullptr,
        mask);
  }

  NSRange rangeOfCharacterFromSet_options_range_(
      NSCharacterSet? searchSet, int mask, NSRange rangeOfReceiverToSearch) {
    return _lib._objc_msgSend_307(
        _id,
        _lib._sel_rangeOfCharacterFromSet_options_range_1,
        searchSet?._id ?? ffi.nullptr,
        mask,
        rangeOfReceiverToSearch);
  }

  NSRange rangeOfComposedCharacterSequenceAtIndex_(int index) {
    return _lib._objc_msgSend_308(
        _id, _lib._sel_rangeOfComposedCharacterSequenceAtIndex_1, index);
  }

  NSRange rangeOfComposedCharacterSequencesForRange_(NSRange range) {
    return _lib._objc_msgSend_309(
        _id, _lib._sel_rangeOfComposedCharacterSequencesForRange_1, range);
  }

  NSString stringByAppendingString_(NSString? aString) {
    final _ret = _lib._objc_msgSend_64(
        _id, _lib._sel_stringByAppendingString_1, aString?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByAppendingFormat_(NSString? format) {
    final _ret = _lib._objc_msgSend_64(
        _id, _lib._sel_stringByAppendingFormat_1, format?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  double get doubleValue {
    return _lib._objc_msgSend_149(_id, _lib._sel_doubleValue1);
  }

  double get floatValue {
    return _lib._objc_msgSend_215(_id, _lib._sel_floatValue1);
  }

  int get intValue {
    return _lib._objc_msgSend_213(_id, _lib._sel_intValue1);
  }

  int get integerValue {
    return _lib._objc_msgSend_78(_id, _lib._sel_integerValue1);
  }

  int get longLongValue {
    return _lib._objc_msgSend_214(_id, _lib._sel_longLongValue1);
  }

  bool get boolValue {
    return _lib._objc_msgSend_12(_id, _lib._sel_boolValue1);
  }

  NSString? get uppercaseString {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_uppercaseString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get lowercaseString {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_lowercaseString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get capitalizedString {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_capitalizedString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get localizedUppercaseString {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_localizedUppercaseString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get localizedLowercaseString {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_localizedLowercaseString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get localizedCapitalizedString {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_localizedCapitalizedString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString uppercaseStringWithLocale_(NSLocale? locale) {
    final _ret = _lib._objc_msgSend_310(
        _id, _lib._sel_uppercaseStringWithLocale_1, locale?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString lowercaseStringWithLocale_(NSLocale? locale) {
    final _ret = _lib._objc_msgSend_310(
        _id, _lib._sel_lowercaseStringWithLocale_1, locale?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString capitalizedStringWithLocale_(NSLocale? locale) {
    final _ret = _lib._objc_msgSend_310(_id,
        _lib._sel_capitalizedStringWithLocale_1, locale?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  void getLineStart_end_contentsEnd_forRange_(
      ffi.Pointer<NSUInteger> startPtr,
      ffi.Pointer<NSUInteger> lineEndPtr,
      ffi.Pointer<NSUInteger> contentsEndPtr,
      NSRange range) {
    return _lib._objc_msgSend_311(
        _id,
        _lib._sel_getLineStart_end_contentsEnd_forRange_1,
        startPtr,
        lineEndPtr,
        contentsEndPtr,
        range);
  }

  NSRange lineRangeForRange_(NSRange range) {
    return _lib._objc_msgSend_309(_id, _lib._sel_lineRangeForRange_1, range);
  }

  void getParagraphStart_end_contentsEnd_forRange_(
      ffi.Pointer<NSUInteger> startPtr,
      ffi.Pointer<NSUInteger> parEndPtr,
      ffi.Pointer<NSUInteger> contentsEndPtr,
      NSRange range) {
    return _lib._objc_msgSend_311(
        _id,
        _lib._sel_getParagraphStart_end_contentsEnd_forRange_1,
        startPtr,
        parEndPtr,
        contentsEndPtr,
        range);
  }

  NSRange paragraphRangeForRange_(NSRange range) {
    return _lib._objc_msgSend_309(
        _id, _lib._sel_paragraphRangeForRange_1, range);
  }

  void enumerateSubstringsInRange_options_usingBlock_(
      NSRange range, int opts, ObjCBlock10 block) {
    return _lib._objc_msgSend_312(
        _id,
        _lib._sel_enumerateSubstringsInRange_options_usingBlock_1,
        range,
        opts,
        block._id);
  }

  void enumerateLinesUsingBlock_(ObjCBlock11 block) {
    return _lib._objc_msgSend_313(
        _id, _lib._sel_enumerateLinesUsingBlock_1, block._id);
  }

  ffi.Pointer<ffi.Char> get UTF8String {
    return _lib._objc_msgSend_13(_id, _lib._sel_UTF8String1);
  }

  int get fastestEncoding {
    return _lib._objc_msgSend_10(_id, _lib._sel_fastestEncoding1);
  }

  int get smallestEncoding {
    return _lib._objc_msgSend_10(_id, _lib._sel_smallestEncoding1);
  }

  NSData dataUsingEncoding_allowLossyConversion_(int encoding, bool lossy) {
    final _ret = _lib._objc_msgSend_314(_id,
        _lib._sel_dataUsingEncoding_allowLossyConversion_1, encoding, lossy);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData dataUsingEncoding_(int encoding) {
    final _ret =
        _lib._objc_msgSend_315(_id, _lib._sel_dataUsingEncoding_1, encoding);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  bool canBeConvertedToEncoding_(int encoding) {
    return _lib._objc_msgSend_89(
        _id, _lib._sel_canBeConvertedToEncoding_1, encoding);
  }

  ffi.Pointer<ffi.Char> cStringUsingEncoding_(int encoding) {
    return _lib._objc_msgSend_11(
        _id, _lib._sel_cStringUsingEncoding_1, encoding);
  }

  bool getCString_maxLength_encoding_(
      ffi.Pointer<ffi.Char> buffer, int maxBufferCount, int encoding) {
    return _lib._objc_msgSend_316(
        _id,
        _lib._sel_getCString_maxLength_encoding_1,
        buffer,
        maxBufferCount,
        encoding);
  }

  bool getBytes_maxLength_usedLength_encoding_options_range_remainingRange_(
      ffi.Pointer<ffi.Void> buffer,
      int maxBufferCount,
      ffi.Pointer<NSUInteger> usedBufferCount,
      int encoding,
      int options,
      NSRange range,
      NSRangePointer leftover) {
    return _lib._objc_msgSend_317(
        _id,
        _lib._sel_getBytes_maxLength_usedLength_encoding_options_range_remainingRange_1,
        buffer,
        maxBufferCount,
        usedBufferCount,
        encoding,
        options,
        range,
        leftover);
  }

  int maximumLengthOfBytesUsingEncoding_(int enc) {
    return _lib._objc_msgSend_86(
        _id, _lib._sel_maximumLengthOfBytesUsingEncoding_1, enc);
  }

  int lengthOfBytesUsingEncoding_(int enc) {
    return _lib._objc_msgSend_86(
        _id, _lib._sel_lengthOfBytesUsingEncoding_1, enc);
  }

  static ffi.Pointer<NSStringEncoding> getAvailableStringEncodings(
      AVFAudio _lib) {
    return _lib._objc_msgSend_318(
        _lib._class_NSString1, _lib._sel_availableStringEncodings1);
  }

  static NSString localizedNameOfStringEncoding_(AVFAudio _lib, int encoding) {
    final _ret = _lib._objc_msgSend_293(_lib._class_NSString1,
        _lib._sel_localizedNameOfStringEncoding_1, encoding);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static int getDefaultCStringEncoding(AVFAudio _lib) {
    return _lib._objc_msgSend_10(
        _lib._class_NSString1, _lib._sel_defaultCStringEncoding1);
  }

  NSString? get decomposedStringWithCanonicalMapping {
    final _ret = _lib._objc_msgSend_20(
        _id, _lib._sel_decomposedStringWithCanonicalMapping1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get precomposedStringWithCanonicalMapping {
    final _ret = _lib._objc_msgSend_20(
        _id, _lib._sel_precomposedStringWithCanonicalMapping1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get decomposedStringWithCompatibilityMapping {
    final _ret = _lib._objc_msgSend_20(
        _id, _lib._sel_decomposedStringWithCompatibilityMapping1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get precomposedStringWithCompatibilityMapping {
    final _ret = _lib._objc_msgSend_20(
        _id, _lib._sel_precomposedStringWithCompatibilityMapping1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray componentsSeparatedByString_(NSString? separator) {
    final _ret = _lib._objc_msgSend_119(_id,
        _lib._sel_componentsSeparatedByString_1, separator?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray componentsSeparatedByCharactersInSet_(NSCharacterSet? separator) {
    final _ret = _lib._objc_msgSend_319(
        _id,
        _lib._sel_componentsSeparatedByCharactersInSet_1,
        separator?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByTrimmingCharactersInSet_(NSCharacterSet? set) {
    final _ret = _lib._objc_msgSend_320(_id,
        _lib._sel_stringByTrimmingCharactersInSet_1, set?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByPaddingToLength_withString_startingAtIndex_(
      int newLength, NSString? padString, int padIndex) {
    final _ret = _lib._objc_msgSend_321(
        _id,
        _lib._sel_stringByPaddingToLength_withString_startingAtIndex_1,
        newLength,
        padString?._id ?? ffi.nullptr,
        padIndex);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByFoldingWithOptions_locale_(int options, NSLocale? locale) {
    final _ret = _lib._objc_msgSend_322(
        _id,
        _lib._sel_stringByFoldingWithOptions_locale_1,
        options,
        locale?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByReplacingOccurrencesOfString_withString_options_range_(
      NSString? target,
      NSString? replacement,
      int options,
      NSRange searchRange) {
    final _ret = _lib._objc_msgSend_323(
        _id,
        _lib._sel_stringByReplacingOccurrencesOfString_withString_options_range_1,
        target?._id ?? ffi.nullptr,
        replacement?._id ?? ffi.nullptr,
        options,
        searchRange);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByReplacingOccurrencesOfString_withString_(
      NSString? target, NSString? replacement) {
    final _ret = _lib._objc_msgSend_324(
        _id,
        _lib._sel_stringByReplacingOccurrencesOfString_withString_1,
        target?._id ?? ffi.nullptr,
        replacement?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByReplacingCharactersInRange_withString_(
      NSRange range, NSString? replacement) {
    final _ret = _lib._objc_msgSend_325(
        _id,
        _lib._sel_stringByReplacingCharactersInRange_withString_1,
        range,
        replacement?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByApplyingTransform_reverse_(
      NSStringTransform transform, bool reverse) {
    final _ret = _lib._objc_msgSend_326(
        _id, _lib._sel_stringByApplyingTransform_reverse_1, transform, reverse);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  bool writeToURL_atomically_encoding_error_(NSURL? url, bool useAuxiliaryFile,
      int enc, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_327(
        _id,
        _lib._sel_writeToURL_atomically_encoding_error_1,
        url?._id ?? ffi.nullptr,
        useAuxiliaryFile,
        enc,
        error);
  }

  bool writeToFile_atomically_encoding_error_(
      NSString? path,
      bool useAuxiliaryFile,
      int enc,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_328(
        _id,
        _lib._sel_writeToFile_atomically_encoding_error_1,
        path?._id ?? ffi.nullptr,
        useAuxiliaryFile,
        enc,
        error);
  }

  NSString? get description {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_description1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get hash {
    return _lib._objc_msgSend_10(_id, _lib._sel_hash1);
  }

  NSString initWithCharactersNoCopy_length_freeWhenDone_(
      ffi.Pointer<unichar> characters, int length, bool freeBuffer) {
    final _ret = _lib._objc_msgSend_329(
        _id,
        _lib._sel_initWithCharactersNoCopy_length_freeWhenDone_1,
        characters,
        length,
        freeBuffer);
    return NSString._(_ret, _lib, retain: false, release: true);
  }

  NSString initWithCharactersNoCopy_length_deallocator_(
      ffi.Pointer<unichar> chars, int len, ObjCBlock12 deallocator) {
    final _ret = _lib._objc_msgSend_330(
        _id,
        _lib._sel_initWithCharactersNoCopy_length_deallocator_1,
        chars,
        len,
        deallocator._id);
    return NSString._(_ret, _lib, retain: false, release: true);
  }

  NSString initWithCharacters_length_(
      ffi.Pointer<unichar> characters, int length) {
    final _ret = _lib._objc_msgSend_331(
        _id, _lib._sel_initWithCharacters_length_1, characters, length);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithUTF8String_(ffi.Pointer<ffi.Char> nullTerminatedCString) {
    final _ret = _lib._objc_msgSend_332(
        _id, _lib._sel_initWithUTF8String_1, nullTerminatedCString);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithString_(NSString? aString) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithString_1, aString?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithFormat_(NSString? format) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithFormat_1, format?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithFormat_arguments_(
      NSString? format, ffi.Pointer<__va_list_tag> argList) {
    final _ret = _lib._objc_msgSend_333(
        _id,
        _lib._sel_initWithFormat_arguments_1,
        format?._id ?? ffi.nullptr,
        argList);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithFormat_locale_(NSString? format, NSObject locale) {
    final _ret = _lib._objc_msgSend_157(_id, _lib._sel_initWithFormat_locale_1,
        format?._id ?? ffi.nullptr, locale._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithFormat_locale_arguments_(
      NSString? format, NSObject locale, ffi.Pointer<__va_list_tag> argList) {
    final _ret = _lib._objc_msgSend_334(
        _id,
        _lib._sel_initWithFormat_locale_arguments_1,
        format?._id ?? ffi.nullptr,
        locale._id,
        argList);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithData_encoding_(NSData? data, int encoding) {
    final _ret = _lib._objc_msgSend_335(_id, _lib._sel_initWithData_encoding_1,
        data?._id ?? ffi.nullptr, encoding);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithBytes_length_encoding_(
      ffi.Pointer<ffi.Void> bytes, int len, int encoding) {
    final _ret = _lib._objc_msgSend_336(
        _id, _lib._sel_initWithBytes_length_encoding_1, bytes, len, encoding);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithBytesNoCopy_length_encoding_freeWhenDone_(
      ffi.Pointer<ffi.Void> bytes, int len, int encoding, bool freeBuffer) {
    final _ret = _lib._objc_msgSend_337(
        _id,
        _lib._sel_initWithBytesNoCopy_length_encoding_freeWhenDone_1,
        bytes,
        len,
        encoding,
        freeBuffer);
    return NSString._(_ret, _lib, retain: false, release: true);
  }

  NSString initWithBytesNoCopy_length_encoding_deallocator_(
      ffi.Pointer<ffi.Void> bytes,
      int len,
      int encoding,
      ObjCBlock9 deallocator) {
    final _ret = _lib._objc_msgSend_338(
        _id,
        _lib._sel_initWithBytesNoCopy_length_encoding_deallocator_1,
        bytes,
        len,
        encoding,
        deallocator._id);
    return NSString._(_ret, _lib, retain: false, release: true);
  }

  static NSString string(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSString1, _lib._sel_string1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString stringWithString_(AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSString1,
        _lib._sel_stringWithString_1, string?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString stringWithCharacters_length_(
      AVFAudio _lib, ffi.Pointer<unichar> characters, int length) {
    final _ret = _lib._objc_msgSend_331(_lib._class_NSString1,
        _lib._sel_stringWithCharacters_length_1, characters, length);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString stringWithUTF8String_(
      AVFAudio _lib, ffi.Pointer<ffi.Char> nullTerminatedCString) {
    final _ret = _lib._objc_msgSend_332(_lib._class_NSString1,
        _lib._sel_stringWithUTF8String_1, nullTerminatedCString);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString stringWithFormat_(AVFAudio _lib, NSString? format) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSString1,
        _lib._sel_stringWithFormat_1, format?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString localizedStringWithFormat_(AVFAudio _lib, NSString? format) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSString1,
        _lib._sel_localizedStringWithFormat_1, format?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithCString_encoding_(
      ffi.Pointer<ffi.Char> nullTerminatedCString, int encoding) {
    final _ret = _lib._objc_msgSend_339(_id,
        _lib._sel_initWithCString_encoding_1, nullTerminatedCString, encoding);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString stringWithCString_encoding_(
      AVFAudio _lib, ffi.Pointer<ffi.Char> cString, int enc) {
    final _ret = _lib._objc_msgSend_339(_lib._class_NSString1,
        _lib._sel_stringWithCString_encoding_1, cString, enc);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithContentsOfURL_encoding_error_(
      NSURL? url, int enc, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_340(
        _id,
        _lib._sel_initWithContentsOfURL_encoding_error_1,
        url?._id ?? ffi.nullptr,
        enc,
        error);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithContentsOfFile_encoding_error_(
      NSString? path, int enc, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_341(
        _id,
        _lib._sel_initWithContentsOfFile_encoding_error_1,
        path?._id ?? ffi.nullptr,
        enc,
        error);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString stringWithContentsOfURL_encoding_error_(AVFAudio _lib,
      NSURL? url, int enc, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_340(
        _lib._class_NSString1,
        _lib._sel_stringWithContentsOfURL_encoding_error_1,
        url?._id ?? ffi.nullptr,
        enc,
        error);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString stringWithContentsOfFile_encoding_error_(AVFAudio _lib,
      NSString? path, int enc, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_341(
        _lib._class_NSString1,
        _lib._sel_stringWithContentsOfFile_encoding_error_1,
        path?._id ?? ffi.nullptr,
        enc,
        error);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithContentsOfURL_usedEncoding_error_(
      NSURL? url,
      ffi.Pointer<NSStringEncoding> enc,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_342(
        _id,
        _lib._sel_initWithContentsOfURL_usedEncoding_error_1,
        url?._id ?? ffi.nullptr,
        enc,
        error);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString initWithContentsOfFile_usedEncoding_error_(
      NSString? path,
      ffi.Pointer<NSStringEncoding> enc,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_343(
        _id,
        _lib._sel_initWithContentsOfFile_usedEncoding_error_1,
        path?._id ?? ffi.nullptr,
        enc,
        error);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString stringWithContentsOfURL_usedEncoding_error_(
      AVFAudio _lib,
      NSURL? url,
      ffi.Pointer<NSStringEncoding> enc,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_342(
        _lib._class_NSString1,
        _lib._sel_stringWithContentsOfURL_usedEncoding_error_1,
        url?._id ?? ffi.nullptr,
        enc,
        error);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString stringWithContentsOfFile_usedEncoding_error_(
      AVFAudio _lib,
      NSString? path,
      ffi.Pointer<NSStringEncoding> enc,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_343(
        _lib._class_NSString1,
        _lib._sel_stringWithContentsOfFile_usedEncoding_error_1,
        path?._id ?? ffi.nullptr,
        enc,
        error);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static int
      stringEncodingForData_encodingOptions_convertedString_usedLossyConversion_(
          AVFAudio _lib,
          NSData? data,
          NSDictionary? opts,
          ffi.Pointer<ffi.Pointer<ObjCObject>> string,
          ffi.Pointer<ffi.Bool> usedLossyConversion) {
    return _lib._objc_msgSend_344(
        _lib._class_NSString1,
        _lib._sel_stringEncodingForData_encodingOptions_convertedString_usedLossyConversion_1,
        data?._id ?? ffi.nullptr,
        opts?._id ?? ffi.nullptr,
        string,
        usedLossyConversion);
  }

  NSObject propertyList() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_propertyList1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary propertyListFromStringsFileFormat() {
    final _ret = _lib._objc_msgSend_164(
        _id, _lib._sel_propertyListFromStringsFileFormat1);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  ffi.Pointer<ffi.Char> cString() {
    return _lib._objc_msgSend_13(_id, _lib._sel_cString1);
  }

  ffi.Pointer<ffi.Char> lossyCString() {
    return _lib._objc_msgSend_13(_id, _lib._sel_lossyCString1);
  }

  int cStringLength() {
    return _lib._objc_msgSend_10(_id, _lib._sel_cStringLength1);
  }

  void getCString_(ffi.Pointer<ffi.Char> bytes) {
    return _lib._objc_msgSend_251(_id, _lib._sel_getCString_1, bytes);
  }

  void getCString_maxLength_(ffi.Pointer<ffi.Char> bytes, int maxLength) {
    return _lib._objc_msgSend_345(
        _id, _lib._sel_getCString_maxLength_1, bytes, maxLength);
  }

  void getCString_maxLength_range_remainingRange_(ffi.Pointer<ffi.Char> bytes,
      int maxLength, NSRange aRange, NSRangePointer leftoverRange) {
    return _lib._objc_msgSend_346(
        _id,
        _lib._sel_getCString_maxLength_range_remainingRange_1,
        bytes,
        maxLength,
        aRange,
        leftoverRange);
  }

  bool writeToFile_atomically_(NSString? path, bool useAuxiliaryFile) {
    return _lib._objc_msgSend_25(_id, _lib._sel_writeToFile_atomically_1,
        path?._id ?? ffi.nullptr, useAuxiliaryFile);
  }

  bool writeToURL_atomically_(NSURL? url, bool atomically) {
    return _lib._objc_msgSend_121(_id, _lib._sel_writeToURL_atomically_1,
        url?._id ?? ffi.nullptr, atomically);
  }

  NSObject initWithContentsOfFile_(NSString? path) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithContentsOfURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_226(
        _id, _lib._sel_initWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject stringWithContentsOfFile_(AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSString1,
        _lib._sel_stringWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject stringWithContentsOfURL_(AVFAudio _lib, NSURL? url) {
    final _ret = _lib._objc_msgSend_226(_lib._class_NSString1,
        _lib._sel_stringWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithCStringNoCopy_length_freeWhenDone_(
      ffi.Pointer<ffi.Char> bytes, int length, bool freeBuffer) {
    final _ret = _lib._objc_msgSend_347(
        _id,
        _lib._sel_initWithCStringNoCopy_length_freeWhenDone_1,
        bytes,
        length,
        freeBuffer);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  NSObject initWithCString_length_(ffi.Pointer<ffi.Char> bytes, int length) {
    final _ret = _lib._objc_msgSend_339(
        _id, _lib._sel_initWithCString_length_1, bytes, length);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithCString_(ffi.Pointer<ffi.Char> bytes) {
    final _ret =
        _lib._objc_msgSend_332(_id, _lib._sel_initWithCString_1, bytes);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject stringWithCString_length_(
      AVFAudio _lib, ffi.Pointer<ffi.Char> bytes, int length) {
    final _ret = _lib._objc_msgSend_339(_lib._class_NSString1,
        _lib._sel_stringWithCString_length_1, bytes, length);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject stringWithCString_(
      AVFAudio _lib, ffi.Pointer<ffi.Char> bytes) {
    final _ret = _lib._objc_msgSend_332(
        _lib._class_NSString1, _lib._sel_stringWithCString_1, bytes);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void getCharacters_(ffi.Pointer<unichar> buffer) {
    return _lib._objc_msgSend_348(_id, _lib._sel_getCharacters_1, buffer);
  }

  NSString variantFittingPresentationWidth_(int width) {
    final _ret = _lib._objc_msgSend_349(
        _id, _lib._sel_variantFittingPresentationWidth_1, width);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString pathWithComponents_(AVFAudio _lib, NSArray? components) {
    final _ret = _lib._objc_msgSend_350(_lib._class_NSString1,
        _lib._sel_pathWithComponents_1, components?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get pathComponents {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_pathComponents1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  bool get absolutePath {
    return _lib._objc_msgSend_12(_id, _lib._sel_isAbsolutePath1);
  }

  NSString? get lastPathComponent {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_lastPathComponent1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get stringByDeletingLastPathComponent {
    final _ret = _lib._objc_msgSend_20(
        _id, _lib._sel_stringByDeletingLastPathComponent1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByAppendingPathComponent_(NSString? str) {
    final _ret = _lib._objc_msgSend_64(_id,
        _lib._sel_stringByAppendingPathComponent_1, str?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get pathExtension {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_pathExtension1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get stringByDeletingPathExtension {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_stringByDeletingPathExtension1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByAppendingPathExtension_(NSString? str) {
    final _ret = _lib._objc_msgSend_64(_id,
        _lib._sel_stringByAppendingPathExtension_1, str?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get stringByAbbreviatingWithTildeInPath {
    final _ret = _lib._objc_msgSend_20(
        _id, _lib._sel_stringByAbbreviatingWithTildeInPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get stringByExpandingTildeInPath {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_stringByExpandingTildeInPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get stringByStandardizingPath {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_stringByStandardizingPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get stringByResolvingSymlinksInPath {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_stringByResolvingSymlinksInPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray stringsByAppendingPaths_(NSArray? paths) {
    final _ret = _lib._objc_msgSend_63(
        _id, _lib._sel_stringsByAppendingPaths_1, paths?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  int completePathIntoString_caseSensitive_matchesIntoArray_filterTypes_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputName,
      bool flag,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputArray,
      NSArray? filterTypes) {
    return _lib._objc_msgSend_351(
        _id,
        _lib._sel_completePathIntoString_caseSensitive_matchesIntoArray_filterTypes_1,
        outputName,
        flag,
        outputArray,
        filterTypes?._id ?? ffi.nullptr);
  }

  ffi.Pointer<ffi.Char> get fileSystemRepresentation {
    return _lib._objc_msgSend_13(_id, _lib._sel_fileSystemRepresentation1);
  }

  bool getFileSystemRepresentation_maxLength_(
      ffi.Pointer<ffi.Char> cname, int max) {
    return _lib._objc_msgSend_218(
        _id, _lib._sel_getFileSystemRepresentation_maxLength_1, cname, max);
  }

  NSString stringByAddingPercentEncodingWithAllowedCharacters_(
      NSCharacterSet? allowedCharacters) {
    final _ret = _lib._objc_msgSend_320(
        _id,
        _lib._sel_stringByAddingPercentEncodingWithAllowedCharacters_1,
        allowedCharacters?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get stringByRemovingPercentEncoding {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_stringByRemovingPercentEncoding1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByAddingPercentEscapesUsingEncoding_(int enc) {
    final _ret = _lib._objc_msgSend_293(
        _id, _lib._sel_stringByAddingPercentEscapesUsingEncoding_1, enc);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString stringByReplacingPercentEscapesUsingEncoding_(int enc) {
    final _ret = _lib._objc_msgSend_293(
        _id, _lib._sel_stringByReplacingPercentEscapesUsingEncoding_1, enc);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray linguisticTagsInRange_scheme_options_orthography_tokenRanges_(
      NSRange range,
      NSLinguisticTagScheme scheme,
      int options,
      NSOrthography? orthography,
      ffi.Pointer<ffi.Pointer<ObjCObject>> tokenRanges) {
    final _ret = _lib._objc_msgSend_353(
        _id,
        _lib._sel_linguisticTagsInRange_scheme_options_orthography_tokenRanges_1,
        range,
        scheme,
        options,
        orthography?._id ?? ffi.nullptr,
        tokenRanges);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  void enumerateLinguisticTagsInRange_scheme_options_orthography_usingBlock_(
      NSRange range,
      NSLinguisticTagScheme scheme,
      int options,
      NSOrthography? orthography,
      ObjCBlock10 block) {
    return _lib._objc_msgSend_354(
        _id,
        _lib._sel_enumerateLinguisticTagsInRange_scheme_options_orthography_usingBlock_1,
        range,
        scheme,
        options,
        orthography?._id ?? ffi.nullptr,
        block._id);
  }

  static NSString new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSString1, _lib._sel_new1);
    return NSString._(_ret, _lib, retain: false, release: true);
  }

  static NSString alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSString1, _lib._sel_alloc1);
    return NSString._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSString1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSString1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSString1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSString1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSString1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSString1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSString1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSString1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSString1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

extension StringToNSString on String {
  NSString toNSString(AVFAudio lib) => NSString(lib, this);
}

typedef unichar = ffi.UnsignedShort;

class NSCoder extends NSObject {
  NSCoder._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSCoder] that points to the same underlying object as [other].
  static NSCoder castFrom<T extends _ObjCWrapper>(T other) {
    return NSCoder._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSCoder] that wraps the given raw object pointer.
  static NSCoder castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSCoder._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSCoder].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSCoder1);
  }

  void encodeValueOfObjCType_at_(
      ffi.Pointer<ffi.Char> type, ffi.Pointer<ffi.Void> addr) {
    return _lib._objc_msgSend_18(
        _id, _lib._sel_encodeValueOfObjCType_at_1, type, addr);
  }

  void encodeDataObject_(NSData? data) {
    return _lib._objc_msgSend_248(
        _id, _lib._sel_encodeDataObject_1, data?._id ?? ffi.nullptr);
  }

  NSData decodeDataObject() {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_decodeDataObject1);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  void decodeValueOfObjCType_at_size_(
      ffi.Pointer<ffi.Char> type, ffi.Pointer<ffi.Void> data, int size) {
    return _lib._objc_msgSend_249(
        _id, _lib._sel_decodeValueOfObjCType_at_size_1, type, data, size);
  }

  int versionForClassName_(NSString? className) {
    return _lib._objc_msgSend_250(
        _id, _lib._sel_versionForClassName_1, className?._id ?? ffi.nullptr);
  }

  void encodeObject_(NSObject object) {
    return _lib._objc_msgSend_15(_id, _lib._sel_encodeObject_1, object._id);
  }

  void encodeRootObject_(NSObject rootObject) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_encodeRootObject_1, rootObject._id);
  }

  void encodeBycopyObject_(NSObject anObject) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_encodeBycopyObject_1, anObject._id);
  }

  void encodeByrefObject_(NSObject anObject) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_encodeByrefObject_1, anObject._id);
  }

  void encodeConditionalObject_(NSObject object) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_encodeConditionalObject_1, object._id);
  }

  void encodeValuesOfObjCTypes_(ffi.Pointer<ffi.Char> types) {
    return _lib._objc_msgSend_251(
        _id, _lib._sel_encodeValuesOfObjCTypes_1, types);
  }

  void encodeArrayOfObjCType_count_at_(
      ffi.Pointer<ffi.Char> type, int count, ffi.Pointer<ffi.Void> array) {
    return _lib._objc_msgSend_252(
        _id, _lib._sel_encodeArrayOfObjCType_count_at_1, type, count, array);
  }

  void encodeBytes_length_(ffi.Pointer<ffi.Void> byteaddr, int length) {
    return _lib._objc_msgSend_21(
        _id, _lib._sel_encodeBytes_length_1, byteaddr, length);
  }

  NSObject decodeObject() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_decodeObject1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject decodeTopLevelObjectAndReturnError_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_253(
        _id, _lib._sel_decodeTopLevelObjectAndReturnError_1, error);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void decodeValuesOfObjCTypes_(ffi.Pointer<ffi.Char> types) {
    return _lib._objc_msgSend_251(
        _id, _lib._sel_decodeValuesOfObjCTypes_1, types);
  }

  void decodeArrayOfObjCType_count_at_(
      ffi.Pointer<ffi.Char> itemType, int count, ffi.Pointer<ffi.Void> array) {
    return _lib._objc_msgSend_252(_id,
        _lib._sel_decodeArrayOfObjCType_count_at_1, itemType, count, array);
  }

  ffi.Pointer<ffi.Void> decodeBytesWithReturnedLength_(
      ffi.Pointer<NSUInteger> lengthp) {
    return _lib._objc_msgSend_254(
        _id, _lib._sel_decodeBytesWithReturnedLength_1, lengthp);
  }

  void encodePropertyList_(NSObject aPropertyList) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_encodePropertyList_1, aPropertyList._id);
  }

  NSObject decodePropertyList() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_decodePropertyList1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void setObjectZone_(ffi.Pointer<NSZone> zone) {
    return _lib._objc_msgSend_255(_id, _lib._sel_setObjectZone_1, zone);
  }

  ffi.Pointer<NSZone> objectZone() {
    return _lib._objc_msgSend_256(_id, _lib._sel_objectZone1);
  }

  int get systemVersion {
    return _lib._objc_msgSend_191(_id, _lib._sel_systemVersion1);
  }

  bool get allowsKeyedCoding {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsKeyedCoding1);
  }

  void encodeObject_forKey_(NSObject object, NSString? key) {
    return _lib._objc_msgSend_122(_id, _lib._sel_encodeObject_forKey_1,
        object._id, key?._id ?? ffi.nullptr);
  }

  void encodeConditionalObject_forKey_(NSObject object, NSString? key) {
    return _lib._objc_msgSend_122(
        _id,
        _lib._sel_encodeConditionalObject_forKey_1,
        object._id,
        key?._id ?? ffi.nullptr);
  }

  void encodeBool_forKey_(bool value, NSString? key) {
    return _lib._objc_msgSend_257(
        _id, _lib._sel_encodeBool_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  void encodeInt_forKey_(int value, NSString? key) {
    return _lib._objc_msgSend_258(
        _id, _lib._sel_encodeInt_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  void encodeInt32_forKey_(int value, NSString? key) {
    return _lib._objc_msgSend_259(
        _id, _lib._sel_encodeInt32_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  void encodeInt64_forKey_(int value, NSString? key) {
    return _lib._objc_msgSend_260(
        _id, _lib._sel_encodeInt64_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  void encodeFloat_forKey_(double value, NSString? key) {
    return _lib._objc_msgSend_261(
        _id, _lib._sel_encodeFloat_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  void encodeDouble_forKey_(double value, NSString? key) {
    return _lib._objc_msgSend_262(
        _id, _lib._sel_encodeDouble_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  void encodeBytes_length_forKey_(
      ffi.Pointer<ffi.Uint8> bytes, int length, NSString? key) {
    return _lib._objc_msgSend_263(_id, _lib._sel_encodeBytes_length_forKey_1,
        bytes, length, key?._id ?? ffi.nullptr);
  }

  bool containsValueForKey_(NSString? key) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_containsValueForKey_1, key?._id ?? ffi.nullptr);
  }

  NSObject decodeObjectForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_decodeObjectForKey_1, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject decodeTopLevelObjectForKey_error_(
      NSString? key, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_264(
        _id,
        _lib._sel_decodeTopLevelObjectForKey_error_1,
        key?._id ?? ffi.nullptr,
        error);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  bool decodeBoolForKey_(NSString? key) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_decodeBoolForKey_1, key?._id ?? ffi.nullptr);
  }

  int decodeIntForKey_(NSString? key) {
    return _lib._objc_msgSend_265(
        _id, _lib._sel_decodeIntForKey_1, key?._id ?? ffi.nullptr);
  }

  int decodeInt32ForKey_(NSString? key) {
    return _lib._objc_msgSend_266(
        _id, _lib._sel_decodeInt32ForKey_1, key?._id ?? ffi.nullptr);
  }

  int decodeInt64ForKey_(NSString? key) {
    return _lib._objc_msgSend_267(
        _id, _lib._sel_decodeInt64ForKey_1, key?._id ?? ffi.nullptr);
  }

  double decodeFloatForKey_(NSString? key) {
    return _lib._objc_msgSend_268(
        _id, _lib._sel_decodeFloatForKey_1, key?._id ?? ffi.nullptr);
  }

  double decodeDoubleForKey_(NSString? key) {
    return _lib._objc_msgSend_269(
        _id, _lib._sel_decodeDoubleForKey_1, key?._id ?? ffi.nullptr);
  }

  ffi.Pointer<ffi.Uint8> decodeBytesForKey_returnedLength_(
      NSString? key, ffi.Pointer<NSUInteger> lengthp) {
    return _lib._objc_msgSend_270(
        _id,
        _lib._sel_decodeBytesForKey_returnedLength_1,
        key?._id ?? ffi.nullptr,
        lengthp);
  }

  void encodeInteger_forKey_(int value, NSString? key) {
    return _lib._objc_msgSend_271(
        _id, _lib._sel_encodeInteger_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  int decodeIntegerForKey_(NSString? key) {
    return _lib._objc_msgSend_250(
        _id, _lib._sel_decodeIntegerForKey_1, key?._id ?? ffi.nullptr);
  }

  bool get requiresSecureCoding {
    return _lib._objc_msgSend_12(_id, _lib._sel_requiresSecureCoding1);
  }

  NSObject decodeObjectOfClass_forKey_(NSObject aClass, NSString? key) {
    final _ret = _lib._objc_msgSend_272(
        _id,
        _lib._sel_decodeObjectOfClass_forKey_1,
        aClass._id,
        key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject decodeTopLevelObjectOfClass_forKey_error_(NSObject aClass,
      NSString? key, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_273(
        _id,
        _lib._sel_decodeTopLevelObjectOfClass_forKey_error_1,
        aClass._id,
        key?._id ?? ffi.nullptr,
        error);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSArray decodeArrayOfObjectsOfClass_forKey_(NSObject cls, NSString? key) {
    final _ret = _lib._objc_msgSend_274(
        _id,
        _lib._sel_decodeArrayOfObjectsOfClass_forKey_1,
        cls._id,
        key?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary decodeDictionaryWithKeysOfClass_objectsOfClass_forKey_(
      NSObject keyCls, NSObject objectCls, NSString? key) {
    final _ret = _lib._objc_msgSend_275(
        _id,
        _lib._sel_decodeDictionaryWithKeysOfClass_objectsOfClass_forKey_1,
        keyCls._id,
        objectCls._id,
        key?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSObject decodeObjectOfClasses_forKey_(NSSet? classes, NSString? key) {
    final _ret = _lib._objc_msgSend_276(
        _id,
        _lib._sel_decodeObjectOfClasses_forKey_1,
        classes?._id ?? ffi.nullptr,
        key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject decodeTopLevelObjectOfClasses_forKey_error_(NSSet? classes,
      NSString? key, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_277(
        _id,
        _lib._sel_decodeTopLevelObjectOfClasses_forKey_error_1,
        classes?._id ?? ffi.nullptr,
        key?._id ?? ffi.nullptr,
        error);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSArray decodeArrayOfObjectsOfClasses_forKey_(NSSet? classes, NSString? key) {
    final _ret = _lib._objc_msgSend_278(
        _id,
        _lib._sel_decodeArrayOfObjectsOfClasses_forKey_1,
        classes?._id ?? ffi.nullptr,
        key?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary decodeDictionaryWithKeysOfClasses_objectsOfClasses_forKey_(
      NSSet? keyClasses, NSSet? objectClasses, NSString? key) {
    final _ret = _lib._objc_msgSend_279(
        _id,
        _lib._sel_decodeDictionaryWithKeysOfClasses_objectsOfClasses_forKey_1,
        keyClasses?._id ?? ffi.nullptr,
        objectClasses?._id ?? ffi.nullptr,
        key?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSObject decodePropertyListForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_decodePropertyListForKey_1, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSSet? get allowedClasses {
    final _ret = _lib._objc_msgSend_280(_id, _lib._sel_allowedClasses1);
    return _ret.address == 0
        ? null
        : NSSet._(_ret, _lib, retain: true, release: true);
  }

  void failWithError_(NSError? error) {
    return _lib._objc_msgSend_281(
        _id, _lib._sel_failWithError_1, error?._id ?? ffi.nullptr);
  }

  int get decodingFailurePolicy {
    return _lib._objc_msgSend_282(_id, _lib._sel_decodingFailurePolicy1);
  }

  NSError? get error {
    final _ret = _lib._objc_msgSend_283(_id, _lib._sel_error1);
    return _ret.address == 0
        ? null
        : NSError._(_ret, _lib, retain: true, release: true);
  }

  void encodeNXObject_(NSObject object) {
    return _lib._objc_msgSend_15(_id, _lib._sel_encodeNXObject_1, object._id);
  }

  NSObject decodeNXObject() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_decodeNXObject1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void decodeValueOfObjCType_at_(
      ffi.Pointer<ffi.Char> type, ffi.Pointer<ffi.Void> data) {
    return _lib._objc_msgSend_18(
        _id, _lib._sel_decodeValueOfObjCType_at_1, type, data);
  }

  void encodePoint_(NSPoint point) {
    return _lib._objc_msgSend_284(_id, _lib._sel_encodePoint_1, point);
  }

  NSPoint decodePoint() {
    return _lib._objc_msgSend_54(_id, _lib._sel_decodePoint1);
  }

  void encodeSize_(NSSize size) {
    return _lib._objc_msgSend_285(_id, _lib._sel_encodeSize_1, size);
  }

  NSSize decodeSize() {
    return _lib._objc_msgSend_55(_id, _lib._sel_decodeSize1);
  }

  void encodeRect_(NSRect rect) {
    return _lib._objc_msgSend_286(_id, _lib._sel_encodeRect_1, rect);
  }

  NSRect decodeRect() {
    return _lib._objc_msgSend_56(_id, _lib._sel_decodeRect1);
  }

  void encodePoint_forKey_(NSPoint point, NSString? key) {
    return _lib._objc_msgSend_287(
        _id, _lib._sel_encodePoint_forKey_1, point, key?._id ?? ffi.nullptr);
  }

  void encodeSize_forKey_(NSSize size, NSString? key) {
    return _lib._objc_msgSend_288(
        _id, _lib._sel_encodeSize_forKey_1, size, key?._id ?? ffi.nullptr);
  }

  void encodeRect_forKey_(NSRect rect, NSString? key) {
    return _lib._objc_msgSend_289(
        _id, _lib._sel_encodeRect_forKey_1, rect, key?._id ?? ffi.nullptr);
  }

  NSPoint decodePointForKey_(NSString? key) {
    return _lib._objc_msgSend_290(
        _id, _lib._sel_decodePointForKey_1, key?._id ?? ffi.nullptr);
  }

  NSSize decodeSizeForKey_(NSString? key) {
    return _lib._objc_msgSend_291(
        _id, _lib._sel_decodeSizeForKey_1, key?._id ?? ffi.nullptr);
  }

  NSRect decodeRectForKey_(NSString? key) {
    return _lib._objc_msgSend_292(
        _id, _lib._sel_decodeRectForKey_1, key?._id ?? ffi.nullptr);
  }

  static NSCoder new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSCoder1, _lib._sel_new1);
    return NSCoder._(_ret, _lib, retain: false, release: true);
  }

  static NSCoder alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSCoder1, _lib._sel_alloc1);
    return NSCoder._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSCoder1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSCoder1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSCoder1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSCoder1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSCoder1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSCoder1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSCoder1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSCoder1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSCoder1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSData extends NSObject {
  NSData._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSData] that points to the same underlying object as [other].
  static NSData castFrom<T extends _ObjCWrapper>(T other) {
    return NSData._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSData] that wraps the given raw object pointer.
  static NSData castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSData._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSData].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSData1);
  }

  int get length {
    return _lib._objc_msgSend_10(_id, _lib._sel_length1);
  }

  ffi.Pointer<ffi.Void> get bytes {
    return _lib._objc_msgSend_19(_id, _lib._sel_bytes1);
  }

  NSString? get description {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_description1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  void getBytes_length_(ffi.Pointer<ffi.Void> buffer, int length) {
    return _lib._objc_msgSend_21(
        _id, _lib._sel_getBytes_length_1, buffer, length);
  }

  void getBytes_range_(ffi.Pointer<ffi.Void> buffer, NSRange range) {
    return _lib._objc_msgSend_22(
        _id, _lib._sel_getBytes_range_1, buffer, range);
  }

  bool isEqualToData_(NSData? other) {
    return _lib._objc_msgSend_23(
        _id, _lib._sel_isEqualToData_1, other?._id ?? ffi.nullptr);
  }

  NSData subdataWithRange_(NSRange range) {
    final _ret =
        _lib._objc_msgSend_24(_id, _lib._sel_subdataWithRange_1, range);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  bool writeToFile_atomically_(NSString? path, bool useAuxiliaryFile) {
    return _lib._objc_msgSend_25(_id, _lib._sel_writeToFile_atomically_1,
        path?._id ?? ffi.nullptr, useAuxiliaryFile);
  }

  bool writeToURL_atomically_(NSURL? url, bool atomically) {
    return _lib._objc_msgSend_121(_id, _lib._sel_writeToURL_atomically_1,
        url?._id ?? ffi.nullptr, atomically);
  }

  bool writeToFile_options_error_(NSString? path, int writeOptionsMask,
      ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr) {
    return _lib._objc_msgSend_233(_id, _lib._sel_writeToFile_options_error_1,
        path?._id ?? ffi.nullptr, writeOptionsMask, errorPtr);
  }

  bool writeToURL_options_error_(NSURL? url, int writeOptionsMask,
      ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr) {
    return _lib._objc_msgSend_234(_id, _lib._sel_writeToURL_options_error_1,
        url?._id ?? ffi.nullptr, writeOptionsMask, errorPtr);
  }

  NSRange rangeOfData_options_range_(
      NSData? dataToFind, int mask, NSRange searchRange) {
    return _lib._objc_msgSend_235(_id, _lib._sel_rangeOfData_options_range_1,
        dataToFind?._id ?? ffi.nullptr, mask, searchRange);
  }

  void enumerateByteRangesUsingBlock_(ObjCBlock8 block) {
    return _lib._objc_msgSend_236(
        _id, _lib._sel_enumerateByteRangesUsingBlock_1, block._id);
  }

  static NSData data(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSData1, _lib._sel_data1);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  static NSData dataWithBytes_length_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> bytes, int length) {
    final _ret = _lib._objc_msgSend_237(
        _lib._class_NSData1, _lib._sel_dataWithBytes_length_1, bytes, length);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  static NSData dataWithBytesNoCopy_length_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> bytes, int length) {
    final _ret = _lib._objc_msgSend_237(_lib._class_NSData1,
        _lib._sel_dataWithBytesNoCopy_length_1, bytes, length);
    return NSData._(_ret, _lib, retain: false, release: true);
  }

  static NSData dataWithBytesNoCopy_length_freeWhenDone_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> bytes, int length, bool b) {
    final _ret = _lib._objc_msgSend_238(_lib._class_NSData1,
        _lib._sel_dataWithBytesNoCopy_length_freeWhenDone_1, bytes, length, b);
    return NSData._(_ret, _lib, retain: false, release: true);
  }

  static NSData dataWithContentsOfFile_options_error_(
      AVFAudio _lib,
      NSString? path,
      int readOptionsMask,
      ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr) {
    final _ret = _lib._objc_msgSend_239(
        _lib._class_NSData1,
        _lib._sel_dataWithContentsOfFile_options_error_1,
        path?._id ?? ffi.nullptr,
        readOptionsMask,
        errorPtr);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  static NSData dataWithContentsOfURL_options_error_(AVFAudio _lib, NSURL? url,
      int readOptionsMask, ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr) {
    final _ret = _lib._objc_msgSend_240(
        _lib._class_NSData1,
        _lib._sel_dataWithContentsOfURL_options_error_1,
        url?._id ?? ffi.nullptr,
        readOptionsMask,
        errorPtr);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  static NSData dataWithContentsOfFile_(AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSData1,
        _lib._sel_dataWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  static NSData dataWithContentsOfURL_(AVFAudio _lib, NSURL? url) {
    final _ret = _lib._objc_msgSend_226(_lib._class_NSData1,
        _lib._sel_dataWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData initWithBytes_length_(ffi.Pointer<ffi.Void> bytes, int length) {
    final _ret = _lib._objc_msgSend_237(
        _id, _lib._sel_initWithBytes_length_1, bytes, length);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData initWithBytesNoCopy_length_(ffi.Pointer<ffi.Void> bytes, int length) {
    final _ret = _lib._objc_msgSend_237(
        _id, _lib._sel_initWithBytesNoCopy_length_1, bytes, length);
    return NSData._(_ret, _lib, retain: false, release: true);
  }

  NSData initWithBytesNoCopy_length_freeWhenDone_(
      ffi.Pointer<ffi.Void> bytes, int length, bool b) {
    final _ret = _lib._objc_msgSend_238(_id,
        _lib._sel_initWithBytesNoCopy_length_freeWhenDone_1, bytes, length, b);
    return NSData._(_ret, _lib, retain: false, release: true);
  }

  NSData initWithBytesNoCopy_length_deallocator_(
      ffi.Pointer<ffi.Void> bytes, int length, ObjCBlock9 deallocator) {
    final _ret = _lib._objc_msgSend_241(
        _id,
        _lib._sel_initWithBytesNoCopy_length_deallocator_1,
        bytes,
        length,
        deallocator._id);
    return NSData._(_ret, _lib, retain: false, release: true);
  }

  NSData initWithContentsOfFile_options_error_(NSString? path,
      int readOptionsMask, ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr) {
    final _ret = _lib._objc_msgSend_239(
        _id,
        _lib._sel_initWithContentsOfFile_options_error_1,
        path?._id ?? ffi.nullptr,
        readOptionsMask,
        errorPtr);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData initWithContentsOfURL_options_error_(NSURL? url, int readOptionsMask,
      ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr) {
    final _ret = _lib._objc_msgSend_240(
        _id,
        _lib._sel_initWithContentsOfURL_options_error_1,
        url?._id ?? ffi.nullptr,
        readOptionsMask,
        errorPtr);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData initWithContentsOfFile_(NSString? path) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData initWithContentsOfURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_226(
        _id, _lib._sel_initWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData initWithData_(NSData? data) {
    final _ret = _lib._objc_msgSend_242(
        _id, _lib._sel_initWithData_1, data?._id ?? ffi.nullptr);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  static NSData dataWithData_(AVFAudio _lib, NSData? data) {
    final _ret = _lib._objc_msgSend_242(_lib._class_NSData1,
        _lib._sel_dataWithData_1, data?._id ?? ffi.nullptr);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData initWithBase64EncodedString_options_(
      NSString? base64String, int options) {
    final _ret = _lib._objc_msgSend_243(
        _id,
        _lib._sel_initWithBase64EncodedString_options_1,
        base64String?._id ?? ffi.nullptr,
        options);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSString base64EncodedStringWithOptions_(int options) {
    final _ret = _lib._objc_msgSend_244(
        _id, _lib._sel_base64EncodedStringWithOptions_1, options);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSData initWithBase64EncodedData_options_(NSData? base64Data, int options) {
    final _ret = _lib._objc_msgSend_245(
        _id,
        _lib._sel_initWithBase64EncodedData_options_1,
        base64Data?._id ?? ffi.nullptr,
        options);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData base64EncodedDataWithOptions_(int options) {
    final _ret = _lib._objc_msgSend_246(
        _id, _lib._sel_base64EncodedDataWithOptions_1, options);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData decompressedDataUsingAlgorithm_error_(
      int algorithm, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_247(_id,
        _lib._sel_decompressedDataUsingAlgorithm_error_1, algorithm, error);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData compressedDataUsingAlgorithm_error_(
      int algorithm, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_247(
        _id, _lib._sel_compressedDataUsingAlgorithm_error_1, algorithm, error);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  void getBytes_(ffi.Pointer<ffi.Void> buffer) {
    return _lib._objc_msgSend_47(_id, _lib._sel_getBytes_1, buffer);
  }

  static NSObject dataWithContentsOfMappedFile_(AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSData1,
        _lib._sel_dataWithContentsOfMappedFile_1, path?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithContentsOfMappedFile_(NSString? path) {
    final _ret = _lib._objc_msgSend_30(_id,
        _lib._sel_initWithContentsOfMappedFile_1, path?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithBase64Encoding_(NSString? base64String) {
    final _ret = _lib._objc_msgSend_30(_id, _lib._sel_initWithBase64Encoding_1,
        base64String?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSString base64Encoding() {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_base64Encoding1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSData new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSData1, _lib._sel_new1);
    return NSData._(_ret, _lib, retain: false, release: true);
  }

  static NSData alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSData1, _lib._sel_alloc1);
    return NSData._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSData1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSData1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSData1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSData1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSData1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSData1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSData1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSData1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSData1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSRange = _NSRange;

final class _NSRange extends ffi.Struct {
  @NSUInteger()
  external int location;

  @NSUInteger()
  external int length;
}

class NSURL extends NSObject {
  NSURL._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURL] that points to the same underlying object as [other].
  static NSURL castFrom<T extends _ObjCWrapper>(T other) {
    return NSURL._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSURL] that wraps the given raw object pointer.
  static NSURL castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURL._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURL].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSURL1);
  }

  NSURL initWithScheme_host_path_(
      NSString? scheme, NSString? host, NSString? path) {
    final _ret = _lib._objc_msgSend_26(
        _id,
        _lib._sel_initWithScheme_host_path_1,
        scheme?._id ?? ffi.nullptr,
        host?._id ?? ffi.nullptr,
        path?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL initFileURLWithPath_isDirectory_relativeToURL_(
      NSString? path, bool isDir, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_27(
        _id,
        _lib._sel_initFileURLWithPath_isDirectory_relativeToURL_1,
        path?._id ?? ffi.nullptr,
        isDir,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL initFileURLWithPath_relativeToURL_(NSString? path, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_28(
        _id,
        _lib._sel_initFileURLWithPath_relativeToURL_1,
        path?._id ?? ffi.nullptr,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL initFileURLWithPath_isDirectory_(NSString? path, bool isDir) {
    final _ret = _lib._objc_msgSend_29(
        _id,
        _lib._sel_initFileURLWithPath_isDirectory_1,
        path?._id ?? ffi.nullptr,
        isDir);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL initFileURLWithPath_(NSString? path) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initFileURLWithPath_1, path?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  static NSURL fileURLWithPath_isDirectory_relativeToURL_(
      AVFAudio _lib, NSString? path, bool isDir, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_31(
        _lib._class_NSURL1,
        _lib._sel_fileURLWithPath_isDirectory_relativeToURL_1,
        path?._id ?? ffi.nullptr,
        isDir,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  static NSURL fileURLWithPath_relativeToURL_(
      AVFAudio _lib, NSString? path, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_32(
        _lib._class_NSURL1,
        _lib._sel_fileURLWithPath_relativeToURL_1,
        path?._id ?? ffi.nullptr,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  static NSURL fileURLWithPath_isDirectory_(
      AVFAudio _lib, NSString? path, bool isDir) {
    final _ret = _lib._objc_msgSend_33(
        _lib._class_NSURL1,
        _lib._sel_fileURLWithPath_isDirectory_1,
        path?._id ?? ffi.nullptr,
        isDir);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  static NSURL fileURLWithPath_(AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_34(_lib._class_NSURL1,
        _lib._sel_fileURLWithPath_1, path?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL initFileURLWithFileSystemRepresentation_isDirectory_relativeToURL_(
      ffi.Pointer<ffi.Char> path, bool isDir, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_35(
        _id,
        _lib._sel_initFileURLWithFileSystemRepresentation_isDirectory_relativeToURL_1,
        path,
        isDir,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  static NSURL fileURLWithFileSystemRepresentation_isDirectory_relativeToURL_(
      AVFAudio _lib, ffi.Pointer<ffi.Char> path, bool isDir, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_36(
        _lib._class_NSURL1,
        _lib._sel_fileURLWithFileSystemRepresentation_isDirectory_relativeToURL_1,
        path,
        isDir,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL initWithString_(NSString? URLString) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithString_1, URLString?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL initWithString_relativeToURL_(NSString? URLString, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_28(
        _id,
        _lib._sel_initWithString_relativeToURL_1,
        URLString?._id ?? ffi.nullptr,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  static NSURL URLWithString_(AVFAudio _lib, NSString? URLString) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSURL1,
        _lib._sel_URLWithString_1, URLString?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  static NSURL URLWithString_relativeToURL_(
      AVFAudio _lib, NSString? URLString, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_28(
        _lib._class_NSURL1,
        _lib._sel_URLWithString_relativeToURL_1,
        URLString?._id ?? ffi.nullptr,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL initWithDataRepresentation_relativeToURL_(
      NSData? data, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_37(
        _id,
        _lib._sel_initWithDataRepresentation_relativeToURL_1,
        data?._id ?? ffi.nullptr,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  static NSURL URLWithDataRepresentation_relativeToURL_(
      AVFAudio _lib, NSData? data, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_38(
        _lib._class_NSURL1,
        _lib._sel_URLWithDataRepresentation_relativeToURL_1,
        data?._id ?? ffi.nullptr,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL initAbsoluteURLWithDataRepresentation_relativeToURL_(
      NSData? data, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_37(
        _id,
        _lib._sel_initAbsoluteURLWithDataRepresentation_relativeToURL_1,
        data?._id ?? ffi.nullptr,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  static NSURL absoluteURLWithDataRepresentation_relativeToURL_(
      AVFAudio _lib, NSData? data, NSURL? baseURL) {
    final _ret = _lib._objc_msgSend_38(
        _lib._class_NSURL1,
        _lib._sel_absoluteURLWithDataRepresentation_relativeToURL_1,
        data?._id ?? ffi.nullptr,
        baseURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSData? get dataRepresentation {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_dataRepresentation1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  NSString? get absoluteString {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_absoluteString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get relativeString {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_relativeString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get baseURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_baseURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get absoluteURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_absoluteURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSString? get scheme {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_scheme1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get resourceSpecifier {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_resourceSpecifier1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get host {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_host1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSNumber? get port {
    final _ret = _lib._objc_msgSend_192(_id, _lib._sel_port1);
    return _ret.address == 0
        ? null
        : NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSString? get user {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_user1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get password {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_password1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get path {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_path1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get fragment {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_fragment1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get parameterString {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_parameterString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get query {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_query1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get relativePath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_relativePath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  bool get hasDirectoryPath {
    return _lib._objc_msgSend_12(_id, _lib._sel_hasDirectoryPath1);
  }

  bool getFileSystemRepresentation_maxLength_(
      ffi.Pointer<ffi.Char> buffer, int maxBufferLength) {
    return _lib._objc_msgSend_218(
        _id,
        _lib._sel_getFileSystemRepresentation_maxLength_1,
        buffer,
        maxBufferLength);
  }

  ffi.Pointer<ffi.Char> get fileSystemRepresentation {
    return _lib._objc_msgSend_13(_id, _lib._sel_fileSystemRepresentation1);
  }

  bool get fileURL {
    return _lib._objc_msgSend_12(_id, _lib._sel_isFileURL1);
  }

  NSURL? get standardizedURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_standardizedURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  bool checkResourceIsReachableAndReturnError_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_219(
        _id, _lib._sel_checkResourceIsReachableAndReturnError_1, error);
  }

  bool isFileReferenceURL() {
    return _lib._objc_msgSend_12(_id, _lib._sel_isFileReferenceURL1);
  }

  NSURL fileReferenceURL() {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_fileReferenceURL1);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get filePathURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_filePathURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  bool getResourceValue_forKey_error_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> value,
      NSURLResourceKey key,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_220(
        _id, _lib._sel_getResourceValue_forKey_error_1, value, key, error);
  }

  bool getPromisedItemResourceValue_forKey_error_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> value,
      NSURLResourceKey key,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_220(
        _id,
        _lib._sel_getPromisedItemResourceValue_forKey_error_1,
        value,
        key,
        error);
  }

  NSDictionary promisedItemResourceValuesForKeys_error_(
      NSArray? keys, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_221(
        _id,
        _lib._sel_promisedItemResourceValuesForKeys_error_1,
        keys?._id ?? ffi.nullptr,
        error);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  bool checkPromisedItemIsReachableAndReturnError_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_219(
        _id, _lib._sel_checkPromisedItemIsReachableAndReturnError_1, error);
  }

  static NSURL fileURLWithPathComponents_(AVFAudio _lib, NSArray? components) {
    final _ret = _lib._objc_msgSend_222(_lib._class_NSURL1,
        _lib._sel_fileURLWithPathComponents_1, components?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get pathComponents {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_pathComponents1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString? get lastPathComponent {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_lastPathComponent1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get pathExtension {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_pathExtension1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSURL URLByAppendingPathComponent_(NSString? pathComponent) {
    final _ret = _lib._objc_msgSend_34(
        _id,
        _lib._sel_URLByAppendingPathComponent_1,
        pathComponent?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL URLByAppendingPathComponent_isDirectory_(
      NSString? pathComponent, bool isDirectory) {
    final _ret = _lib._objc_msgSend_33(
        _id,
        _lib._sel_URLByAppendingPathComponent_isDirectory_1,
        pathComponent?._id ?? ffi.nullptr,
        isDirectory);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get URLByDeletingLastPathComponent {
    final _ret =
        _lib._objc_msgSend_40(_id, _lib._sel_URLByDeletingLastPathComponent1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL URLByAppendingPathExtension_(NSString? pathExtension) {
    final _ret = _lib._objc_msgSend_34(
        _id,
        _lib._sel_URLByAppendingPathExtension_1,
        pathExtension?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get URLByDeletingPathExtension {
    final _ret =
        _lib._objc_msgSend_40(_id, _lib._sel_URLByDeletingPathExtension1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get URLByStandardizingPath {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_URLByStandardizingPath1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get URLByResolvingSymlinksInPath {
    final _ret =
        _lib._objc_msgSend_40(_id, _lib._sel_URLByResolvingSymlinksInPath1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSData resourceDataUsingCache_(bool shouldUseCache) {
    final _ret = _lib._objc_msgSend_223(
        _id, _lib._sel_resourceDataUsingCache_1, shouldUseCache);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  void loadResourceDataNotifyingClient_usingCache_(
      NSObject client, bool shouldUseCache) {
    return _lib._objc_msgSend_224(
        _id,
        _lib._sel_loadResourceDataNotifyingClient_usingCache_1,
        client._id,
        shouldUseCache);
  }

  NSObject propertyForKey_(NSString? propertyKey) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_propertyForKey_1, propertyKey?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  bool setResourceData_(NSData? data) {
    return _lib._objc_msgSend_23(
        _id, _lib._sel_setResourceData_1, data?._id ?? ffi.nullptr);
  }

  bool setProperty_forKey_(NSObject property, NSString? propertyKey) {
    return _lib._objc_msgSend_225(_id, _lib._sel_setProperty_forKey_1,
        property._id, propertyKey?._id ?? ffi.nullptr);
  }

  NSURLHandle URLHandleUsingCache_(bool shouldUseCache) {
    final _ret = _lib._objc_msgSend_232(
        _id, _lib._sel_URLHandleUsingCache_1, shouldUseCache);
    return NSURLHandle._(_ret, _lib, retain: true, release: true);
  }

  static NSURL new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSURL1, _lib._sel_new1);
    return NSURL._(_ret, _lib, retain: false, release: true);
  }

  static NSURL alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSURL1, _lib._sel_alloc1);
    return NSURL._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURL1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURL1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURL1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURL1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURL1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURL1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURL1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSURL1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURL1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSNumber extends NSValue {
  NSNumber._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSNumber] that points to the same underlying object as [other].
  static NSNumber castFrom<T extends _ObjCWrapper>(T other) {
    return NSNumber._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSNumber] that wraps the given raw object pointer.
  static NSNumber castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSNumber._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSNumber].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSNumber1);
  }

  @override
  NSNumber initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithChar_(int value) {
    final _ret = _lib._objc_msgSend_196(_id, _lib._sel_initWithChar_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithUnsignedChar_(int value) {
    final _ret =
        _lib._objc_msgSend_197(_id, _lib._sel_initWithUnsignedChar_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithShort_(int value) {
    final _ret = _lib._objc_msgSend_198(_id, _lib._sel_initWithShort_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithUnsignedShort_(int value) {
    final _ret =
        _lib._objc_msgSend_199(_id, _lib._sel_initWithUnsignedShort_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithInt_(int value) {
    final _ret = _lib._objc_msgSend_200(_id, _lib._sel_initWithInt_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithUnsignedInt_(int value) {
    final _ret =
        _lib._objc_msgSend_201(_id, _lib._sel_initWithUnsignedInt_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithLong_(int value) {
    final _ret = _lib._objc_msgSend_202(_id, _lib._sel_initWithLong_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithUnsignedLong_(int value) {
    final _ret =
        _lib._objc_msgSend_203(_id, _lib._sel_initWithUnsignedLong_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithLongLong_(int value) {
    final _ret =
        _lib._objc_msgSend_204(_id, _lib._sel_initWithLongLong_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithUnsignedLongLong_(int value) {
    final _ret = _lib._objc_msgSend_205(
        _id, _lib._sel_initWithUnsignedLongLong_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithFloat_(double value) {
    final _ret = _lib._objc_msgSend_206(_id, _lib._sel_initWithFloat_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithDouble_(double value) {
    final _ret = _lib._objc_msgSend_207(_id, _lib._sel_initWithDouble_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithBool_(bool value) {
    final _ret = _lib._objc_msgSend_208(_id, _lib._sel_initWithBool_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithInteger_(int value) {
    final _ret =
        _lib._objc_msgSend_202(_id, _lib._sel_initWithInteger_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber initWithUnsignedInteger_(int value) {
    final _ret =
        _lib._objc_msgSend_203(_id, _lib._sel_initWithUnsignedInteger_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  int get charValue {
    return _lib._objc_msgSend_209(_id, _lib._sel_charValue1);
  }

  int get unsignedCharValue {
    return _lib._objc_msgSend_210(_id, _lib._sel_unsignedCharValue1);
  }

  int get shortValue {
    return _lib._objc_msgSend_211(_id, _lib._sel_shortValue1);
  }

  int get unsignedShortValue {
    return _lib._objc_msgSend_212(_id, _lib._sel_unsignedShortValue1);
  }

  int get intValue {
    return _lib._objc_msgSend_213(_id, _lib._sel_intValue1);
  }

  int get unsignedIntValue {
    return _lib._objc_msgSend_191(_id, _lib._sel_unsignedIntValue1);
  }

  int get longValue {
    return _lib._objc_msgSend_78(_id, _lib._sel_longValue1);
  }

  int get unsignedLongValue {
    return _lib._objc_msgSend_10(_id, _lib._sel_unsignedLongValue1);
  }

  int get longLongValue {
    return _lib._objc_msgSend_214(_id, _lib._sel_longLongValue1);
  }

  int get unsignedLongLongValue {
    return _lib._objc_msgSend_148(_id, _lib._sel_unsignedLongLongValue1);
  }

  double get floatValue {
    return _lib._objc_msgSend_215(_id, _lib._sel_floatValue1);
  }

  double get doubleValue {
    return _lib._objc_msgSend_149(_id, _lib._sel_doubleValue1);
  }

  bool get boolValue {
    return _lib._objc_msgSend_12(_id, _lib._sel_boolValue1);
  }

  int get integerValue {
    return _lib._objc_msgSend_78(_id, _lib._sel_integerValue1);
  }

  int get unsignedIntegerValue {
    return _lib._objc_msgSend_10(_id, _lib._sel_unsignedIntegerValue1);
  }

  NSString? get stringValue {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_stringValue1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int compare_(NSNumber? otherNumber) {
    return _lib._objc_msgSend_216(
        _id, _lib._sel_compare_1, otherNumber?._id ?? ffi.nullptr);
  }

  bool isEqualToNumber_(NSNumber? number) {
    return _lib._objc_msgSend_217(
        _id, _lib._sel_isEqualToNumber_1, number?._id ?? ffi.nullptr);
  }

  NSString descriptionWithLocale_(NSObject locale) {
    final _ret = _lib._objc_msgSend_65(
        _id, _lib._sel_descriptionWithLocale_1, locale._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithChar_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_196(
        _lib._class_NSNumber1, _lib._sel_numberWithChar_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithUnsignedChar_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_197(
        _lib._class_NSNumber1, _lib._sel_numberWithUnsignedChar_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithShort_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_198(
        _lib._class_NSNumber1, _lib._sel_numberWithShort_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithUnsignedShort_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_199(
        _lib._class_NSNumber1, _lib._sel_numberWithUnsignedShort_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithInt_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_200(
        _lib._class_NSNumber1, _lib._sel_numberWithInt_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithUnsignedInt_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_201(
        _lib._class_NSNumber1, _lib._sel_numberWithUnsignedInt_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithLong_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_202(
        _lib._class_NSNumber1, _lib._sel_numberWithLong_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithUnsignedLong_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_203(
        _lib._class_NSNumber1, _lib._sel_numberWithUnsignedLong_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithLongLong_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_204(
        _lib._class_NSNumber1, _lib._sel_numberWithLongLong_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithUnsignedLongLong_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_205(
        _lib._class_NSNumber1, _lib._sel_numberWithUnsignedLongLong_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithFloat_(AVFAudio _lib, double value) {
    final _ret = _lib._objc_msgSend_206(
        _lib._class_NSNumber1, _lib._sel_numberWithFloat_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithDouble_(AVFAudio _lib, double value) {
    final _ret = _lib._objc_msgSend_207(
        _lib._class_NSNumber1, _lib._sel_numberWithDouble_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithBool_(AVFAudio _lib, bool value) {
    final _ret = _lib._objc_msgSend_208(
        _lib._class_NSNumber1, _lib._sel_numberWithBool_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithInteger_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_202(
        _lib._class_NSNumber1, _lib._sel_numberWithInteger_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber numberWithUnsignedInteger_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_203(
        _lib._class_NSNumber1, _lib._sel_numberWithUnsignedInteger_1, value);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithBytes_objCType_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> value, ffi.Pointer<ffi.Char> type) {
    final _ret = _lib._objc_msgSend_43(_lib._class_NSNumber1,
        _lib._sel_valueWithBytes_objCType_1, value, type);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue value_withObjCType_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> value, ffi.Pointer<ffi.Char> type) {
    final _ret = _lib._objc_msgSend_43(
        _lib._class_NSNumber1, _lib._sel_value_withObjCType_1, value, type);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithNonretainedObject_(AVFAudio _lib, NSObject anObject) {
    final _ret = _lib._objc_msgSend_44(_lib._class_NSNumber1,
        _lib._sel_valueWithNonretainedObject_1, anObject._id);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithPointer_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> pointer) {
    final _ret = _lib._objc_msgSend_45(
        _lib._class_NSNumber1, _lib._sel_valueWithPointer_1, pointer);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithRange_(AVFAudio _lib, NSRange range) {
    final _ret = _lib._objc_msgSend_48(
        _lib._class_NSNumber1, _lib._sel_valueWithRange_1, range);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithPoint_(AVFAudio _lib, NSPoint point) {
    final _ret = _lib._objc_msgSend_50(
        _lib._class_NSNumber1, _lib._sel_valueWithPoint_1, point);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithSize_(AVFAudio _lib, NSSize size) {
    final _ret = _lib._objc_msgSend_51(
        _lib._class_NSNumber1, _lib._sel_valueWithSize_1, size);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithRect_(AVFAudio _lib, NSRect rect) {
    final _ret = _lib._objc_msgSend_52(
        _lib._class_NSNumber1, _lib._sel_valueWithRect_1, rect);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithEdgeInsets_(AVFAudio _lib, NSEdgeInsets insets) {
    final _ret = _lib._objc_msgSend_53(
        _lib._class_NSNumber1, _lib._sel_valueWithEdgeInsets_1, insets);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSNumber new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSNumber1, _lib._sel_new1);
    return NSNumber._(_ret, _lib, retain: false, release: true);
  }

  static NSNumber alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSNumber1, _lib._sel_alloc1);
    return NSNumber._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSNumber1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSNumber1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSNumber1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSNumber1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSNumber1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSNumber1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSNumber1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSNumber1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSNumber1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSValue extends NSObject {
  NSValue._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSValue] that points to the same underlying object as [other].
  static NSValue castFrom<T extends _ObjCWrapper>(T other) {
    return NSValue._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSValue] that wraps the given raw object pointer.
  static NSValue castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSValue._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSValue].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSValue1);
  }

  void getValue_size_(ffi.Pointer<ffi.Void> value, int size) {
    return _lib._objc_msgSend_21(_id, _lib._sel_getValue_size_1, value, size);
  }

  ffi.Pointer<ffi.Char> get objCType {
    return _lib._objc_msgSend_13(_id, _lib._sel_objCType1);
  }

  NSValue initWithBytes_objCType_(
      ffi.Pointer<ffi.Void> value, ffi.Pointer<ffi.Char> type) {
    final _ret = _lib._objc_msgSend_41(
        _id, _lib._sel_initWithBytes_objCType_1, value, type);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  NSValue initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithBytes_objCType_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> value, ffi.Pointer<ffi.Char> type) {
    final _ret = _lib._objc_msgSend_43(
        _lib._class_NSValue1, _lib._sel_valueWithBytes_objCType_1, value, type);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue value_withObjCType_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> value, ffi.Pointer<ffi.Char> type) {
    final _ret = _lib._objc_msgSend_43(
        _lib._class_NSValue1, _lib._sel_value_withObjCType_1, value, type);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithNonretainedObject_(AVFAudio _lib, NSObject anObject) {
    final _ret = _lib._objc_msgSend_44(_lib._class_NSValue1,
        _lib._sel_valueWithNonretainedObject_1, anObject._id);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  NSObject get nonretainedObjectValue {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_nonretainedObjectValue1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithPointer_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> pointer) {
    final _ret = _lib._objc_msgSend_45(
        _lib._class_NSValue1, _lib._sel_valueWithPointer_1, pointer);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  ffi.Pointer<ffi.Void> get pointerValue {
    return _lib._objc_msgSend_19(_id, _lib._sel_pointerValue1);
  }

  bool isEqualToValue_(NSValue? value) {
    return _lib._objc_msgSend_46(
        _id, _lib._sel_isEqualToValue_1, value?._id ?? ffi.nullptr);
  }

  void getValue_(ffi.Pointer<ffi.Void> value) {
    return _lib._objc_msgSend_47(_id, _lib._sel_getValue_1, value);
  }

  static NSValue valueWithRange_(AVFAudio _lib, NSRange range) {
    final _ret = _lib._objc_msgSend_48(
        _lib._class_NSValue1, _lib._sel_valueWithRange_1, range);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  NSRange get rangeValue {
    return _lib._objc_msgSend_49(_id, _lib._sel_rangeValue1);
  }

  static NSValue valueWithPoint_(AVFAudio _lib, NSPoint point) {
    final _ret = _lib._objc_msgSend_50(
        _lib._class_NSValue1, _lib._sel_valueWithPoint_1, point);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithSize_(AVFAudio _lib, NSSize size) {
    final _ret = _lib._objc_msgSend_51(
        _lib._class_NSValue1, _lib._sel_valueWithSize_1, size);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithRect_(AVFAudio _lib, NSRect rect) {
    final _ret = _lib._objc_msgSend_52(
        _lib._class_NSValue1, _lib._sel_valueWithRect_1, rect);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  static NSValue valueWithEdgeInsets_(AVFAudio _lib, NSEdgeInsets insets) {
    final _ret = _lib._objc_msgSend_53(
        _lib._class_NSValue1, _lib._sel_valueWithEdgeInsets_1, insets);
    return NSValue._(_ret, _lib, retain: true, release: true);
  }

  NSPoint get pointValue {
    return _lib._objc_msgSend_54(_id, _lib._sel_pointValue1);
  }

  NSSize get sizeValue {
    return _lib._objc_msgSend_55(_id, _lib._sel_sizeValue1);
  }

  NSRect get rectValue {
    return _lib._objc_msgSend_56(_id, _lib._sel_rectValue1);
  }

  NSEdgeInsets get edgeInsetsValue {
    return _lib._objc_msgSend_57(_id, _lib._sel_edgeInsetsValue1);
  }

  static NSValue new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSValue1, _lib._sel_new1);
    return NSValue._(_ret, _lib, retain: false, release: true);
  }

  static NSValue alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSValue1, _lib._sel_alloc1);
    return NSValue._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSValue1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSValue1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSValue1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSValue1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSValue1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSValue1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSValue1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSValue1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSValue1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSPoint = CGPoint;

final class CGPoint extends ffi.Struct {
  @CGFloat()
  external double x;

  @CGFloat()
  external double y;
}

typedef CGFloat = ffi.Double;
typedef NSSize = CGSize;

final class CGSize extends ffi.Struct {
  @CGFloat()
  external double width;

  @CGFloat()
  external double height;
}

typedef NSRect = CGRect;

final class CGRect extends ffi.Struct {
  external CGPoint origin;

  external CGSize size;
}

final class NSEdgeInsets extends ffi.Struct {
  @CGFloat()
  external double top;

  @CGFloat()
  external double left;

  @CGFloat()
  external double bottom;

  @CGFloat()
  external double right;
}

class NSArray extends NSObject {
  NSArray._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSArray] that points to the same underlying object as [other].
  static NSArray castFrom<T extends _ObjCWrapper>(T other) {
    return NSArray._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSArray] that wraps the given raw object pointer.
  static NSArray castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSArray._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSArray].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSArray1);
  }

  int get count {
    return _lib._objc_msgSend_10(_id, _lib._sel_count1);
  }

  NSObject objectAtIndex_(int index) {
    final _ret = _lib._objc_msgSend_60(_id, _lib._sel_objectAtIndex_1, index);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSArray init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray initWithObjects_count_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> objects, int cnt) {
    final _ret = _lib._objc_msgSend_61(
        _id, _lib._sel_initWithObjects_count_1, objects, cnt);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray arrayByAddingObject_(NSObject anObject) {
    final _ret = _lib._objc_msgSend_62(
        _id, _lib._sel_arrayByAddingObject_1, anObject._id);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray arrayByAddingObjectsFromArray_(NSArray? otherArray) {
    final _ret = _lib._objc_msgSend_63(
        _id,
        _lib._sel_arrayByAddingObjectsFromArray_1,
        otherArray?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString componentsJoinedByString_(NSString? separator) {
    final _ret = _lib._objc_msgSend_64(_id,
        _lib._sel_componentsJoinedByString_1, separator?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  bool containsObject_(NSObject anObject) {
    return _lib._objc_msgSend_0(_id, _lib._sel_containsObject_1, anObject._id);
  }

  NSString? get description {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_description1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString descriptionWithLocale_(NSObject locale) {
    final _ret = _lib._objc_msgSend_65(
        _id, _lib._sel_descriptionWithLocale_1, locale._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString descriptionWithLocale_indent_(NSObject locale, int level) {
    final _ret = _lib._objc_msgSend_66(
        _id, _lib._sel_descriptionWithLocale_indent_1, locale._id, level);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSObject firstObjectCommonWithArray_(NSArray? otherArray) {
    final _ret = _lib._objc_msgSend_67(_id,
        _lib._sel_firstObjectCommonWithArray_1, otherArray?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void getObjects_range_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> objects, NSRange range) {
    return _lib._objc_msgSend_68(
        _id, _lib._sel_getObjects_range_1, objects, range);
  }

  int indexOfObject_(NSObject anObject) {
    return _lib._objc_msgSend_69(_id, _lib._sel_indexOfObject_1, anObject._id);
  }

  int indexOfObject_inRange_(NSObject anObject, NSRange range) {
    return _lib._objc_msgSend_70(
        _id, _lib._sel_indexOfObject_inRange_1, anObject._id, range);
  }

  int indexOfObjectIdenticalTo_(NSObject anObject) {
    return _lib._objc_msgSend_69(
        _id, _lib._sel_indexOfObjectIdenticalTo_1, anObject._id);
  }

  int indexOfObjectIdenticalTo_inRange_(NSObject anObject, NSRange range) {
    return _lib._objc_msgSend_70(
        _id, _lib._sel_indexOfObjectIdenticalTo_inRange_1, anObject._id, range);
  }

  bool isEqualToArray_(NSArray? otherArray) {
    return _lib._objc_msgSend_71(
        _id, _lib._sel_isEqualToArray_1, otherArray?._id ?? ffi.nullptr);
  }

  NSObject get firstObject {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_firstObject1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject get lastObject {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_lastObject1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSEnumerator objectEnumerator() {
    final _ret = _lib._objc_msgSend_72(_id, _lib._sel_objectEnumerator1);
    return NSEnumerator._(_ret, _lib, retain: true, release: true);
  }

  NSEnumerator reverseObjectEnumerator() {
    final _ret = _lib._objc_msgSend_72(_id, _lib._sel_reverseObjectEnumerator1);
    return NSEnumerator._(_ret, _lib, retain: true, release: true);
  }

  NSData? get sortedArrayHint {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_sortedArrayHint1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  NSArray sortedArrayUsingFunction_context_(
      ffi.Pointer<
              ffi.NativeFunction<
                  NSInteger Function(ffi.Pointer<ObjCObject>,
                      ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>
          comparator,
      ffi.Pointer<ffi.Void> context) {
    final _ret = _lib._objc_msgSend_73(
        _id, _lib._sel_sortedArrayUsingFunction_context_1, comparator, context);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray sortedArrayUsingFunction_context_hint_(
      ffi.Pointer<
              ffi.NativeFunction<
                  NSInteger Function(ffi.Pointer<ObjCObject>,
                      ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>
          comparator,
      ffi.Pointer<ffi.Void> context,
      NSData? hint) {
    final _ret = _lib._objc_msgSend_74(
        _id,
        _lib._sel_sortedArrayUsingFunction_context_hint_1,
        comparator,
        context,
        hint?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray sortedArrayUsingSelector_(ffi.Pointer<ObjCSel> comparator) {
    final _ret = _lib._objc_msgSend_75(
        _id, _lib._sel_sortedArrayUsingSelector_1, comparator);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray subarrayWithRange_(NSRange range) {
    final _ret =
        _lib._objc_msgSend_76(_id, _lib._sel_subarrayWithRange_1, range);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  bool writeToURL_error_(
      NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_81(
        _id, _lib._sel_writeToURL_error_1, url?._id ?? ffi.nullptr, error);
  }

  void makeObjectsPerformSelector_(ffi.Pointer<ObjCSel> aSelector) {
    return _lib._objc_msgSend_7(
        _id, _lib._sel_makeObjectsPerformSelector_1, aSelector);
  }

  void makeObjectsPerformSelector_withObject_(
      ffi.Pointer<ObjCSel> aSelector, NSObject argument) {
    return _lib._objc_msgSend_82(
        _id,
        _lib._sel_makeObjectsPerformSelector_withObject_1,
        aSelector,
        argument._id);
  }

  NSArray objectsAtIndexes_(NSIndexSet? indexes) {
    final _ret = _lib._objc_msgSend_103(
        _id, _lib._sel_objectsAtIndexes_1, indexes?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSObject objectAtIndexedSubscript_(int idx) {
    final _ret =
        _lib._objc_msgSend_60(_id, _lib._sel_objectAtIndexedSubscript_1, idx);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void enumerateObjectsUsingBlock_(ObjCBlock3 block) {
    return _lib._objc_msgSend_104(
        _id, _lib._sel_enumerateObjectsUsingBlock_1, block._id);
  }

  void enumerateObjectsWithOptions_usingBlock_(int opts, ObjCBlock3 block) {
    return _lib._objc_msgSend_105(_id,
        _lib._sel_enumerateObjectsWithOptions_usingBlock_1, opts, block._id);
  }

  void enumerateObjectsAtIndexes_options_usingBlock_(
      NSIndexSet? s, int opts, ObjCBlock3 block) {
    return _lib._objc_msgSend_106(
        _id,
        _lib._sel_enumerateObjectsAtIndexes_options_usingBlock_1,
        s?._id ?? ffi.nullptr,
        opts,
        block._id);
  }

  int indexOfObjectPassingTest_(ObjCBlock4 predicate) {
    return _lib._objc_msgSend_107(
        _id, _lib._sel_indexOfObjectPassingTest_1, predicate._id);
  }

  int indexOfObjectWithOptions_passingTest_(int opts, ObjCBlock4 predicate) {
    return _lib._objc_msgSend_108(_id,
        _lib._sel_indexOfObjectWithOptions_passingTest_1, opts, predicate._id);
  }

  int indexOfObjectAtIndexes_options_passingTest_(
      NSIndexSet? s, int opts, ObjCBlock4 predicate) {
    return _lib._objc_msgSend_109(
        _id,
        _lib._sel_indexOfObjectAtIndexes_options_passingTest_1,
        s?._id ?? ffi.nullptr,
        opts,
        predicate._id);
  }

  NSIndexSet indexesOfObjectsPassingTest_(ObjCBlock4 predicate) {
    final _ret = _lib._objc_msgSend_110(
        _id, _lib._sel_indexesOfObjectsPassingTest_1, predicate._id);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  NSIndexSet indexesOfObjectsWithOptions_passingTest_(
      int opts, ObjCBlock4 predicate) {
    final _ret = _lib._objc_msgSend_111(
        _id,
        _lib._sel_indexesOfObjectsWithOptions_passingTest_1,
        opts,
        predicate._id);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  NSIndexSet indexesOfObjectsAtIndexes_options_passingTest_(
      NSIndexSet? s, int opts, ObjCBlock4 predicate) {
    final _ret = _lib._objc_msgSend_112(
        _id,
        _lib._sel_indexesOfObjectsAtIndexes_options_passingTest_1,
        s?._id ?? ffi.nullptr,
        opts,
        predicate._id);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  NSArray sortedArrayUsingComparator_(NSComparator cmptr) {
    final _ret = _lib._objc_msgSend_113(
        _id, _lib._sel_sortedArrayUsingComparator_1, cmptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray sortedArrayWithOptions_usingComparator_(
      int opts, NSComparator cmptr) {
    final _ret = _lib._objc_msgSend_114(
        _id, _lib._sel_sortedArrayWithOptions_usingComparator_1, opts, cmptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  int indexOfObject_inSortedRange_options_usingComparator_(
      NSObject obj, NSRange r, int opts, NSComparator cmp) {
    return _lib._objc_msgSend_115(
        _id,
        _lib._sel_indexOfObject_inSortedRange_options_usingComparator_1,
        obj._id,
        r,
        opts,
        cmp);
  }

  static NSArray array(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSArray1, _lib._sel_array1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray arrayWithObject_(AVFAudio _lib, NSObject anObject) {
    final _ret = _lib._objc_msgSend_16(
        _lib._class_NSArray1, _lib._sel_arrayWithObject_1, anObject._id);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray arrayWithObjects_count_(
      AVFAudio _lib, ffi.Pointer<ffi.Pointer<ObjCObject>> objects, int cnt) {
    final _ret = _lib._objc_msgSend_61(
        _lib._class_NSArray1, _lib._sel_arrayWithObjects_count_1, objects, cnt);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray arrayWithObjects_(AVFAudio _lib, NSObject firstObj) {
    final _ret = _lib._objc_msgSend_16(
        _lib._class_NSArray1, _lib._sel_arrayWithObjects_1, firstObj._id);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray arrayWithArray_(AVFAudio _lib, NSArray? array) {
    final _ret = _lib._objc_msgSend_67(_lib._class_NSArray1,
        _lib._sel_arrayWithArray_1, array?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray initWithObjects_(NSObject firstObj) {
    final _ret =
        _lib._objc_msgSend_16(_id, _lib._sel_initWithObjects_1, firstObj._id);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray initWithArray_(NSArray? array) {
    final _ret = _lib._objc_msgSend_67(
        _id, _lib._sel_initWithArray_1, array?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray initWithArray_copyItems_(NSArray? array, bool flag) {
    final _ret = _lib._objc_msgSend_116(_id,
        _lib._sel_initWithArray_copyItems_1, array?._id ?? ffi.nullptr, flag);
    return NSArray._(_ret, _lib, retain: false, release: true);
  }

  NSArray initWithContentsOfURL_error_(
      NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_117(
        _id,
        _lib._sel_initWithContentsOfURL_error_1,
        url?._id ?? ffi.nullptr,
        error);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray arrayWithContentsOfURL_error_(
      AVFAudio _lib, NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_117(
        _lib._class_NSArray1,
        _lib._sel_arrayWithContentsOfURL_error_1,
        url?._id ?? ffi.nullptr,
        error);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  void getObjects_(ffi.Pointer<ffi.Pointer<ObjCObject>> objects) {
    return _lib._objc_msgSend_118(_id, _lib._sel_getObjects_1, objects);
  }

  static NSArray arrayWithContentsOfFile_(AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_119(_lib._class_NSArray1,
        _lib._sel_arrayWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray arrayWithContentsOfURL_(AVFAudio _lib, NSURL? url) {
    final _ret = _lib._objc_msgSend_120(_lib._class_NSArray1,
        _lib._sel_arrayWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray initWithContentsOfFile_(NSString? path) {
    final _ret = _lib._objc_msgSend_119(
        _id, _lib._sel_initWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray initWithContentsOfURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_120(
        _id, _lib._sel_initWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  bool writeToFile_atomically_(NSString? path, bool useAuxiliaryFile) {
    return _lib._objc_msgSend_25(_id, _lib._sel_writeToFile_atomically_1,
        path?._id ?? ffi.nullptr, useAuxiliaryFile);
  }

  bool writeToURL_atomically_(NSURL? url, bool atomically) {
    return _lib._objc_msgSend_121(_id, _lib._sel_writeToURL_atomically_1,
        url?._id ?? ffi.nullptr, atomically);
  }

  NSArray pathsMatchingExtensions_(NSArray? filterTypes) {
    final _ret = _lib._objc_msgSend_63(_id, _lib._sel_pathsMatchingExtensions_1,
        filterTypes?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSObject valueForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_valueForKey_1, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  @override
  void setValue_forKey_(NSObject value, NSString? key) {
    return _lib._objc_msgSend_122(
        _id, _lib._sel_setValue_forKey_1, value._id, key?._id ?? ffi.nullptr);
  }

  void addObserver_toObjectsAtIndexes_forKeyPath_options_context_(
      NSObject? observer,
      NSIndexSet? indexes,
      NSString? keyPath,
      int options,
      ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_123(
        _id,
        _lib._sel_addObserver_toObjectsAtIndexes_forKeyPath_options_context_1,
        observer?._id ?? ffi.nullptr,
        indexes?._id ?? ffi.nullptr,
        keyPath?._id ?? ffi.nullptr,
        options,
        context);
  }

  void removeObserver_fromObjectsAtIndexes_forKeyPath_context_(
      NSObject? observer,
      NSIndexSet? indexes,
      NSString? keyPath,
      ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_124(
        _id,
        _lib._sel_removeObserver_fromObjectsAtIndexes_forKeyPath_context_1,
        observer?._id ?? ffi.nullptr,
        indexes?._id ?? ffi.nullptr,
        keyPath?._id ?? ffi.nullptr,
        context);
  }

  void removeObserver_fromObjectsAtIndexes_forKeyPath_(
      NSObject? observer, NSIndexSet? indexes, NSString? keyPath) {
    return _lib._objc_msgSend_125(
        _id,
        _lib._sel_removeObserver_fromObjectsAtIndexes_forKeyPath_1,
        observer?._id ?? ffi.nullptr,
        indexes?._id ?? ffi.nullptr,
        keyPath?._id ?? ffi.nullptr);
  }

  @override
  void addObserver_forKeyPath_options_context_(NSObject? observer,
      NSString? keyPath, int options, ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_126(
        _id,
        _lib._sel_addObserver_forKeyPath_options_context_1,
        observer?._id ?? ffi.nullptr,
        keyPath?._id ?? ffi.nullptr,
        options,
        context);
  }

  @override
  void removeObserver_forKeyPath_context_(
      NSObject? observer, NSString? keyPath, ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_127(
        _id,
        _lib._sel_removeObserver_forKeyPath_context_1,
        observer?._id ?? ffi.nullptr,
        keyPath?._id ?? ffi.nullptr,
        context);
  }

  @override
  void removeObserver_forKeyPath_(NSObject? observer, NSString? keyPath) {
    return _lib._objc_msgSend_128(_id, _lib._sel_removeObserver_forKeyPath_1,
        observer?._id ?? ffi.nullptr, keyPath?._id ?? ffi.nullptr);
  }

  NSArray sortedArrayUsingDescriptors_(NSArray? sortDescriptors) {
    final _ret = _lib._objc_msgSend_63(
        _id,
        _lib._sel_sortedArrayUsingDescriptors_1,
        sortDescriptors?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray filteredArrayUsingPredicate_(NSPredicate? predicate) {
    final _ret = _lib._objc_msgSend_195(_id,
        _lib._sel_filteredArrayUsingPredicate_1, predicate?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSArray1, _lib._sel_new1);
    return NSArray._(_ret, _lib, retain: false, release: true);
  }

  static NSArray alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSArray1, _lib._sel_alloc1);
    return NSArray._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSArray1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSArray1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSArray1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSArray1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSArray1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSArray1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSArray1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSArray1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSArray1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSInteger = ffi.Long;

class NSError extends NSObject {
  NSError._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSError] that points to the same underlying object as [other].
  static NSError castFrom<T extends _ObjCWrapper>(T other) {
    return NSError._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSError] that wraps the given raw object pointer.
  static NSError castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSError._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSError].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSError1);
  }

  NSError initWithDomain_code_userInfo_(NSErrorDomain domain, int code) {
    final _ret = _lib._objc_msgSend_77(
        _id, _lib._sel_initWithDomain_code_userInfo_1, domain, code);
    return NSError._(_ret, _lib, retain: true, release: true);
  }

  static NSError errorWithDomain_code_userInfo_(
      AVFAudio _lib, NSErrorDomain domain, int code) {
    final _ret = _lib._objc_msgSend_77(_lib._class_NSError1,
        _lib._sel_errorWithDomain_code_userInfo_1, domain, code);
    return NSError._(_ret, _lib, retain: true, release: true);
  }

  NSErrorDomain get domain {
    return _lib._objc_msgSend_20(_id, _lib._sel_domain1);
  }

  int get code {
    return _lib._objc_msgSend_78(_id, _lib._sel_code1);
  }

  static NSError new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSError1, _lib._sel_new1);
    return NSError._(_ret, _lib, retain: false, release: true);
  }

  static NSError alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSError1, _lib._sel_alloc1);
    return NSError._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSError1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSError1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSError1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSError1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSError1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSError1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSError1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSError1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSError1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSErrorDomain = ffi.Pointer<ObjCObject>;

class NSIndexSet extends NSObject {
  NSIndexSet._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSIndexSet] that points to the same underlying object as [other].
  static NSIndexSet castFrom<T extends _ObjCWrapper>(T other) {
    return NSIndexSet._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSIndexSet] that wraps the given raw object pointer.
  static NSIndexSet castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSIndexSet._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSIndexSet].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSIndexSet1);
  }

  static NSIndexSet indexSet(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSIndexSet1, _lib._sel_indexSet1);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  static NSIndexSet indexSetWithIndex_(AVFAudio _lib, int value) {
    final _ret = _lib._objc_msgSend_60(
        _lib._class_NSIndexSet1, _lib._sel_indexSetWithIndex_1, value);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  static NSIndexSet indexSetWithIndexesInRange_(AVFAudio _lib, NSRange range) {
    final _ret = _lib._objc_msgSend_83(
        _lib._class_NSIndexSet1, _lib._sel_indexSetWithIndexesInRange_1, range);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  NSIndexSet initWithIndexesInRange_(NSRange range) {
    final _ret =
        _lib._objc_msgSend_83(_id, _lib._sel_initWithIndexesInRange_1, range);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  NSIndexSet initWithIndexSet_(NSIndexSet? indexSet) {
    final _ret = _lib._objc_msgSend_84(
        _id, _lib._sel_initWithIndexSet_1, indexSet?._id ?? ffi.nullptr);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  NSIndexSet initWithIndex_(int value) {
    final _ret = _lib._objc_msgSend_60(_id, _lib._sel_initWithIndex_1, value);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  bool isEqualToIndexSet_(NSIndexSet? indexSet) {
    return _lib._objc_msgSend_85(
        _id, _lib._sel_isEqualToIndexSet_1, indexSet?._id ?? ffi.nullptr);
  }

  int get count {
    return _lib._objc_msgSend_10(_id, _lib._sel_count1);
  }

  int get firstIndex {
    return _lib._objc_msgSend_10(_id, _lib._sel_firstIndex1);
  }

  int get lastIndex {
    return _lib._objc_msgSend_10(_id, _lib._sel_lastIndex1);
  }

  int indexGreaterThanIndex_(int value) {
    return _lib._objc_msgSend_86(_id, _lib._sel_indexGreaterThanIndex_1, value);
  }

  int indexLessThanIndex_(int value) {
    return _lib._objc_msgSend_86(_id, _lib._sel_indexLessThanIndex_1, value);
  }

  int indexGreaterThanOrEqualToIndex_(int value) {
    return _lib._objc_msgSend_86(
        _id, _lib._sel_indexGreaterThanOrEqualToIndex_1, value);
  }

  int indexLessThanOrEqualToIndex_(int value) {
    return _lib._objc_msgSend_86(
        _id, _lib._sel_indexLessThanOrEqualToIndex_1, value);
  }

  int getIndexes_maxCount_inIndexRange_(ffi.Pointer<NSUInteger> indexBuffer,
      int bufferSize, NSRangePointer range) {
    return _lib._objc_msgSend_87(
        _id,
        _lib._sel_getIndexes_maxCount_inIndexRange_1,
        indexBuffer,
        bufferSize,
        range);
  }

  int countOfIndexesInRange_(NSRange range) {
    return _lib._objc_msgSend_88(_id, _lib._sel_countOfIndexesInRange_1, range);
  }

  bool containsIndex_(int value) {
    return _lib._objc_msgSend_89(_id, _lib._sel_containsIndex_1, value);
  }

  bool containsIndexesInRange_(NSRange range) {
    return _lib._objc_msgSend_90(
        _id, _lib._sel_containsIndexesInRange_1, range);
  }

  bool containsIndexes_(NSIndexSet? indexSet) {
    return _lib._objc_msgSend_85(
        _id, _lib._sel_containsIndexes_1, indexSet?._id ?? ffi.nullptr);
  }

  bool intersectsIndexesInRange_(NSRange range) {
    return _lib._objc_msgSend_90(
        _id, _lib._sel_intersectsIndexesInRange_1, range);
  }

  void enumerateIndexesUsingBlock_(ObjCBlock block) {
    return _lib._objc_msgSend_91(
        _id, _lib._sel_enumerateIndexesUsingBlock_1, block._id);
  }

  void enumerateIndexesWithOptions_usingBlock_(int opts, ObjCBlock block) {
    return _lib._objc_msgSend_92(_id,
        _lib._sel_enumerateIndexesWithOptions_usingBlock_1, opts, block._id);
  }

  void enumerateIndexesInRange_options_usingBlock_(
      NSRange range, int opts, ObjCBlock block) {
    return _lib._objc_msgSend_93(
        _id,
        _lib._sel_enumerateIndexesInRange_options_usingBlock_1,
        range,
        opts,
        block._id);
  }

  int indexPassingTest_(ObjCBlock1 predicate) {
    return _lib._objc_msgSend_94(
        _id, _lib._sel_indexPassingTest_1, predicate._id);
  }

  int indexWithOptions_passingTest_(int opts, ObjCBlock1 predicate) {
    return _lib._objc_msgSend_95(
        _id, _lib._sel_indexWithOptions_passingTest_1, opts, predicate._id);
  }

  int indexInRange_options_passingTest_(
      NSRange range, int opts, ObjCBlock1 predicate) {
    return _lib._objc_msgSend_96(
        _id,
        _lib._sel_indexInRange_options_passingTest_1,
        range,
        opts,
        predicate._id);
  }

  NSIndexSet indexesPassingTest_(ObjCBlock1 predicate) {
    final _ret = _lib._objc_msgSend_97(
        _id, _lib._sel_indexesPassingTest_1, predicate._id);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  NSIndexSet indexesWithOptions_passingTest_(int opts, ObjCBlock1 predicate) {
    final _ret = _lib._objc_msgSend_98(
        _id, _lib._sel_indexesWithOptions_passingTest_1, opts, predicate._id);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  NSIndexSet indexesInRange_options_passingTest_(
      NSRange range, int opts, ObjCBlock1 predicate) {
    final _ret = _lib._objc_msgSend_99(
        _id,
        _lib._sel_indexesInRange_options_passingTest_1,
        range,
        opts,
        predicate._id);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  void enumerateRangesUsingBlock_(ObjCBlock2 block) {
    return _lib._objc_msgSend_100(
        _id, _lib._sel_enumerateRangesUsingBlock_1, block._id);
  }

  void enumerateRangesWithOptions_usingBlock_(int opts, ObjCBlock2 block) {
    return _lib._objc_msgSend_101(_id,
        _lib._sel_enumerateRangesWithOptions_usingBlock_1, opts, block._id);
  }

  void enumerateRangesInRange_options_usingBlock_(
      NSRange range, int opts, ObjCBlock2 block) {
    return _lib._objc_msgSend_102(
        _id,
        _lib._sel_enumerateRangesInRange_options_usingBlock_1,
        range,
        opts,
        block._id);
  }

  static NSIndexSet new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSIndexSet1, _lib._sel_new1);
    return NSIndexSet._(_ret, _lib, retain: false, release: true);
  }

  static NSIndexSet alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSIndexSet1, _lib._sel_alloc1);
    return NSIndexSet._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSIndexSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSIndexSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSIndexSet1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSIndexSet1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSIndexSet1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSIndexSet1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSIndexSet1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSIndexSet1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSIndexSet1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSRangePointer = ffi.Pointer<NSRange>;

class _ObjCBlockBase implements ffi.Finalizable {
  final ffi.Pointer<_ObjCBlock> _id;
  final AVFAudio _lib;
  bool _pendingRelease;

  _ObjCBlockBase._(this._id, this._lib,
      {bool retain = false, bool release = false})
      : _pendingRelease = release {
    if (retain) {
      _lib._Block_copy(_id.cast());
    }
    if (release) {
      _lib._objc_releaseFinalizer11.attach(this, _id.cast(), detach: this);
    }
  }

  /// Releases the reference to the underlying ObjC block held by this wrapper.
  /// Throws a StateError if this wrapper doesn't currently hold a reference.
  void release() {
    if (_pendingRelease) {
      _pendingRelease = false;
      _lib._Block_release(_id.cast());
      _lib._objc_releaseFinalizer11.detach(this);
    } else {
      throw StateError(
          'Released an ObjC block that was unowned or already released.');
    }
  }

  @override
  bool operator ==(Object other) {
    return other is _ObjCBlockBase && _id == other._id;
  }

  @override
  int get hashCode => _id.hashCode;
}

void _ObjCBlock_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, int arg0, ffi.Pointer<ffi.Bool> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(NSUInteger arg0, ffi.Pointer<ffi.Bool> arg1)>>()
      .asFunction<
          void Function(int arg0, ffi.Pointer<ffi.Bool> arg1)>()(arg0, arg1);
}

final _ObjCBlock_closureRegistry = <int, Function>{};
int _ObjCBlock_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock_registerClosure(Function fn) {
  final id = ++_ObjCBlock_closureRegistryIndex;
  _ObjCBlock_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, int arg0, ffi.Pointer<ffi.Bool> arg1) {
  return _ObjCBlock_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock extends _ObjCBlockBase {
  ObjCBlock._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      NSUInteger arg0, ffi.Pointer<ffi.Bool> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                NSUInteger arg0, ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock.fromFunction(
      AVFAudio lib, void Function(int arg0, ffi.Pointer<ffi.Bool> arg1) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                NSUInteger arg0, ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock_closureTrampoline)
                    .cast(),
                _ObjCBlock_registerClosure(fn)),
            lib);
  void call(int arg0, ffi.Pointer<ffi.Bool> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    NSUInteger arg0, ffi.Pointer<ffi.Bool> arg1)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block, int arg0,
                ffi.Pointer<ffi.Bool> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

final class _ObjCBlockDesc extends ffi.Struct {
  @ffi.UnsignedLong()
  external int reserved;

  @ffi.UnsignedLong()
  external int size;

  external ffi.Pointer<ffi.Void> copy_helper;

  external ffi.Pointer<ffi.Void> dispose_helper;

  external ffi.Pointer<ffi.Char> signature;
}

final class _ObjCBlock extends ffi.Struct {
  external ffi.Pointer<ffi.Void> isa;

  @ffi.Int()
  external int flags;

  @ffi.Int()
  external int reserved;

  external ffi.Pointer<ffi.Void> invoke;

  external ffi.Pointer<_ObjCBlockDesc> descriptor;

  external ffi.Pointer<ffi.Void> target;
}

abstract class NSEnumerationOptions {
  static const int NSEnumerationConcurrent = 1;
  static const int NSEnumerationReverse = 2;
}

bool _ObjCBlock1_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, int arg0, ffi.Pointer<ffi.Bool> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Bool Function(NSUInteger arg0, ffi.Pointer<ffi.Bool> arg1)>>()
      .asFunction<
          bool Function(int arg0, ffi.Pointer<ffi.Bool> arg1)>()(arg0, arg1);
}

final _ObjCBlock1_closureRegistry = <int, Function>{};
int _ObjCBlock1_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock1_registerClosure(Function fn) {
  final id = ++_ObjCBlock1_closureRegistryIndex;
  _ObjCBlock1_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

bool _ObjCBlock1_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, int arg0, ffi.Pointer<ffi.Bool> arg1) {
  return _ObjCBlock1_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock1 extends _ObjCBlockBase {
  ObjCBlock1._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock1.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Bool Function(
                      NSUInteger arg0, ffi.Pointer<ffi.Bool> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Bool Function(ffi.Pointer<_ObjCBlock> block,
                                NSUInteger arg0, ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock1_fnPtrTrampoline, false)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock1.fromFunction(
      AVFAudio lib, bool Function(int arg0, ffi.Pointer<ffi.Bool> arg1) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Bool Function(ffi.Pointer<_ObjCBlock> block,
                                NSUInteger arg0, ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock1_closureTrampoline, false)
                    .cast(),
                _ObjCBlock1_registerClosure(fn)),
            lib);
  bool call(int arg0, ffi.Pointer<ffi.Bool> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Bool Function(ffi.Pointer<_ObjCBlock> block,
                    NSUInteger arg0, ffi.Pointer<ffi.Bool> arg1)>>()
        .asFunction<
            bool Function(ffi.Pointer<_ObjCBlock> block, int arg0,
                ffi.Pointer<ffi.Bool> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

void _ObjCBlock2_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, NSRange arg0, ffi.Pointer<ffi.Bool> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(NSRange arg0, ffi.Pointer<ffi.Bool> arg1)>>()
      .asFunction<
          void Function(
              NSRange arg0, ffi.Pointer<ffi.Bool> arg1)>()(arg0, arg1);
}

final _ObjCBlock2_closureRegistry = <int, Function>{};
int _ObjCBlock2_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock2_registerClosure(Function fn) {
  final id = ++_ObjCBlock2_closureRegistryIndex;
  _ObjCBlock2_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock2_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, NSRange arg0, ffi.Pointer<ffi.Bool> arg1) {
  return _ObjCBlock2_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock2 extends _ObjCBlockBase {
  ObjCBlock2._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock2.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(NSRange arg0, ffi.Pointer<ffi.Bool> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                NSRange arg0, ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock2_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock2.fromFunction(
      AVFAudio lib, void Function(NSRange arg0, ffi.Pointer<ffi.Bool> arg1) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                NSRange arg0, ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock2_closureTrampoline)
                    .cast(),
                _ObjCBlock2_registerClosure(fn)),
            lib);
  void call(NSRange arg0, ffi.Pointer<ffi.Bool> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block, NSRange arg0,
                    ffi.Pointer<ffi.Bool> arg1)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block, NSRange arg0,
                ffi.Pointer<ffi.Bool> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

void _ObjCBlock3_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, int arg1, ffi.Pointer<ffi.Bool> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0, NSUInteger arg1,
                  ffi.Pointer<ffi.Bool> arg2)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0, int arg1,
              ffi.Pointer<ffi.Bool> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock3_closureRegistry = <int, Function>{};
int _ObjCBlock3_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock3_registerClosure(Function fn) {
  final id = ++_ObjCBlock3_closureRegistryIndex;
  _ObjCBlock3_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock3_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, int arg1, ffi.Pointer<ffi.Bool> arg2) {
  return _ObjCBlock3_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock3 extends _ObjCBlockBase {
  ObjCBlock3._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock3.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                      NSUInteger arg1, ffi.Pointer<ffi.Bool> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                NSUInteger arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock3_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock3.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, int arg1,
              ffi.Pointer<ffi.Bool> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                NSUInteger arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock3_closureTrampoline)
                    .cast(),
                _ObjCBlock3_registerClosure(fn)),
            lib);
  void call(
      ffi.Pointer<ObjCObject> arg0, int arg1, ffi.Pointer<ffi.Bool> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    NSUInteger arg1,
                    ffi.Pointer<ffi.Bool> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                int arg1,
                ffi.Pointer<ffi.Bool> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

bool _ObjCBlock4_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, int arg1, ffi.Pointer<ffi.Bool> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Bool Function(ffi.Pointer<ObjCObject> arg0, NSUInteger arg1,
                  ffi.Pointer<ffi.Bool> arg2)>>()
      .asFunction<
          bool Function(ffi.Pointer<ObjCObject> arg0, int arg1,
              ffi.Pointer<ffi.Bool> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock4_closureRegistry = <int, Function>{};
int _ObjCBlock4_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock4_registerClosure(Function fn) {
  final id = ++_ObjCBlock4_closureRegistryIndex;
  _ObjCBlock4_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

bool _ObjCBlock4_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, int arg1, ffi.Pointer<ffi.Bool> arg2) {
  return _ObjCBlock4_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock4 extends _ObjCBlockBase {
  ObjCBlock4._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock4.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Bool Function(ffi.Pointer<ObjCObject> arg0,
                      NSUInteger arg1, ffi.Pointer<ffi.Bool> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Bool Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                NSUInteger arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock4_fnPtrTrampoline, false)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock4.fromFunction(
      AVFAudio lib,
      bool Function(ffi.Pointer<ObjCObject> arg0, int arg1,
              ffi.Pointer<ffi.Bool> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Bool Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                NSUInteger arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock4_closureTrampoline, false)
                    .cast(),
                _ObjCBlock4_registerClosure(fn)),
            lib);
  bool call(
      ffi.Pointer<ObjCObject> arg0, int arg1, ffi.Pointer<ffi.Bool> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Bool Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    NSUInteger arg1,
                    ffi.Pointer<ffi.Bool> arg2)>>()
        .asFunction<
            bool Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                int arg1,
                ffi.Pointer<ffi.Bool> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

typedef NSComparator = ffi.Pointer<_ObjCBlock>;
int _ObjCBlock5_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Int32 Function(ffi.Pointer<ObjCObject> arg0,
                  ffi.Pointer<ObjCObject> arg1)>>()
      .asFunction<
          int Function(ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ObjCObject> arg1)>()(arg0, arg1);
}

final _ObjCBlock5_closureRegistry = <int, Function>{};
int _ObjCBlock5_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock5_registerClosure(Function fn) {
  final id = ++_ObjCBlock5_closureRegistryIndex;
  _ObjCBlock5_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

int _ObjCBlock5_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return _ObjCBlock5_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock5 extends _ObjCBlockBase {
  ObjCBlock5._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock5.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Int32 Function(ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ObjCObject> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Int32 Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock5_fnPtrTrampoline, 0)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock5.fromFunction(
      AVFAudio lib,
      int Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Int32 Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock5_closureTrampoline, 0)
                    .cast(),
                _ObjCBlock5_registerClosure(fn)),
            lib);
  int call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Int32 Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ObjCObject> arg1)>>()
        .asFunction<
            int Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ObjCObject> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

abstract class NSComparisonResult {
  static const int NSOrderedAscending = -1;
  static const int NSOrderedSame = 0;
  static const int NSOrderedDescending = 1;
}

abstract class NSSortOptions {
  static const int NSSortConcurrent = 1;
  static const int NSSortStable = 16;
}

abstract class NSBinarySearchingOptions {
  static const int NSBinarySearchingFirstEqual = 256;
  static const int NSBinarySearchingLastEqual = 512;
  static const int NSBinarySearchingInsertionIndex = 1024;
}

abstract class NSKeyValueObservingOptions {
  static const int NSKeyValueObservingOptionNew = 1;
  static const int NSKeyValueObservingOptionOld = 2;
  static const int NSKeyValueObservingOptionInitial = 4;
  static const int NSKeyValueObservingOptionPrior = 8;
}

class NSPredicate extends NSObject {
  NSPredicate._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSPredicate] that points to the same underlying object as [other].
  static NSPredicate castFrom<T extends _ObjCWrapper>(T other) {
    return NSPredicate._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSPredicate] that wraps the given raw object pointer.
  static NSPredicate castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSPredicate._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSPredicate].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSPredicate1);
  }

  static NSPredicate predicateWithFormat_argumentArray_(
      AVFAudio _lib, NSString? predicateFormat, NSArray? arguments) {
    final _ret = _lib._objc_msgSend_129(
        _lib._class_NSPredicate1,
        _lib._sel_predicateWithFormat_argumentArray_1,
        predicateFormat?._id ?? ffi.nullptr,
        arguments?._id ?? ffi.nullptr);
    return NSPredicate._(_ret, _lib, retain: true, release: true);
  }

  static NSPredicate predicateWithFormat_(
      AVFAudio _lib, NSString? predicateFormat) {
    final _ret = _lib._objc_msgSend_130(_lib._class_NSPredicate1,
        _lib._sel_predicateWithFormat_1, predicateFormat?._id ?? ffi.nullptr);
    return NSPredicate._(_ret, _lib, retain: true, release: true);
  }

  static NSPredicate predicateWithFormat_arguments_(AVFAudio _lib,
      NSString? predicateFormat, ffi.Pointer<__va_list_tag> argList) {
    final _ret = _lib._objc_msgSend_131(
        _lib._class_NSPredicate1,
        _lib._sel_predicateWithFormat_arguments_1,
        predicateFormat?._id ?? ffi.nullptr,
        argList);
    return NSPredicate._(_ret, _lib, retain: true, release: true);
  }

  static NSPredicate predicateFromMetadataQueryString_(
      AVFAudio _lib, NSString? queryString) {
    final _ret = _lib._objc_msgSend_130(
        _lib._class_NSPredicate1,
        _lib._sel_predicateFromMetadataQueryString_1,
        queryString?._id ?? ffi.nullptr);
    return NSPredicate._(_ret, _lib, retain: true, release: true);
  }

  static NSPredicate predicateWithValue_(AVFAudio _lib, bool value) {
    final _ret = _lib._objc_msgSend_132(
        _lib._class_NSPredicate1, _lib._sel_predicateWithValue_1, value);
    return NSPredicate._(_ret, _lib, retain: true, release: true);
  }

  static NSPredicate predicateWithBlock_(AVFAudio _lib, ObjCBlock6 block) {
    final _ret = _lib._objc_msgSend_193(
        _lib._class_NSPredicate1, _lib._sel_predicateWithBlock_1, block._id);
    return NSPredicate._(_ret, _lib, retain: true, release: true);
  }

  NSString? get predicateFormat {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_predicateFormat1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSPredicate predicateWithSubstitutionVariables_(NSDictionary? variables) {
    final _ret = _lib._objc_msgSend_143(
        _id,
        _lib._sel_predicateWithSubstitutionVariables_1,
        variables?._id ?? ffi.nullptr);
    return NSPredicate._(_ret, _lib, retain: true, release: true);
  }

  bool evaluateWithObject_(NSObject object) {
    return _lib._objc_msgSend_0(
        _id, _lib._sel_evaluateWithObject_1, object._id);
  }

  bool evaluateWithObject_substitutionVariables_(
      NSObject object, NSDictionary? bindings) {
    return _lib._objc_msgSend_194(
        _id,
        _lib._sel_evaluateWithObject_substitutionVariables_1,
        object._id,
        bindings?._id ?? ffi.nullptr);
  }

  void allowEvaluation() {
    return _lib._objc_msgSend_1(_id, _lib._sel_allowEvaluation1);
  }

  static NSPredicate new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSPredicate1, _lib._sel_new1);
    return NSPredicate._(_ret, _lib, retain: false, release: true);
  }

  static NSPredicate alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSPredicate1, _lib._sel_alloc1);
    return NSPredicate._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSPredicate1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSPredicate1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSPredicate1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSPredicate1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSPredicate1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSPredicate1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSPredicate1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSPredicate1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSPredicate1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

final class __va_list_tag extends ffi.Struct {
  @ffi.UnsignedInt()
  external int gp_offset;

  @ffi.UnsignedInt()
  external int fp_offset;

  external ffi.Pointer<ffi.Void> overflow_arg_area;

  external ffi.Pointer<ffi.Void> reg_save_area;
}

bool _ObjCBlock6_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Bool Function(ffi.Pointer<ObjCObject> arg0,
                  ffi.Pointer<ObjCObject> arg1)>>()
      .asFunction<
          bool Function(ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ObjCObject> arg1)>()(arg0, arg1);
}

final _ObjCBlock6_closureRegistry = <int, Function>{};
int _ObjCBlock6_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock6_registerClosure(Function fn) {
  final id = ++_ObjCBlock6_closureRegistryIndex;
  _ObjCBlock6_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

bool _ObjCBlock6_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return _ObjCBlock6_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock6 extends _ObjCBlockBase {
  ObjCBlock6._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock6.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Bool Function(ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ObjCObject> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Bool Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock6_fnPtrTrampoline, false)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock6.fromFunction(
      AVFAudio lib,
      bool Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Bool Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock6_closureTrampoline, false)
                    .cast(),
                _ObjCBlock6_registerClosure(fn)),
            lib);
  bool call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Bool Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ObjCObject> arg1)>>()
        .asFunction<
            bool Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ObjCObject> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSDictionary extends NSObject {
  NSDictionary._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSDictionary] that points to the same underlying object as [other].
  static NSDictionary castFrom<T extends _ObjCWrapper>(T other) {
    return NSDictionary._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSDictionary] that wraps the given raw object pointer.
  static NSDictionary castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSDictionary._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSDictionary].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSDictionary1);
  }

  int get count {
    return _lib._objc_msgSend_10(_id, _lib._sel_count1);
  }

  NSObject objectForKey_(NSObject aKey) {
    final _ret = _lib._objc_msgSend_16(_id, _lib._sel_objectForKey_1, aKey._id);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSEnumerator keyEnumerator() {
    final _ret = _lib._objc_msgSend_72(_id, _lib._sel_keyEnumerator1);
    return NSEnumerator._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSDictionary init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary initWithObjects_forKeys_count_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
      ffi.Pointer<ffi.Pointer<ObjCObject>> keys,
      int cnt) {
    final _ret = _lib._objc_msgSend_133(
        _id, _lib._sel_initWithObjects_forKeys_count_1, objects, keys, cnt);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get allKeys {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_allKeys1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray allKeysForObject_(NSObject anObject) {
    final _ret =
        _lib._objc_msgSend_62(_id, _lib._sel_allKeysForObject_1, anObject._id);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get allValues {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_allValues1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString? get description {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_description1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get descriptionInStringsFileFormat {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_descriptionInStringsFileFormat1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString descriptionWithLocale_(NSObject locale) {
    final _ret = _lib._objc_msgSend_65(
        _id, _lib._sel_descriptionWithLocale_1, locale._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString descriptionWithLocale_indent_(NSObject locale, int level) {
    final _ret = _lib._objc_msgSend_66(
        _id, _lib._sel_descriptionWithLocale_indent_1, locale._id, level);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  bool isEqualToDictionary_(NSDictionary? otherDictionary) {
    return _lib._objc_msgSend_134(_id, _lib._sel_isEqualToDictionary_1,
        otherDictionary?._id ?? ffi.nullptr);
  }

  NSEnumerator objectEnumerator() {
    final _ret = _lib._objc_msgSend_72(_id, _lib._sel_objectEnumerator1);
    return NSEnumerator._(_ret, _lib, retain: true, release: true);
  }

  NSArray objectsForKeys_notFoundMarker_(NSArray? keys, NSObject marker) {
    final _ret = _lib._objc_msgSend_135(
        _id,
        _lib._sel_objectsForKeys_notFoundMarker_1,
        keys?._id ?? ffi.nullptr,
        marker._id);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  bool writeToURL_error_(
      NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_81(
        _id, _lib._sel_writeToURL_error_1, url?._id ?? ffi.nullptr, error);
  }

  NSArray keysSortedByValueUsingSelector_(ffi.Pointer<ObjCSel> comparator) {
    final _ret = _lib._objc_msgSend_75(
        _id, _lib._sel_keysSortedByValueUsingSelector_1, comparator);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  void getObjects_andKeys_count_(ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
      ffi.Pointer<ffi.Pointer<ObjCObject>> keys, int count) {
    return _lib._objc_msgSend_136(
        _id, _lib._sel_getObjects_andKeys_count_1, objects, keys, count);
  }

  NSObject objectForKeyedSubscript_(NSObject key) {
    final _ret = _lib._objc_msgSend_16(
        _id, _lib._sel_objectForKeyedSubscript_1, key._id);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void enumerateKeysAndObjectsUsingBlock_(ObjCBlock7 block) {
    return _lib._objc_msgSend_137(
        _id, _lib._sel_enumerateKeysAndObjectsUsingBlock_1, block._id);
  }

  void enumerateKeysAndObjectsWithOptions_usingBlock_(
      int opts, ObjCBlock7 block) {
    return _lib._objc_msgSend_138(
        _id,
        _lib._sel_enumerateKeysAndObjectsWithOptions_usingBlock_1,
        opts,
        block._id);
  }

  NSArray keysSortedByValueUsingComparator_(NSComparator cmptr) {
    final _ret = _lib._objc_msgSend_113(
        _id, _lib._sel_keysSortedByValueUsingComparator_1, cmptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray keysSortedByValueWithOptions_usingComparator_(
      int opts, NSComparator cmptr) {
    final _ret = _lib._objc_msgSend_114(_id,
        _lib._sel_keysSortedByValueWithOptions_usingComparator_1, opts, cmptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  void getObjects_andKeys_(ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
      ffi.Pointer<ffi.Pointer<ObjCObject>> keys) {
    return _lib._objc_msgSend_139(
        _id, _lib._sel_getObjects_andKeys_1, objects, keys);
  }

  static NSDictionary dictionaryWithContentsOfFile_(
      AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_140(_lib._class_NSDictionary1,
        _lib._sel_dictionaryWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary dictionaryWithContentsOfURL_(AVFAudio _lib, NSURL? url) {
    final _ret = _lib._objc_msgSend_141(_lib._class_NSDictionary1,
        _lib._sel_dictionaryWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary initWithContentsOfFile_(NSString? path) {
    final _ret = _lib._objc_msgSend_140(
        _id, _lib._sel_initWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary initWithContentsOfURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_141(
        _id, _lib._sel_initWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  bool writeToFile_atomically_(NSString? path, bool useAuxiliaryFile) {
    return _lib._objc_msgSend_25(_id, _lib._sel_writeToFile_atomically_1,
        path?._id ?? ffi.nullptr, useAuxiliaryFile);
  }

  bool writeToURL_atomically_(NSURL? url, bool atomically) {
    return _lib._objc_msgSend_121(_id, _lib._sel_writeToURL_atomically_1,
        url?._id ?? ffi.nullptr, atomically);
  }

  static NSDictionary dictionary(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSDictionary1, _lib._sel_dictionary1);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary dictionaryWithObject_forKey_(
      AVFAudio _lib, NSObject object, NSObject key) {
    final _ret = _lib._objc_msgSend_142(_lib._class_NSDictionary1,
        _lib._sel_dictionaryWithObject_forKey_1, object._id, key._id);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary dictionaryWithObjects_forKeys_count_(
      AVFAudio _lib,
      ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
      ffi.Pointer<ffi.Pointer<ObjCObject>> keys,
      int cnt) {
    final _ret = _lib._objc_msgSend_133(_lib._class_NSDictionary1,
        _lib._sel_dictionaryWithObjects_forKeys_count_1, objects, keys, cnt);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary dictionaryWithObjectsAndKeys_(
      AVFAudio _lib, NSObject firstObject) {
    final _ret = _lib._objc_msgSend_16(_lib._class_NSDictionary1,
        _lib._sel_dictionaryWithObjectsAndKeys_1, firstObject._id);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary dictionaryWithDictionary_(
      AVFAudio _lib, NSDictionary? dict) {
    final _ret = _lib._objc_msgSend_143(_lib._class_NSDictionary1,
        _lib._sel_dictionaryWithDictionary_1, dict?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary dictionaryWithObjects_forKeys_(
      AVFAudio _lib, NSArray? objects, NSArray? keys) {
    final _ret = _lib._objc_msgSend_144(
        _lib._class_NSDictionary1,
        _lib._sel_dictionaryWithObjects_forKeys_1,
        objects?._id ?? ffi.nullptr,
        keys?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary initWithObjectsAndKeys_(NSObject firstObject) {
    final _ret = _lib._objc_msgSend_16(
        _id, _lib._sel_initWithObjectsAndKeys_1, firstObject._id);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary initWithDictionary_(NSDictionary? otherDictionary) {
    final _ret = _lib._objc_msgSend_143(_id, _lib._sel_initWithDictionary_1,
        otherDictionary?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary initWithDictionary_copyItems_(
      NSDictionary? otherDictionary, bool flag) {
    final _ret = _lib._objc_msgSend_145(
        _id,
        _lib._sel_initWithDictionary_copyItems_1,
        otherDictionary?._id ?? ffi.nullptr,
        flag);
    return NSDictionary._(_ret, _lib, retain: false, release: true);
  }

  NSDictionary initWithObjects_forKeys_(NSArray? objects, NSArray? keys) {
    final _ret = _lib._objc_msgSend_144(
        _id,
        _lib._sel_initWithObjects_forKeys_1,
        objects?._id ?? ffi.nullptr,
        keys?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary initWithContentsOfURL_error_(
      NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_146(
        _id,
        _lib._sel_initWithContentsOfURL_error_1,
        url?._id ?? ffi.nullptr,
        error);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary dictionaryWithContentsOfURL_error_(
      AVFAudio _lib, NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_146(
        _lib._class_NSDictionary1,
        _lib._sel_dictionaryWithContentsOfURL_error_1,
        url?._id ?? ffi.nullptr,
        error);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSObject sharedKeySetForKeys_(AVFAudio _lib, NSArray? keys) {
    final _ret = _lib._objc_msgSend_67(_lib._class_NSDictionary1,
        _lib._sel_sharedKeySetForKeys_1, keys?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  int countByEnumeratingWithState_objects_count_(
      ffi.Pointer<NSFastEnumerationState> state,
      ffi.Pointer<ffi.Pointer<ObjCObject>> buffer,
      int len) {
    return _lib._objc_msgSend_147(
        _id,
        _lib._sel_countByEnumeratingWithState_objects_count_1,
        state,
        buffer,
        len);
  }

  int fileSize() {
    return _lib._objc_msgSend_148(_id, _lib._sel_fileSize1);
  }

  NSDate fileModificationDate() {
    final _ret = _lib._objc_msgSend_156(_id, _lib._sel_fileModificationDate1);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSString fileType() {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_fileType1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  int filePosixPermissions() {
    return _lib._objc_msgSend_10(_id, _lib._sel_filePosixPermissions1);
  }

  NSString fileOwnerAccountName() {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_fileOwnerAccountName1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString fileGroupOwnerAccountName() {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_fileGroupOwnerAccountName1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  int fileSystemNumber() {
    return _lib._objc_msgSend_78(_id, _lib._sel_fileSystemNumber1);
  }

  int fileSystemFileNumber() {
    return _lib._objc_msgSend_10(_id, _lib._sel_fileSystemFileNumber1);
  }

  bool fileExtensionHidden() {
    return _lib._objc_msgSend_12(_id, _lib._sel_fileExtensionHidden1);
  }

  int fileHFSCreatorCode() {
    return _lib._objc_msgSend_191(_id, _lib._sel_fileHFSCreatorCode1);
  }

  int fileHFSTypeCode() {
    return _lib._objc_msgSend_191(_id, _lib._sel_fileHFSTypeCode1);
  }

  bool fileIsImmutable() {
    return _lib._objc_msgSend_12(_id, _lib._sel_fileIsImmutable1);
  }

  bool fileIsAppendOnly() {
    return _lib._objc_msgSend_12(_id, _lib._sel_fileIsAppendOnly1);
  }

  NSDate fileCreationDate() {
    final _ret = _lib._objc_msgSend_156(_id, _lib._sel_fileCreationDate1);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSNumber fileOwnerAccountID() {
    final _ret = _lib._objc_msgSend_192(_id, _lib._sel_fileOwnerAccountID1);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSNumber fileGroupOwnerAccountID() {
    final _ret =
        _lib._objc_msgSend_192(_id, _lib._sel_fileGroupOwnerAccountID1);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSObject valueForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_valueForKey_1, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSDictionary1, _lib._sel_new1);
    return NSDictionary._(_ret, _lib, retain: false, release: true);
  }

  static NSDictionary alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSDictionary1, _lib._sel_alloc1);
    return NSDictionary._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSDictionary1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSDictionary1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSDictionary1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSDictionary1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSDictionary1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSDictionary1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSDictionary1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSDictionary1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSDictionary1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

void _ObjCBlock7_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ffi.Bool> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                  ffi.Pointer<ObjCObject> arg1, ffi.Pointer<ffi.Bool> arg2)>>()
      .asFunction<
          void Function(
              ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ObjCObject> arg1,
              ffi.Pointer<ffi.Bool> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock7_closureRegistry = <int, Function>{};
int _ObjCBlock7_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock7_registerClosure(Function fn) {
  final id = ++_ObjCBlock7_closureRegistryIndex;
  _ObjCBlock7_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock7_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ffi.Bool> arg2) {
  return _ObjCBlock7_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock7 extends _ObjCBlockBase {
  ObjCBlock7._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock7.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ObjCObject> arg1,
                      ffi.Pointer<ffi.Bool> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock7_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock7.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1,
              ffi.Pointer<ffi.Bool> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock7_closureTrampoline)
                    .cast(),
                _ObjCBlock7_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1,
      ffi.Pointer<ffi.Bool> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ObjCObject> arg1,
                    ffi.Pointer<ffi.Bool> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ObjCObject> arg1,
                ffi.Pointer<ffi.Bool> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

final class NSFastEnumerationState extends ffi.Struct {
  @ffi.UnsignedLong()
  external int state;

  external ffi.Pointer<ffi.Pointer<ObjCObject>> itemsPtr;

  external ffi.Pointer<ffi.UnsignedLong> mutationsPtr;

  @ffi.Array.multi([5])
  external ffi.Array<ffi.UnsignedLong> extra;
}

class NSDate extends NSObject {
  NSDate._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSDate] that points to the same underlying object as [other].
  static NSDate castFrom<T extends _ObjCWrapper>(T other) {
    return NSDate._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSDate] that wraps the given raw object pointer.
  static NSDate castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSDate._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSDate].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSDate1);
  }

  double get timeIntervalSinceReferenceDate {
    return _lib._objc_msgSend_149(
        _id, _lib._sel_timeIntervalSinceReferenceDate1);
  }

  @override
  NSDate init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate initWithTimeIntervalSinceReferenceDate_(double ti) {
    final _ret = _lib._objc_msgSend_150(
        _id, _lib._sel_initWithTimeIntervalSinceReferenceDate_1, ti);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  double timeIntervalSinceDate_(NSDate? anotherDate) {
    return _lib._objc_msgSend_151(_id, _lib._sel_timeIntervalSinceDate_1,
        anotherDate?._id ?? ffi.nullptr);
  }

  double get timeIntervalSinceNow {
    return _lib._objc_msgSend_149(_id, _lib._sel_timeIntervalSinceNow1);
  }

  double get timeIntervalSince1970 {
    return _lib._objc_msgSend_149(_id, _lib._sel_timeIntervalSince19701);
  }

  NSObject addTimeInterval_(double seconds) {
    final _ret =
        _lib._objc_msgSend_150(_id, _lib._sel_addTimeInterval_1, seconds);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSDate dateByAddingTimeInterval_(double ti) {
    final _ret =
        _lib._objc_msgSend_150(_id, _lib._sel_dateByAddingTimeInterval_1, ti);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate earlierDate_(NSDate? anotherDate) {
    final _ret = _lib._objc_msgSend_152(
        _id, _lib._sel_earlierDate_1, anotherDate?._id ?? ffi.nullptr);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate laterDate_(NSDate? anotherDate) {
    final _ret = _lib._objc_msgSend_152(
        _id, _lib._sel_laterDate_1, anotherDate?._id ?? ffi.nullptr);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  int compare_(NSDate? other) {
    return _lib._objc_msgSend_153(
        _id, _lib._sel_compare_1, other?._id ?? ffi.nullptr);
  }

  bool isEqualToDate_(NSDate? otherDate) {
    return _lib._objc_msgSend_154(
        _id, _lib._sel_isEqualToDate_1, otherDate?._id ?? ffi.nullptr);
  }

  NSString? get description {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_description1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString descriptionWithLocale_(NSObject locale) {
    final _ret = _lib._objc_msgSend_65(
        _id, _lib._sel_descriptionWithLocale_1, locale._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSDate date(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSDate1, _lib._sel_date1);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSDate dateWithTimeIntervalSinceNow_(AVFAudio _lib, double secs) {
    final _ret = _lib._objc_msgSend_150(
        _lib._class_NSDate1, _lib._sel_dateWithTimeIntervalSinceNow_1, secs);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSDate dateWithTimeIntervalSinceReferenceDate_(
      AVFAudio _lib, double ti) {
    final _ret = _lib._objc_msgSend_150(_lib._class_NSDate1,
        _lib._sel_dateWithTimeIntervalSinceReferenceDate_1, ti);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSDate dateWithTimeIntervalSince1970_(AVFAudio _lib, double secs) {
    final _ret = _lib._objc_msgSend_150(
        _lib._class_NSDate1, _lib._sel_dateWithTimeIntervalSince1970_1, secs);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSDate dateWithTimeInterval_sinceDate_(
      AVFAudio _lib, double secsToBeAdded, NSDate? date) {
    final _ret = _lib._objc_msgSend_155(
        _lib._class_NSDate1,
        _lib._sel_dateWithTimeInterval_sinceDate_1,
        secsToBeAdded,
        date?._id ?? ffi.nullptr);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSDate? getDistantFuture(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_156(_lib._class_NSDate1, _lib._sel_distantFuture1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSDate? getDistantPast(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_156(_lib._class_NSDate1, _lib._sel_distantPast1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSDate? getNow(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_156(_lib._class_NSDate1, _lib._sel_now1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate initWithTimeIntervalSinceNow_(double secs) {
    final _ret = _lib._objc_msgSend_150(
        _id, _lib._sel_initWithTimeIntervalSinceNow_1, secs);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate initWithTimeIntervalSince1970_(double secs) {
    final _ret = _lib._objc_msgSend_150(
        _id, _lib._sel_initWithTimeIntervalSince1970_1, secs);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate initWithTimeInterval_sinceDate_(double secsToBeAdded, NSDate? date) {
    final _ret = _lib._objc_msgSend_155(
        _id,
        _lib._sel_initWithTimeInterval_sinceDate_1,
        secsToBeAdded,
        date?._id ?? ffi.nullptr);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSObject dateWithNaturalLanguageString_locale_(
      AVFAudio _lib, NSString? string, NSObject locale) {
    final _ret = _lib._objc_msgSend_157(
        _lib._class_NSDate1,
        _lib._sel_dateWithNaturalLanguageString_locale_1,
        string?._id ?? ffi.nullptr,
        locale._id);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject dateWithNaturalLanguageString_(
      AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSDate1,
        _lib._sel_dateWithNaturalLanguageString_1, string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject dateWithString_(AVFAudio _lib, NSString? aString) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSDate1,
        _lib._sel_dateWithString_1, aString?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSCalendarDate dateWithCalendarFormat_timeZone_(
      NSString? format, NSTimeZone? aTimeZone) {
    final _ret = _lib._objc_msgSend_189(
        _id,
        _lib._sel_dateWithCalendarFormat_timeZone_1,
        format?._id ?? ffi.nullptr,
        aTimeZone?._id ?? ffi.nullptr);
    return NSCalendarDate._(_ret, _lib, retain: true, release: true);
  }

  NSString descriptionWithCalendarFormat_timeZone_locale_(
      NSString? format, NSTimeZone? aTimeZone, NSObject locale) {
    final _ret = _lib._objc_msgSend_190(
        _id,
        _lib._sel_descriptionWithCalendarFormat_timeZone_locale_1,
        format?._id ?? ffi.nullptr,
        aTimeZone?._id ?? ffi.nullptr,
        locale._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithString_(NSString? description) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithString_1, description?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSDate new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSDate1, _lib._sel_new1);
    return NSDate._(_ret, _lib, retain: false, release: true);
  }

  static NSDate alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSDate1, _lib._sel_alloc1);
    return NSDate._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSDate1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSDate1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSDate1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSDate1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSDate1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSDate1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSDate1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSDate1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSDate1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSTimeInterval = ffi.Double;

class NSCalendarDate extends NSDate {
  NSCalendarDate._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSCalendarDate] that points to the same underlying object as [other].
  static NSCalendarDate castFrom<T extends _ObjCWrapper>(T other) {
    return NSCalendarDate._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSCalendarDate] that wraps the given raw object pointer.
  static NSCalendarDate castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSCalendarDate._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSCalendarDate].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSCalendarDate1);
  }

  static NSObject calendarDate(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSCalendarDate1, _lib._sel_calendarDate1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject dateWithString_calendarFormat_locale_(
      AVFAudio _lib, NSString? description, NSString? format, NSObject locale) {
    final _ret = _lib._objc_msgSend_158(
        _lib._class_NSCalendarDate1,
        _lib._sel_dateWithString_calendarFormat_locale_1,
        description?._id ?? ffi.nullptr,
        format?._id ?? ffi.nullptr,
        locale._id);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject dateWithString_calendarFormat_(
      AVFAudio _lib, NSString? description, NSString? format) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSCalendarDate1,
        _lib._sel_dateWithString_calendarFormat_1,
        description?._id ?? ffi.nullptr,
        format?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject dateWithYear_month_day_hour_minute_second_timeZone_(
      AVFAudio _lib,
      int year,
      int month,
      int day,
      int hour,
      int minute,
      int second,
      NSTimeZone? aTimeZone) {
    final _ret = _lib._objc_msgSend_184(
        _lib._class_NSCalendarDate1,
        _lib._sel_dateWithYear_month_day_hour_minute_second_timeZone_1,
        year,
        month,
        day,
        hour,
        minute,
        second,
        aTimeZone?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSCalendarDate dateByAddingYears_months_days_hours_minutes_seconds_(
      int year, int month, int day, int hour, int minute, int second) {
    final _ret = _lib._objc_msgSend_185(
        _id,
        _lib._sel_dateByAddingYears_months_days_hours_minutes_seconds_1,
        year,
        month,
        day,
        hour,
        minute,
        second);
    return NSCalendarDate._(_ret, _lib, retain: true, release: true);
  }

  int dayOfCommonEra() {
    return _lib._objc_msgSend_78(_id, _lib._sel_dayOfCommonEra1);
  }

  int dayOfMonth() {
    return _lib._objc_msgSend_78(_id, _lib._sel_dayOfMonth1);
  }

  int dayOfWeek() {
    return _lib._objc_msgSend_78(_id, _lib._sel_dayOfWeek1);
  }

  int dayOfYear() {
    return _lib._objc_msgSend_78(_id, _lib._sel_dayOfYear1);
  }

  int hourOfDay() {
    return _lib._objc_msgSend_78(_id, _lib._sel_hourOfDay1);
  }

  int minuteOfHour() {
    return _lib._objc_msgSend_78(_id, _lib._sel_minuteOfHour1);
  }

  int monthOfYear() {
    return _lib._objc_msgSend_78(_id, _lib._sel_monthOfYear1);
  }

  int secondOfMinute() {
    return _lib._objc_msgSend_78(_id, _lib._sel_secondOfMinute1);
  }

  int yearOfCommonEra() {
    return _lib._objc_msgSend_78(_id, _lib._sel_yearOfCommonEra1);
  }

  NSString calendarFormat() {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_calendarFormat1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString descriptionWithCalendarFormat_locale_(
      NSString? format, NSObject locale) {
    final _ret = _lib._objc_msgSend_167(
        _id,
        _lib._sel_descriptionWithCalendarFormat_locale_1,
        format?._id ?? ffi.nullptr,
        locale._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString descriptionWithCalendarFormat_(NSString? format) {
    final _ret = _lib._objc_msgSend_64(_id,
        _lib._sel_descriptionWithCalendarFormat_1, format?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSString descriptionWithLocale_(NSObject locale) {
    final _ret = _lib._objc_msgSend_65(
        _id, _lib._sel_descriptionWithLocale_1, locale._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSTimeZone timeZone() {
    final _ret = _lib._objc_msgSend_162(_id, _lib._sel_timeZone1);
    return NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithString_calendarFormat_locale_(
      NSString? description, NSString? format, NSObject locale) {
    final _ret = _lib._objc_msgSend_158(
        _id,
        _lib._sel_initWithString_calendarFormat_locale_1,
        description?._id ?? ffi.nullptr,
        format?._id ?? ffi.nullptr,
        locale._id);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithString_calendarFormat_(
      NSString? description, NSString? format) {
    final _ret = _lib._objc_msgSend_159(
        _id,
        _lib._sel_initWithString_calendarFormat_1,
        description?._id ?? ffi.nullptr,
        format?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSObject initWithString_(NSString? description) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithString_1, description?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithYear_month_day_hour_minute_second_timeZone_(
      int year,
      int month,
      int day,
      int hour,
      int minute,
      int second,
      NSTimeZone? aTimeZone) {
    final _ret = _lib._objc_msgSend_184(
        _id,
        _lib._sel_initWithYear_month_day_hour_minute_second_timeZone_1,
        year,
        month,
        day,
        hour,
        minute,
        second,
        aTimeZone?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void setCalendarFormat_(NSString? format) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_setCalendarFormat_1, format?._id ?? ffi.nullptr);
  }

  void setTimeZone_(NSTimeZone? aTimeZone) {
    return _lib._objc_msgSend_187(
        _id, _lib._sel_setTimeZone_1, aTimeZone?._id ?? ffi.nullptr);
  }

  void years_months_days_hours_minutes_seconds_sinceDate_(
      ffi.Pointer<NSInteger> yp,
      ffi.Pointer<NSInteger> mop,
      ffi.Pointer<NSInteger> dp,
      ffi.Pointer<NSInteger> hp,
      ffi.Pointer<NSInteger> mip,
      ffi.Pointer<NSInteger> sp,
      NSCalendarDate? date) {
    return _lib._objc_msgSend_188(
        _id,
        _lib._sel_years_months_days_hours_minutes_seconds_sinceDate_1,
        yp,
        mop,
        dp,
        hp,
        mip,
        sp,
        date?._id ?? ffi.nullptr);
  }

  static NSDate? getDistantFuture(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_156(
        _lib._class_NSCalendarDate1, _lib._sel_distantFuture1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSDate? getDistantPast(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_156(
        _lib._class_NSCalendarDate1, _lib._sel_distantPast1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSCalendarDate date(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSCalendarDate1, _lib._sel_date1);
    return NSCalendarDate._(_ret, _lib, retain: true, release: true);
  }

  static NSCalendarDate dateWithTimeIntervalSinceNow_(
      AVFAudio _lib, double secs) {
    final _ret = _lib._objc_msgSend_150(_lib._class_NSCalendarDate1,
        _lib._sel_dateWithTimeIntervalSinceNow_1, secs);
    return NSCalendarDate._(_ret, _lib, retain: true, release: true);
  }

  static NSCalendarDate dateWithTimeIntervalSinceReferenceDate_(
      AVFAudio _lib, double ti) {
    final _ret = _lib._objc_msgSend_150(_lib._class_NSCalendarDate1,
        _lib._sel_dateWithTimeIntervalSinceReferenceDate_1, ti);
    return NSCalendarDate._(_ret, _lib, retain: true, release: true);
  }

  static NSCalendarDate dateWithTimeIntervalSince1970_(
      AVFAudio _lib, double secs) {
    final _ret = _lib._objc_msgSend_150(_lib._class_NSCalendarDate1,
        _lib._sel_dateWithTimeIntervalSince1970_1, secs);
    return NSCalendarDate._(_ret, _lib, retain: true, release: true);
  }

  static NSCalendarDate dateWithTimeInterval_sinceDate_(
      AVFAudio _lib, double secsToBeAdded, NSDate? date) {
    final _ret = _lib._objc_msgSend_155(
        _lib._class_NSCalendarDate1,
        _lib._sel_dateWithTimeInterval_sinceDate_1,
        secsToBeAdded,
        date?._id ?? ffi.nullptr);
    return NSCalendarDate._(_ret, _lib, retain: true, release: true);
  }

  static NSDate? getNow(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_156(_lib._class_NSCalendarDate1, _lib._sel_now1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSObject dateWithNaturalLanguageString_locale_(
      AVFAudio _lib, NSString? string, NSObject locale) {
    final _ret = _lib._objc_msgSend_157(
        _lib._class_NSCalendarDate1,
        _lib._sel_dateWithNaturalLanguageString_locale_1,
        string?._id ?? ffi.nullptr,
        locale._id);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject dateWithNaturalLanguageString_(
      AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSCalendarDate1,
        _lib._sel_dateWithNaturalLanguageString_1, string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject dateWithString_(AVFAudio _lib, NSString? aString) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSCalendarDate1,
        _lib._sel_dateWithString_1, aString?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSCalendarDate new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSCalendarDate1, _lib._sel_new1);
    return NSCalendarDate._(_ret, _lib, retain: false, release: true);
  }

  static NSCalendarDate alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSCalendarDate1, _lib._sel_alloc1);
    return NSCalendarDate._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSCalendarDate1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSCalendarDate1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSCalendarDate1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSCalendarDate1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSCalendarDate1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSCalendarDate1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSCalendarDate1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSCalendarDate1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSCalendarDate1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSTimeZone extends NSObject {
  NSTimeZone._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSTimeZone] that points to the same underlying object as [other].
  static NSTimeZone castFrom<T extends _ObjCWrapper>(T other) {
    return NSTimeZone._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSTimeZone] that wraps the given raw object pointer.
  static NSTimeZone castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSTimeZone._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSTimeZone].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSTimeZone1);
  }

  NSString? get name {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_name1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSData? get data {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_data1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  int secondsFromGMTForDate_(NSDate? aDate) {
    return _lib._objc_msgSend_160(
        _id, _lib._sel_secondsFromGMTForDate_1, aDate?._id ?? ffi.nullptr);
  }

  NSString abbreviationForDate_(NSDate? aDate) {
    final _ret = _lib._objc_msgSend_161(
        _id, _lib._sel_abbreviationForDate_1, aDate?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  bool isDaylightSavingTimeForDate_(NSDate? aDate) {
    return _lib._objc_msgSend_154(_id, _lib._sel_isDaylightSavingTimeForDate_1,
        aDate?._id ?? ffi.nullptr);
  }

  double daylightSavingTimeOffsetForDate_(NSDate? aDate) {
    return _lib._objc_msgSend_151(_id,
        _lib._sel_daylightSavingTimeOffsetForDate_1, aDate?._id ?? ffi.nullptr);
  }

  NSDate nextDaylightSavingTimeTransitionAfterDate_(NSDate? aDate) {
    final _ret = _lib._objc_msgSend_152(
        _id,
        _lib._sel_nextDaylightSavingTimeTransitionAfterDate_1,
        aDate?._id ?? ffi.nullptr);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSTimeZone? getSystemTimeZone(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_162(
        _lib._class_NSTimeZone1, _lib._sel_systemTimeZone1);
    return _ret.address == 0
        ? null
        : NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  static void resetSystemTimeZone(AVFAudio _lib) {
    return _lib._objc_msgSend_1(
        _lib._class_NSTimeZone1, _lib._sel_resetSystemTimeZone1);
  }

  static NSTimeZone? getDefaultTimeZone(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_162(
        _lib._class_NSTimeZone1, _lib._sel_defaultTimeZone1);
    return _ret.address == 0
        ? null
        : NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  static void setDefaultTimeZone(AVFAudio _lib, NSTimeZone? value) {
    _lib._objc_msgSend_163(_lib._class_NSTimeZone1,
        _lib._sel_setDefaultTimeZone_1, value?._id ?? ffi.nullptr);
  }

  static NSTimeZone? getLocalTimeZone(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_162(
        _lib._class_NSTimeZone1, _lib._sel_localTimeZone1);
    return _ret.address == 0
        ? null
        : NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  static NSArray? getKnownTimeZoneNames(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSTimeZone1, _lib._sel_knownTimeZoneNames1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary? getAbbreviationDictionary(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_164(
        _lib._class_NSTimeZone1, _lib._sel_abbreviationDictionary1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static void setAbbreviationDictionary(AVFAudio _lib, NSDictionary? value) {
    _lib._objc_msgSend_165(_lib._class_NSTimeZone1,
        _lib._sel_setAbbreviationDictionary_1, value?._id ?? ffi.nullptr);
  }

  static NSString? getTimeZoneDataVersion(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_20(
        _lib._class_NSTimeZone1, _lib._sel_timeZoneDataVersion1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get secondsFromGMT {
    return _lib._objc_msgSend_78(_id, _lib._sel_secondsFromGMT1);
  }

  NSString? get abbreviation {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_abbreviation1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  bool get daylightSavingTime {
    return _lib._objc_msgSend_12(_id, _lib._sel_isDaylightSavingTime1);
  }

  double get daylightSavingTimeOffset {
    return _lib._objc_msgSend_149(_id, _lib._sel_daylightSavingTimeOffset1);
  }

  NSDate? get nextDaylightSavingTimeTransition {
    final _ret = _lib._objc_msgSend_156(
        _id, _lib._sel_nextDaylightSavingTimeTransition1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSString? get description {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_description1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  bool isEqualToTimeZone_(NSTimeZone? aTimeZone) {
    return _lib._objc_msgSend_166(
        _id, _lib._sel_isEqualToTimeZone_1, aTimeZone?._id ?? ffi.nullptr);
  }

  NSString localizedName_locale_(int style, NSLocale? locale) {
    final _ret = _lib._objc_msgSend_181(_id, _lib._sel_localizedName_locale_1,
        style, locale?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSTimeZone timeZoneWithName_(AVFAudio _lib, NSString? tzName) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSTimeZone1,
        _lib._sel_timeZoneWithName_1, tzName?._id ?? ffi.nullptr);
    return NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  static NSTimeZone timeZoneWithName_data_(
      AVFAudio _lib, NSString? tzName, NSData? aData) {
    final _ret = _lib._objc_msgSend_182(
        _lib._class_NSTimeZone1,
        _lib._sel_timeZoneWithName_data_1,
        tzName?._id ?? ffi.nullptr,
        aData?._id ?? ffi.nullptr);
    return NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  NSTimeZone initWithName_(NSString? tzName) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithName_1, tzName?._id ?? ffi.nullptr);
    return NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  NSTimeZone initWithName_data_(NSString? tzName, NSData? aData) {
    final _ret = _lib._objc_msgSend_182(_id, _lib._sel_initWithName_data_1,
        tzName?._id ?? ffi.nullptr, aData?._id ?? ffi.nullptr);
    return NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  static NSTimeZone timeZoneForSecondsFromGMT_(AVFAudio _lib, int seconds) {
    final _ret = _lib._objc_msgSend_183(_lib._class_NSTimeZone1,
        _lib._sel_timeZoneForSecondsFromGMT_1, seconds);
    return NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  static NSTimeZone timeZoneWithAbbreviation_(
      AVFAudio _lib, NSString? abbreviation) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSTimeZone1,
        _lib._sel_timeZoneWithAbbreviation_1, abbreviation?._id ?? ffi.nullptr);
    return NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  static NSTimeZone new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSTimeZone1, _lib._sel_new1);
    return NSTimeZone._(_ret, _lib, retain: false, release: true);
  }

  static NSTimeZone alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSTimeZone1, _lib._sel_alloc1);
    return NSTimeZone._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSTimeZone1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSTimeZone1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSTimeZone1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSTimeZone1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSTimeZone1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSTimeZone1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSTimeZone1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSTimeZone1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSTimeZone1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSTimeZoneNameStyle {
  static const int NSTimeZoneNameStyleStandard = 0;
  static const int NSTimeZoneNameStyleShortStandard = 1;
  static const int NSTimeZoneNameStyleDaylightSaving = 2;
  static const int NSTimeZoneNameStyleShortDaylightSaving = 3;
  static const int NSTimeZoneNameStyleGeneric = 4;
  static const int NSTimeZoneNameStyleShortGeneric = 5;
}

class NSLocale extends NSObject {
  NSLocale._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSLocale] that points to the same underlying object as [other].
  static NSLocale castFrom<T extends _ObjCWrapper>(T other) {
    return NSLocale._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSLocale] that wraps the given raw object pointer.
  static NSLocale castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSLocale._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSLocale].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSLocale1);
  }

  NSObject objectForKey_(NSLocaleKey key) {
    final _ret = _lib._objc_msgSend_30(_id, _lib._sel_objectForKey_1, key);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSString displayNameForKey_value_(NSLocaleKey key, NSObject value) {
    final _ret = _lib._objc_msgSend_167(
        _id, _lib._sel_displayNameForKey_value_1, key, value._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSLocale initWithLocaleIdentifier_(NSString? string) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithLocaleIdentifier_1, string?._id ?? ffi.nullptr);
    return NSLocale._(_ret, _lib, retain: true, release: true);
  }

  NSLocale initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSLocale._(_ret, _lib, retain: true, release: true);
  }

  NSString? get localeIdentifier {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_localeIdentifier1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString localizedStringForLocaleIdentifier_(NSString? localeIdentifier) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_localizedStringForLocaleIdentifier_1,
        localeIdentifier?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get languageCode {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_languageCode1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString localizedStringForLanguageCode_(NSString? languageCode) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_localizedStringForLanguageCode_1,
        languageCode?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get countryCode {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_countryCode1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString localizedStringForCountryCode_(NSString? countryCode) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_localizedStringForCountryCode_1,
        countryCode?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get scriptCode {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_scriptCode1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString localizedStringForScriptCode_(NSString? scriptCode) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_localizedStringForScriptCode_1,
        scriptCode?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get variantCode {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_variantCode1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString localizedStringForVariantCode_(NSString? variantCode) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_localizedStringForVariantCode_1,
        variantCode?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSCharacterSet? get exemplarCharacterSet {
    final _ret = _lib._objc_msgSend_168(_id, _lib._sel_exemplarCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  NSString? get calendarIdentifier {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_calendarIdentifier1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString localizedStringForCalendarIdentifier_(NSString? calendarIdentifier) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_localizedStringForCalendarIdentifier_1,
        calendarIdentifier?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get collationIdentifier {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_collationIdentifier1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString localizedStringForCollationIdentifier_(
      NSString? collationIdentifier) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_localizedStringForCollationIdentifier_1,
        collationIdentifier?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  bool get usesMetricSystem {
    return _lib._objc_msgSend_12(_id, _lib._sel_usesMetricSystem1);
  }

  NSString? get decimalSeparator {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_decimalSeparator1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get groupingSeparator {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_groupingSeparator1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get currencySymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_currencySymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get currencyCode {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_currencyCode1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString localizedStringForCurrencyCode_(NSString? currencyCode) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_localizedStringForCurrencyCode_1,
        currencyCode?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get collatorIdentifier {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_collatorIdentifier1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString localizedStringForCollatorIdentifier_(NSString? collatorIdentifier) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_localizedStringForCollatorIdentifier_1,
        collatorIdentifier?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get quotationBeginDelimiter {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_quotationBeginDelimiter1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get quotationEndDelimiter {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_quotationEndDelimiter1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get alternateQuotationBeginDelimiter {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_alternateQuotationBeginDelimiter1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get alternateQuotationEndDelimiter {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_alternateQuotationEndDelimiter1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSLocale? getAutoupdatingCurrentLocale(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_176(
        _lib._class_NSLocale1, _lib._sel_autoupdatingCurrentLocale1);
    return _ret.address == 0
        ? null
        : NSLocale._(_ret, _lib, retain: true, release: true);
  }

  static NSLocale? getCurrentLocale(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_176(_lib._class_NSLocale1, _lib._sel_currentLocale1);
    return _ret.address == 0
        ? null
        : NSLocale._(_ret, _lib, retain: true, release: true);
  }

  static NSLocale? getSystemLocale(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_176(_lib._class_NSLocale1, _lib._sel_systemLocale1);
    return _ret.address == 0
        ? null
        : NSLocale._(_ret, _lib, retain: true, release: true);
  }

  static NSLocale localeWithLocaleIdentifier_(AVFAudio _lib, NSString? ident) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSLocale1,
        _lib._sel_localeWithLocaleIdentifier_1, ident?._id ?? ffi.nullptr);
    return NSLocale._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSLocale init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSLocale._(_ret, _lib, retain: true, release: true);
  }

  static NSArray? getAvailableLocaleIdentifiers(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSLocale1, _lib._sel_availableLocaleIdentifiers1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray? getISOLanguageCodes(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSLocale1, _lib._sel_ISOLanguageCodes1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray? getISOCountryCodes(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSLocale1, _lib._sel_ISOCountryCodes1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray? getISOCurrencyCodes(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSLocale1, _lib._sel_ISOCurrencyCodes1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray? getCommonISOCurrencyCodes(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSLocale1, _lib._sel_commonISOCurrencyCodes1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray? getPreferredLanguages(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSLocale1, _lib._sel_preferredLanguages1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary componentsFromLocaleIdentifier_(
      AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_140(_lib._class_NSLocale1,
        _lib._sel_componentsFromLocaleIdentifier_1, string?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSString localeIdentifierFromComponents_(
      AVFAudio _lib, NSDictionary? dict) {
    final _ret = _lib._objc_msgSend_177(_lib._class_NSLocale1,
        _lib._sel_localeIdentifierFromComponents_1, dict?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString canonicalLocaleIdentifierFromString_(
      AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_64(
        _lib._class_NSLocale1,
        _lib._sel_canonicalLocaleIdentifierFromString_1,
        string?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString canonicalLanguageIdentifierFromString_(
      AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_64(
        _lib._class_NSLocale1,
        _lib._sel_canonicalLanguageIdentifierFromString_1,
        string?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString localeIdentifierFromWindowsLocaleCode_(
      AVFAudio _lib, int lcid) {
    final _ret = _lib._objc_msgSend_178(_lib._class_NSLocale1,
        _lib._sel_localeIdentifierFromWindowsLocaleCode_1, lcid);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static int windowsLocaleCodeFromLocaleIdentifier_(
      AVFAudio _lib, NSString? localeIdentifier) {
    return _lib._objc_msgSend_179(
        _lib._class_NSLocale1,
        _lib._sel_windowsLocaleCodeFromLocaleIdentifier_1,
        localeIdentifier?._id ?? ffi.nullptr);
  }

  static int characterDirectionForLanguage_(
      AVFAudio _lib, NSString? isoLangCode) {
    return _lib._objc_msgSend_180(
        _lib._class_NSLocale1,
        _lib._sel_characterDirectionForLanguage_1,
        isoLangCode?._id ?? ffi.nullptr);
  }

  static int lineDirectionForLanguage_(AVFAudio _lib, NSString? isoLangCode) {
    return _lib._objc_msgSend_180(_lib._class_NSLocale1,
        _lib._sel_lineDirectionForLanguage_1, isoLangCode?._id ?? ffi.nullptr);
  }

  static NSLocale new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSLocale1, _lib._sel_new1);
    return NSLocale._(_ret, _lib, retain: false, release: true);
  }

  static NSLocale alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSLocale1, _lib._sel_alloc1);
    return NSLocale._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSLocale1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSLocale1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSLocale1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSLocale1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSLocale1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSLocale1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSLocale1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSLocale1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSLocale1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSLocaleKey = ffi.Pointer<ObjCObject>;

class NSCharacterSet extends NSObject {
  NSCharacterSet._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSCharacterSet] that points to the same underlying object as [other].
  static NSCharacterSet castFrom<T extends _ObjCWrapper>(T other) {
    return NSCharacterSet._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSCharacterSet] that wraps the given raw object pointer.
  static NSCharacterSet castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSCharacterSet._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSCharacterSet].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSCharacterSet1);
  }

  static NSCharacterSet? getControlCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_controlCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getWhitespaceCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_whitespaceCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getWhitespaceAndNewlineCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(_lib._class_NSCharacterSet1,
        _lib._sel_whitespaceAndNewlineCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getDecimalDigitCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_decimalDigitCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getLetterCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_letterCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getLowercaseLetterCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_lowercaseLetterCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getUppercaseLetterCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_uppercaseLetterCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getNonBaseCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_nonBaseCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getAlphanumericCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_alphanumericCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getDecomposableCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_decomposableCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getIllegalCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_illegalCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getPunctuationCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_punctuationCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getCapitalizedLetterCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_capitalizedLetterCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getSymbolCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_symbolCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getNewlineCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_newlineCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: false, release: true);
  }

  static NSCharacterSet characterSetWithRange_(AVFAudio _lib, NSRange aRange) {
    final _ret = _lib._objc_msgSend_169(
        _lib._class_NSCharacterSet1, _lib._sel_characterSetWithRange_1, aRange);
    return NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet characterSetWithCharactersInString_(
      AVFAudio _lib, NSString? aString) {
    final _ret = _lib._objc_msgSend_170(
        _lib._class_NSCharacterSet1,
        _lib._sel_characterSetWithCharactersInString_1,
        aString?._id ?? ffi.nullptr);
    return NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet characterSetWithBitmapRepresentation_(
      AVFAudio _lib, NSData? data) {
    final _ret = _lib._objc_msgSend_171(
        _lib._class_NSCharacterSet1,
        _lib._sel_characterSetWithBitmapRepresentation_1,
        data?._id ?? ffi.nullptr);
    return NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet characterSetWithContentsOfFile_(
      AVFAudio _lib, NSString? fName) {
    final _ret = _lib._objc_msgSend_170(_lib._class_NSCharacterSet1,
        _lib._sel_characterSetWithContentsOfFile_1, fName?._id ?? ffi.nullptr);
    return NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  NSCharacterSet initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  bool characterIsMember_(int aCharacter) {
    return _lib._objc_msgSend_172(
        _id, _lib._sel_characterIsMember_1, aCharacter);
  }

  NSData? get bitmapRepresentation {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_bitmapRepresentation1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  NSCharacterSet? get invertedSet {
    final _ret = _lib._objc_msgSend_168(_id, _lib._sel_invertedSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  bool longCharacterIsMember_(int theLongChar) {
    return _lib._objc_msgSend_173(
        _id, _lib._sel_longCharacterIsMember_1, theLongChar);
  }

  bool isSupersetOfSet_(NSCharacterSet? theOtherSet) {
    return _lib._objc_msgSend_174(
        _id, _lib._sel_isSupersetOfSet_1, theOtherSet?._id ?? ffi.nullptr);
  }

  bool hasMemberInPlane_(int thePlane) {
    return _lib._objc_msgSend_175(_id, _lib._sel_hasMemberInPlane_1, thePlane);
  }

  static NSCharacterSet? getURLUserAllowedCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_URLUserAllowedCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getURLPasswordAllowedCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_URLPasswordAllowedCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getURLHostAllowedCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_URLHostAllowedCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getURLPathAllowedCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_URLPathAllowedCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getURLQueryAllowedCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_URLQueryAllowedCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet? getURLFragmentAllowedCharacterSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_168(
        _lib._class_NSCharacterSet1, _lib._sel_URLFragmentAllowedCharacterSet1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  static NSCharacterSet new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSCharacterSet1, _lib._sel_new1);
    return NSCharacterSet._(_ret, _lib, retain: false, release: true);
  }

  static NSCharacterSet alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSCharacterSet1, _lib._sel_alloc1);
    return NSCharacterSet._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSCharacterSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSCharacterSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSCharacterSet1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSCharacterSet1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSCharacterSet1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSCharacterSet1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSCharacterSet1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSCharacterSet1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSCharacterSet1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef UTF32Char = UInt32;
typedef UInt32 = ffi.UnsignedInt;

abstract class NSLocaleLanguageDirection {
  static const int NSLocaleLanguageDirectionUnknown = 0;
  static const int NSLocaleLanguageDirectionLeftToRight = 1;
  static const int NSLocaleLanguageDirectionRightToLeft = 2;
  static const int NSLocaleLanguageDirectionTopToBottom = 3;
  static const int NSLocaleLanguageDirectionBottomToTop = 4;
}

typedef OSType = FourCharCode;
typedef FourCharCode = UInt32;
typedef NSURLResourceKey = ffi.Pointer<ObjCObject>;

class NSURLHandle extends NSObject {
  NSURLHandle._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLHandle] that points to the same underlying object as [other].
  static NSURLHandle castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLHandle._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSURLHandle] that wraps the given raw object pointer.
  static NSURLHandle castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLHandle._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLHandle].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSURLHandle1);
  }

  static void registerURLHandleClass_(
      AVFAudio _lib, NSObject anURLHandleSubclass) {
    return _lib._objc_msgSend_15(_lib._class_NSURLHandle1,
        _lib._sel_registerURLHandleClass_1, anURLHandleSubclass._id);
  }

  static NSObject URLHandleClassForURL_(AVFAudio _lib, NSURL? anURL) {
    final _ret = _lib._objc_msgSend_226(_lib._class_NSURLHandle1,
        _lib._sel_URLHandleClassForURL_1, anURL?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  int status() {
    return _lib._objc_msgSend_227(_id, _lib._sel_status1);
  }

  NSString failureReason() {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_failureReason1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  void addClient_(NSObject? client) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_addClient_1, client?._id ?? ffi.nullptr);
  }

  void removeClient_(NSObject? client) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_removeClient_1, client?._id ?? ffi.nullptr);
  }

  void loadInBackground() {
    return _lib._objc_msgSend_1(_id, _lib._sel_loadInBackground1);
  }

  void cancelLoadInBackground() {
    return _lib._objc_msgSend_1(_id, _lib._sel_cancelLoadInBackground1);
  }

  NSData resourceData() {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_resourceData1);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData availableResourceData() {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_availableResourceData1);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  int expectedResourceDataSize() {
    return _lib._objc_msgSend_214(_id, _lib._sel_expectedResourceDataSize1);
  }

  void flushCachedData() {
    return _lib._objc_msgSend_1(_id, _lib._sel_flushCachedData1);
  }

  void backgroundLoadDidFailWithReason_(NSString? reason) {
    return _lib._objc_msgSend_186(
        _id,
        _lib._sel_backgroundLoadDidFailWithReason_1,
        reason?._id ?? ffi.nullptr);
  }

  void didLoadBytes_loadComplete_(NSData? newBytes, bool yorn) {
    return _lib._objc_msgSend_228(_id, _lib._sel_didLoadBytes_loadComplete_1,
        newBytes?._id ?? ffi.nullptr, yorn);
  }

  static bool canInitWithURL_(AVFAudio _lib, NSURL? anURL) {
    return _lib._objc_msgSend_229(_lib._class_NSURLHandle1,
        _lib._sel_canInitWithURL_1, anURL?._id ?? ffi.nullptr);
  }

  static NSURLHandle cachedHandleForURL_(AVFAudio _lib, NSURL? anURL) {
    final _ret = _lib._objc_msgSend_230(_lib._class_NSURLHandle1,
        _lib._sel_cachedHandleForURL_1, anURL?._id ?? ffi.nullptr);
    return NSURLHandle._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithURL_cached_(NSURL? anURL, bool willCache) {
    final _ret = _lib._objc_msgSend_231(_id, _lib._sel_initWithURL_cached_1,
        anURL?._id ?? ffi.nullptr, willCache);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject propertyForKey_(NSString? propertyKey) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_propertyForKey_1, propertyKey?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject propertyForKeyIfAvailable_(NSString? propertyKey) {
    final _ret = _lib._objc_msgSend_30(_id,
        _lib._sel_propertyForKeyIfAvailable_1, propertyKey?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  bool writeProperty_forKey_(NSObject propertyValue, NSString? propertyKey) {
    return _lib._objc_msgSend_225(_id, _lib._sel_writeProperty_forKey_1,
        propertyValue._id, propertyKey?._id ?? ffi.nullptr);
  }

  bool writeData_(NSData? data) {
    return _lib._objc_msgSend_23(
        _id, _lib._sel_writeData_1, data?._id ?? ffi.nullptr);
  }

  NSData loadInForeground() {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_loadInForeground1);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  void beginLoadInBackground() {
    return _lib._objc_msgSend_1(_id, _lib._sel_beginLoadInBackground1);
  }

  void endLoadInBackground() {
    return _lib._objc_msgSend_1(_id, _lib._sel_endLoadInBackground1);
  }

  static NSURLHandle new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSURLHandle1, _lib._sel_new1);
    return NSURLHandle._(_ret, _lib, retain: false, release: true);
  }

  static NSURLHandle alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLHandle1, _lib._sel_alloc1);
    return NSURLHandle._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLHandle1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLHandle1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLHandle1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLHandle1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLHandle1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLHandle1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLHandle1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSURLHandle1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLHandle1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSURLHandleStatus {
  static const int NSURLHandleNotLoaded = 0;
  static const int NSURLHandleLoadSucceeded = 1;
  static const int NSURLHandleLoadInProgress = 2;
  static const int NSURLHandleLoadFailed = 3;
}

abstract class NSDataWritingOptions {
  static const int NSDataWritingAtomic = 1;
  static const int NSDataWritingWithoutOverwriting = 2;
  static const int NSDataWritingFileProtectionNone = 268435456;
  static const int NSDataWritingFileProtectionComplete = 536870912;
  static const int NSDataWritingFileProtectionCompleteUnlessOpen = 805306368;
  static const int
      NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication =
      1073741824;
  static const int NSDataWritingFileProtectionMask = 4026531840;
  static const int NSAtomicWrite = 1;
}

abstract class NSDataSearchOptions {
  static const int NSDataSearchBackwards = 1;
  static const int NSDataSearchAnchored = 2;
}

void _ObjCBlock8_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ffi.Void> arg0, NSRange arg1, ffi.Pointer<ffi.Bool> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ffi.Void> arg0, NSRange arg1,
                  ffi.Pointer<ffi.Bool> arg2)>>()
      .asFunction<
          void Function(ffi.Pointer<ffi.Void> arg0, NSRange arg1,
              ffi.Pointer<ffi.Bool> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock8_closureRegistry = <int, Function>{};
int _ObjCBlock8_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock8_registerClosure(Function fn) {
  final id = ++_ObjCBlock8_closureRegistryIndex;
  _ObjCBlock8_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock8_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ffi.Void> arg0, NSRange arg1, ffi.Pointer<ffi.Bool> arg2) {
  return _ObjCBlock8_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock8 extends _ObjCBlockBase {
  ObjCBlock8._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock8.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ffi.Void> arg0, NSRange arg1,
                      ffi.Pointer<ffi.Bool> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ffi.Void> arg0,
                                NSRange arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock8_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock8.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ffi.Void> arg0, NSRange arg1,
              ffi.Pointer<ffi.Bool> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ffi.Void> arg0,
                                NSRange arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock8_closureTrampoline)
                    .cast(),
                _ObjCBlock8_registerClosure(fn)),
            lib);
  void call(
      ffi.Pointer<ffi.Void> arg0, NSRange arg1, ffi.Pointer<ffi.Bool> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ffi.Void> arg0,
                    NSRange arg1,
                    ffi.Pointer<ffi.Bool> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ffi.Void> arg0,
                NSRange arg1,
                ffi.Pointer<ffi.Bool> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

abstract class NSDataReadingOptions {
  static const int NSDataReadingMappedIfSafe = 1;
  static const int NSDataReadingUncached = 2;
  static const int NSDataReadingMappedAlways = 8;
  static const int NSDataReadingMapped = 1;
  static const int NSMappedRead = 1;
  static const int NSUncachedRead = 2;
}

void _ObjCBlock9_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ffi.Void> arg0, int arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ffi.Void> arg0, NSUInteger arg1)>>()
      .asFunction<
          void Function(ffi.Pointer<ffi.Void> arg0, int arg1)>()(arg0, arg1);
}

final _ObjCBlock9_closureRegistry = <int, Function>{};
int _ObjCBlock9_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock9_registerClosure(Function fn) {
  final id = ++_ObjCBlock9_closureRegistryIndex;
  _ObjCBlock9_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock9_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ffi.Void> arg0, int arg1) {
  return _ObjCBlock9_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock9 extends _ObjCBlockBase {
  ObjCBlock9._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock9.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      ffi.Pointer<ffi.Void> arg0, NSUInteger arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                        ffi.Void Function(
                            ffi.Pointer<_ObjCBlock> block,
                            ffi.Pointer<ffi.Void> arg0,
                            NSUInteger arg1)>(_ObjCBlock9_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock9.fromFunction(
      AVFAudio lib, void Function(ffi.Pointer<ffi.Void> arg0, int arg1) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                        ffi.Void Function(
                            ffi.Pointer<_ObjCBlock> block,
                            ffi.Pointer<ffi.Void> arg0,
                            NSUInteger arg1)>(_ObjCBlock9_closureTrampoline)
                    .cast(),
                _ObjCBlock9_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ffi.Void> arg0, int arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ffi.Void> arg0, NSUInteger arg1)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ffi.Void> arg0, int arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

abstract class NSDataBase64DecodingOptions {
  static const int NSDataBase64DecodingIgnoreUnknownCharacters = 1;
}

abstract class NSDataBase64EncodingOptions {
  static const int NSDataBase64Encoding64CharacterLineLength = 1;
  static const int NSDataBase64Encoding76CharacterLineLength = 2;
  static const int NSDataBase64EncodingEndLineWithCarriageReturn = 16;
  static const int NSDataBase64EncodingEndLineWithLineFeed = 32;
}

abstract class NSDataCompressionAlgorithm {
  static const int NSDataCompressionAlgorithmLZFSE = 0;
  static const int NSDataCompressionAlgorithmLZ4 = 1;
  static const int NSDataCompressionAlgorithmLZMA = 2;
  static const int NSDataCompressionAlgorithmZlib = 3;
}

typedef NSZone = _NSZone;

abstract class NSDecodingFailurePolicy {
  static const int NSDecodingFailurePolicyRaiseException = 0;
  static const int NSDecodingFailurePolicySetErrorAndReturn = 1;
}

abstract class NSStringCompareOptions {
  static const int NSCaseInsensitiveSearch = 1;
  static const int NSLiteralSearch = 2;
  static const int NSBackwardsSearch = 4;
  static const int NSAnchoredSearch = 8;
  static const int NSNumericSearch = 64;
  static const int NSDiacriticInsensitiveSearch = 128;
  static const int NSWidthInsensitiveSearch = 256;
  static const int NSForcedOrderingSearch = 512;
  static const int NSRegularExpressionSearch = 1024;
}

abstract class NSStringEnumerationOptions {
  static const int NSStringEnumerationByLines = 0;
  static const int NSStringEnumerationByParagraphs = 1;
  static const int NSStringEnumerationByComposedCharacterSequences = 2;
  static const int NSStringEnumerationByWords = 3;
  static const int NSStringEnumerationBySentences = 4;
  static const int NSStringEnumerationByCaretPositions = 5;
  static const int NSStringEnumerationByDeletionClusters = 6;
  static const int NSStringEnumerationReverse = 256;
  static const int NSStringEnumerationSubstringNotRequired = 512;
  static const int NSStringEnumerationLocalized = 1024;
}

void _ObjCBlock10_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    NSRange arg1,
    NSRange arg2,
    ffi.Pointer<ffi.Bool> arg3) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0, NSRange arg1,
                  NSRange arg2, ffi.Pointer<ffi.Bool> arg3)>>()
      .asFunction<
          void Function(
              ffi.Pointer<ObjCObject> arg0,
              NSRange arg1,
              NSRange arg2,
              ffi.Pointer<ffi.Bool> arg3)>()(arg0, arg1, arg2, arg3);
}

final _ObjCBlock10_closureRegistry = <int, Function>{};
int _ObjCBlock10_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock10_registerClosure(Function fn) {
  final id = ++_ObjCBlock10_closureRegistryIndex;
  _ObjCBlock10_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock10_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    NSRange arg1,
    NSRange arg2,
    ffi.Pointer<ffi.Bool> arg3) {
  return _ObjCBlock10_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2, arg3);
}

class ObjCBlock10 extends _ObjCBlockBase {
  ObjCBlock10._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock10.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0, NSRange arg1,
                      NSRange arg2, ffi.Pointer<ffi.Bool> arg3)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                NSRange arg1,
                                NSRange arg2,
                                ffi.Pointer<ffi.Bool> arg3)>(
                        _ObjCBlock10_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock10.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, NSRange arg1, NSRange arg2,
              ffi.Pointer<ffi.Bool> arg3)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                NSRange arg1,
                                NSRange arg2,
                                ffi.Pointer<ffi.Bool> arg3)>(
                        _ObjCBlock10_closureTrampoline)
                    .cast(),
                _ObjCBlock10_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, NSRange arg1, NSRange arg2,
      ffi.Pointer<ffi.Bool> arg3) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    NSRange arg1,
                    NSRange arg2,
                    ffi.Pointer<ffi.Bool> arg3)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                NSRange arg1,
                NSRange arg2,
                ffi.Pointer<ffi.Bool> arg3)>()(_id, arg0, arg1, arg2, arg3);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

void _ObjCBlock11_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(
                  ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ffi.Bool> arg1)>()(arg0, arg1);
}

final _ObjCBlock11_closureRegistry = <int, Function>{};
int _ObjCBlock11_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock11_registerClosure(Function fn) {
  final id = ++_ObjCBlock11_closureRegistryIndex;
  _ObjCBlock11_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock11_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1) {
  return _ObjCBlock11_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock11 extends _ObjCBlockBase {
  ObjCBlock11._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock11.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ffi.Bool> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock11_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock11.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock11_closureTrampoline)
                    .cast(),
                _ObjCBlock11_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ffi.Bool> arg1)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ffi.Bool> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

typedef NSStringEncoding = NSUInteger;

abstract class NSStringEncodingConversionOptions {
  static const int NSStringEncodingConversionAllowLossy = 1;
  static const int NSStringEncodingConversionExternalRepresentation = 2;
}

typedef NSStringTransform = ffi.Pointer<ObjCObject>;
void _ObjCBlock12_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<unichar> arg0, int arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<unichar> arg0, NSUInteger arg1)>>()
      .asFunction<
          void Function(ffi.Pointer<unichar> arg0, int arg1)>()(arg0, arg1);
}

final _ObjCBlock12_closureRegistry = <int, Function>{};
int _ObjCBlock12_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock12_registerClosure(Function fn) {
  final id = ++_ObjCBlock12_closureRegistryIndex;
  _ObjCBlock12_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock12_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<unichar> arg0, int arg1) {
  return _ObjCBlock12_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock12 extends _ObjCBlockBase {
  ObjCBlock12._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock12.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      ffi.Pointer<unichar> arg0, NSUInteger arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                        ffi.Void Function(
                            ffi.Pointer<_ObjCBlock> block,
                            ffi.Pointer<unichar> arg0,
                            NSUInteger arg1)>(_ObjCBlock12_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock12.fromFunction(
      AVFAudio lib, void Function(ffi.Pointer<unichar> arg0, int arg1) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                        ffi.Void Function(
                            ffi.Pointer<_ObjCBlock> block,
                            ffi.Pointer<unichar> arg0,
                            NSUInteger arg1)>(_ObjCBlock12_closureTrampoline)
                    .cast(),
                _ObjCBlock12_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<unichar> arg0, int arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<unichar> arg0, NSUInteger arg1)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<unichar> arg0, int arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

typedef NSLinguisticTagScheme = ffi.Pointer<ObjCObject>;

abstract class NSLinguisticTaggerOptions {
  static const int NSLinguisticTaggerOmitWords = 1;
  static const int NSLinguisticTaggerOmitPunctuation = 2;
  static const int NSLinguisticTaggerOmitWhitespace = 4;
  static const int NSLinguisticTaggerOmitOther = 8;
  static const int NSLinguisticTaggerJoinNames = 16;
}

class NSOrthography extends NSObject {
  NSOrthography._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSOrthography] that points to the same underlying object as [other].
  static NSOrthography castFrom<T extends _ObjCWrapper>(T other) {
    return NSOrthography._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSOrthography] that wraps the given raw object pointer.
  static NSOrthography castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSOrthography._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSOrthography].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSOrthography1);
  }

  NSString? get dominantScript {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_dominantScript1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get languageMap {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_languageMap1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSOrthography initWithDominantScript_languageMap_(
      NSString? script, NSDictionary? map) {
    final _ret = _lib._objc_msgSend_352(
        _id,
        _lib._sel_initWithDominantScript_languageMap_1,
        script?._id ?? ffi.nullptr,
        map?._id ?? ffi.nullptr);
    return NSOrthography._(_ret, _lib, retain: true, release: true);
  }

  NSOrthography initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSOrthography._(_ret, _lib, retain: true, release: true);
  }

  NSArray languagesForScript_(NSString? script) {
    final _ret = _lib._objc_msgSend_119(
        _id, _lib._sel_languagesForScript_1, script?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString dominantLanguageForScript_(NSString? script) {
    final _ret = _lib._objc_msgSend_64(
        _id, _lib._sel_dominantLanguageForScript_1, script?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get dominantLanguage {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_dominantLanguage1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get allScripts {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_allScripts1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get allLanguages {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_allLanguages1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSOrthography defaultOrthographyForLanguage_(
      AVFAudio _lib, NSString? language) {
    final _ret = _lib._objc_msgSend_30(
        _lib._class_NSOrthography1,
        _lib._sel_defaultOrthographyForLanguage_1,
        language?._id ?? ffi.nullptr);
    return NSOrthography._(_ret, _lib, retain: true, release: true);
  }

  static NSOrthography orthographyWithDominantScript_languageMap_(
      AVFAudio _lib, NSString? script, NSDictionary? map) {
    final _ret = _lib._objc_msgSend_352(
        _lib._class_NSOrthography1,
        _lib._sel_orthographyWithDominantScript_languageMap_1,
        script?._id ?? ffi.nullptr,
        map?._id ?? ffi.nullptr);
    return NSOrthography._(_ret, _lib, retain: true, release: true);
  }

  static NSOrthography new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSOrthography1, _lib._sel_new1);
    return NSOrthography._(_ret, _lib, retain: false, release: true);
  }

  static NSOrthography alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSOrthography1, _lib._sel_alloc1);
    return NSOrthography._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSOrthography1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSOrthography1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSOrthography1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSOrthography1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSOrthography1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSOrthography1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSOrthography1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSOrthography1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSOrthography1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

void _ObjCBlock13_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(
                  ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ffi.Bool> arg1)>()(arg0, arg1);
}

final _ObjCBlock13_closureRegistry = <int, Function>{};
int _ObjCBlock13_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock13_registerClosure(Function fn) {
  final id = ++_ObjCBlock13_closureRegistryIndex;
  _ObjCBlock13_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock13_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1) {
  return _ObjCBlock13_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock13 extends _ObjCBlockBase {
  ObjCBlock13._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock13.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ffi.Bool> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock13_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock13.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock13_closureTrampoline)
                    .cast(),
                _ObjCBlock13_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ffi.Bool> arg1)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ffi.Bool> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

bool _ObjCBlock14_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Bool Function(
                  ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1)>>()
      .asFunction<
          bool Function(ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ffi.Bool> arg1)>()(arg0, arg1);
}

final _ObjCBlock14_closureRegistry = <int, Function>{};
int _ObjCBlock14_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock14_registerClosure(Function fn) {
  final id = ++_ObjCBlock14_closureRegistryIndex;
  _ObjCBlock14_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

bool _ObjCBlock14_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1) {
  return _ObjCBlock14_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock14 extends _ObjCBlockBase {
  ObjCBlock14._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock14.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Bool Function(ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ffi.Bool> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Bool Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock14_fnPtrTrampoline, false)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock14.fromFunction(
      AVFAudio lib,
      bool Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Bool Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ffi.Bool> arg1)>(
                        _ObjCBlock14_closureTrampoline, false)
                    .cast(),
                _ObjCBlock14_registerClosure(fn)),
            lib);
  bool call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ffi.Bool> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Bool Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ffi.Bool> arg1)>>()
        .asFunction<
            bool Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ffi.Bool> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSFileManager extends NSObject {
  NSFileManager._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSFileManager] that points to the same underlying object as [other].
  static NSFileManager castFrom<T extends _ObjCWrapper>(T other) {
    return NSFileManager._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSFileManager] that wraps the given raw object pointer.
  static NSFileManager castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSFileManager._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSFileManager].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSFileManager1);
  }

  static NSFileManager? getDefaultManager(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_382(
        _lib._class_NSFileManager1, _lib._sel_defaultManager1);
    return _ret.address == 0
        ? null
        : NSFileManager._(_ret, _lib, retain: true, release: true);
  }

  NSArray mountedVolumeURLsIncludingResourceValuesForKeys_options_(
      NSArray? propertyKeys, int options) {
    final _ret = _lib._objc_msgSend_383(
        _id,
        _lib._sel_mountedVolumeURLsIncludingResourceValuesForKeys_options_1,
        propertyKeys?._id ?? ffi.nullptr,
        options);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  void unmountVolumeAtURL_options_completionHandler_(
      NSURL? url, int mask, ObjCBlock15 completionHandler) {
    return _lib._objc_msgSend_384(
        _id,
        _lib._sel_unmountVolumeAtURL_options_completionHandler_1,
        url?._id ?? ffi.nullptr,
        mask,
        completionHandler._id);
  }

  NSArray contentsOfDirectoryAtURL_includingPropertiesForKeys_options_error_(
      NSURL? url,
      NSArray? keys,
      int mask,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_385(
        _id,
        _lib._sel_contentsOfDirectoryAtURL_includingPropertiesForKeys_options_error_1,
        url?._id ?? ffi.nullptr,
        keys?._id ?? ffi.nullptr,
        mask,
        error);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray URLsForDirectory_inDomains_(int directory, int domainMask) {
    final _ret = _lib._objc_msgSend_386(
        _id, _lib._sel_URLsForDirectory_inDomains_1, directory, domainMask);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSURL URLForDirectory_inDomain_appropriateForURL_create_error_(
      int directory,
      int domain,
      NSURL? url,
      bool shouldCreate,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_387(
        _id,
        _lib._sel_URLForDirectory_inDomain_appropriateForURL_create_error_1,
        directory,
        domain,
        url?._id ?? ffi.nullptr,
        shouldCreate,
        error);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  bool getRelationship_ofDirectoryAtURL_toItemAtURL_error_(
      ffi.Pointer<ffi.Int32> outRelationship,
      NSURL? directoryURL,
      NSURL? otherURL,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_388(
        _id,
        _lib._sel_getRelationship_ofDirectoryAtURL_toItemAtURL_error_1,
        outRelationship,
        directoryURL?._id ?? ffi.nullptr,
        otherURL?._id ?? ffi.nullptr,
        error);
  }

  bool getRelationship_ofDirectory_inDomain_toItemAtURL_error_(
      ffi.Pointer<ffi.Int32> outRelationship,
      int directory,
      int domainMask,
      NSURL? url,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_389(
        _id,
        _lib._sel_getRelationship_ofDirectory_inDomain_toItemAtURL_error_1,
        outRelationship,
        directory,
        domainMask,
        url?._id ?? ffi.nullptr,
        error);
  }

  bool createDirectoryAtURL_withIntermediateDirectories_attributes_error_(
      NSURL? url,
      bool createIntermediates,
      NSDictionary? attributes,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_390(
        _id,
        _lib._sel_createDirectoryAtURL_withIntermediateDirectories_attributes_error_1,
        url?._id ?? ffi.nullptr,
        createIntermediates,
        attributes?._id ?? ffi.nullptr,
        error);
  }

  bool createSymbolicLinkAtURL_withDestinationURL_error_(
      NSURL? url, NSURL? destURL, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_391(
        _id,
        _lib._sel_createSymbolicLinkAtURL_withDestinationURL_error_1,
        url?._id ?? ffi.nullptr,
        destURL?._id ?? ffi.nullptr,
        error);
  }

  NSObject? get delegate {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_delegate1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  set delegate(NSObject? value) {
    _lib._objc_msgSend_368(
        _id, _lib._sel_setDelegate_1, value?._id ?? ffi.nullptr);
  }

  bool setAttributes_ofItemAtPath_error_(NSDictionary? attributes,
      NSString? path, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_392(
        _id,
        _lib._sel_setAttributes_ofItemAtPath_error_1,
        attributes?._id ?? ffi.nullptr,
        path?._id ?? ffi.nullptr,
        error);
  }

  bool createDirectoryAtPath_withIntermediateDirectories_attributes_error_(
      NSString? path,
      bool createIntermediates,
      NSDictionary? attributes,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_393(
        _id,
        _lib._sel_createDirectoryAtPath_withIntermediateDirectories_attributes_error_1,
        path?._id ?? ffi.nullptr,
        createIntermediates,
        attributes?._id ?? ffi.nullptr,
        error);
  }

  NSArray contentsOfDirectoryAtPath_error_(
      NSString? path, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_394(
        _id,
        _lib._sel_contentsOfDirectoryAtPath_error_1,
        path?._id ?? ffi.nullptr,
        error);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray subpathsOfDirectoryAtPath_error_(
      NSString? path, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_394(
        _id,
        _lib._sel_subpathsOfDirectoryAtPath_error_1,
        path?._id ?? ffi.nullptr,
        error);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary attributesOfItemAtPath_error_(
      NSString? path, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_395(
        _id,
        _lib._sel_attributesOfItemAtPath_error_1,
        path?._id ?? ffi.nullptr,
        error);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary attributesOfFileSystemForPath_error_(
      NSString? path, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_395(
        _id,
        _lib._sel_attributesOfFileSystemForPath_error_1,
        path?._id ?? ffi.nullptr,
        error);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  bool createSymbolicLinkAtPath_withDestinationPath_error_(NSString? path,
      NSString? destPath, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_396(
        _id,
        _lib._sel_createSymbolicLinkAtPath_withDestinationPath_error_1,
        path?._id ?? ffi.nullptr,
        destPath?._id ?? ffi.nullptr,
        error);
  }

  NSString destinationOfSymbolicLinkAtPath_error_(
      NSString? path, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_397(
        _id,
        _lib._sel_destinationOfSymbolicLinkAtPath_error_1,
        path?._id ?? ffi.nullptr,
        error);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  bool copyItemAtPath_toPath_error_(NSString? srcPath, NSString? dstPath,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_396(_id, _lib._sel_copyItemAtPath_toPath_error_1,
        srcPath?._id ?? ffi.nullptr, dstPath?._id ?? ffi.nullptr, error);
  }

  bool moveItemAtPath_toPath_error_(NSString? srcPath, NSString? dstPath,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_396(_id, _lib._sel_moveItemAtPath_toPath_error_1,
        srcPath?._id ?? ffi.nullptr, dstPath?._id ?? ffi.nullptr, error);
  }

  bool linkItemAtPath_toPath_error_(NSString? srcPath, NSString? dstPath,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_396(_id, _lib._sel_linkItemAtPath_toPath_error_1,
        srcPath?._id ?? ffi.nullptr, dstPath?._id ?? ffi.nullptr, error);
  }

  bool removeItemAtPath_error_(
      NSString? path, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_398(_id, _lib._sel_removeItemAtPath_error_1,
        path?._id ?? ffi.nullptr, error);
  }

  bool copyItemAtURL_toURL_error_(NSURL? srcURL, NSURL? dstURL,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_391(_id, _lib._sel_copyItemAtURL_toURL_error_1,
        srcURL?._id ?? ffi.nullptr, dstURL?._id ?? ffi.nullptr, error);
  }

  bool moveItemAtURL_toURL_error_(NSURL? srcURL, NSURL? dstURL,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_391(_id, _lib._sel_moveItemAtURL_toURL_error_1,
        srcURL?._id ?? ffi.nullptr, dstURL?._id ?? ffi.nullptr, error);
  }

  bool linkItemAtURL_toURL_error_(NSURL? srcURL, NSURL? dstURL,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_391(_id, _lib._sel_linkItemAtURL_toURL_error_1,
        srcURL?._id ?? ffi.nullptr, dstURL?._id ?? ffi.nullptr, error);
  }

  bool removeItemAtURL_error_(
      NSURL? URL, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_81(
        _id, _lib._sel_removeItemAtURL_error_1, URL?._id ?? ffi.nullptr, error);
  }

  bool trashItemAtURL_resultingItemURL_error_(
      NSURL? url,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outResultingURL,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_399(
        _id,
        _lib._sel_trashItemAtURL_resultingItemURL_error_1,
        url?._id ?? ffi.nullptr,
        outResultingURL,
        error);
  }

  NSDictionary fileAttributesAtPath_traverseLink_(NSString? path, bool yorn) {
    final _ret = _lib._objc_msgSend_400(
        _id,
        _lib._sel_fileAttributesAtPath_traverseLink_1,
        path?._id ?? ffi.nullptr,
        yorn);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  bool changeFileAttributes_atPath_(NSDictionary? attributes, NSString? path) {
    return _lib._objc_msgSend_401(_id, _lib._sel_changeFileAttributes_atPath_1,
        attributes?._id ?? ffi.nullptr, path?._id ?? ffi.nullptr);
  }

  NSArray directoryContentsAtPath_(NSString? path) {
    final _ret = _lib._objc_msgSend_119(
        _id, _lib._sel_directoryContentsAtPath_1, path?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary fileSystemAttributesAtPath_(NSString? path) {
    final _ret = _lib._objc_msgSend_140(
        _id, _lib._sel_fileSystemAttributesAtPath_1, path?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSString pathContentOfSymbolicLinkAtPath_(NSString? path) {
    final _ret = _lib._objc_msgSend_64(_id,
        _lib._sel_pathContentOfSymbolicLinkAtPath_1, path?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  bool createSymbolicLinkAtPath_pathContent_(
      NSString? path, NSString? otherpath) {
    return _lib._objc_msgSend_402(
        _id,
        _lib._sel_createSymbolicLinkAtPath_pathContent_1,
        path?._id ?? ffi.nullptr,
        otherpath?._id ?? ffi.nullptr);
  }

  bool createDirectoryAtPath_attributes_(
      NSString? path, NSDictionary? attributes) {
    return _lib._objc_msgSend_403(
        _id,
        _lib._sel_createDirectoryAtPath_attributes_1,
        path?._id ?? ffi.nullptr,
        attributes?._id ?? ffi.nullptr);
  }

  bool linkPath_toPath_handler_(
      NSString? src, NSString? dest, NSObject handler) {
    return _lib._objc_msgSend_404(_id, _lib._sel_linkPath_toPath_handler_1,
        src?._id ?? ffi.nullptr, dest?._id ?? ffi.nullptr, handler._id);
  }

  bool copyPath_toPath_handler_(
      NSString? src, NSString? dest, NSObject handler) {
    return _lib._objc_msgSend_404(_id, _lib._sel_copyPath_toPath_handler_1,
        src?._id ?? ffi.nullptr, dest?._id ?? ffi.nullptr, handler._id);
  }

  bool movePath_toPath_handler_(
      NSString? src, NSString? dest, NSObject handler) {
    return _lib._objc_msgSend_404(_id, _lib._sel_movePath_toPath_handler_1,
        src?._id ?? ffi.nullptr, dest?._id ?? ffi.nullptr, handler._id);
  }

  bool removeFileAtPath_handler_(NSString? path, NSObject handler) {
    return _lib._objc_msgSend_405(_id, _lib._sel_removeFileAtPath_handler_1,
        path?._id ?? ffi.nullptr, handler._id);
  }

  NSString? get currentDirectoryPath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_currentDirectoryPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  bool changeCurrentDirectoryPath_(NSString? path) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_changeCurrentDirectoryPath_1, path?._id ?? ffi.nullptr);
  }

  bool fileExistsAtPath_(NSString? path) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_fileExistsAtPath_1, path?._id ?? ffi.nullptr);
  }

  bool fileExistsAtPath_isDirectory_(
      NSString? path, ffi.Pointer<ffi.Bool> isDirectory) {
    return _lib._objc_msgSend_406(_id, _lib._sel_fileExistsAtPath_isDirectory_1,
        path?._id ?? ffi.nullptr, isDirectory);
  }

  bool isReadableFileAtPath_(NSString? path) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_isReadableFileAtPath_1, path?._id ?? ffi.nullptr);
  }

  bool isWritableFileAtPath_(NSString? path) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_isWritableFileAtPath_1, path?._id ?? ffi.nullptr);
  }

  bool isExecutableFileAtPath_(NSString? path) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_isExecutableFileAtPath_1, path?._id ?? ffi.nullptr);
  }

  bool isDeletableFileAtPath_(NSString? path) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_isDeletableFileAtPath_1, path?._id ?? ffi.nullptr);
  }

  bool contentsEqualAtPath_andPath_(NSString? path1, NSString? path2) {
    return _lib._objc_msgSend_402(_id, _lib._sel_contentsEqualAtPath_andPath_1,
        path1?._id ?? ffi.nullptr, path2?._id ?? ffi.nullptr);
  }

  NSString displayNameAtPath_(NSString? path) {
    final _ret = _lib._objc_msgSend_64(
        _id, _lib._sel_displayNameAtPath_1, path?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray componentsToDisplayForPath_(NSString? path) {
    final _ret = _lib._objc_msgSend_119(
        _id, _lib._sel_componentsToDisplayForPath_1, path?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get homeDirectoryForCurrentUser {
    final _ret =
        _lib._objc_msgSend_40(_id, _lib._sel_homeDirectoryForCurrentUser1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get temporaryDirectory {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_temporaryDirectory1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL homeDirectoryForUser_(NSString? userName) {
    final _ret = _lib._objc_msgSend_34(
        _id, _lib._sel_homeDirectoryForUser_1, userName?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  static NSFileManager new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSFileManager1, _lib._sel_new1);
    return NSFileManager._(_ret, _lib, retain: false, release: true);
  }

  static NSFileManager alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSFileManager1, _lib._sel_alloc1);
    return NSFileManager._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSFileManager1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSFileManager1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSFileManager1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSFileManager1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSFileManager1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSFileManager1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSFileManager1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSFileManager1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSFileManager1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSVolumeEnumerationOptions {
  static const int NSVolumeEnumerationSkipHiddenVolumes = 2;
  static const int NSVolumeEnumerationProduceFileReferenceURLs = 4;
}

abstract class NSFileManagerUnmountOptions {
  static const int NSFileManagerUnmountAllPartitionsAndEjectDisk = 1;
  static const int NSFileManagerUnmountWithoutUI = 2;
}

void _ObjCBlock15_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>()
      .asFunction<void Function(ffi.Pointer<ObjCObject> arg0)>()(arg0);
}

final _ObjCBlock15_closureRegistry = <int, Function>{};
int _ObjCBlock15_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock15_registerClosure(Function fn) {
  final id = ++_ObjCBlock15_closureRegistryIndex;
  _ObjCBlock15_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock15_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return _ObjCBlock15_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock15 extends _ObjCBlockBase {
  ObjCBlock15._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock15.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi
              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock15_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock15.fromFunction(
      AVFAudio lib, void Function(ffi.Pointer<ObjCObject> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock15_closureTrampoline)
                    .cast(),
                _ObjCBlock15_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

abstract class NSDirectoryEnumerationOptions {
  static const int NSDirectoryEnumerationSkipsSubdirectoryDescendants = 1;
  static const int NSDirectoryEnumerationSkipsPackageDescendants = 2;
  static const int NSDirectoryEnumerationSkipsHiddenFiles = 4;
  static const int NSDirectoryEnumerationIncludesDirectoriesPostOrder = 8;
  static const int NSDirectoryEnumerationProducesRelativePathURLs = 16;
}

abstract class NSSearchPathDirectory {
  static const int NSApplicationDirectory = 1;
  static const int NSDemoApplicationDirectory = 2;
  static const int NSDeveloperApplicationDirectory = 3;
  static const int NSAdminApplicationDirectory = 4;
  static const int NSLibraryDirectory = 5;
  static const int NSDeveloperDirectory = 6;
  static const int NSUserDirectory = 7;
  static const int NSDocumentationDirectory = 8;
  static const int NSDocumentDirectory = 9;
  static const int NSCoreServiceDirectory = 10;
  static const int NSAutosavedInformationDirectory = 11;
  static const int NSDesktopDirectory = 12;
  static const int NSCachesDirectory = 13;
  static const int NSApplicationSupportDirectory = 14;
  static const int NSDownloadsDirectory = 15;
  static const int NSInputMethodsDirectory = 16;
  static const int NSMoviesDirectory = 17;
  static const int NSMusicDirectory = 18;
  static const int NSPicturesDirectory = 19;
  static const int NSPrinterDescriptionDirectory = 20;
  static const int NSSharedPublicDirectory = 21;
  static const int NSPreferencePanesDirectory = 22;
  static const int NSApplicationScriptsDirectory = 23;
  static const int NSItemReplacementDirectory = 99;
  static const int NSAllApplicationsDirectory = 100;
  static const int NSAllLibrariesDirectory = 101;
  static const int NSTrashDirectory = 102;
}

abstract class NSSearchPathDomainMask {
  static const int NSUserDomainMask = 1;
  static const int NSLocalDomainMask = 2;
  static const int NSNetworkDomainMask = 4;
  static const int NSSystemDomainMask = 8;
  static const int NSAllDomainsMask = 65535;
}

abstract class NSURLRelationship {
  static const int NSURLRelationshipContains = 0;
  static const int NSURLRelationshipSame = 1;
  static const int NSURLRelationshipOther = 2;
}

class NSMutableArray extends NSArray {
  NSMutableArray._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSMutableArray] that points to the same underlying object as [other].
  static NSMutableArray castFrom<T extends _ObjCWrapper>(T other) {
    return NSMutableArray._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSMutableArray] that wraps the given raw object pointer.
  static NSMutableArray castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSMutableArray._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSMutableArray].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSMutableArray1);
  }

  void addObject_(NSObject anObject) {
    return _lib._objc_msgSend_15(_id, _lib._sel_addObject_1, anObject._id);
  }

  void insertObject_atIndex_(NSObject anObject, int index) {
    return _lib._objc_msgSend_409(
        _id, _lib._sel_insertObject_atIndex_1, anObject._id, index);
  }

  void removeLastObject() {
    return _lib._objc_msgSend_1(_id, _lib._sel_removeLastObject1);
  }

  void removeObjectAtIndex_(int index) {
    return _lib._objc_msgSend_410(_id, _lib._sel_removeObjectAtIndex_1, index);
  }

  void replaceObjectAtIndex_withObject_(int index, NSObject anObject) {
    return _lib._objc_msgSend_411(
        _id, _lib._sel_replaceObjectAtIndex_withObject_1, index, anObject._id);
  }

  @override
  NSMutableArray init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  NSMutableArray initWithCapacity_(int numItems) {
    final _ret =
        _lib._objc_msgSend_60(_id, _lib._sel_initWithCapacity_1, numItems);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSMutableArray initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  void addObjectsFromArray_(NSArray? otherArray) {
    return _lib._objc_msgSend_412(
        _id, _lib._sel_addObjectsFromArray_1, otherArray?._id ?? ffi.nullptr);
  }

  void exchangeObjectAtIndex_withObjectAtIndex_(int idx1, int idx2) {
    return _lib._objc_msgSend_413(
        _id, _lib._sel_exchangeObjectAtIndex_withObjectAtIndex_1, idx1, idx2);
  }

  void removeAllObjects() {
    return _lib._objc_msgSend_1(_id, _lib._sel_removeAllObjects1);
  }

  void removeObject_inRange_(NSObject anObject, NSRange range) {
    return _lib._objc_msgSend_414(
        _id, _lib._sel_removeObject_inRange_1, anObject._id, range);
  }

  void removeObject_(NSObject anObject) {
    return _lib._objc_msgSend_15(_id, _lib._sel_removeObject_1, anObject._id);
  }

  void removeObjectIdenticalTo_inRange_(NSObject anObject, NSRange range) {
    return _lib._objc_msgSend_414(
        _id, _lib._sel_removeObjectIdenticalTo_inRange_1, anObject._id, range);
  }

  void removeObjectIdenticalTo_(NSObject anObject) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_removeObjectIdenticalTo_1, anObject._id);
  }

  void removeObjectsFromIndices_numIndices_(
      ffi.Pointer<NSUInteger> indices, int cnt) {
    return _lib._objc_msgSend_415(
        _id, _lib._sel_removeObjectsFromIndices_numIndices_1, indices, cnt);
  }

  void removeObjectsInArray_(NSArray? otherArray) {
    return _lib._objc_msgSend_412(
        _id, _lib._sel_removeObjectsInArray_1, otherArray?._id ?? ffi.nullptr);
  }

  void removeObjectsInRange_(NSRange range) {
    return _lib._objc_msgSend_416(_id, _lib._sel_removeObjectsInRange_1, range);
  }

  void replaceObjectsInRange_withObjectsFromArray_range_(
      NSRange range, NSArray? otherArray, NSRange otherRange) {
    return _lib._objc_msgSend_417(
        _id,
        _lib._sel_replaceObjectsInRange_withObjectsFromArray_range_1,
        range,
        otherArray?._id ?? ffi.nullptr,
        otherRange);
  }

  void replaceObjectsInRange_withObjectsFromArray_(
      NSRange range, NSArray? otherArray) {
    return _lib._objc_msgSend_418(
        _id,
        _lib._sel_replaceObjectsInRange_withObjectsFromArray_1,
        range,
        otherArray?._id ?? ffi.nullptr);
  }

  void setArray_(NSArray? otherArray) {
    return _lib._objc_msgSend_412(
        _id, _lib._sel_setArray_1, otherArray?._id ?? ffi.nullptr);
  }

  void sortUsingFunction_context_(
      ffi.Pointer<
              ffi.NativeFunction<
                  NSInteger Function(ffi.Pointer<ObjCObject>,
                      ffi.Pointer<ObjCObject>, ffi.Pointer<ffi.Void>)>>
          compare,
      ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_419(
        _id, _lib._sel_sortUsingFunction_context_1, compare, context);
  }

  void sortUsingSelector_(ffi.Pointer<ObjCSel> comparator) {
    return _lib._objc_msgSend_7(_id, _lib._sel_sortUsingSelector_1, comparator);
  }

  void insertObjects_atIndexes_(NSArray? objects, NSIndexSet? indexes) {
    return _lib._objc_msgSend_420(_id, _lib._sel_insertObjects_atIndexes_1,
        objects?._id ?? ffi.nullptr, indexes?._id ?? ffi.nullptr);
  }

  void removeObjectsAtIndexes_(NSIndexSet? indexes) {
    return _lib._objc_msgSend_421(
        _id, _lib._sel_removeObjectsAtIndexes_1, indexes?._id ?? ffi.nullptr);
  }

  void replaceObjectsAtIndexes_withObjects_(
      NSIndexSet? indexes, NSArray? objects) {
    return _lib._objc_msgSend_422(
        _id,
        _lib._sel_replaceObjectsAtIndexes_withObjects_1,
        indexes?._id ?? ffi.nullptr,
        objects?._id ?? ffi.nullptr);
  }

  void setObject_atIndexedSubscript_(NSObject obj, int idx) {
    return _lib._objc_msgSend_409(
        _id, _lib._sel_setObject_atIndexedSubscript_1, obj._id, idx);
  }

  void sortUsingComparator_(NSComparator cmptr) {
    return _lib._objc_msgSend_423(_id, _lib._sel_sortUsingComparator_1, cmptr);
  }

  void sortWithOptions_usingComparator_(int opts, NSComparator cmptr) {
    return _lib._objc_msgSend_424(
        _id, _lib._sel_sortWithOptions_usingComparator_1, opts, cmptr);
  }

  static NSMutableArray arrayWithCapacity_(AVFAudio _lib, int numItems) {
    final _ret = _lib._objc_msgSend_60(
        _lib._class_NSMutableArray1, _lib._sel_arrayWithCapacity_1, numItems);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableArray arrayWithContentsOfFile_(
      AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_425(_lib._class_NSMutableArray1,
        _lib._sel_arrayWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableArray arrayWithContentsOfURL_(AVFAudio _lib, NSURL? url) {
    final _ret = _lib._objc_msgSend_426(_lib._class_NSMutableArray1,
        _lib._sel_arrayWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  NSMutableArray initWithContentsOfFile_(NSString? path) {
    final _ret = _lib._objc_msgSend_425(
        _id, _lib._sel_initWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  NSMutableArray initWithContentsOfURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_426(
        _id, _lib._sel_initWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  void applyDifference_() {
    return _lib._objc_msgSend_1(_id, _lib._sel_applyDifference_1);
  }

  void sortUsingDescriptors_(NSArray? sortDescriptors) {
    return _lib._objc_msgSend_412(_id, _lib._sel_sortUsingDescriptors_1,
        sortDescriptors?._id ?? ffi.nullptr);
  }

  void filterUsingPredicate_(NSPredicate? predicate) {
    return _lib._objc_msgSend_427(
        _id, _lib._sel_filterUsingPredicate_1, predicate?._id ?? ffi.nullptr);
  }

  static NSMutableArray array(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableArray1, _lib._sel_array1);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableArray arrayWithObject_(AVFAudio _lib, NSObject anObject) {
    final _ret = _lib._objc_msgSend_16(
        _lib._class_NSMutableArray1, _lib._sel_arrayWithObject_1, anObject._id);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableArray arrayWithObjects_count_(
      AVFAudio _lib, ffi.Pointer<ffi.Pointer<ObjCObject>> objects, int cnt) {
    final _ret = _lib._objc_msgSend_61(_lib._class_NSMutableArray1,
        _lib._sel_arrayWithObjects_count_1, objects, cnt);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableArray arrayWithObjects_(AVFAudio _lib, NSObject firstObj) {
    final _ret = _lib._objc_msgSend_16(_lib._class_NSMutableArray1,
        _lib._sel_arrayWithObjects_1, firstObj._id);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableArray arrayWithArray_(AVFAudio _lib, NSArray? array) {
    final _ret = _lib._objc_msgSend_67(_lib._class_NSMutableArray1,
        _lib._sel_arrayWithArray_1, array?._id ?? ffi.nullptr);
    return NSMutableArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray arrayWithContentsOfURL_error_(
      AVFAudio _lib, NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_117(
        _lib._class_NSMutableArray1,
        _lib._sel_arrayWithContentsOfURL_error_1,
        url?._id ?? ffi.nullptr,
        error);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableArray new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableArray1, _lib._sel_new1);
    return NSMutableArray._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableArray alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableArray1, _lib._sel_alloc1);
    return NSMutableArray._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSMutableArray1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSMutableArray1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSMutableArray1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMutableArray1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSMutableArray1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSMutableArray1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSMutableArray1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSMutableArray1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableArray1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSMutableOrderedSet extends NSOrderedSet {
  NSMutableOrderedSet._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSMutableOrderedSet] that points to the same underlying object as [other].
  static NSMutableOrderedSet castFrom<T extends _ObjCWrapper>(T other) {
    return NSMutableOrderedSet._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSMutableOrderedSet] that wraps the given raw object pointer.
  static NSMutableOrderedSet castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSMutableOrderedSet._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSMutableOrderedSet].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSMutableOrderedSet1);
  }

  void insertObject_atIndex_(NSObject object, int idx) {
    return _lib._objc_msgSend_409(
        _id, _lib._sel_insertObject_atIndex_1, object._id, idx);
  }

  void removeObjectAtIndex_(int idx) {
    return _lib._objc_msgSend_410(_id, _lib._sel_removeObjectAtIndex_1, idx);
  }

  void replaceObjectAtIndex_withObject_(int idx, NSObject object) {
    return _lib._objc_msgSend_411(
        _id, _lib._sel_replaceObjectAtIndex_withObject_1, idx, object._id);
  }

  @override
  NSMutableOrderedSet initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSMutableOrderedSet init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  NSMutableOrderedSet initWithCapacity_(int numItems) {
    final _ret =
        _lib._objc_msgSend_60(_id, _lib._sel_initWithCapacity_1, numItems);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  void addObject_(NSObject object) {
    return _lib._objc_msgSend_15(_id, _lib._sel_addObject_1, object._id);
  }

  void addObjects_count_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> objects, int count) {
    return _lib._objc_msgSend_435(
        _id, _lib._sel_addObjects_count_1, objects, count);
  }

  void addObjectsFromArray_(NSArray? array) {
    return _lib._objc_msgSend_412(
        _id, _lib._sel_addObjectsFromArray_1, array?._id ?? ffi.nullptr);
  }

  void exchangeObjectAtIndex_withObjectAtIndex_(int idx1, int idx2) {
    return _lib._objc_msgSend_413(
        _id, _lib._sel_exchangeObjectAtIndex_withObjectAtIndex_1, idx1, idx2);
  }

  void moveObjectsAtIndexes_toIndex_(NSIndexSet? indexes, int idx) {
    return _lib._objc_msgSend_436(_id, _lib._sel_moveObjectsAtIndexes_toIndex_1,
        indexes?._id ?? ffi.nullptr, idx);
  }

  void insertObjects_atIndexes_(NSArray? objects, NSIndexSet? indexes) {
    return _lib._objc_msgSend_420(_id, _lib._sel_insertObjects_atIndexes_1,
        objects?._id ?? ffi.nullptr, indexes?._id ?? ffi.nullptr);
  }

  void setObject_atIndex_(NSObject obj, int idx) {
    return _lib._objc_msgSend_409(
        _id, _lib._sel_setObject_atIndex_1, obj._id, idx);
  }

  void setObject_atIndexedSubscript_(NSObject obj, int idx) {
    return _lib._objc_msgSend_409(
        _id, _lib._sel_setObject_atIndexedSubscript_1, obj._id, idx);
  }

  void replaceObjectsInRange_withObjects_count_(
      NSRange range, ffi.Pointer<ffi.Pointer<ObjCObject>> objects, int count) {
    return _lib._objc_msgSend_437(
        _id,
        _lib._sel_replaceObjectsInRange_withObjects_count_1,
        range,
        objects,
        count);
  }

  void replaceObjectsAtIndexes_withObjects_(
      NSIndexSet? indexes, NSArray? objects) {
    return _lib._objc_msgSend_422(
        _id,
        _lib._sel_replaceObjectsAtIndexes_withObjects_1,
        indexes?._id ?? ffi.nullptr,
        objects?._id ?? ffi.nullptr);
  }

  void removeObjectsInRange_(NSRange range) {
    return _lib._objc_msgSend_416(_id, _lib._sel_removeObjectsInRange_1, range);
  }

  void removeObjectsAtIndexes_(NSIndexSet? indexes) {
    return _lib._objc_msgSend_421(
        _id, _lib._sel_removeObjectsAtIndexes_1, indexes?._id ?? ffi.nullptr);
  }

  void removeAllObjects() {
    return _lib._objc_msgSend_1(_id, _lib._sel_removeAllObjects1);
  }

  void removeObject_(NSObject object) {
    return _lib._objc_msgSend_15(_id, _lib._sel_removeObject_1, object._id);
  }

  void removeObjectsInArray_(NSArray? array) {
    return _lib._objc_msgSend_412(
        _id, _lib._sel_removeObjectsInArray_1, array?._id ?? ffi.nullptr);
  }

  void intersectOrderedSet_(NSOrderedSet? other) {
    return _lib._objc_msgSend_438(
        _id, _lib._sel_intersectOrderedSet_1, other?._id ?? ffi.nullptr);
  }

  void minusOrderedSet_(NSOrderedSet? other) {
    return _lib._objc_msgSend_438(
        _id, _lib._sel_minusOrderedSet_1, other?._id ?? ffi.nullptr);
  }

  void unionOrderedSet_(NSOrderedSet? other) {
    return _lib._objc_msgSend_438(
        _id, _lib._sel_unionOrderedSet_1, other?._id ?? ffi.nullptr);
  }

  void intersectSet_(NSSet? other) {
    return _lib._objc_msgSend_439(
        _id, _lib._sel_intersectSet_1, other?._id ?? ffi.nullptr);
  }

  void minusSet_(NSSet? other) {
    return _lib._objc_msgSend_439(
        _id, _lib._sel_minusSet_1, other?._id ?? ffi.nullptr);
  }

  void unionSet_(NSSet? other) {
    return _lib._objc_msgSend_439(
        _id, _lib._sel_unionSet_1, other?._id ?? ffi.nullptr);
  }

  void sortUsingComparator_(NSComparator cmptr) {
    return _lib._objc_msgSend_423(_id, _lib._sel_sortUsingComparator_1, cmptr);
  }

  void sortWithOptions_usingComparator_(int opts, NSComparator cmptr) {
    return _lib._objc_msgSend_424(
        _id, _lib._sel_sortWithOptions_usingComparator_1, opts, cmptr);
  }

  void sortRange_options_usingComparator_(
      NSRange range, int opts, NSComparator cmptr) {
    return _lib._objc_msgSend_440(
        _id, _lib._sel_sortRange_options_usingComparator_1, range, opts, cmptr);
  }

  static NSMutableOrderedSet orderedSetWithCapacity_(
      AVFAudio _lib, int numItems) {
    final _ret = _lib._objc_msgSend_60(_lib._class_NSMutableOrderedSet1,
        _lib._sel_orderedSetWithCapacity_1, numItems);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  void applyDifference_() {
    return _lib._objc_msgSend_1(_id, _lib._sel_applyDifference_1);
  }

  void sortUsingDescriptors_(NSArray? sortDescriptors) {
    return _lib._objc_msgSend_412(_id, _lib._sel_sortUsingDescriptors_1,
        sortDescriptors?._id ?? ffi.nullptr);
  }

  void filterUsingPredicate_(NSPredicate? p) {
    return _lib._objc_msgSend_427(
        _id, _lib._sel_filterUsingPredicate_1, p?._id ?? ffi.nullptr);
  }

  static NSMutableOrderedSet orderedSet(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableOrderedSet1, _lib._sel_orderedSet1);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableOrderedSet orderedSetWithObject_(
      AVFAudio _lib, NSObject object) {
    final _ret = _lib._objc_msgSend_16(_lib._class_NSMutableOrderedSet1,
        _lib._sel_orderedSetWithObject_1, object._id);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableOrderedSet orderedSetWithObjects_count_(
      AVFAudio _lib, ffi.Pointer<ffi.Pointer<ObjCObject>> objects, int cnt) {
    final _ret = _lib._objc_msgSend_61(_lib._class_NSMutableOrderedSet1,
        _lib._sel_orderedSetWithObjects_count_1, objects, cnt);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableOrderedSet orderedSetWithObjects_(
      AVFAudio _lib, NSObject firstObj) {
    final _ret = _lib._objc_msgSend_16(_lib._class_NSMutableOrderedSet1,
        _lib._sel_orderedSetWithObjects_1, firstObj._id);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableOrderedSet orderedSetWithOrderedSet_(
      AVFAudio _lib, NSOrderedSet? set) {
    final _ret = _lib._objc_msgSend_430(_lib._class_NSMutableOrderedSet1,
        _lib._sel_orderedSetWithOrderedSet_1, set?._id ?? ffi.nullptr);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableOrderedSet orderedSetWithOrderedSet_range_copyItems_(
      AVFAudio _lib, NSOrderedSet? set, NSRange range, bool flag) {
    final _ret = _lib._objc_msgSend_431(
        _lib._class_NSMutableOrderedSet1,
        _lib._sel_orderedSetWithOrderedSet_range_copyItems_1,
        set?._id ?? ffi.nullptr,
        range,
        flag);
    return NSMutableOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableOrderedSet orderedSetWithArray_(
      AVFAudio _lib, NSArray? array) {
    final _ret = _lib._objc_msgSend_67(_lib._class_NSMutableOrderedSet1,
        _lib._sel_orderedSetWithArray_1, array?._id ?? ffi.nullptr);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableOrderedSet orderedSetWithArray_range_copyItems_(
      AVFAudio _lib, NSArray? array, NSRange range, bool flag) {
    final _ret = _lib._objc_msgSend_432(
        _lib._class_NSMutableOrderedSet1,
        _lib._sel_orderedSetWithArray_range_copyItems_1,
        array?._id ?? ffi.nullptr,
        range,
        flag);
    return NSMutableOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableOrderedSet orderedSetWithSet_(AVFAudio _lib, NSSet? set) {
    final _ret = _lib._objc_msgSend_363(_lib._class_NSMutableOrderedSet1,
        _lib._sel_orderedSetWithSet_1, set?._id ?? ffi.nullptr);
    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableOrderedSet orderedSetWithSet_copyItems_(
      AVFAudio _lib, NSSet? set, bool flag) {
    final _ret = _lib._objc_msgSend_364(_lib._class_NSMutableOrderedSet1,
        _lib._sel_orderedSetWithSet_copyItems_1, set?._id ?? ffi.nullptr, flag);
    return NSMutableOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableOrderedSet new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableOrderedSet1, _lib._sel_new1);
    return NSMutableOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableOrderedSet alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableOrderedSet1, _lib._sel_alloc1);
    return NSMutableOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSMutableOrderedSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSMutableOrderedSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSMutableOrderedSet1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMutableOrderedSet1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSMutableOrderedSet1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSMutableOrderedSet1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSMutableOrderedSet1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSMutableOrderedSet1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableOrderedSet1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSOrderedSet extends NSObject {
  NSOrderedSet._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSOrderedSet] that points to the same underlying object as [other].
  static NSOrderedSet castFrom<T extends _ObjCWrapper>(T other) {
    return NSOrderedSet._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSOrderedSet] that wraps the given raw object pointer.
  static NSOrderedSet castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSOrderedSet._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSOrderedSet].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSOrderedSet1);
  }

  int get count {
    return _lib._objc_msgSend_10(_id, _lib._sel_count1);
  }

  NSObject objectAtIndex_(int idx) {
    final _ret = _lib._objc_msgSend_60(_id, _lib._sel_objectAtIndex_1, idx);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  int indexOfObject_(NSObject object) {
    return _lib._objc_msgSend_69(_id, _lib._sel_indexOfObject_1, object._id);
  }

  @override
  NSOrderedSet init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  NSOrderedSet initWithObjects_count_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> objects, int cnt) {
    final _ret = _lib._objc_msgSend_61(
        _id, _lib._sel_initWithObjects_count_1, objects, cnt);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  NSOrderedSet initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  void getObjects_range_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> objects, NSRange range) {
    return _lib._objc_msgSend_68(
        _id, _lib._sel_getObjects_range_1, objects, range);
  }

  NSArray objectsAtIndexes_(NSIndexSet? indexes) {
    final _ret = _lib._objc_msgSend_103(
        _id, _lib._sel_objectsAtIndexes_1, indexes?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSObject get firstObject {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_firstObject1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject get lastObject {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_lastObject1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  bool isEqualToOrderedSet_(NSOrderedSet? other) {
    return _lib._objc_msgSend_428(
        _id, _lib._sel_isEqualToOrderedSet_1, other?._id ?? ffi.nullptr);
  }

  bool containsObject_(NSObject object) {
    return _lib._objc_msgSend_0(_id, _lib._sel_containsObject_1, object._id);
  }

  bool intersectsOrderedSet_(NSOrderedSet? other) {
    return _lib._objc_msgSend_428(
        _id, _lib._sel_intersectsOrderedSet_1, other?._id ?? ffi.nullptr);
  }

  bool intersectsSet_(NSSet? set) {
    return _lib._objc_msgSend_355(
        _id, _lib._sel_intersectsSet_1, set?._id ?? ffi.nullptr);
  }

  bool isSubsetOfOrderedSet_(NSOrderedSet? other) {
    return _lib._objc_msgSend_428(
        _id, _lib._sel_isSubsetOfOrderedSet_1, other?._id ?? ffi.nullptr);
  }

  bool isSubsetOfSet_(NSSet? set) {
    return _lib._objc_msgSend_355(
        _id, _lib._sel_isSubsetOfSet_1, set?._id ?? ffi.nullptr);
  }

  NSObject objectAtIndexedSubscript_(int idx) {
    final _ret =
        _lib._objc_msgSend_60(_id, _lib._sel_objectAtIndexedSubscript_1, idx);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSEnumerator objectEnumerator() {
    final _ret = _lib._objc_msgSend_72(_id, _lib._sel_objectEnumerator1);
    return NSEnumerator._(_ret, _lib, retain: true, release: true);
  }

  NSEnumerator reverseObjectEnumerator() {
    final _ret = _lib._objc_msgSend_72(_id, _lib._sel_reverseObjectEnumerator1);
    return NSEnumerator._(_ret, _lib, retain: true, release: true);
  }

  NSOrderedSet? get reversedOrderedSet {
    final _ret = _lib._objc_msgSend_429(_id, _lib._sel_reversedOrderedSet1);
    return _ret.address == 0
        ? null
        : NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get array {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_array1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSSet? get set1 {
    final _ret = _lib._objc_msgSend_280(_id, _lib._sel_set1);
    return _ret.address == 0
        ? null
        : NSSet._(_ret, _lib, retain: true, release: true);
  }

  void enumerateObjectsUsingBlock_(ObjCBlock3 block) {
    return _lib._objc_msgSend_104(
        _id, _lib._sel_enumerateObjectsUsingBlock_1, block._id);
  }

  void enumerateObjectsWithOptions_usingBlock_(int opts, ObjCBlock3 block) {
    return _lib._objc_msgSend_105(_id,
        _lib._sel_enumerateObjectsWithOptions_usingBlock_1, opts, block._id);
  }

  void enumerateObjectsAtIndexes_options_usingBlock_(
      NSIndexSet? s, int opts, ObjCBlock3 block) {
    return _lib._objc_msgSend_106(
        _id,
        _lib._sel_enumerateObjectsAtIndexes_options_usingBlock_1,
        s?._id ?? ffi.nullptr,
        opts,
        block._id);
  }

  int indexOfObjectPassingTest_(ObjCBlock4 predicate) {
    return _lib._objc_msgSend_107(
        _id, _lib._sel_indexOfObjectPassingTest_1, predicate._id);
  }

  int indexOfObjectWithOptions_passingTest_(int opts, ObjCBlock4 predicate) {
    return _lib._objc_msgSend_108(_id,
        _lib._sel_indexOfObjectWithOptions_passingTest_1, opts, predicate._id);
  }

  int indexOfObjectAtIndexes_options_passingTest_(
      NSIndexSet? s, int opts, ObjCBlock4 predicate) {
    return _lib._objc_msgSend_109(
        _id,
        _lib._sel_indexOfObjectAtIndexes_options_passingTest_1,
        s?._id ?? ffi.nullptr,
        opts,
        predicate._id);
  }

  NSIndexSet indexesOfObjectsPassingTest_(ObjCBlock4 predicate) {
    final _ret = _lib._objc_msgSend_110(
        _id, _lib._sel_indexesOfObjectsPassingTest_1, predicate._id);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  NSIndexSet indexesOfObjectsWithOptions_passingTest_(
      int opts, ObjCBlock4 predicate) {
    final _ret = _lib._objc_msgSend_111(
        _id,
        _lib._sel_indexesOfObjectsWithOptions_passingTest_1,
        opts,
        predicate._id);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  NSIndexSet indexesOfObjectsAtIndexes_options_passingTest_(
      NSIndexSet? s, int opts, ObjCBlock4 predicate) {
    final _ret = _lib._objc_msgSend_112(
        _id,
        _lib._sel_indexesOfObjectsAtIndexes_options_passingTest_1,
        s?._id ?? ffi.nullptr,
        opts,
        predicate._id);
    return NSIndexSet._(_ret, _lib, retain: true, release: true);
  }

  int indexOfObject_inSortedRange_options_usingComparator_(
      NSObject object, NSRange range, int opts, NSComparator cmp) {
    return _lib._objc_msgSend_115(
        _id,
        _lib._sel_indexOfObject_inSortedRange_options_usingComparator_1,
        object._id,
        range,
        opts,
        cmp);
  }

  NSArray sortedArrayUsingComparator_(NSComparator cmptr) {
    final _ret = _lib._objc_msgSend_113(
        _id, _lib._sel_sortedArrayUsingComparator_1, cmptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray sortedArrayWithOptions_usingComparator_(
      int opts, NSComparator cmptr) {
    final _ret = _lib._objc_msgSend_114(
        _id, _lib._sel_sortedArrayWithOptions_usingComparator_1, opts, cmptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString? get description {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_description1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString descriptionWithLocale_(NSObject locale) {
    final _ret = _lib._objc_msgSend_65(
        _id, _lib._sel_descriptionWithLocale_1, locale._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString descriptionWithLocale_indent_(NSObject locale, int level) {
    final _ret = _lib._objc_msgSend_66(
        _id, _lib._sel_descriptionWithLocale_indent_1, locale._id, level);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSOrderedSet orderedSet(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSOrderedSet1, _lib._sel_orderedSet1);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSOrderedSet orderedSetWithObject_(AVFAudio _lib, NSObject object) {
    final _ret = _lib._objc_msgSend_16(_lib._class_NSOrderedSet1,
        _lib._sel_orderedSetWithObject_1, object._id);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSOrderedSet orderedSetWithObjects_count_(
      AVFAudio _lib, ffi.Pointer<ffi.Pointer<ObjCObject>> objects, int cnt) {
    final _ret = _lib._objc_msgSend_61(_lib._class_NSOrderedSet1,
        _lib._sel_orderedSetWithObjects_count_1, objects, cnt);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSOrderedSet orderedSetWithObjects_(AVFAudio _lib, NSObject firstObj) {
    final _ret = _lib._objc_msgSend_16(_lib._class_NSOrderedSet1,
        _lib._sel_orderedSetWithObjects_1, firstObj._id);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSOrderedSet orderedSetWithOrderedSet_(
      AVFAudio _lib, NSOrderedSet? set) {
    final _ret = _lib._objc_msgSend_430(_lib._class_NSOrderedSet1,
        _lib._sel_orderedSetWithOrderedSet_1, set?._id ?? ffi.nullptr);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSOrderedSet orderedSetWithOrderedSet_range_copyItems_(
      AVFAudio _lib, NSOrderedSet? set, NSRange range, bool flag) {
    final _ret = _lib._objc_msgSend_431(
        _lib._class_NSOrderedSet1,
        _lib._sel_orderedSetWithOrderedSet_range_copyItems_1,
        set?._id ?? ffi.nullptr,
        range,
        flag);
    return NSOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  static NSOrderedSet orderedSetWithArray_(AVFAudio _lib, NSArray? array) {
    final _ret = _lib._objc_msgSend_67(_lib._class_NSOrderedSet1,
        _lib._sel_orderedSetWithArray_1, array?._id ?? ffi.nullptr);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSOrderedSet orderedSetWithArray_range_copyItems_(
      AVFAudio _lib, NSArray? array, NSRange range, bool flag) {
    final _ret = _lib._objc_msgSend_432(
        _lib._class_NSOrderedSet1,
        _lib._sel_orderedSetWithArray_range_copyItems_1,
        array?._id ?? ffi.nullptr,
        range,
        flag);
    return NSOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  static NSOrderedSet orderedSetWithSet_(AVFAudio _lib, NSSet? set) {
    final _ret = _lib._objc_msgSend_363(_lib._class_NSOrderedSet1,
        _lib._sel_orderedSetWithSet_1, set?._id ?? ffi.nullptr);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSOrderedSet orderedSetWithSet_copyItems_(
      AVFAudio _lib, NSSet? set, bool flag) {
    final _ret = _lib._objc_msgSend_364(_lib._class_NSOrderedSet1,
        _lib._sel_orderedSetWithSet_copyItems_1, set?._id ?? ffi.nullptr, flag);
    return NSOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  NSOrderedSet initWithObject_(NSObject object) {
    final _ret =
        _lib._objc_msgSend_16(_id, _lib._sel_initWithObject_1, object._id);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  NSOrderedSet initWithObjects_(NSObject firstObj) {
    final _ret =
        _lib._objc_msgSend_16(_id, _lib._sel_initWithObjects_1, firstObj._id);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  NSOrderedSet initWithOrderedSet_(NSOrderedSet? set) {
    final _ret = _lib._objc_msgSend_430(
        _id, _lib._sel_initWithOrderedSet_1, set?._id ?? ffi.nullptr);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  NSOrderedSet initWithOrderedSet_copyItems_(NSOrderedSet? set, bool flag) {
    final _ret = _lib._objc_msgSend_433(
        _id,
        _lib._sel_initWithOrderedSet_copyItems_1,
        set?._id ?? ffi.nullptr,
        flag);
    return NSOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  NSOrderedSet initWithOrderedSet_range_copyItems_(
      NSOrderedSet? set, NSRange range, bool flag) {
    final _ret = _lib._objc_msgSend_431(
        _id,
        _lib._sel_initWithOrderedSet_range_copyItems_1,
        set?._id ?? ffi.nullptr,
        range,
        flag);
    return NSOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  NSOrderedSet initWithArray_(NSArray? array) {
    final _ret = _lib._objc_msgSend_67(
        _id, _lib._sel_initWithArray_1, array?._id ?? ffi.nullptr);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  NSOrderedSet initWithArray_copyItems_(NSArray? set, bool flag) {
    final _ret = _lib._objc_msgSend_116(_id,
        _lib._sel_initWithArray_copyItems_1, set?._id ?? ffi.nullptr, flag);
    return NSOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  NSOrderedSet initWithArray_range_copyItems_(
      NSArray? set, NSRange range, bool flag) {
    final _ret = _lib._objc_msgSend_432(
        _id,
        _lib._sel_initWithArray_range_copyItems_1,
        set?._id ?? ffi.nullptr,
        range,
        flag);
    return NSOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  NSOrderedSet initWithSet_(NSSet? set) {
    final _ret = _lib._objc_msgSend_363(
        _id, _lib._sel_initWithSet_1, set?._id ?? ffi.nullptr);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  NSOrderedSet initWithSet_copyItems_(NSSet? set, bool flag) {
    final _ret = _lib._objc_msgSend_364(
        _id, _lib._sel_initWithSet_copyItems_1, set?._id ?? ffi.nullptr, flag);
    return NSOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  @override
  NSObject valueForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_valueForKey_1, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  @override
  void setValue_forKey_(NSObject value, NSString? key) {
    return _lib._objc_msgSend_122(
        _id, _lib._sel_setValue_forKey_1, value._id, key?._id ?? ffi.nullptr);
  }

  @override
  void addObserver_forKeyPath_options_context_(NSObject? observer,
      NSString? keyPath, int options, ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_126(
        _id,
        _lib._sel_addObserver_forKeyPath_options_context_1,
        observer?._id ?? ffi.nullptr,
        keyPath?._id ?? ffi.nullptr,
        options,
        context);
  }

  @override
  void removeObserver_forKeyPath_context_(
      NSObject? observer, NSString? keyPath, ffi.Pointer<ffi.Void> context) {
    return _lib._objc_msgSend_127(
        _id,
        _lib._sel_removeObserver_forKeyPath_context_1,
        observer?._id ?? ffi.nullptr,
        keyPath?._id ?? ffi.nullptr,
        context);
  }

  @override
  void removeObserver_forKeyPath_(NSObject? observer, NSString? keyPath) {
    return _lib._objc_msgSend_128(_id, _lib._sel_removeObserver_forKeyPath_1,
        observer?._id ?? ffi.nullptr, keyPath?._id ?? ffi.nullptr);
  }

  NSArray sortedArrayUsingDescriptors_(NSArray? sortDescriptors) {
    final _ret = _lib._objc_msgSend_63(
        _id,
        _lib._sel_sortedArrayUsingDescriptors_1,
        sortDescriptors?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSOrderedSet filteredOrderedSetUsingPredicate_(NSPredicate? p) {
    final _ret = _lib._objc_msgSend_434(_id,
        _lib._sel_filteredOrderedSetUsingPredicate_1, p?._id ?? ffi.nullptr);
    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
  }

  static NSOrderedSet new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSOrderedSet1, _lib._sel_new1);
    return NSOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  static NSOrderedSet alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSOrderedSet1, _lib._sel_alloc1);
    return NSOrderedSet._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSOrderedSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSOrderedSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSOrderedSet1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSOrderedSet1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSOrderedSet1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSOrderedSet1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSOrderedSet1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSOrderedSet1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSOrderedSet1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSMutableSet extends NSSet {
  NSMutableSet._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSMutableSet] that points to the same underlying object as [other].
  static NSMutableSet castFrom<T extends _ObjCWrapper>(T other) {
    return NSMutableSet._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSMutableSet] that wraps the given raw object pointer.
  static NSMutableSet castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSMutableSet._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSMutableSet].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSMutableSet1);
  }

  void addObject_(NSObject object) {
    return _lib._objc_msgSend_15(_id, _lib._sel_addObject_1, object._id);
  }

  void removeObject_(NSObject object) {
    return _lib._objc_msgSend_15(_id, _lib._sel_removeObject_1, object._id);
  }

  @override
  NSMutableSet initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSMutableSet init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  NSMutableSet initWithCapacity_(int numItems) {
    final _ret =
        _lib._objc_msgSend_60(_id, _lib._sel_initWithCapacity_1, numItems);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  void addObjectsFromArray_(NSArray? array) {
    return _lib._objc_msgSend_412(
        _id, _lib._sel_addObjectsFromArray_1, array?._id ?? ffi.nullptr);
  }

  void intersectSet_(NSSet? otherSet) {
    return _lib._objc_msgSend_439(
        _id, _lib._sel_intersectSet_1, otherSet?._id ?? ffi.nullptr);
  }

  void minusSet_(NSSet? otherSet) {
    return _lib._objc_msgSend_439(
        _id, _lib._sel_minusSet_1, otherSet?._id ?? ffi.nullptr);
  }

  void removeAllObjects() {
    return _lib._objc_msgSend_1(_id, _lib._sel_removeAllObjects1);
  }

  void unionSet_(NSSet? otherSet) {
    return _lib._objc_msgSend_439(
        _id, _lib._sel_unionSet_1, otherSet?._id ?? ffi.nullptr);
  }

  void setSet_(NSSet? otherSet) {
    return _lib._objc_msgSend_439(
        _id, _lib._sel_setSet_1, otherSet?._id ?? ffi.nullptr);
  }

  static NSMutableSet setWithCapacity_(AVFAudio _lib, int numItems) {
    final _ret = _lib._objc_msgSend_60(
        _lib._class_NSMutableSet1, _lib._sel_setWithCapacity_1, numItems);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  void filterUsingPredicate_(NSPredicate? predicate) {
    return _lib._objc_msgSend_427(
        _id, _lib._sel_filterUsingPredicate_1, predicate?._id ?? ffi.nullptr);
  }

  static NSMutableSet set1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableSet1, _lib._sel_set1);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableSet setWithObject_(AVFAudio _lib, NSObject object) {
    final _ret = _lib._objc_msgSend_16(
        _lib._class_NSMutableSet1, _lib._sel_setWithObject_1, object._id);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableSet setWithObjects_count_(
      AVFAudio _lib, ffi.Pointer<ffi.Pointer<ObjCObject>> objects, int cnt) {
    final _ret = _lib._objc_msgSend_61(_lib._class_NSMutableSet1,
        _lib._sel_setWithObjects_count_1, objects, cnt);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableSet setWithObjects_(AVFAudio _lib, NSObject firstObj) {
    final _ret = _lib._objc_msgSend_16(
        _lib._class_NSMutableSet1, _lib._sel_setWithObjects_1, firstObj._id);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableSet setWithSet_(AVFAudio _lib, NSSet? set) {
    final _ret = _lib._objc_msgSend_363(_lib._class_NSMutableSet1,
        _lib._sel_setWithSet_1, set?._id ?? ffi.nullptr);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableSet setWithArray_(AVFAudio _lib, NSArray? array) {
    final _ret = _lib._objc_msgSend_67(_lib._class_NSMutableSet1,
        _lib._sel_setWithArray_1, array?._id ?? ffi.nullptr);
    return NSMutableSet._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableSet new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableSet1, _lib._sel_new1);
    return NSMutableSet._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableSet alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableSet1, _lib._sel_alloc1);
    return NSMutableSet._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSMutableSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSMutableSet1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMutableSet1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMutableSet1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSMutableSet1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSMutableSet1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSMutableSet1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSMutableSet1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableSet1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSKeyValueChange {
  static const int NSKeyValueChangeSetting = 1;
  static const int NSKeyValueChangeInsertion = 2;
  static const int NSKeyValueChangeRemoval = 3;
  static const int NSKeyValueChangeReplacement = 4;
}

abstract class NSKeyValueSetMutationKind {
  static const int NSKeyValueUnionSetMutation = 1;
  static const int NSKeyValueMinusSetMutation = 2;
  static const int NSKeyValueIntersectSetMutation = 3;
  static const int NSKeyValueSetSetMutation = 4;
}

class NSKeyedArchiver extends NSCoder {
  NSKeyedArchiver._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSKeyedArchiver] that points to the same underlying object as [other].
  static NSKeyedArchiver castFrom<T extends _ObjCWrapper>(T other) {
    return NSKeyedArchiver._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSKeyedArchiver] that wraps the given raw object pointer.
  static NSKeyedArchiver castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSKeyedArchiver._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSKeyedArchiver].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSKeyedArchiver1);
  }

  NSKeyedArchiver initRequiringSecureCoding_(bool requiresSecureCoding) {
    final _ret = _lib._objc_msgSend_449(
        _id, _lib._sel_initRequiringSecureCoding_1, requiresSecureCoding);
    return NSKeyedArchiver._(_ret, _lib, retain: true, release: true);
  }

  static NSData archivedDataWithRootObject_requiringSecureCoding_error_(
      AVFAudio _lib,
      NSObject object,
      bool requiresSecureCoding,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_450(
        _lib._class_NSKeyedArchiver1,
        _lib._sel_archivedDataWithRootObject_requiringSecureCoding_error_1,
        object._id,
        requiresSecureCoding,
        error);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSKeyedArchiver init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSKeyedArchiver._(_ret, _lib, retain: true, release: true);
  }

  NSKeyedArchiver initForWritingWithMutableData_(NSMutableData? data) {
    final _ret = _lib._objc_msgSend_455(_id,
        _lib._sel_initForWritingWithMutableData_1, data?._id ?? ffi.nullptr);
    return NSKeyedArchiver._(_ret, _lib, retain: true, release: true);
  }

  static NSData archivedDataWithRootObject_(
      AVFAudio _lib, NSObject rootObject) {
    final _ret = _lib._objc_msgSend_456(_lib._class_NSKeyedArchiver1,
        _lib._sel_archivedDataWithRootObject_1, rootObject._id);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  static bool archiveRootObject_toFile_(
      AVFAudio _lib, NSObject rootObject, NSString? path) {
    return _lib._objc_msgSend_225(
        _lib._class_NSKeyedArchiver1,
        _lib._sel_archiveRootObject_toFile_1,
        rootObject._id,
        path?._id ?? ffi.nullptr);
  }

  NSObject? get delegate {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_delegate1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  set delegate(NSObject? value) {
    _lib._objc_msgSend_368(
        _id, _lib._sel_setDelegate_1, value?._id ?? ffi.nullptr);
  }

  int get outputFormat {
    return _lib._objc_msgSend_457(_id, _lib._sel_outputFormat1);
  }

  set outputFormat(int value) {
    _lib._objc_msgSend_458(_id, _lib._sel_setOutputFormat_1, value);
  }

  NSData? get encodedData {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_encodedData1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  void finishEncoding() {
    return _lib._objc_msgSend_1(_id, _lib._sel_finishEncoding1);
  }

  static void setClassName_forClass_(
      AVFAudio _lib, NSString? codedName, NSObject cls) {
    return _lib._objc_msgSend_459(
        _lib._class_NSKeyedArchiver1,
        _lib._sel_setClassName_forClass_1,
        codedName?._id ?? ffi.nullptr,
        cls._id);
  }

  static NSString classNameForClass_(AVFAudio _lib, NSObject cls) {
    final _ret = _lib._objc_msgSend_65(
        _lib._class_NSKeyedArchiver1, _lib._sel_classNameForClass_1, cls._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  @override
  void encodeObject_forKey_(NSObject object, NSString? key) {
    return _lib._objc_msgSend_122(_id, _lib._sel_encodeObject_forKey_1,
        object._id, key?._id ?? ffi.nullptr);
  }

  @override
  void encodeConditionalObject_forKey_(NSObject object, NSString? key) {
    return _lib._objc_msgSend_122(
        _id,
        _lib._sel_encodeConditionalObject_forKey_1,
        object._id,
        key?._id ?? ffi.nullptr);
  }

  @override
  void encodeBool_forKey_(bool value, NSString? key) {
    return _lib._objc_msgSend_257(
        _id, _lib._sel_encodeBool_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  @override
  void encodeInt_forKey_(int value, NSString? key) {
    return _lib._objc_msgSend_258(
        _id, _lib._sel_encodeInt_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  @override
  void encodeInt32_forKey_(int value, NSString? key) {
    return _lib._objc_msgSend_259(
        _id, _lib._sel_encodeInt32_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  @override
  void encodeInt64_forKey_(int value, NSString? key) {
    return _lib._objc_msgSend_260(
        _id, _lib._sel_encodeInt64_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  @override
  void encodeFloat_forKey_(double value, NSString? key) {
    return _lib._objc_msgSend_261(
        _id, _lib._sel_encodeFloat_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  @override
  void encodeDouble_forKey_(double value, NSString? key) {
    return _lib._objc_msgSend_262(
        _id, _lib._sel_encodeDouble_forKey_1, value, key?._id ?? ffi.nullptr);
  }

  @override
  void encodeBytes_length_forKey_(
      ffi.Pointer<ffi.Uint8> bytes, int length, NSString? key) {
    return _lib._objc_msgSend_263(_id, _lib._sel_encodeBytes_length_forKey_1,
        bytes, length, key?._id ?? ffi.nullptr);
  }

  @override
  bool get requiresSecureCoding {
    return _lib._objc_msgSend_12(_id, _lib._sel_requiresSecureCoding1);
  }

  set requiresSecureCoding(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setRequiresSecureCoding_1, value);
  }

  static NSKeyedArchiver new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSKeyedArchiver1, _lib._sel_new1);
    return NSKeyedArchiver._(_ret, _lib, retain: false, release: true);
  }

  static NSKeyedArchiver alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSKeyedArchiver1, _lib._sel_alloc1);
    return NSKeyedArchiver._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSKeyedArchiver1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSKeyedArchiver1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSKeyedArchiver1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSKeyedArchiver1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSKeyedArchiver1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSKeyedArchiver1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSKeyedArchiver1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSKeyedArchiver1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSKeyedArchiver1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSMutableData extends NSData {
  NSMutableData._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSMutableData] that points to the same underlying object as [other].
  static NSMutableData castFrom<T extends _ObjCWrapper>(T other) {
    return NSMutableData._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSMutableData] that wraps the given raw object pointer.
  static NSMutableData castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSMutableData._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSMutableData].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSMutableData1);
  }

  ffi.Pointer<ffi.Void> get mutableBytes {
    return _lib._objc_msgSend_19(_id, _lib._sel_mutableBytes1);
  }

  @override
  int get length {
    return _lib._objc_msgSend_10(_id, _lib._sel_length1);
  }

  set length(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setLength_1, value);
  }

  void appendBytes_length_(ffi.Pointer<ffi.Void> bytes, int length) {
    return _lib._objc_msgSend_21(
        _id, _lib._sel_appendBytes_length_1, bytes, length);
  }

  void appendData_(NSData? other) {
    return _lib._objc_msgSend_248(
        _id, _lib._sel_appendData_1, other?._id ?? ffi.nullptr);
  }

  void increaseLengthBy_(int extraLength) {
    return _lib._objc_msgSend_410(
        _id, _lib._sel_increaseLengthBy_1, extraLength);
  }

  void replaceBytesInRange_withBytes_(
      NSRange range, ffi.Pointer<ffi.Void> bytes) {
    return _lib._objc_msgSend_452(
        _id, _lib._sel_replaceBytesInRange_withBytes_1, range, bytes);
  }

  void resetBytesInRange_(NSRange range) {
    return _lib._objc_msgSend_416(_id, _lib._sel_resetBytesInRange_1, range);
  }

  void setData_(NSData? data) {
    return _lib._objc_msgSend_248(
        _id, _lib._sel_setData_1, data?._id ?? ffi.nullptr);
  }

  void replaceBytesInRange_withBytes_length_(NSRange range,
      ffi.Pointer<ffi.Void> replacementBytes, int replacementLength) {
    return _lib._objc_msgSend_453(
        _id,
        _lib._sel_replaceBytesInRange_withBytes_length_1,
        range,
        replacementBytes,
        replacementLength);
  }

  static NSMutableData dataWithCapacity_(AVFAudio _lib, int aNumItems) {
    final _ret = _lib._objc_msgSend_60(
        _lib._class_NSMutableData1, _lib._sel_dataWithCapacity_1, aNumItems);
    return NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableData dataWithLength_(AVFAudio _lib, int length) {
    final _ret = _lib._objc_msgSend_60(
        _lib._class_NSMutableData1, _lib._sel_dataWithLength_1, length);
    return NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  NSMutableData initWithCapacity_(int capacity) {
    final _ret =
        _lib._objc_msgSend_60(_id, _lib._sel_initWithCapacity_1, capacity);
    return NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  NSMutableData initWithLength_(int length) {
    final _ret = _lib._objc_msgSend_60(_id, _lib._sel_initWithLength_1, length);
    return NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  bool decompressUsingAlgorithm_error_(
      int algorithm, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_454(
        _id, _lib._sel_decompressUsingAlgorithm_error_1, algorithm, error);
  }

  bool compressUsingAlgorithm_error_(
      int algorithm, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_454(
        _id, _lib._sel_compressUsingAlgorithm_error_1, algorithm, error);
  }

  static NSMutableData data(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableData1, _lib._sel_data1);
    return NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableData dataWithBytes_length_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> bytes, int length) {
    final _ret = _lib._objc_msgSend_237(_lib._class_NSMutableData1,
        _lib._sel_dataWithBytes_length_1, bytes, length);
    return NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableData dataWithBytesNoCopy_length_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> bytes, int length) {
    final _ret = _lib._objc_msgSend_237(_lib._class_NSMutableData1,
        _lib._sel_dataWithBytesNoCopy_length_1, bytes, length);
    return NSMutableData._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableData dataWithBytesNoCopy_length_freeWhenDone_(
      AVFAudio _lib, ffi.Pointer<ffi.Void> bytes, int length, bool b) {
    final _ret = _lib._objc_msgSend_238(_lib._class_NSMutableData1,
        _lib._sel_dataWithBytesNoCopy_length_freeWhenDone_1, bytes, length, b);
    return NSMutableData._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableData dataWithContentsOfFile_options_error_(
      AVFAudio _lib,
      NSString? path,
      int readOptionsMask,
      ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr) {
    final _ret = _lib._objc_msgSend_239(
        _lib._class_NSMutableData1,
        _lib._sel_dataWithContentsOfFile_options_error_1,
        path?._id ?? ffi.nullptr,
        readOptionsMask,
        errorPtr);
    return NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableData dataWithContentsOfURL_options_error_(
      AVFAudio _lib,
      NSURL? url,
      int readOptionsMask,
      ffi.Pointer<ffi.Pointer<ObjCObject>> errorPtr) {
    final _ret = _lib._objc_msgSend_240(
        _lib._class_NSMutableData1,
        _lib._sel_dataWithContentsOfURL_options_error_1,
        url?._id ?? ffi.nullptr,
        readOptionsMask,
        errorPtr);
    return NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableData dataWithContentsOfFile_(AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSMutableData1,
        _lib._sel_dataWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableData dataWithContentsOfURL_(AVFAudio _lib, NSURL? url) {
    final _ret = _lib._objc_msgSend_226(_lib._class_NSMutableData1,
        _lib._sel_dataWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableData dataWithData_(AVFAudio _lib, NSData? data) {
    final _ret = _lib._objc_msgSend_242(_lib._class_NSMutableData1,
        _lib._sel_dataWithData_1, data?._id ?? ffi.nullptr);
    return NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  static NSObject dataWithContentsOfMappedFile_(AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSMutableData1,
        _lib._sel_dataWithContentsOfMappedFile_1, path?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableData new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableData1, _lib._sel_new1);
    return NSMutableData._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableData alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableData1, _lib._sel_alloc1);
    return NSMutableData._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSMutableData1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSMutableData1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMutableData1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMutableData1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSMutableData1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSMutableData1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSMutableData1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSMutableData1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableData1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSPropertyListFormat {
  static const int NSPropertyListOpenStepFormat = 1;
  static const int NSPropertyListXMLFormat_v1_0 = 100;
  static const int NSPropertyListBinaryFormat_v1_0 = 200;
}

class NSThread extends NSObject {
  NSThread._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSThread] that points to the same underlying object as [other].
  static NSThread castFrom<T extends _ObjCWrapper>(T other) {
    return NSThread._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSThread] that wraps the given raw object pointer.
  static NSThread castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSThread._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSThread].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSThread1);
  }

  static NSThread? getCurrentThread(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_464(_lib._class_NSThread1, _lib._sel_currentThread1);
    return _ret.address == 0
        ? null
        : NSThread._(_ret, _lib, retain: true, release: true);
  }

  static void detachNewThreadWithBlock_(AVFAudio _lib, ObjCBlock16 block) {
    return _lib._objc_msgSend_465(
        _lib._class_NSThread1, _lib._sel_detachNewThreadWithBlock_1, block._id);
  }

  static void detachNewThreadSelector_toTarget_withObject_(AVFAudio _lib,
      ffi.Pointer<ObjCSel> selector, NSObject target, NSObject argument) {
    return _lib._objc_msgSend_466(
        _lib._class_NSThread1,
        _lib._sel_detachNewThreadSelector_toTarget_withObject_1,
        selector,
        target._id,
        argument._id);
  }

  static bool isMultiThreaded(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSThread1, _lib._sel_isMultiThreaded1);
  }

  NSMutableDictionary? get threadDictionary {
    final _ret = _lib._objc_msgSend_471(_id, _lib._sel_threadDictionary1);
    return _ret.address == 0
        ? null
        : NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  static void sleepUntilDate_(AVFAudio _lib, NSDate? date) {
    return _lib._objc_msgSend_472(_lib._class_NSThread1,
        _lib._sel_sleepUntilDate_1, date?._id ?? ffi.nullptr);
  }

  static void sleepForTimeInterval_(AVFAudio _lib, double ti) {
    return _lib._objc_msgSend_473(
        _lib._class_NSThread1, _lib._sel_sleepForTimeInterval_1, ti);
  }

  static void exit(AVFAudio _lib) {
    return _lib._objc_msgSend_1(_lib._class_NSThread1, _lib._sel_exit1);
  }

  double get threadPriority {
    return _lib._objc_msgSend_149(_id, _lib._sel_threadPriority1);
  }

  set threadPriority(double value) {
    _lib._objc_msgSend_474(_id, _lib._sel_setThreadPriority_1, value);
  }

  int get qualityOfService {
    return _lib._objc_msgSend_475(_id, _lib._sel_qualityOfService1);
  }

  set qualityOfService(int value) {
    _lib._objc_msgSend_476(_id, _lib._sel_setQualityOfService_1, value);
  }

  static NSArray? getCallStackReturnAddresses(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSThread1, _lib._sel_callStackReturnAddresses1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray? getCallStackSymbols(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSThread1, _lib._sel_callStackSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString? get name {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_name1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set name(NSString? value) {
    _lib._objc_msgSend_477(_id, _lib._sel_setName_1, value?._id ?? ffi.nullptr);
  }

  int get stackSize {
    return _lib._objc_msgSend_10(_id, _lib._sel_stackSize1);
  }

  set stackSize(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setStackSize_1, value);
  }

  bool get isMainThread {
    return _lib._objc_msgSend_12(_id, _lib._sel_isMainThread1);
  }

  static NSThread? getMainThread(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_464(_lib._class_NSThread1, _lib._sel_mainThread1);
    return _ret.address == 0
        ? null
        : NSThread._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSThread init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSThread._(_ret, _lib, retain: true, release: true);
  }

  NSThread initWithTarget_selector_object_(
      NSObject target, ffi.Pointer<ObjCSel> selector, NSObject argument) {
    final _ret = _lib._objc_msgSend_478(
        _id,
        _lib._sel_initWithTarget_selector_object_1,
        target._id,
        selector,
        argument._id);
    return NSThread._(_ret, _lib, retain: true, release: true);
  }

  NSThread initWithBlock_(ObjCBlock16 block) {
    final _ret =
        _lib._objc_msgSend_479(_id, _lib._sel_initWithBlock_1, block._id);
    return NSThread._(_ret, _lib, retain: true, release: true);
  }

  bool get executing {
    return _lib._objc_msgSend_12(_id, _lib._sel_isExecuting1);
  }

  bool get finished {
    return _lib._objc_msgSend_12(_id, _lib._sel_isFinished1);
  }

  bool get cancelled {
    return _lib._objc_msgSend_12(_id, _lib._sel_isCancelled1);
  }

  void cancel() {
    return _lib._objc_msgSend_1(_id, _lib._sel_cancel1);
  }

  void start() {
    return _lib._objc_msgSend_1(_id, _lib._sel_start1);
  }

  void main() {
    return _lib._objc_msgSend_1(_id, _lib._sel_main1);
  }

  static NSThread new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSThread1, _lib._sel_new1);
    return NSThread._(_ret, _lib, retain: false, release: true);
  }

  static NSThread alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSThread1, _lib._sel_alloc1);
    return NSThread._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSThread1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSThread1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSThread1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSThread1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSThread1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSThread1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSThread1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSThread1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSThread1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

void _ObjCBlock16_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block) {
  return block.ref.target
      .cast<ffi.NativeFunction<ffi.Void Function()>>()
      .asFunction<void Function()>()();
}

final _ObjCBlock16_closureRegistry = <int, Function>{};
int _ObjCBlock16_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock16_registerClosure(Function fn) {
  final id = ++_ObjCBlock16_closureRegistryIndex;
  _ObjCBlock16_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock16_closureTrampoline(ffi.Pointer<_ObjCBlock> block) {
  return _ObjCBlock16_closureRegistry[block.ref.target.address]!();
}

class ObjCBlock16 extends _ObjCBlockBase {
  ObjCBlock16._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock16.fromFunctionPointer(
      AVFAudio lib, ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block)>(
                        _ObjCBlock16_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock16.fromFunction(AVFAudio lib, void Function() fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block)>(
                        _ObjCBlock16_closureTrampoline)
                    .cast(),
                _ObjCBlock16_registerClosure(fn)),
            lib);
  void call() {
    return _id.ref.invoke
        .cast<
            ffi
            .NativeFunction<ffi.Void Function(ffi.Pointer<_ObjCBlock> block)>>()
        .asFunction<void Function(ffi.Pointer<_ObjCBlock> block)>()(_id);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSMutableDictionary extends NSDictionary {
  NSMutableDictionary._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSMutableDictionary] that points to the same underlying object as [other].
  static NSMutableDictionary castFrom<T extends _ObjCWrapper>(T other) {
    return NSMutableDictionary._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSMutableDictionary] that wraps the given raw object pointer.
  static NSMutableDictionary castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSMutableDictionary._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSMutableDictionary].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSMutableDictionary1);
  }

  void removeObjectForKey_(NSObject aKey) {
    return _lib._objc_msgSend_15(_id, _lib._sel_removeObjectForKey_1, aKey._id);
  }

  void setObject_forKey_(NSObject anObject, NSObject aKey) {
    return _lib._objc_msgSend_467(
        _id, _lib._sel_setObject_forKey_1, anObject._id, aKey._id);
  }

  @override
  NSMutableDictionary init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSMutableDictionary initWithCapacity_(int numItems) {
    final _ret =
        _lib._objc_msgSend_60(_id, _lib._sel_initWithCapacity_1, numItems);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSMutableDictionary initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  void addEntriesFromDictionary_(NSDictionary? otherDictionary) {
    return _lib._objc_msgSend_444(_id, _lib._sel_addEntriesFromDictionary_1,
        otherDictionary?._id ?? ffi.nullptr);
  }

  void removeAllObjects() {
    return _lib._objc_msgSend_1(_id, _lib._sel_removeAllObjects1);
  }

  void removeObjectsForKeys_(NSArray? keyArray) {
    return _lib._objc_msgSend_412(
        _id, _lib._sel_removeObjectsForKeys_1, keyArray?._id ?? ffi.nullptr);
  }

  void setDictionary_(NSDictionary? otherDictionary) {
    return _lib._objc_msgSend_444(
        _id, _lib._sel_setDictionary_1, otherDictionary?._id ?? ffi.nullptr);
  }

  void setObject_forKeyedSubscript_(NSObject obj, NSObject key) {
    return _lib._objc_msgSend_467(
        _id, _lib._sel_setObject_forKeyedSubscript_1, obj._id, key._id);
  }

  static NSMutableDictionary dictionaryWithCapacity_(
      AVFAudio _lib, int numItems) {
    final _ret = _lib._objc_msgSend_60(_lib._class_NSMutableDictionary1,
        _lib._sel_dictionaryWithCapacity_1, numItems);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableDictionary dictionaryWithContentsOfFile_(
      AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_468(_lib._class_NSMutableDictionary1,
        _lib._sel_dictionaryWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableDictionary dictionaryWithContentsOfURL_(
      AVFAudio _lib, NSURL? url) {
    final _ret = _lib._objc_msgSend_469(_lib._class_NSMutableDictionary1,
        _lib._sel_dictionaryWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSMutableDictionary initWithContentsOfFile_(NSString? path) {
    final _ret = _lib._objc_msgSend_468(
        _id, _lib._sel_initWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSMutableDictionary initWithContentsOfURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_469(
        _id, _lib._sel_initWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableDictionary dictionaryWithSharedKeySet_(
      AVFAudio _lib, NSObject keyset) {
    final _ret = _lib._objc_msgSend_470(_lib._class_NSMutableDictionary1,
        _lib._sel_dictionaryWithSharedKeySet_1, keyset._id);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  void setValue_forKey_(NSObject value, NSString? key) {
    return _lib._objc_msgSend_122(
        _id, _lib._sel_setValue_forKey_1, value._id, key?._id ?? ffi.nullptr);
  }

  static NSMutableDictionary dictionary(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableDictionary1, _lib._sel_dictionary1);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableDictionary dictionaryWithObject_forKey_(
      AVFAudio _lib, NSObject object, NSObject key) {
    final _ret = _lib._objc_msgSend_142(_lib._class_NSMutableDictionary1,
        _lib._sel_dictionaryWithObject_forKey_1, object._id, key._id);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableDictionary dictionaryWithObjects_forKeys_count_(
      AVFAudio _lib,
      ffi.Pointer<ffi.Pointer<ObjCObject>> objects,
      ffi.Pointer<ffi.Pointer<ObjCObject>> keys,
      int cnt) {
    final _ret = _lib._objc_msgSend_133(_lib._class_NSMutableDictionary1,
        _lib._sel_dictionaryWithObjects_forKeys_count_1, objects, keys, cnt);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableDictionary dictionaryWithObjectsAndKeys_(
      AVFAudio _lib, NSObject firstObject) {
    final _ret = _lib._objc_msgSend_16(_lib._class_NSMutableDictionary1,
        _lib._sel_dictionaryWithObjectsAndKeys_1, firstObject._id);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableDictionary dictionaryWithDictionary_(
      AVFAudio _lib, NSDictionary? dict) {
    final _ret = _lib._objc_msgSend_143(_lib._class_NSMutableDictionary1,
        _lib._sel_dictionaryWithDictionary_1, dict?._id ?? ffi.nullptr);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableDictionary dictionaryWithObjects_forKeys_(
      AVFAudio _lib, NSArray? objects, NSArray? keys) {
    final _ret = _lib._objc_msgSend_144(
        _lib._class_NSMutableDictionary1,
        _lib._sel_dictionaryWithObjects_forKeys_1,
        objects?._id ?? ffi.nullptr,
        keys?._id ?? ffi.nullptr);
    return NSMutableDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary dictionaryWithContentsOfURL_error_(
      AVFAudio _lib, NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_146(
        _lib._class_NSMutableDictionary1,
        _lib._sel_dictionaryWithContentsOfURL_error_1,
        url?._id ?? ffi.nullptr,
        error);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSObject sharedKeySetForKeys_(AVFAudio _lib, NSArray? keys) {
    final _ret = _lib._objc_msgSend_67(_lib._class_NSMutableDictionary1,
        _lib._sel_sharedKeySetForKeys_1, keys?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableDictionary new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableDictionary1, _lib._sel_new1);
    return NSMutableDictionary._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableDictionary alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableDictionary1, _lib._sel_alloc1);
    return NSMutableDictionary._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSMutableDictionary1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSMutableDictionary1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSMutableDictionary1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMutableDictionary1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSMutableDictionary1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSMutableDictionary1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSMutableDictionary1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSMutableDictionary1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableDictionary1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSQualityOfService {
  static const int NSQualityOfServiceUserInteractive = 33;
  static const int NSQualityOfServiceUserInitiated = 25;
  static const int NSQualityOfServiceUtility = 17;
  static const int NSQualityOfServiceBackground = 9;
  static const int NSQualityOfServiceDefault = -1;
}

class NSArchiver extends NSCoder {
  NSArchiver._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSArchiver] that points to the same underlying object as [other].
  static NSArchiver castFrom<T extends _ObjCWrapper>(T other) {
    return NSArchiver._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSArchiver] that wraps the given raw object pointer.
  static NSArchiver castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSArchiver._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSArchiver].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSArchiver1);
  }

  NSArchiver initForWritingWithMutableData_(NSMutableData? mdata) {
    final _ret = _lib._objc_msgSend_455(_id,
        _lib._sel_initForWritingWithMutableData_1, mdata?._id ?? ffi.nullptr);
    return NSArchiver._(_ret, _lib, retain: true, release: true);
  }

  NSMutableData? get archiverData {
    final _ret = _lib._objc_msgSend_482(_id, _lib._sel_archiverData1);
    return _ret.address == 0
        ? null
        : NSMutableData._(_ret, _lib, retain: true, release: true);
  }

  @override
  void encodeRootObject_(NSObject rootObject) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_encodeRootObject_1, rootObject._id);
  }

  @override
  void encodeConditionalObject_(NSObject object) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_encodeConditionalObject_1, object._id);
  }

  static NSData archivedDataWithRootObject_(
      AVFAudio _lib, NSObject rootObject) {
    final _ret = _lib._objc_msgSend_456(_lib._class_NSArchiver1,
        _lib._sel_archivedDataWithRootObject_1, rootObject._id);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  static bool archiveRootObject_toFile_(
      AVFAudio _lib, NSObject rootObject, NSString? path) {
    return _lib._objc_msgSend_225(
        _lib._class_NSArchiver1,
        _lib._sel_archiveRootObject_toFile_1,
        rootObject._id,
        path?._id ?? ffi.nullptr);
  }

  void encodeClassName_intoClassName_(
      NSString? trueName, NSString? inArchiveName) {
    return _lib._objc_msgSend_483(
        _id,
        _lib._sel_encodeClassName_intoClassName_1,
        trueName?._id ?? ffi.nullptr,
        inArchiveName?._id ?? ffi.nullptr);
  }

  NSString classNameEncodedForTrueClassName_(NSString? trueName) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_classNameEncodedForTrueClassName_1,
        trueName?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  void replaceObject_withObject_(NSObject object, NSObject newObject) {
    return _lib._objc_msgSend_467(
        _id, _lib._sel_replaceObject_withObject_1, object._id, newObject._id);
  }

  static NSArchiver new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSArchiver1, _lib._sel_new1);
    return NSArchiver._(_ret, _lib, retain: false, release: true);
  }

  static NSArchiver alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSArchiver1, _lib._sel_alloc1);
    return NSArchiver._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSArchiver1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSArchiver1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSArchiver1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSArchiver1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSArchiver1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSArchiver1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSArchiver1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSArchiver1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSArchiver1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSPortCoder extends NSCoder {
  NSPortCoder._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSPortCoder] that points to the same underlying object as [other].
  static NSPortCoder castFrom<T extends _ObjCWrapper>(T other) {
    return NSPortCoder._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSPortCoder] that wraps the given raw object pointer.
  static NSPortCoder castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSPortCoder._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSPortCoder].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSPortCoder1);
  }

  bool isBycopy() {
    return _lib._objc_msgSend_12(_id, _lib._sel_isBycopy1);
  }

  bool isByref() {
    return _lib._objc_msgSend_12(_id, _lib._sel_isByref1);
  }

  void encodePortObject_(NSPort? aport) {
    return _lib._objc_msgSend_520(
        _id, _lib._sel_encodePortObject_1, aport?._id ?? ffi.nullptr);
  }

  NSPort decodePortObject() {
    final _ret = _lib._objc_msgSend_485(_id, _lib._sel_decodePortObject1);
    return NSPort._(_ret, _lib, retain: true, release: true);
  }

  NSConnection connection() {
    final _ret = _lib._objc_msgSend_504(_id, _lib._sel_connection1);
    return NSConnection._(_ret, _lib, retain: true, release: true);
  }

  static NSObject portCoderWithReceivePort_sendPort_components_(
      AVFAudio _lib, NSPort? rcvPort, NSPort? sndPort, NSArray? comps) {
    final _ret = _lib._objc_msgSend_521(
        _lib._class_NSPortCoder1,
        _lib._sel_portCoderWithReceivePort_sendPort_components_1,
        rcvPort?._id ?? ffi.nullptr,
        sndPort?._id ?? ffi.nullptr,
        comps?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithReceivePort_sendPort_components_(
      NSPort? rcvPort, NSPort? sndPort, NSArray? comps) {
    final _ret = _lib._objc_msgSend_521(
        _id,
        _lib._sel_initWithReceivePort_sendPort_components_1,
        rcvPort?._id ?? ffi.nullptr,
        sndPort?._id ?? ffi.nullptr,
        comps?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void dispatch() {
    return _lib._objc_msgSend_1(_id, _lib._sel_dispatch1);
  }

  static NSPortCoder new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSPortCoder1, _lib._sel_new1);
    return NSPortCoder._(_ret, _lib, retain: false, release: true);
  }

  static NSPortCoder alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSPortCoder1, _lib._sel_alloc1);
    return NSPortCoder._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSPortCoder1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSPortCoder1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSPortCoder1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSPortCoder1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSPortCoder1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSPortCoder1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSPortCoder1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSPortCoder1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSPortCoder1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSPort extends NSObject {
  NSPort._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSPort] that points to the same underlying object as [other].
  static NSPort castFrom<T extends _ObjCWrapper>(T other) {
    return NSPort._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSPort] that wraps the given raw object pointer.
  static NSPort castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSPort._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSPort].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSPort1);
  }

  static NSPort port(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_485(_lib._class_NSPort1, _lib._sel_port1);
    return NSPort._(_ret, _lib, retain: true, release: true);
  }

  void invalidate() {
    return _lib._objc_msgSend_1(_id, _lib._sel_invalidate1);
  }

  bool get valid {
    return _lib._objc_msgSend_12(_id, _lib._sel_isValid1);
  }

  void setDelegate_(NSObject? anObject) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_setDelegate_1, anObject?._id ?? ffi.nullptr);
  }

  NSObject delegate() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_delegate1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void scheduleInRunLoop_forMode_(NSRunLoop? runLoop, NSRunLoopMode mode) {
    return _lib._objc_msgSend_501(_id, _lib._sel_scheduleInRunLoop_forMode_1,
        runLoop?._id ?? ffi.nullptr, mode);
  }

  void removeFromRunLoop_forMode_(NSRunLoop? runLoop, NSRunLoopMode mode) {
    return _lib._objc_msgSend_501(_id, _lib._sel_removeFromRunLoop_forMode_1,
        runLoop?._id ?? ffi.nullptr, mode);
  }

  int get reservedSpaceLength {
    return _lib._objc_msgSend_10(_id, _lib._sel_reservedSpaceLength1);
  }

  bool sendBeforeDate_components_from_reserved_(
      NSDate? limitDate,
      NSMutableArray? components,
      NSPort? receivePort,
      int headerSpaceReserved) {
    return _lib._objc_msgSend_502(
        _id,
        _lib._sel_sendBeforeDate_components_from_reserved_1,
        limitDate?._id ?? ffi.nullptr,
        components?._id ?? ffi.nullptr,
        receivePort?._id ?? ffi.nullptr,
        headerSpaceReserved);
  }

  bool sendBeforeDate_msgid_components_from_reserved_(
      NSDate? limitDate,
      int msgID,
      NSMutableArray? components,
      NSPort? receivePort,
      int headerSpaceReserved) {
    return _lib._objc_msgSend_503(
        _id,
        _lib._sel_sendBeforeDate_msgid_components_from_reserved_1,
        limitDate?._id ?? ffi.nullptr,
        msgID,
        components?._id ?? ffi.nullptr,
        receivePort?._id ?? ffi.nullptr,
        headerSpaceReserved);
  }

  void addConnection_toRunLoop_forMode_(
      NSConnection? conn, NSRunLoop? runLoop, NSRunLoopMode mode) {
    return _lib._objc_msgSend_519(
        _id,
        _lib._sel_addConnection_toRunLoop_forMode_1,
        conn?._id ?? ffi.nullptr,
        runLoop?._id ?? ffi.nullptr,
        mode);
  }

  void removeConnection_fromRunLoop_forMode_(
      NSConnection? conn, NSRunLoop? runLoop, NSRunLoopMode mode) {
    return _lib._objc_msgSend_519(
        _id,
        _lib._sel_removeConnection_fromRunLoop_forMode_1,
        conn?._id ?? ffi.nullptr,
        runLoop?._id ?? ffi.nullptr,
        mode);
  }

  static NSPort new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSPort1, _lib._sel_new1);
    return NSPort._(_ret, _lib, retain: false, release: true);
  }

  static NSPort alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSPort1, _lib._sel_alloc1);
    return NSPort._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSPort1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSPort1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSPort1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSPort1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSPort1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSPort1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSPort1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSPort1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSPort1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSRunLoop extends NSObject {
  NSRunLoop._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSRunLoop] that points to the same underlying object as [other].
  static NSRunLoop castFrom<T extends _ObjCWrapper>(T other) {
    return NSRunLoop._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSRunLoop] that wraps the given raw object pointer.
  static NSRunLoop castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSRunLoop._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSRunLoop].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSRunLoop1);
  }

  static NSRunLoop? getCurrentRunLoop(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_486(
        _lib._class_NSRunLoop1, _lib._sel_currentRunLoop1);
    return _ret.address == 0
        ? null
        : NSRunLoop._(_ret, _lib, retain: true, release: true);
  }

  static NSRunLoop? getMainRunLoop(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_486(_lib._class_NSRunLoop1, _lib._sel_mainRunLoop1);
    return _ret.address == 0
        ? null
        : NSRunLoop._(_ret, _lib, retain: true, release: true);
  }

  NSRunLoopMode get currentMode {
    return _lib._objc_msgSend_20(_id, _lib._sel_currentMode1);
  }

  CFRunLoopRef getCFRunLoop() {
    return _lib._objc_msgSend_487(_id, _lib._sel_getCFRunLoop1);
  }

  void addTimer_forMode_(NSTimer? timer, NSRunLoopMode mode) {
    return _lib._objc_msgSend_494(
        _id, _lib._sel_addTimer_forMode_1, timer?._id ?? ffi.nullptr, mode);
  }

  void addPort_forMode_(NSPort? aPort, NSRunLoopMode mode) {
    return _lib._objc_msgSend_495(
        _id, _lib._sel_addPort_forMode_1, aPort?._id ?? ffi.nullptr, mode);
  }

  void removePort_forMode_(NSPort? aPort, NSRunLoopMode mode) {
    return _lib._objc_msgSend_495(
        _id, _lib._sel_removePort_forMode_1, aPort?._id ?? ffi.nullptr, mode);
  }

  NSDate limitDateForMode_(NSRunLoopMode mode) {
    final _ret =
        _lib._objc_msgSend_496(_id, _lib._sel_limitDateForMode_1, mode);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  void acceptInputForMode_beforeDate_(NSRunLoopMode mode, NSDate? limitDate) {
    return _lib._objc_msgSend_497(
        _id,
        _lib._sel_acceptInputForMode_beforeDate_1,
        mode,
        limitDate?._id ?? ffi.nullptr);
  }

  void run() {
    return _lib._objc_msgSend_1(_id, _lib._sel_run1);
  }

  void runUntilDate_(NSDate? limitDate) {
    return _lib._objc_msgSend_472(
        _id, _lib._sel_runUntilDate_1, limitDate?._id ?? ffi.nullptr);
  }

  bool runMode_beforeDate_(NSRunLoopMode mode, NSDate? limitDate) {
    return _lib._objc_msgSend_498(_id, _lib._sel_runMode_beforeDate_1, mode,
        limitDate?._id ?? ffi.nullptr);
  }

  void configureAsServer() {
    return _lib._objc_msgSend_1(_id, _lib._sel_configureAsServer1);
  }

  void performInModes_block_(NSArray? modes, ObjCBlock16 block) {
    return _lib._objc_msgSend_499(_id, _lib._sel_performInModes_block_1,
        modes?._id ?? ffi.nullptr, block._id);
  }

  void performBlock_(ObjCBlock16 block) {
    return _lib._objc_msgSend_465(_id, _lib._sel_performBlock_1, block._id);
  }

  void performSelector_target_argument_order_modes_(
      ffi.Pointer<ObjCSel> aSelector,
      NSObject target,
      NSObject arg,
      int order,
      NSArray? modes) {
    return _lib._objc_msgSend_500(
        _id,
        _lib._sel_performSelector_target_argument_order_modes_1,
        aSelector,
        target._id,
        arg._id,
        order,
        modes?._id ?? ffi.nullptr);
  }

  void cancelPerformSelector_target_argument_(
      ffi.Pointer<ObjCSel> aSelector, NSObject target, NSObject arg) {
    return _lib._objc_msgSend_466(
        _id,
        _lib._sel_cancelPerformSelector_target_argument_1,
        aSelector,
        target._id,
        arg._id);
  }

  void cancelPerformSelectorsWithTarget_(NSObject target) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_cancelPerformSelectorsWithTarget_1, target._id);
  }

  static NSRunLoop new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSRunLoop1, _lib._sel_new1);
    return NSRunLoop._(_ret, _lib, retain: false, release: true);
  }

  static NSRunLoop alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSRunLoop1, _lib._sel_alloc1);
    return NSRunLoop._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSRunLoop1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSRunLoop1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSRunLoop1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSRunLoop1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSRunLoop1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSRunLoop1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSRunLoop1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSRunLoop1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSRunLoop1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSRunLoopMode = ffi.Pointer<ObjCObject>;
typedef CFRunLoopRef = ffi.Pointer<__CFRunLoop>;

final class __CFRunLoop extends ffi.Opaque {}

class NSTimer extends NSObject {
  NSTimer._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSTimer] that points to the same underlying object as [other].
  static NSTimer castFrom<T extends _ObjCWrapper>(T other) {
    return NSTimer._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSTimer] that wraps the given raw object pointer.
  static NSTimer castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSTimer._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSTimer].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSTimer1);
  }

  static NSTimer timerWithTimeInterval_invocation_repeats_(
      AVFAudio _lib, double ti, NSInvocation? invocation, bool yesOrNo) {
    final _ret = _lib._objc_msgSend_488(
        _lib._class_NSTimer1,
        _lib._sel_timerWithTimeInterval_invocation_repeats_1,
        ti,
        invocation?._id ?? ffi.nullptr,
        yesOrNo);
    return NSTimer._(_ret, _lib, retain: true, release: true);
  }

  static NSTimer scheduledTimerWithTimeInterval_invocation_repeats_(
      AVFAudio _lib, double ti, NSInvocation? invocation, bool yesOrNo) {
    final _ret = _lib._objc_msgSend_488(
        _lib._class_NSTimer1,
        _lib._sel_scheduledTimerWithTimeInterval_invocation_repeats_1,
        ti,
        invocation?._id ?? ffi.nullptr,
        yesOrNo);
    return NSTimer._(_ret, _lib, retain: true, release: true);
  }

  static NSTimer timerWithTimeInterval_target_selector_userInfo_repeats_(
      AVFAudio _lib,
      double ti,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject userInfo,
      bool yesOrNo) {
    final _ret = _lib._objc_msgSend_489(
        _lib._class_NSTimer1,
        _lib._sel_timerWithTimeInterval_target_selector_userInfo_repeats_1,
        ti,
        aTarget._id,
        aSelector,
        userInfo._id,
        yesOrNo);
    return NSTimer._(_ret, _lib, retain: true, release: true);
  }

  static NSTimer
      scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(
          AVFAudio _lib,
          double ti,
          NSObject aTarget,
          ffi.Pointer<ObjCSel> aSelector,
          NSObject userInfo,
          bool yesOrNo) {
    final _ret = _lib._objc_msgSend_489(
        _lib._class_NSTimer1,
        _lib._sel_scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_1,
        ti,
        aTarget._id,
        aSelector,
        userInfo._id,
        yesOrNo);
    return NSTimer._(_ret, _lib, retain: true, release: true);
  }

  static NSTimer timerWithTimeInterval_repeats_block_(
      AVFAudio _lib, double interval, bool repeats, ObjCBlock17 block) {
    final _ret = _lib._objc_msgSend_490(
        _lib._class_NSTimer1,
        _lib._sel_timerWithTimeInterval_repeats_block_1,
        interval,
        repeats,
        block._id);
    return NSTimer._(_ret, _lib, retain: true, release: true);
  }

  static NSTimer scheduledTimerWithTimeInterval_repeats_block_(
      AVFAudio _lib, double interval, bool repeats, ObjCBlock17 block) {
    final _ret = _lib._objc_msgSend_490(
        _lib._class_NSTimer1,
        _lib._sel_scheduledTimerWithTimeInterval_repeats_block_1,
        interval,
        repeats,
        block._id);
    return NSTimer._(_ret, _lib, retain: true, release: true);
  }

  NSTimer initWithFireDate_interval_repeats_block_(
      NSDate? date, double interval, bool repeats, ObjCBlock17 block) {
    final _ret = _lib._objc_msgSend_491(
        _id,
        _lib._sel_initWithFireDate_interval_repeats_block_1,
        date?._id ?? ffi.nullptr,
        interval,
        repeats,
        block._id);
    return NSTimer._(_ret, _lib, retain: true, release: true);
  }

  NSTimer initWithFireDate_interval_target_selector_userInfo_repeats_(
      NSDate? date,
      double ti,
      NSObject t,
      ffi.Pointer<ObjCSel> s,
      NSObject ui,
      bool rep) {
    final _ret = _lib._objc_msgSend_492(
        _id,
        _lib._sel_initWithFireDate_interval_target_selector_userInfo_repeats_1,
        date?._id ?? ffi.nullptr,
        ti,
        t._id,
        s,
        ui._id,
        rep);
    return NSTimer._(_ret, _lib, retain: true, release: true);
  }

  void fire() {
    return _lib._objc_msgSend_1(_id, _lib._sel_fire1);
  }

  NSDate? get fireDate {
    final _ret = _lib._objc_msgSend_156(_id, _lib._sel_fireDate1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  set fireDate(NSDate? value) {
    _lib._objc_msgSend_493(
        _id, _lib._sel_setFireDate_1, value?._id ?? ffi.nullptr);
  }

  double get timeInterval {
    return _lib._objc_msgSend_149(_id, _lib._sel_timeInterval1);
  }

  double get tolerance {
    return _lib._objc_msgSend_149(_id, _lib._sel_tolerance1);
  }

  set tolerance(double value) {
    _lib._objc_msgSend_474(_id, _lib._sel_setTolerance_1, value);
  }

  void invalidate() {
    return _lib._objc_msgSend_1(_id, _lib._sel_invalidate1);
  }

  bool get valid {
    return _lib._objc_msgSend_12(_id, _lib._sel_isValid1);
  }

  NSObject get userInfo {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_userInfo1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSTimer new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSTimer1, _lib._sel_new1);
    return NSTimer._(_ret, _lib, retain: false, release: true);
  }

  static NSTimer alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSTimer1, _lib._sel_alloc1);
    return NSTimer._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSTimer1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSTimer1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSTimer1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSTimer1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSTimer1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSTimer1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSTimer1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSTimer1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSTimer1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

void _ObjCBlock17_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>()
      .asFunction<void Function(ffi.Pointer<ObjCObject> arg0)>()(arg0);
}

final _ObjCBlock17_closureRegistry = <int, Function>{};
int _ObjCBlock17_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock17_registerClosure(Function fn) {
  final id = ++_ObjCBlock17_closureRegistryIndex;
  _ObjCBlock17_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock17_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return _ObjCBlock17_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock17 extends _ObjCBlockBase {
  ObjCBlock17._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock17.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi
              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock17_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock17.fromFunction(
      AVFAudio lib, void Function(ffi.Pointer<ObjCObject> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock17_closureTrampoline)
                    .cast(),
                _ObjCBlock17_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSConnection extends NSObject {
  NSConnection._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSConnection] that points to the same underlying object as [other].
  static NSConnection castFrom<T extends _ObjCWrapper>(T other) {
    return NSConnection._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSConnection] that wraps the given raw object pointer.
  static NSConnection castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSConnection._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSConnection].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSConnection1);
  }

  NSDictionary? get statistics {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_statistics1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSArray allConnections(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSConnection1, _lib._sel_allConnections1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSConnection defaultConnection(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_504(
        _lib._class_NSConnection1, _lib._sel_defaultConnection1);
    return NSConnection._(_ret, _lib, retain: true, release: true);
  }

  static NSConnection connectionWithRegisteredName_host_(
      AVFAudio _lib, NSString? name, NSString? hostName) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSConnection1,
        _lib._sel_connectionWithRegisteredName_host_1,
        name?._id ?? ffi.nullptr,
        hostName?._id ?? ffi.nullptr);
    return NSConnection._(_ret, _lib, retain: true, release: true);
  }

  static NSConnection connectionWithRegisteredName_host_usingNameServer_(
      AVFAudio _lib,
      NSString? name,
      NSString? hostName,
      NSPortNameServer? server) {
    final _ret = _lib._objc_msgSend_509(
        _lib._class_NSConnection1,
        _lib._sel_connectionWithRegisteredName_host_usingNameServer_1,
        name?._id ?? ffi.nullptr,
        hostName?._id ?? ffi.nullptr,
        server?._id ?? ffi.nullptr);
    return NSConnection._(_ret, _lib, retain: true, release: true);
  }

  static NSDistantObject rootProxyForConnectionWithRegisteredName_host_(
      AVFAudio _lib, NSString? name, NSString? hostName) {
    final _ret = _lib._objc_msgSend_512(
        _lib._class_NSConnection1,
        _lib._sel_rootProxyForConnectionWithRegisteredName_host_1,
        name?._id ?? ffi.nullptr,
        hostName?._id ?? ffi.nullptr);
    return NSDistantObject._(_ret, _lib, retain: true, release: true);
  }

  static NSDistantObject
      rootProxyForConnectionWithRegisteredName_host_usingNameServer_(
          AVFAudio _lib,
          NSString? name,
          NSString? hostName,
          NSPortNameServer? server) {
    final _ret = _lib._objc_msgSend_513(
        _lib._class_NSConnection1,
        _lib._sel_rootProxyForConnectionWithRegisteredName_host_usingNameServer_1,
        name?._id ?? ffi.nullptr,
        hostName?._id ?? ffi.nullptr,
        server?._id ?? ffi.nullptr);
    return NSDistantObject._(_ret, _lib, retain: true, release: true);
  }

  static NSConnection serviceConnectionWithName_rootObject_usingNameServer_(
      AVFAudio _lib, NSString? name, NSObject root, NSPortNameServer? server) {
    final _ret = _lib._objc_msgSend_514(
        _lib._class_NSConnection1,
        _lib._sel_serviceConnectionWithName_rootObject_usingNameServer_1,
        name?._id ?? ffi.nullptr,
        root._id,
        server?._id ?? ffi.nullptr);
    return NSConnection._(_ret, _lib, retain: true, release: true);
  }

  static NSConnection serviceConnectionWithName_rootObject_(
      AVFAudio _lib, NSString? name, NSObject root) {
    final _ret = _lib._objc_msgSend_157(
        _lib._class_NSConnection1,
        _lib._sel_serviceConnectionWithName_rootObject_1,
        name?._id ?? ffi.nullptr,
        root._id);
    return NSConnection._(_ret, _lib, retain: true, release: true);
  }

  double get requestTimeout {
    return _lib._objc_msgSend_149(_id, _lib._sel_requestTimeout1);
  }

  set requestTimeout(double value) {
    _lib._objc_msgSend_474(_id, _lib._sel_setRequestTimeout_1, value);
  }

  double get replyTimeout {
    return _lib._objc_msgSend_149(_id, _lib._sel_replyTimeout1);
  }

  set replyTimeout(double value) {
    _lib._objc_msgSend_474(_id, _lib._sel_setReplyTimeout_1, value);
  }

  NSObject get rootObject {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_rootObject1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  set rootObject(NSObject value) {
    _lib._objc_msgSend_368(_id, _lib._sel_setRootObject_1, value._id);
  }

  NSObject? get delegate {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_delegate1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  set delegate(NSObject? value) {
    _lib._objc_msgSend_368(
        _id, _lib._sel_setDelegate_1, value?._id ?? ffi.nullptr);
  }

  bool get independentConversationQueueing {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_independentConversationQueueing1);
  }

  set independentConversationQueueing(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setIndependentConversationQueueing_1, value);
  }

  bool get valid {
    return _lib._objc_msgSend_12(_id, _lib._sel_isValid1);
  }

  NSDistantObject? get rootProxy {
    final _ret = _lib._objc_msgSend_515(_id, _lib._sel_rootProxy1);
    return _ret.address == 0
        ? null
        : NSDistantObject._(_ret, _lib, retain: true, release: true);
  }

  void invalidate() {
    return _lib._objc_msgSend_1(_id, _lib._sel_invalidate1);
  }

  void addRequestMode_(NSString? rmode) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_addRequestMode_1, rmode?._id ?? ffi.nullptr);
  }

  void removeRequestMode_(NSString? rmode) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_removeRequestMode_1, rmode?._id ?? ffi.nullptr);
  }

  NSArray? get requestModes {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_requestModes1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  bool registerName_(NSString? name) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_registerName_1, name?._id ?? ffi.nullptr);
  }

  bool registerName_withNameServer_(NSString? name, NSPortNameServer? server) {
    return _lib._objc_msgSend_516(_id, _lib._sel_registerName_withNameServer_1,
        name?._id ?? ffi.nullptr, server?._id ?? ffi.nullptr);
  }

  static NSConnection connectionWithReceivePort_sendPort_(
      AVFAudio _lib, NSPort? receivePort, NSPort? sendPort) {
    final _ret = _lib._objc_msgSend_517(
        _lib._class_NSConnection1,
        _lib._sel_connectionWithReceivePort_sendPort_1,
        receivePort?._id ?? ffi.nullptr,
        sendPort?._id ?? ffi.nullptr);
    return NSConnection._(_ret, _lib, retain: true, release: true);
  }

  static NSObject currentConversation(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSConnection1, _lib._sel_currentConversation1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSConnection initWithReceivePort_sendPort_(
      NSPort? receivePort, NSPort? sendPort) {
    final _ret = _lib._objc_msgSend_517(
        _id,
        _lib._sel_initWithReceivePort_sendPort_1,
        receivePort?._id ?? ffi.nullptr,
        sendPort?._id ?? ffi.nullptr);
    return NSConnection._(_ret, _lib, retain: true, release: true);
  }

  NSPort? get sendPort {
    final _ret = _lib._objc_msgSend_485(_id, _lib._sel_sendPort1);
    return _ret.address == 0
        ? null
        : NSPort._(_ret, _lib, retain: true, release: true);
  }

  NSPort? get receivePort {
    final _ret = _lib._objc_msgSend_485(_id, _lib._sel_receivePort1);
    return _ret.address == 0
        ? null
        : NSPort._(_ret, _lib, retain: true, release: true);
  }

  void enableMultipleThreads() {
    return _lib._objc_msgSend_1(_id, _lib._sel_enableMultipleThreads1);
  }

  bool get multipleThreadsEnabled {
    return _lib._objc_msgSend_12(_id, _lib._sel_multipleThreadsEnabled1);
  }

  void addRunLoop_(NSRunLoop? runloop) {
    return _lib._objc_msgSend_518(
        _id, _lib._sel_addRunLoop_1, runloop?._id ?? ffi.nullptr);
  }

  void removeRunLoop_(NSRunLoop? runloop) {
    return _lib._objc_msgSend_518(
        _id, _lib._sel_removeRunLoop_1, runloop?._id ?? ffi.nullptr);
  }

  void runInNewThread() {
    return _lib._objc_msgSend_1(_id, _lib._sel_runInNewThread1);
  }

  NSArray? get remoteObjects {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_remoteObjects1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get localObjects {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_localObjects1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  void dispatchWithComponents_(NSArray? components) {
    return _lib._objc_msgSend_412(_id, _lib._sel_dispatchWithComponents_1,
        components?._id ?? ffi.nullptr);
  }

  static NSConnection new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSConnection1, _lib._sel_new1);
    return NSConnection._(_ret, _lib, retain: false, release: true);
  }

  static NSConnection alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSConnection1, _lib._sel_alloc1);
    return NSConnection._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSConnection1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSConnection1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSConnection1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSConnection1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSConnection1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSConnection1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSConnection1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSConnection1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSConnection1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSPortNameServer extends NSObject {
  NSPortNameServer._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSPortNameServer] that points to the same underlying object as [other].
  static NSPortNameServer castFrom<T extends _ObjCWrapper>(T other) {
    return NSPortNameServer._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSPortNameServer] that wraps the given raw object pointer.
  static NSPortNameServer castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSPortNameServer._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSPortNameServer].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSPortNameServer1);
  }

  static NSPortNameServer systemDefaultPortNameServer(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_505(
        _lib._class_NSPortNameServer1, _lib._sel_systemDefaultPortNameServer1);
    return NSPortNameServer._(_ret, _lib, retain: true, release: true);
  }

  NSPort portForName_(NSString? name) {
    final _ret = _lib._objc_msgSend_506(
        _id, _lib._sel_portForName_1, name?._id ?? ffi.nullptr);
    return NSPort._(_ret, _lib, retain: true, release: true);
  }

  NSPort portForName_host_(NSString? name, NSString? host) {
    final _ret = _lib._objc_msgSend_507(_id, _lib._sel_portForName_host_1,
        name?._id ?? ffi.nullptr, host?._id ?? ffi.nullptr);
    return NSPort._(_ret, _lib, retain: true, release: true);
  }

  bool registerPort_name_(NSPort? port, NSString? name) {
    return _lib._objc_msgSend_508(_id, _lib._sel_registerPort_name_1,
        port?._id ?? ffi.nullptr, name?._id ?? ffi.nullptr);
  }

  bool removePortForName_(NSString? name) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_removePortForName_1, name?._id ?? ffi.nullptr);
  }

  static NSPortNameServer new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSPortNameServer1, _lib._sel_new1);
    return NSPortNameServer._(_ret, _lib, retain: false, release: true);
  }

  static NSPortNameServer alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSPortNameServer1, _lib._sel_alloc1);
    return NSPortNameServer._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSPortNameServer1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSPortNameServer1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSPortNameServer1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSPortNameServer1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSPortNameServer1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSPortNameServer1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSPortNameServer1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSPortNameServer1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSPortNameServer1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSDistantObject extends NSProxy {
  NSDistantObject._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSDistantObject] that points to the same underlying object as [other].
  static NSDistantObject castFrom<T extends _ObjCWrapper>(T other) {
    return NSDistantObject._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSDistantObject] that wraps the given raw object pointer.
  static NSDistantObject castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSDistantObject._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSDistantObject].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSDistantObject1);
  }

  static NSObject proxyWithTarget_connection_(
      AVFAudio _lib, NSObject target, NSConnection? connection) {
    final _ret = _lib._objc_msgSend_510(
        _lib._class_NSDistantObject1,
        _lib._sel_proxyWithTarget_connection_1,
        target._id,
        connection?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSDistantObject initWithTarget_connection_(
      NSObject target, NSConnection? connection) {
    final _ret = _lib._objc_msgSend_510(
        _id,
        _lib._sel_initWithTarget_connection_1,
        target._id,
        connection?._id ?? ffi.nullptr);
    return NSDistantObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject proxyWithLocal_connection_(
      AVFAudio _lib, NSObject target, NSConnection? connection) {
    final _ret = _lib._objc_msgSend_510(
        _lib._class_NSDistantObject1,
        _lib._sel_proxyWithLocal_connection_1,
        target._id,
        connection?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSDistantObject initWithLocal_connection_(
      NSObject target, NSConnection? connection) {
    final _ret = _lib._objc_msgSend_510(
        _id,
        _lib._sel_initWithLocal_connection_1,
        target._id,
        connection?._id ?? ffi.nullptr);
    return NSDistantObject._(_ret, _lib, retain: true, release: true);
  }

  NSDistantObject initWithCoder_(NSCoder? inCoder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, inCoder?._id ?? ffi.nullptr);
    return NSDistantObject._(_ret, _lib, retain: true, release: true);
  }

  void setProtocolForProxy_(Protocol? proto) {
    return _lib._objc_msgSend_511(
        _id, _lib._sel_setProtocolForProxy_1, proto?._id ?? ffi.nullptr);
  }

  NSConnection? get connectionForProxy {
    final _ret = _lib._objc_msgSend_504(_id, _lib._sel_connectionForProxy1);
    return _ret.address == 0
        ? null
        : NSConnection._(_ret, _lib, retain: true, release: true);
  }

  static NSObject alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSDistantObject1, _lib._sel_alloc1);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  static bool respondsToSelector_(
      AVFAudio _lib, ffi.Pointer<ObjCSel> aSelector) {
    return _lib._objc_msgSend_4(_lib._class_NSDistantObject1,
        _lib._sel_respondsToSelector_1, aSelector);
  }
}

class NSProxy extends _ObjCWrapper {
  NSProxy._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSProxy] that points to the same underlying object as [other].
  static NSProxy castFrom<T extends _ObjCWrapper>(T other) {
    return NSProxy._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSProxy] that wraps the given raw object pointer.
  static NSProxy castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSProxy._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSProxy].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSProxy1);
  }

  static NSObject alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSProxy1, _lib._sel_alloc1);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  static NSObject allocWithZone_(AVFAudio _lib, ffi.Pointer<NSZone> zone) {
    final _ret = _lib._objc_msgSend_3(
        _lib._class_NSProxy1, _lib._sel_allocWithZone_1, zone);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  static NSObject class1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSProxy1, _lib._sel_class1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void forwardInvocation_(NSInvocation? invocation) {
    return _lib._objc_msgSend_372(
        _id, _lib._sel_forwardInvocation_1, invocation?._id ?? ffi.nullptr);
  }

  NSMethodSignature methodSignatureForSelector_(ffi.Pointer<ObjCSel> sel) {
    final _ret = _lib._objc_msgSend_373(
        _id, _lib._sel_methodSignatureForSelector_1, sel);
    return NSMethodSignature._(_ret, _lib, retain: true, release: true);
  }

  void dealloc() {
    return _lib._objc_msgSend_1(_id, _lib._sel_dealloc1);
  }

  void finalize() {
    return _lib._objc_msgSend_1(_id, _lib._sel_finalize1);
  }

  NSString? get description {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_description1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get debugDescription {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_debugDescription1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  static bool respondsToSelector_(
      AVFAudio _lib, ffi.Pointer<ObjCSel> aSelector) {
    return _lib._objc_msgSend_4(
        _lib._class_NSProxy1, _lib._sel_respondsToSelector_1, aSelector);
  }

  bool allowsWeakReference() {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsWeakReference1);
  }

  bool retainWeakReference() {
    return _lib._objc_msgSend_12(_id, _lib._sel_retainWeakReference1);
  }
}

class NSClassDescription extends NSObject {
  NSClassDescription._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSClassDescription] that points to the same underlying object as [other].
  static NSClassDescription castFrom<T extends _ObjCWrapper>(T other) {
    return NSClassDescription._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSClassDescription] that wraps the given raw object pointer.
  static NSClassDescription castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSClassDescription._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSClassDescription].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSClassDescription1);
  }

  static void registerClassDescription_forClass_(
      AVFAudio _lib, NSClassDescription? description, NSObject aClass) {
    return _lib._objc_msgSend_523(
        _lib._class_NSClassDescription1,
        _lib._sel_registerClassDescription_forClass_1,
        description?._id ?? ffi.nullptr,
        aClass._id);
  }

  static void invalidateClassDescriptionCache(AVFAudio _lib) {
    return _lib._objc_msgSend_1(_lib._class_NSClassDescription1,
        _lib._sel_invalidateClassDescriptionCache1);
  }

  static NSClassDescription classDescriptionForClass_(
      AVFAudio _lib, NSObject aClass) {
    final _ret = _lib._objc_msgSend_524(_lib._class_NSClassDescription1,
        _lib._sel_classDescriptionForClass_1, aClass._id);
    return NSClassDescription._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSArray? get attributeKeys {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_attributeKeys1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSArray? get toOneRelationshipKeys {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_toOneRelationshipKeys1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSArray? get toManyRelationshipKeys {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_toManyRelationshipKeys1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSString inverseForRelationshipKey_(NSString? relationshipKey) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_inverseForRelationshipKey_1,
        relationshipKey?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSClassDescription new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSClassDescription1, _lib._sel_new1);
    return NSClassDescription._(_ret, _lib, retain: false, release: true);
  }

  static NSClassDescription alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSClassDescription1, _lib._sel_alloc1);
    return NSClassDescription._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSClassDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSClassDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSClassDescription1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSClassDescription1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSClassDescription1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSClassDescription1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSClassDescription1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSClassDescription1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSClassDescription1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSScriptObjectSpecifier extends NSObject {
  NSScriptObjectSpecifier._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSScriptObjectSpecifier] that points to the same underlying object as [other].
  static NSScriptObjectSpecifier castFrom<T extends _ObjCWrapper>(T other) {
    return NSScriptObjectSpecifier._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSScriptObjectSpecifier] that wraps the given raw object pointer.
  static NSScriptObjectSpecifier castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSScriptObjectSpecifier._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSScriptObjectSpecifier].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSScriptObjectSpecifier1);
  }

  static NSScriptObjectSpecifier objectSpecifierWithDescriptor_(
      AVFAudio _lib, NSAppleEventDescriptor? descriptor) {
    final _ret = _lib._objc_msgSend_548(
        _lib._class_NSScriptObjectSpecifier1,
        _lib._sel_objectSpecifierWithDescriptor_1,
        descriptor?._id ?? ffi.nullptr);
    return NSScriptObjectSpecifier._(_ret, _lib, retain: true, release: true);
  }

  NSScriptObjectSpecifier initWithContainerSpecifier_key_(
      NSScriptObjectSpecifier? container, NSString? property) {
    final _ret = _lib._objc_msgSend_549(
        _id,
        _lib._sel_initWithContainerSpecifier_key_1,
        container?._id ?? ffi.nullptr,
        property?._id ?? ffi.nullptr);
    return NSScriptObjectSpecifier._(_ret, _lib, retain: true, release: true);
  }

  NSScriptObjectSpecifier
      initWithContainerClassDescription_containerSpecifier_key_(
          NSScriptClassDescription? classDesc,
          NSScriptObjectSpecifier? container,
          NSString? property) {
    final _ret = _lib._objc_msgSend_566(
        _id,
        _lib._sel_initWithContainerClassDescription_containerSpecifier_key_1,
        classDesc?._id ?? ffi.nullptr,
        container?._id ?? ffi.nullptr,
        property?._id ?? ffi.nullptr);
    return NSScriptObjectSpecifier._(_ret, _lib, retain: true, release: true);
  }

  NSScriptObjectSpecifier initWithCoder_(NSCoder? inCoder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, inCoder?._id ?? ffi.nullptr);
    return NSScriptObjectSpecifier._(_ret, _lib, retain: true, release: true);
  }

  NSScriptObjectSpecifier? get childSpecifier {
    final _ret = _lib._objc_msgSend_556(_id, _lib._sel_childSpecifier1);
    return _ret.address == 0
        ? null
        : NSScriptObjectSpecifier._(_ret, _lib, retain: true, release: true);
  }

  set childSpecifier(NSScriptObjectSpecifier? value) {
    _lib._objc_msgSend_557(
        _id, _lib._sel_setChildSpecifier_1, value?._id ?? ffi.nullptr);
  }

  NSScriptObjectSpecifier? get containerSpecifier {
    final _ret = _lib._objc_msgSend_556(_id, _lib._sel_containerSpecifier1);
    return _ret.address == 0
        ? null
        : NSScriptObjectSpecifier._(_ret, _lib, retain: true, release: true);
  }

  set containerSpecifier(NSScriptObjectSpecifier? value) {
    _lib._objc_msgSend_557(
        _id, _lib._sel_setContainerSpecifier_1, value?._id ?? ffi.nullptr);
  }

  bool get containerIsObjectBeingTested {
    return _lib._objc_msgSend_12(_id, _lib._sel_containerIsObjectBeingTested1);
  }

  set containerIsObjectBeingTested(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setContainerIsObjectBeingTested_1, value);
  }

  bool get containerIsRangeContainerObject {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_containerIsRangeContainerObject1);
  }

  set containerIsRangeContainerObject(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setContainerIsRangeContainerObject_1, value);
  }

  NSString? get key {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_key1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set key(NSString? value) {
    _lib._objc_msgSend_477(_id, _lib._sel_setKey_1, value?._id ?? ffi.nullptr);
  }

  NSScriptClassDescription? get containerClassDescription {
    final _ret =
        _lib._objc_msgSend_552(_id, _lib._sel_containerClassDescription1);
    return _ret.address == 0
        ? null
        : NSScriptClassDescription._(_ret, _lib, retain: true, release: true);
  }

  set containerClassDescription(NSScriptClassDescription? value) {
    _lib._objc_msgSend_567(_id, _lib._sel_setContainerClassDescription_1,
        value?._id ?? ffi.nullptr);
  }

  NSScriptClassDescription? get keyClassDescription {
    final _ret = _lib._objc_msgSend_552(_id, _lib._sel_keyClassDescription1);
    return _ret.address == 0
        ? null
        : NSScriptClassDescription._(_ret, _lib, retain: true, release: true);
  }

  ffi.Pointer<NSInteger> indicesOfObjectsByEvaluatingWithContainer_count_(
      NSObject container, ffi.Pointer<NSInteger> count) {
    return _lib._objc_msgSend_568(
        _id,
        _lib._sel_indicesOfObjectsByEvaluatingWithContainer_count_1,
        container._id,
        count);
  }

  NSObject objectsByEvaluatingWithContainers_(NSObject containers) {
    final _ret = _lib._objc_msgSend_16(
        _id, _lib._sel_objectsByEvaluatingWithContainers_1, containers._id);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject get objectsByEvaluatingSpecifier {
    final _ret =
        _lib._objc_msgSend_2(_id, _lib._sel_objectsByEvaluatingSpecifier1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  int get evaluationErrorNumber {
    return _lib._objc_msgSend_78(_id, _lib._sel_evaluationErrorNumber1);
  }

  set evaluationErrorNumber(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setEvaluationErrorNumber_1, value);
  }

  NSScriptObjectSpecifier? get evaluationErrorSpecifier {
    final _ret =
        _lib._objc_msgSend_556(_id, _lib._sel_evaluationErrorSpecifier1);
    return _ret.address == 0
        ? null
        : NSScriptObjectSpecifier._(_ret, _lib, retain: true, release: true);
  }

  NSAppleEventDescriptor? get descriptor {
    final _ret = _lib._objc_msgSend_526(_id, _lib._sel_descriptor1);
    return _ret.address == 0
        ? null
        : NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSScriptObjectSpecifier new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSScriptObjectSpecifier1, _lib._sel_new1);
    return NSScriptObjectSpecifier._(_ret, _lib, retain: false, release: true);
  }

  static NSScriptObjectSpecifier alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSScriptObjectSpecifier1, _lib._sel_alloc1);
    return NSScriptObjectSpecifier._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSScriptObjectSpecifier1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSScriptObjectSpecifier1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSScriptObjectSpecifier1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSScriptObjectSpecifier1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSScriptObjectSpecifier1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSScriptObjectSpecifier1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSScriptObjectSpecifier1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSScriptObjectSpecifier1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSScriptObjectSpecifier1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSAppleEventDescriptor extends NSObject {
  NSAppleEventDescriptor._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSAppleEventDescriptor] that points to the same underlying object as [other].
  static NSAppleEventDescriptor castFrom<T extends _ObjCWrapper>(T other) {
    return NSAppleEventDescriptor._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSAppleEventDescriptor] that wraps the given raw object pointer.
  static NSAppleEventDescriptor castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSAppleEventDescriptor._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSAppleEventDescriptor].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSAppleEventDescriptor1);
  }

  static NSAppleEventDescriptor nullDescriptor(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_526(
        _lib._class_NSAppleEventDescriptor1, _lib._sel_nullDescriptor1);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithDescriptorType_bytes_length_(
      AVFAudio _lib,
      int descriptorType,
      ffi.Pointer<ffi.Void> bytes,
      int byteCount) {
    final _ret = _lib._objc_msgSend_527(
        _lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithDescriptorType_bytes_length_1,
        descriptorType,
        bytes,
        byteCount);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithDescriptorType_data_(
      AVFAudio _lib, int descriptorType, NSData? data) {
    final _ret = _lib._objc_msgSend_528(
        _lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithDescriptorType_data_1,
        descriptorType,
        data?._id ?? ffi.nullptr);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithBoolean_(
      AVFAudio _lib, int boolean) {
    final _ret = _lib._objc_msgSend_529(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithBoolean_1, boolean);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithEnumCode_(
      AVFAudio _lib, int enumerator) {
    final _ret = _lib._objc_msgSend_530(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithEnumCode_1, enumerator);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithInt32_(
      AVFAudio _lib, int signedInt) {
    final _ret = _lib._objc_msgSend_531(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithInt32_1, signedInt);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithDouble_(
      AVFAudio _lib, double doubleValue) {
    final _ret = _lib._objc_msgSend_532(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithDouble_1, doubleValue);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithTypeCode_(
      AVFAudio _lib, int typeCode) {
    final _ret = _lib._objc_msgSend_530(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithTypeCode_1, typeCode);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithString_(
      AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_533(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithString_1, string?._id ?? ffi.nullptr);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithDate_(
      AVFAudio _lib, NSDate? date) {
    final _ret = _lib._objc_msgSend_534(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithDate_1, date?._id ?? ffi.nullptr);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithFileURL_(
      AVFAudio _lib, NSURL? fileURL) {
    final _ret = _lib._objc_msgSend_535(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithFileURL_1, fileURL?._id ?? ffi.nullptr);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor
      appleEventWithEventClass_eventID_targetDescriptor_returnID_transactionID_(
          AVFAudio _lib,
          int eventClass,
          int eventID,
          NSAppleEventDescriptor? targetDescriptor,
          int returnID,
          int transactionID) {
    final _ret = _lib._objc_msgSend_536(
        _lib._class_NSAppleEventDescriptor1,
        _lib._sel_appleEventWithEventClass_eventID_targetDescriptor_returnID_transactionID_1,
        eventClass,
        eventID,
        targetDescriptor?._id ?? ffi.nullptr,
        returnID,
        transactionID);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor listDescriptor(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_526(
        _lib._class_NSAppleEventDescriptor1, _lib._sel_listDescriptor1);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor recordDescriptor(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_526(
        _lib._class_NSAppleEventDescriptor1, _lib._sel_recordDescriptor1);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor currentProcessDescriptor(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_526(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_currentProcessDescriptor1);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithProcessIdentifier_(
      AVFAudio _lib, int processIdentifier) {
    final _ret = _lib._objc_msgSend_531(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithProcessIdentifier_1, processIdentifier);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithBundleIdentifier_(
      AVFAudio _lib, NSString? bundleIdentifier) {
    final _ret = _lib._objc_msgSend_533(
        _lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithBundleIdentifier_1,
        bundleIdentifier?._id ?? ffi.nullptr);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor descriptorWithApplicationURL_(
      AVFAudio _lib, NSURL? applicationURL) {
    final _ret = _lib._objc_msgSend_535(
        _lib._class_NSAppleEventDescriptor1,
        _lib._sel_descriptorWithApplicationURL_1,
        applicationURL?._id ?? ffi.nullptr);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  NSAppleEventDescriptor initWithAEDescNoCopy_(ffi.Pointer<AEDesc> aeDesc) {
    final _ret =
        _lib._objc_msgSend_537(_id, _lib._sel_initWithAEDescNoCopy_1, aeDesc);
    return NSAppleEventDescriptor._(_ret, _lib, retain: false, release: true);
  }

  NSAppleEventDescriptor initWithDescriptorType_bytes_length_(
      int descriptorType, ffi.Pointer<ffi.Void> bytes, int byteCount) {
    final _ret = _lib._objc_msgSend_538(
        _id,
        _lib._sel_initWithDescriptorType_bytes_length_1,
        descriptorType,
        bytes,
        byteCount);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  NSAppleEventDescriptor initWithDescriptorType_data_(
      int descriptorType, NSData? data) {
    final _ret = _lib._objc_msgSend_539(
        _id,
        _lib._sel_initWithDescriptorType_data_1,
        descriptorType,
        data?._id ?? ffi.nullptr);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  NSAppleEventDescriptor
      initWithEventClass_eventID_targetDescriptor_returnID_transactionID_(
          int eventClass,
          int eventID,
          NSAppleEventDescriptor? targetDescriptor,
          int returnID,
          int transactionID) {
    final _ret = _lib._objc_msgSend_540(
        _id,
        _lib._sel_initWithEventClass_eventID_targetDescriptor_returnID_transactionID_1,
        eventClass,
        eventID,
        targetDescriptor?._id ?? ffi.nullptr,
        returnID,
        transactionID);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  NSAppleEventDescriptor initListDescriptor() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_initListDescriptor1);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  NSAppleEventDescriptor initRecordDescriptor() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_initRecordDescriptor1);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  ffi.Pointer<AEDesc> get aeDesc {
    return _lib._objc_msgSend_541(_id, _lib._sel_aeDesc1);
  }

  int get descriptorType {
    return _lib._objc_msgSend_191(_id, _lib._sel_descriptorType1);
  }

  NSData? get data {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_data1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  int get booleanValue {
    return _lib._objc_msgSend_210(_id, _lib._sel_booleanValue1);
  }

  int get enumCodeValue {
    return _lib._objc_msgSend_191(_id, _lib._sel_enumCodeValue1);
  }

  int get int32Value {
    return _lib._objc_msgSend_213(_id, _lib._sel_int32Value1);
  }

  double get doubleValue {
    return _lib._objc_msgSend_149(_id, _lib._sel_doubleValue1);
  }

  int get typeCodeValue {
    return _lib._objc_msgSend_191(_id, _lib._sel_typeCodeValue1);
  }

  NSString? get stringValue {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_stringValue1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSDate? get dateValue {
    final _ret = _lib._objc_msgSend_156(_id, _lib._sel_dateValue1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get fileURLValue {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_fileURLValue1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  int get eventClass {
    return _lib._objc_msgSend_191(_id, _lib._sel_eventClass1);
  }

  int get eventID {
    return _lib._objc_msgSend_191(_id, _lib._sel_eventID1);
  }

  int get returnID {
    return _lib._objc_msgSend_211(_id, _lib._sel_returnID1);
  }

  int get transactionID {
    return _lib._objc_msgSend_213(_id, _lib._sel_transactionID1);
  }

  void setParamDescriptor_forKeyword_(
      NSAppleEventDescriptor? descriptor, int keyword) {
    return _lib._objc_msgSend_542(
        _id,
        _lib._sel_setParamDescriptor_forKeyword_1,
        descriptor?._id ?? ffi.nullptr,
        keyword);
  }

  NSAppleEventDescriptor paramDescriptorForKeyword_(int keyword) {
    final _ret = _lib._objc_msgSend_530(
        _id, _lib._sel_paramDescriptorForKeyword_1, keyword);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  void removeParamDescriptorWithKeyword_(int keyword) {
    return _lib._objc_msgSend_543(
        _id, _lib._sel_removeParamDescriptorWithKeyword_1, keyword);
  }

  void setAttributeDescriptor_forKeyword_(
      NSAppleEventDescriptor? descriptor, int keyword) {
    return _lib._objc_msgSend_542(
        _id,
        _lib._sel_setAttributeDescriptor_forKeyword_1,
        descriptor?._id ?? ffi.nullptr,
        keyword);
  }

  NSAppleEventDescriptor attributeDescriptorForKeyword_(int keyword) {
    final _ret = _lib._objc_msgSend_530(
        _id, _lib._sel_attributeDescriptorForKeyword_1, keyword);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  NSAppleEventDescriptor sendEventWithOptions_timeout_error_(int sendOptions,
      double timeoutInSeconds, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_544(
        _id,
        _lib._sel_sendEventWithOptions_timeout_error_1,
        sendOptions,
        timeoutInSeconds,
        error);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  bool get isRecordDescriptor {
    return _lib._objc_msgSend_12(_id, _lib._sel_isRecordDescriptor1);
  }

  int get numberOfItems {
    return _lib._objc_msgSend_78(_id, _lib._sel_numberOfItems1);
  }

  void insertDescriptor_atIndex_(
      NSAppleEventDescriptor? descriptor, int index) {
    return _lib._objc_msgSend_545(_id, _lib._sel_insertDescriptor_atIndex_1,
        descriptor?._id ?? ffi.nullptr, index);
  }

  NSAppleEventDescriptor descriptorAtIndex_(int index) {
    final _ret =
        _lib._objc_msgSend_546(_id, _lib._sel_descriptorAtIndex_1, index);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  void removeDescriptorAtIndex_(int index) {
    return _lib._objc_msgSend_374(
        _id, _lib._sel_removeDescriptorAtIndex_1, index);
  }

  void setDescriptor_forKeyword_(
      NSAppleEventDescriptor? descriptor, int keyword) {
    return _lib._objc_msgSend_542(_id, _lib._sel_setDescriptor_forKeyword_1,
        descriptor?._id ?? ffi.nullptr, keyword);
  }

  NSAppleEventDescriptor descriptorForKeyword_(int keyword) {
    final _ret =
        _lib._objc_msgSend_530(_id, _lib._sel_descriptorForKeyword_1, keyword);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  void removeDescriptorWithKeyword_(int keyword) {
    return _lib._objc_msgSend_543(
        _id, _lib._sel_removeDescriptorWithKeyword_1, keyword);
  }

  int keywordForDescriptorAtIndex_(int index) {
    return _lib._objc_msgSend_547(
        _id, _lib._sel_keywordForDescriptorAtIndex_1, index);
  }

  NSAppleEventDescriptor coerceToDescriptorType_(int descriptorType) {
    final _ret = _lib._objc_msgSend_530(
        _id, _lib._sel_coerceToDescriptorType_1, descriptorType);
    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  static NSAppleEventDescriptor new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSAppleEventDescriptor1, _lib._sel_new1);
    return NSAppleEventDescriptor._(_ret, _lib, retain: false, release: true);
  }

  static NSAppleEventDescriptor alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSAppleEventDescriptor1, _lib._sel_alloc1);
    return NSAppleEventDescriptor._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSAppleEventDescriptor1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSAppleEventDescriptor1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSAppleEventDescriptor1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSAppleEventDescriptor1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSAppleEventDescriptor1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSAppleEventDescriptor1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef DescType = ResType;
typedef ResType = FourCharCode;
typedef Boolean = ffi.UnsignedChar;
typedef SInt32 = ffi.Int;
typedef AEEventClass = FourCharCode;
typedef AEEventID = FourCharCode;
typedef AEReturnID = SInt16;
typedef SInt16 = ffi.Short;
typedef AETransactionID = SInt32;
typedef pid_t = __darwin_pid_t;
typedef __darwin_pid_t = __int32_t;
typedef __int32_t = ffi.Int;

@ffi.Packed(2)
final class AEDesc extends ffi.Struct {
  @DescType()
  external int descriptorType;

  external AEDataStorage dataHandle;
}

typedef AEDataStorage = ffi.Pointer<AEDataStorageType>;
typedef AEDataStorageType = ffi.Pointer<OpaqueAEDataStorageType>;

final class OpaqueAEDataStorageType extends ffi.Opaque {}

typedef AEKeyword = FourCharCode;

abstract class NSAppleEventSendOptions {
  static const int NSAppleEventSendNoReply = 1;
  static const int NSAppleEventSendQueueReply = 2;
  static const int NSAppleEventSendWaitForReply = 3;
  static const int NSAppleEventSendNeverInteract = 16;
  static const int NSAppleEventSendCanInteract = 32;
  static const int NSAppleEventSendAlwaysInteract = 48;
  static const int NSAppleEventSendCanSwitchLayer = 64;
  static const int NSAppleEventSendDontRecord = 4096;
  static const int NSAppleEventSendDontExecute = 8192;
  static const int NSAppleEventSendDontAnnotate = 65536;
  static const int NSAppleEventSendDefaultOptions = 35;
}

class NSScriptClassDescription extends NSClassDescription {
  NSScriptClassDescription._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSScriptClassDescription] that points to the same underlying object as [other].
  static NSScriptClassDescription castFrom<T extends _ObjCWrapper>(T other) {
    return NSScriptClassDescription._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSScriptClassDescription] that wraps the given raw object pointer.
  static NSScriptClassDescription castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSScriptClassDescription._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSScriptClassDescription].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSScriptClassDescription1);
  }

  static NSScriptClassDescription classDescriptionForClass_(
      AVFAudio _lib, NSObject aClass) {
    final _ret = _lib._objc_msgSend_550(_lib._class_NSScriptClassDescription1,
        _lib._sel_classDescriptionForClass_1, aClass._id);
    return NSScriptClassDescription._(_ret, _lib, retain: true, release: true);
  }

  NSScriptClassDescription initWithSuiteName_className_dictionary_(
      NSString? suiteName,
      NSString? className,
      NSDictionary? classDeclaration) {
    final _ret = _lib._objc_msgSend_551(
        _id,
        _lib._sel_initWithSuiteName_className_dictionary_1,
        suiteName?._id ?? ffi.nullptr,
        className?._id ?? ffi.nullptr,
        classDeclaration?._id ?? ffi.nullptr);
    return NSScriptClassDescription._(_ret, _lib, retain: true, release: true);
  }

  NSString? get suiteName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_suiteName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get className {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_className1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get implementationClassName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_implementationClassName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSScriptClassDescription? get superclassDescription {
    final _ret = _lib._objc_msgSend_552(_id, _lib._sel_superclassDescription1);
    return _ret.address == 0
        ? null
        : NSScriptClassDescription._(_ret, _lib, retain: true, release: true);
  }

  int get appleEventCode {
    return _lib._objc_msgSend_191(_id, _lib._sel_appleEventCode1);
  }

  bool matchesAppleEventCode_(int appleEventCode) {
    return _lib._objc_msgSend_173(
        _id, _lib._sel_matchesAppleEventCode_1, appleEventCode);
  }

  bool supportsCommand_(NSScriptCommandDescription? commandDescription) {
    return _lib._objc_msgSend_562(_id, _lib._sel_supportsCommand_1,
        commandDescription?._id ?? ffi.nullptr);
  }

  ffi.Pointer<ObjCSel> selectorForCommand_(
      NSScriptCommandDescription? commandDescription) {
    return _lib._objc_msgSend_563(_id, _lib._sel_selectorForCommand_1,
        commandDescription?._id ?? ffi.nullptr);
  }

  NSString typeForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_64(
        _id, _lib._sel_typeForKey_1, key?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSScriptClassDescription classDescriptionForKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_564(
        _id, _lib._sel_classDescriptionForKey_1, key?._id ?? ffi.nullptr);
    return NSScriptClassDescription._(_ret, _lib, retain: true, release: true);
  }

  int appleEventCodeForKey_(NSString? key) {
    return _lib._objc_msgSend_553(
        _id, _lib._sel_appleEventCodeForKey_1, key?._id ?? ffi.nullptr);
  }

  NSString keyWithAppleEventCode_(int appleEventCode) {
    final _ret = _lib._objc_msgSend_565(
        _id, _lib._sel_keyWithAppleEventCode_1, appleEventCode);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get defaultSubcontainerAttributeKey {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_defaultSubcontainerAttributeKey1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  bool isLocationRequiredToCreateForKey_(NSString? toManyRelationshipKey) {
    return _lib._objc_msgSend_59(
        _id,
        _lib._sel_isLocationRequiredToCreateForKey_1,
        toManyRelationshipKey?._id ?? ffi.nullptr);
  }

  bool hasPropertyForKey_(NSString? key) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_hasPropertyForKey_1, key?._id ?? ffi.nullptr);
  }

  bool hasOrderedToManyRelationshipForKey_(NSString? key) {
    return _lib._objc_msgSend_59(
        _id,
        _lib._sel_hasOrderedToManyRelationshipForKey_1,
        key?._id ?? ffi.nullptr);
  }

  bool hasReadablePropertyForKey_(NSString? key) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_hasReadablePropertyForKey_1, key?._id ?? ffi.nullptr);
  }

  bool hasWritablePropertyForKey_(NSString? key) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_hasWritablePropertyForKey_1, key?._id ?? ffi.nullptr);
  }

  bool isReadOnlyKey_(NSString? key) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_isReadOnlyKey_1, key?._id ?? ffi.nullptr);
  }

  static void registerClassDescription_forClass_(
      AVFAudio _lib, NSClassDescription? description, NSObject aClass) {
    return _lib._objc_msgSend_523(
        _lib._class_NSScriptClassDescription1,
        _lib._sel_registerClassDescription_forClass_1,
        description?._id ?? ffi.nullptr,
        aClass._id);
  }

  static void invalidateClassDescriptionCache(AVFAudio _lib) {
    return _lib._objc_msgSend_1(_lib._class_NSScriptClassDescription1,
        _lib._sel_invalidateClassDescriptionCache1);
  }

  static NSScriptClassDescription new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSScriptClassDescription1, _lib._sel_new1);
    return NSScriptClassDescription._(_ret, _lib, retain: false, release: true);
  }

  static NSScriptClassDescription alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSScriptClassDescription1, _lib._sel_alloc1);
    return NSScriptClassDescription._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSScriptClassDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSScriptClassDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSScriptClassDescription1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSScriptClassDescription1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSScriptClassDescription1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSScriptClassDescription1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSScriptClassDescription1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSScriptClassDescription1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSScriptClassDescription1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSScriptCommandDescription extends NSObject {
  NSScriptCommandDescription._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSScriptCommandDescription] that points to the same underlying object as [other].
  static NSScriptCommandDescription castFrom<T extends _ObjCWrapper>(T other) {
    return NSScriptCommandDescription._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSScriptCommandDescription] that wraps the given raw object pointer.
  static NSScriptCommandDescription castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSScriptCommandDescription._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSScriptCommandDescription].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSScriptCommandDescription1);
  }

  @override
  NSObject init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSScriptCommandDescription initWithSuiteName_commandName_dictionary_(
      NSString? suiteName,
      NSString? commandName,
      NSDictionary? commandDeclaration) {
    final _ret = _lib._objc_msgSend_551(
        _id,
        _lib._sel_initWithSuiteName_commandName_dictionary_1,
        suiteName?._id ?? ffi.nullptr,
        commandName?._id ?? ffi.nullptr,
        commandDeclaration?._id ?? ffi.nullptr);
    return NSScriptCommandDescription._(_ret, _lib,
        retain: true, release: true);
  }

  NSScriptCommandDescription initWithCoder_(NSCoder? inCoder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, inCoder?._id ?? ffi.nullptr);
    return NSScriptCommandDescription._(_ret, _lib,
        retain: true, release: true);
  }

  NSString? get suiteName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_suiteName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get commandName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_commandName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get appleEventClassCode {
    return _lib._objc_msgSend_191(_id, _lib._sel_appleEventClassCode1);
  }

  int get appleEventCode {
    return _lib._objc_msgSend_191(_id, _lib._sel_appleEventCode1);
  }

  NSString? get commandClassName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_commandClassName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get returnType {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_returnType1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get appleEventCodeForReturnType {
    return _lib._objc_msgSend_191(_id, _lib._sel_appleEventCodeForReturnType1);
  }

  NSArray? get argumentNames {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_argumentNames1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString typeForArgumentWithName_(NSString? argumentName) {
    final _ret = _lib._objc_msgSend_64(_id, _lib._sel_typeForArgumentWithName_1,
        argumentName?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  int appleEventCodeForArgumentWithName_(NSString? argumentName) {
    return _lib._objc_msgSend_553(
        _id,
        _lib._sel_appleEventCodeForArgumentWithName_1,
        argumentName?._id ?? ffi.nullptr);
  }

  bool isOptionalArgumentWithName_(NSString? argumentName) {
    return _lib._objc_msgSend_59(_id, _lib._sel_isOptionalArgumentWithName_1,
        argumentName?._id ?? ffi.nullptr);
  }

  NSScriptCommand createCommandInstance() {
    final _ret = _lib._objc_msgSend_560(_id, _lib._sel_createCommandInstance1);
    return NSScriptCommand._(_ret, _lib, retain: true, release: true);
  }

  NSScriptCommand createCommandInstanceWithZone_(ffi.Pointer<NSZone> zone) {
    final _ret = _lib._objc_msgSend_561(
        _id, _lib._sel_createCommandInstanceWithZone_1, zone);
    return NSScriptCommand._(_ret, _lib, retain: true, release: true);
  }

  static NSScriptCommandDescription new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSScriptCommandDescription1, _lib._sel_new1);
    return NSScriptCommandDescription._(_ret, _lib,
        retain: false, release: true);
  }

  static NSScriptCommandDescription alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSScriptCommandDescription1, _lib._sel_alloc1);
    return NSScriptCommandDescription._(_ret, _lib,
        retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSScriptCommandDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSScriptCommandDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSScriptCommandDescription1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSScriptCommandDescription1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSScriptCommandDescription1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSScriptCommandDescription1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSScriptCommandDescription1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSScriptCommandDescription1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSScriptCommandDescription1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSScriptCommand extends NSObject {
  NSScriptCommand._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSScriptCommand] that points to the same underlying object as [other].
  static NSScriptCommand castFrom<T extends _ObjCWrapper>(T other) {
    return NSScriptCommand._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSScriptCommand] that wraps the given raw object pointer.
  static NSScriptCommand castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSScriptCommand._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSScriptCommand].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSScriptCommand1);
  }

  NSScriptCommand initWithCommandDescription_(
      NSScriptCommandDescription? commandDef) {
    final _ret = _lib._objc_msgSend_554(_id,
        _lib._sel_initWithCommandDescription_1, commandDef?._id ?? ffi.nullptr);
    return NSScriptCommand._(_ret, _lib, retain: true, release: true);
  }

  NSScriptCommand initWithCoder_(NSCoder? inCoder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, inCoder?._id ?? ffi.nullptr);
    return NSScriptCommand._(_ret, _lib, retain: true, release: true);
  }

  NSScriptCommandDescription? get commandDescription {
    final _ret = _lib._objc_msgSend_555(_id, _lib._sel_commandDescription1);
    return _ret.address == 0
        ? null
        : NSScriptCommandDescription._(_ret, _lib, retain: true, release: true);
  }

  NSObject get directParameter {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_directParameter1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  set directParameter(NSObject value) {
    _lib._objc_msgSend_368(_id, _lib._sel_setDirectParameter_1, value._id);
  }

  NSScriptObjectSpecifier? get receiversSpecifier {
    final _ret = _lib._objc_msgSend_556(_id, _lib._sel_receiversSpecifier1);
    return _ret.address == 0
        ? null
        : NSScriptObjectSpecifier._(_ret, _lib, retain: true, release: true);
  }

  set receiversSpecifier(NSScriptObjectSpecifier? value) {
    _lib._objc_msgSend_557(
        _id, _lib._sel_setReceiversSpecifier_1, value?._id ?? ffi.nullptr);
  }

  NSObject get evaluatedReceivers {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_evaluatedReceivers1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get arguments {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_arguments1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set arguments(NSDictionary? value) {
    _lib._objc_msgSend_165(
        _id, _lib._sel_setArguments_1, value?._id ?? ffi.nullptr);
  }

  NSDictionary? get evaluatedArguments {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_evaluatedArguments1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  bool get wellFormed {
    return _lib._objc_msgSend_12(_id, _lib._sel_isWellFormed1);
  }

  NSObject performDefaultImplementation() {
    final _ret =
        _lib._objc_msgSend_2(_id, _lib._sel_performDefaultImplementation1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject executeCommand() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_executeCommand1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  int get scriptErrorNumber {
    return _lib._objc_msgSend_78(_id, _lib._sel_scriptErrorNumber1);
  }

  set scriptErrorNumber(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setScriptErrorNumber_1, value);
  }

  NSAppleEventDescriptor? get scriptErrorOffendingObjectDescriptor {
    final _ret = _lib._objc_msgSend_526(
        _id, _lib._sel_scriptErrorOffendingObjectDescriptor1);
    return _ret.address == 0
        ? null
        : NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  set scriptErrorOffendingObjectDescriptor(NSAppleEventDescriptor? value) {
    _lib._objc_msgSend_559(
        _id,
        _lib._sel_setScriptErrorOffendingObjectDescriptor_1,
        value?._id ?? ffi.nullptr);
  }

  NSAppleEventDescriptor? get scriptErrorExpectedTypeDescriptor {
    final _ret = _lib._objc_msgSend_526(
        _id, _lib._sel_scriptErrorExpectedTypeDescriptor1);
    return _ret.address == 0
        ? null
        : NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  set scriptErrorExpectedTypeDescriptor(NSAppleEventDescriptor? value) {
    _lib._objc_msgSend_559(
        _id,
        _lib._sel_setScriptErrorExpectedTypeDescriptor_1,
        value?._id ?? ffi.nullptr);
  }

  NSString? get scriptErrorString {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_scriptErrorString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set scriptErrorString(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setScriptErrorString_1, value?._id ?? ffi.nullptr);
  }

  static NSScriptCommand currentCommand(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_560(
        _lib._class_NSScriptCommand1, _lib._sel_currentCommand1);
    return NSScriptCommand._(_ret, _lib, retain: true, release: true);
  }

  NSAppleEventDescriptor? get appleEvent {
    final _ret = _lib._objc_msgSend_526(_id, _lib._sel_appleEvent1);
    return _ret.address == 0
        ? null
        : NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
  }

  void suspendExecution() {
    return _lib._objc_msgSend_1(_id, _lib._sel_suspendExecution1);
  }

  void resumeExecutionWithResult_(NSObject result) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_resumeExecutionWithResult_1, result._id);
  }

  static NSScriptCommand new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSScriptCommand1, _lib._sel_new1);
    return NSScriptCommand._(_ret, _lib, retain: false, release: true);
  }

  static NSScriptCommand alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSScriptCommand1, _lib._sel_alloc1);
    return NSScriptCommand._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSScriptCommand1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSScriptCommand1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSScriptCommand1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSScriptCommand1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSScriptCommand1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSScriptCommand1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSScriptCommand1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSScriptCommand1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSScriptCommand1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSItemProvider extends NSObject {
  NSItemProvider._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSItemProvider] that points to the same underlying object as [other].
  static NSItemProvider castFrom<T extends _ObjCWrapper>(T other) {
    return NSItemProvider._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSItemProvider] that wraps the given raw object pointer.
  static NSItemProvider castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSItemProvider._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSItemProvider].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSItemProvider1);
  }

  @override
  NSItemProvider init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSItemProvider._(_ret, _lib, retain: true, release: true);
  }

  void registerDataRepresentationForTypeIdentifier_visibility_loadHandler_(
      NSString? typeIdentifier, int visibility, ObjCBlock18 loadHandler) {
    return _lib._objc_msgSend_588(
        _id,
        _lib._sel_registerDataRepresentationForTypeIdentifier_visibility_loadHandler_1,
        typeIdentifier?._id ?? ffi.nullptr,
        visibility,
        loadHandler._id);
  }

  void
      registerFileRepresentationForTypeIdentifier_fileOptions_visibility_loadHandler_(
          NSString? typeIdentifier,
          int fileOptions,
          int visibility,
          ObjCBlock20 loadHandler) {
    return _lib._objc_msgSend_589(
        _id,
        _lib._sel_registerFileRepresentationForTypeIdentifier_fileOptions_visibility_loadHandler_1,
        typeIdentifier?._id ?? ffi.nullptr,
        fileOptions,
        visibility,
        loadHandler._id);
  }

  NSArray? get registeredTypeIdentifiers {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_registeredTypeIdentifiers1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray registeredTypeIdentifiersWithFileOptions_(int fileOptions) {
    final _ret = _lib._objc_msgSend_590(
        _id, _lib._sel_registeredTypeIdentifiersWithFileOptions_1, fileOptions);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  bool hasItemConformingToTypeIdentifier_(NSString? typeIdentifier) {
    return _lib._objc_msgSend_59(
        _id,
        _lib._sel_hasItemConformingToTypeIdentifier_1,
        typeIdentifier?._id ?? ffi.nullptr);
  }

  bool hasRepresentationConformingToTypeIdentifier_fileOptions_(
      NSString? typeIdentifier, int fileOptions) {
    return _lib._objc_msgSend_591(
        _id,
        _lib._sel_hasRepresentationConformingToTypeIdentifier_fileOptions_1,
        typeIdentifier?._id ?? ffi.nullptr,
        fileOptions);
  }

  NSProgress loadDataRepresentationForTypeIdentifier_completionHandler_(
      NSString? typeIdentifier, ObjCBlock19 completionHandler) {
    final _ret = _lib._objc_msgSend_592(
        _id,
        _lib._sel_loadDataRepresentationForTypeIdentifier_completionHandler_1,
        typeIdentifier?._id ?? ffi.nullptr,
        completionHandler._id);
    return NSProgress._(_ret, _lib, retain: true, release: true);
  }

  NSProgress loadFileRepresentationForTypeIdentifier_completionHandler_(
      NSString? typeIdentifier, ObjCBlock22 completionHandler) {
    final _ret = _lib._objc_msgSend_593(
        _id,
        _lib._sel_loadFileRepresentationForTypeIdentifier_completionHandler_1,
        typeIdentifier?._id ?? ffi.nullptr,
        completionHandler._id);
    return NSProgress._(_ret, _lib, retain: true, release: true);
  }

  NSProgress loadInPlaceFileRepresentationForTypeIdentifier_completionHandler_(
      NSString? typeIdentifier, ObjCBlock21 completionHandler) {
    final _ret = _lib._objc_msgSend_594(
        _id,
        _lib._sel_loadInPlaceFileRepresentationForTypeIdentifier_completionHandler_1,
        typeIdentifier?._id ?? ffi.nullptr,
        completionHandler._id);
    return NSProgress._(_ret, _lib, retain: true, release: true);
  }

  NSString? get suggestedName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_suggestedName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set suggestedName(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setSuggestedName_1, value?._id ?? ffi.nullptr);
  }

  NSItemProvider initWithObject_(NSObject? object) {
    final _ret = _lib._objc_msgSend_16(
        _id, _lib._sel_initWithObject_1, object?._id ?? ffi.nullptr);
    return NSItemProvider._(_ret, _lib, retain: true, release: true);
  }

  void registerObject_visibility_(NSObject? object, int visibility) {
    return _lib._objc_msgSend_595(_id, _lib._sel_registerObject_visibility_1,
        object?._id ?? ffi.nullptr, visibility);
  }

  void registerObjectOfClass_visibility_loadHandler_(
      NSObject? aClass, int visibility, ObjCBlock23 loadHandler) {
    return _lib._objc_msgSend_596(
        _id,
        _lib._sel_registerObjectOfClass_visibility_loadHandler_1,
        aClass?._id ?? ffi.nullptr,
        visibility,
        loadHandler._id);
  }

  bool canLoadObjectOfClass_(NSObject? aClass) {
    return _lib._objc_msgSend_0(
        _id, _lib._sel_canLoadObjectOfClass_1, aClass?._id ?? ffi.nullptr);
  }

  NSProgress loadObjectOfClass_completionHandler_(
      NSObject? aClass, ObjCBlock24 completionHandler) {
    final _ret = _lib._objc_msgSend_597(
        _id,
        _lib._sel_loadObjectOfClass_completionHandler_1,
        aClass?._id ?? ffi.nullptr,
        completionHandler._id);
    return NSProgress._(_ret, _lib, retain: true, release: true);
  }

  NSItemProvider initWithItem_typeIdentifier_(
      NSObject? item, NSString? typeIdentifier) {
    final _ret = _lib._objc_msgSend_272(
        _id,
        _lib._sel_initWithItem_typeIdentifier_1,
        item?._id ?? ffi.nullptr,
        typeIdentifier?._id ?? ffi.nullptr);
    return NSItemProvider._(_ret, _lib, retain: true, release: true);
  }

  NSItemProvider initWithContentsOfURL_(NSURL? fileURL) {
    final _ret = _lib._objc_msgSend_226(
        _id, _lib._sel_initWithContentsOfURL_1, fileURL?._id ?? ffi.nullptr);
    return NSItemProvider._(_ret, _lib, retain: true, release: true);
  }

  void registerItemForTypeIdentifier_loadHandler_(
      NSString? typeIdentifier, NSItemProviderLoadHandler loadHandler) {
    return _lib._objc_msgSend_598(
        _id,
        _lib._sel_registerItemForTypeIdentifier_loadHandler_1,
        typeIdentifier?._id ?? ffi.nullptr,
        loadHandler);
  }

  void loadItemForTypeIdentifier_options_completionHandler_(
      NSString? typeIdentifier,
      NSDictionary? options,
      NSItemProviderCompletionHandler completionHandler) {
    return _lib._objc_msgSend_599(
        _id,
        _lib._sel_loadItemForTypeIdentifier_options_completionHandler_1,
        typeIdentifier?._id ?? ffi.nullptr,
        options?._id ?? ffi.nullptr,
        completionHandler);
  }

  NSItemProviderLoadHandler get previewImageHandler {
    return _lib._objc_msgSend_600(_id, _lib._sel_previewImageHandler1);
  }

  set previewImageHandler(NSItemProviderLoadHandler value) {
    _lib._objc_msgSend_601(_id, _lib._sel_setPreviewImageHandler_1, value);
  }

  void loadPreviewImageWithOptions_completionHandler_(NSDictionary? options,
      NSItemProviderCompletionHandler completionHandler) {
    return _lib._objc_msgSend_602(
        _id,
        _lib._sel_loadPreviewImageWithOptions_completionHandler_1,
        options?._id ?? ffi.nullptr,
        completionHandler);
  }

  static NSItemProvider new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSItemProvider1, _lib._sel_new1);
    return NSItemProvider._(_ret, _lib, retain: false, release: true);
  }

  static NSItemProvider alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSItemProvider1, _lib._sel_alloc1);
    return NSItemProvider._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSItemProvider1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSItemProvider1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSItemProvider1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSItemProvider1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSItemProvider1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSItemProvider1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSItemProvider1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSItemProvider1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSItemProvider1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSItemProviderRepresentationVisibility {
  static const int NSItemProviderRepresentationVisibilityAll = 0;
  static const int NSItemProviderRepresentationVisibilityTeam = 1;
  static const int NSItemProviderRepresentationVisibilityGroup = 2;
  static const int NSItemProviderRepresentationVisibilityOwnProcess = 3;
}

ffi.Pointer<ObjCObject> _ObjCBlock18_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<_ObjCBlock> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> arg0)>>()
      .asFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<_ObjCBlock> arg0)>()(arg0);
}

final _ObjCBlock18_closureRegistry = <int, Function>{};
int _ObjCBlock18_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock18_registerClosure(Function fn) {
  final id = ++_ObjCBlock18_closureRegistryIndex;
  _ObjCBlock18_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

ffi.Pointer<ObjCObject> _ObjCBlock18_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<_ObjCBlock> arg0) {
  return _ObjCBlock18_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock18 extends _ObjCBlockBase {
  ObjCBlock18._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock18.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Pointer<ObjCObject> Function(
                      ffi.Pointer<_ObjCBlock> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Pointer<ObjCObject> Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<_ObjCBlock> arg0)>(
                        _ObjCBlock18_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock18.fromFunction(AVFAudio lib,
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Pointer<ObjCObject> Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<_ObjCBlock> arg0)>(
                        _ObjCBlock18_closureTrampoline)
                    .cast(),
                _ObjCBlock18_registerClosure(fn)),
            lib);
  ffi.Pointer<ObjCObject> call(ffi.Pointer<_ObjCBlock> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<_ObjCBlock> arg0)>>()
        .asFunction<
            ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<_ObjCBlock> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSProgress extends NSObject {
  NSProgress._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSProgress] that points to the same underlying object as [other].
  static NSProgress castFrom<T extends _ObjCWrapper>(T other) {
    return NSProgress._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSProgress] that wraps the given raw object pointer.
  static NSProgress castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSProgress._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSProgress].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSProgress1);
  }

  static NSProgress currentProgress(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_577(
        _lib._class_NSProgress1, _lib._sel_currentProgress1);
    return NSProgress._(_ret, _lib, retain: true, release: true);
  }

  static NSProgress progressWithTotalUnitCount_(AVFAudio _lib, int unitCount) {
    final _ret = _lib._objc_msgSend_578(_lib._class_NSProgress1,
        _lib._sel_progressWithTotalUnitCount_1, unitCount);
    return NSProgress._(_ret, _lib, retain: true, release: true);
  }

  static NSProgress discreteProgressWithTotalUnitCount_(
      AVFAudio _lib, int unitCount) {
    final _ret = _lib._objc_msgSend_578(_lib._class_NSProgress1,
        _lib._sel_discreteProgressWithTotalUnitCount_1, unitCount);
    return NSProgress._(_ret, _lib, retain: true, release: true);
  }

  static NSProgress progressWithTotalUnitCount_parent_pendingUnitCount_(
      AVFAudio _lib,
      int unitCount,
      NSProgress? parent,
      int portionOfParentTotalUnitCount) {
    final _ret = _lib._objc_msgSend_579(
        _lib._class_NSProgress1,
        _lib._sel_progressWithTotalUnitCount_parent_pendingUnitCount_1,
        unitCount,
        parent?._id ?? ffi.nullptr,
        portionOfParentTotalUnitCount);
    return NSProgress._(_ret, _lib, retain: true, release: true);
  }

  NSProgress initWithParent_userInfo_(NSProgress? parentProgressOrNil) {
    final _ret = _lib._objc_msgSend_580(
        _id,
        _lib._sel_initWithParent_userInfo_1,
        parentProgressOrNil?._id ?? ffi.nullptr);
    return NSProgress._(_ret, _lib, retain: true, release: true);
  }

  void becomeCurrentWithPendingUnitCount_(int unitCount) {
    return _lib._objc_msgSend_581(
        _id, _lib._sel_becomeCurrentWithPendingUnitCount_1, unitCount);
  }

  void performAsCurrentWithPendingUnitCount_usingBlock_(
      int unitCount, ObjCBlock16 work) {
    return _lib._objc_msgSend_582(
        _id,
        _lib._sel_performAsCurrentWithPendingUnitCount_usingBlock_1,
        unitCount,
        work._id);
  }

  void resignCurrent() {
    return _lib._objc_msgSend_1(_id, _lib._sel_resignCurrent1);
  }

  void addChild_withPendingUnitCount_(NSProgress? child, int inUnitCount) {
    return _lib._objc_msgSend_583(
        _id,
        _lib._sel_addChild_withPendingUnitCount_1,
        child?._id ?? ffi.nullptr,
        inUnitCount);
  }

  int get totalUnitCount {
    return _lib._objc_msgSend_584(_id, _lib._sel_totalUnitCount1);
  }

  set totalUnitCount(int value) {
    _lib._objc_msgSend_585(_id, _lib._sel_setTotalUnitCount_1, value);
  }

  int get completedUnitCount {
    return _lib._objc_msgSend_584(_id, _lib._sel_completedUnitCount1);
  }

  set completedUnitCount(int value) {
    _lib._objc_msgSend_585(_id, _lib._sel_setCompletedUnitCount_1, value);
  }

  NSString? get localizedDescription {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_localizedDescription1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set localizedDescription(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setLocalizedDescription_1, value?._id ?? ffi.nullptr);
  }

  NSString? get localizedAdditionalDescription {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_localizedAdditionalDescription1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set localizedAdditionalDescription(NSString? value) {
    _lib._objc_msgSend_477(_id, _lib._sel_setLocalizedAdditionalDescription_1,
        value?._id ?? ffi.nullptr);
  }

  bool get cancellable {
    return _lib._objc_msgSend_12(_id, _lib._sel_isCancellable1);
  }

  set cancellable(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setCancellable_1, value);
  }

  bool get pausable {
    return _lib._objc_msgSend_12(_id, _lib._sel_isPausable1);
  }

  set pausable(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setPausable_1, value);
  }

  bool get cancelled {
    return _lib._objc_msgSend_12(_id, _lib._sel_isCancelled1);
  }

  bool get paused {
    return _lib._objc_msgSend_12(_id, _lib._sel_isPaused1);
  }

  ObjCBlock16 get cancellationHandler {
    final _ret = _lib._objc_msgSend_586(_id, _lib._sel_cancellationHandler1);
    return ObjCBlock16._(_ret, _lib);
  }

  set cancellationHandler(ObjCBlock16 value) {
    _lib._objc_msgSend_587(_id, _lib._sel_setCancellationHandler_1, value._id);
  }

  ObjCBlock16 get pausingHandler {
    final _ret = _lib._objc_msgSend_586(_id, _lib._sel_pausingHandler1);
    return ObjCBlock16._(_ret, _lib);
  }

  set pausingHandler(ObjCBlock16 value) {
    _lib._objc_msgSend_587(_id, _lib._sel_setPausingHandler_1, value._id);
  }

  ObjCBlock16 get resumingHandler {
    final _ret = _lib._objc_msgSend_586(_id, _lib._sel_resumingHandler1);
    return ObjCBlock16._(_ret, _lib);
  }

  set resumingHandler(ObjCBlock16 value) {
    _lib._objc_msgSend_587(_id, _lib._sel_setResumingHandler_1, value._id);
  }

  void setUserInfoObject_forKey_(
      NSObject objectOrNil, NSProgressUserInfoKey key) {
    return _lib._objc_msgSend_122(
        _id, _lib._sel_setUserInfoObject_forKey_1, objectOrNil._id, key);
  }

  bool get indeterminate {
    return _lib._objc_msgSend_12(_id, _lib._sel_isIndeterminate1);
  }

  double get fractionCompleted {
    return _lib._objc_msgSend_149(_id, _lib._sel_fractionCompleted1);
  }

  bool get finished {
    return _lib._objc_msgSend_12(_id, _lib._sel_isFinished1);
  }

  void cancel() {
    return _lib._objc_msgSend_1(_id, _lib._sel_cancel1);
  }

  void pause() {
    return _lib._objc_msgSend_1(_id, _lib._sel_pause1);
  }

  void resume() {
    return _lib._objc_msgSend_1(_id, _lib._sel_resume1);
  }

  static NSProgress new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSProgress1, _lib._sel_new1);
    return NSProgress._(_ret, _lib, retain: false, release: true);
  }

  static NSProgress alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSProgress1, _lib._sel_alloc1);
    return NSProgress._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSProgress1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSProgress1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSProgress1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSProgress1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSProgress1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSProgress1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSProgress1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSProgress1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSProgress1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSProgressUserInfoKey = ffi.Pointer<ObjCObject>;
void _ObjCBlock19_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                  ffi.Pointer<ObjCObject> arg1)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ObjCObject> arg1)>()(arg0, arg1);
}

final _ObjCBlock19_closureRegistry = <int, Function>{};
int _ObjCBlock19_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock19_registerClosure(Function fn) {
  final id = ++_ObjCBlock19_closureRegistryIndex;
  _ObjCBlock19_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock19_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return _ObjCBlock19_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock19 extends _ObjCBlockBase {
  ObjCBlock19._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock19.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ObjCObject> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock19_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock19.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock19_closureTrampoline)
                    .cast(),
                _ObjCBlock19_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ObjCObject> arg1)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ObjCObject> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

abstract class NSItemProviderFileOptions {
  static const int NSItemProviderFileOptionOpenInPlace = 1;
}

ffi.Pointer<ObjCObject> _ObjCBlock20_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<_ObjCBlock> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> arg0)>>()
      .asFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<_ObjCBlock> arg0)>()(arg0);
}

final _ObjCBlock20_closureRegistry = <int, Function>{};
int _ObjCBlock20_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock20_registerClosure(Function fn) {
  final id = ++_ObjCBlock20_closureRegistryIndex;
  _ObjCBlock20_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

ffi.Pointer<ObjCObject> _ObjCBlock20_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<_ObjCBlock> arg0) {
  return _ObjCBlock20_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock20 extends _ObjCBlockBase {
  ObjCBlock20._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock20.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Pointer<ObjCObject> Function(
                      ffi.Pointer<_ObjCBlock> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Pointer<ObjCObject> Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<_ObjCBlock> arg0)>(
                        _ObjCBlock20_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock20.fromFunction(AVFAudio lib,
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Pointer<ObjCObject> Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<_ObjCBlock> arg0)>(
                        _ObjCBlock20_closureTrampoline)
                    .cast(),
                _ObjCBlock20_registerClosure(fn)),
            lib);
  ffi.Pointer<ObjCObject> call(ffi.Pointer<_ObjCBlock> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<_ObjCBlock> arg0)>>()
        .asFunction<
            ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<_ObjCBlock> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

void _ObjCBlock21_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, bool arg1, ffi.Pointer<ObjCObject> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0, ffi.Bool arg1,
                  ffi.Pointer<ObjCObject> arg2)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0, bool arg1,
              ffi.Pointer<ObjCObject> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock21_closureRegistry = <int, Function>{};
int _ObjCBlock21_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock21_registerClosure(Function fn) {
  final id = ++_ObjCBlock21_closureRegistryIndex;
  _ObjCBlock21_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock21_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, bool arg1, ffi.Pointer<ObjCObject> arg2) {
  return _ObjCBlock21_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock21 extends _ObjCBlockBase {
  ObjCBlock21._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock21.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0, ffi.Bool arg1,
                      ffi.Pointer<ObjCObject> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Bool arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock21_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock21.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, bool arg1,
              ffi.Pointer<ObjCObject> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Bool arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock21_closureTrampoline)
                    .cast(),
                _ObjCBlock21_registerClosure(fn)),
            lib);
  void call(
      ffi.Pointer<ObjCObject> arg0, bool arg1, ffi.Pointer<ObjCObject> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Bool arg1,
                    ffi.Pointer<ObjCObject> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                bool arg1,
                ffi.Pointer<ObjCObject> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

void _ObjCBlock22_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                  ffi.Pointer<ObjCObject> arg1)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ObjCObject> arg1)>()(arg0, arg1);
}

final _ObjCBlock22_closureRegistry = <int, Function>{};
int _ObjCBlock22_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock22_registerClosure(Function fn) {
  final id = ++_ObjCBlock22_closureRegistryIndex;
  _ObjCBlock22_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock22_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return _ObjCBlock22_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock22 extends _ObjCBlockBase {
  ObjCBlock22._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock22.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ObjCObject> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock22_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock22.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock22_closureTrampoline)
                    .cast(),
                _ObjCBlock22_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ObjCObject> arg1)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ObjCObject> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

ffi.Pointer<ObjCObject> _ObjCBlock23_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<_ObjCBlock> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> arg0)>>()
      .asFunction<
          ffi.Pointer<ObjCObject> Function(
              ffi.Pointer<_ObjCBlock> arg0)>()(arg0);
}

final _ObjCBlock23_closureRegistry = <int, Function>{};
int _ObjCBlock23_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock23_registerClosure(Function fn) {
  final id = ++_ObjCBlock23_closureRegistryIndex;
  _ObjCBlock23_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

ffi.Pointer<ObjCObject> _ObjCBlock23_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<_ObjCBlock> arg0) {
  return _ObjCBlock23_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock23 extends _ObjCBlockBase {
  ObjCBlock23._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock23.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Pointer<ObjCObject> Function(
                      ffi.Pointer<_ObjCBlock> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Pointer<ObjCObject> Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<_ObjCBlock> arg0)>(
                        _ObjCBlock23_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock23.fromFunction(AVFAudio lib,
      ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Pointer<ObjCObject> Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<_ObjCBlock> arg0)>(
                        _ObjCBlock23_closureTrampoline)
                    .cast(),
                _ObjCBlock23_registerClosure(fn)),
            lib);
  ffi.Pointer<ObjCObject> call(ffi.Pointer<_ObjCBlock> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<_ObjCBlock> arg0)>>()
        .asFunction<
            ffi.Pointer<ObjCObject> Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<_ObjCBlock> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

void _ObjCBlock24_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                  ffi.Pointer<ObjCObject> arg1)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ObjCObject> arg1)>()(arg0, arg1);
}

final _ObjCBlock24_closureRegistry = <int, Function>{};
int _ObjCBlock24_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock24_registerClosure(Function fn) {
  final id = ++_ObjCBlock24_closureRegistryIndex;
  _ObjCBlock24_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock24_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return _ObjCBlock24_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock24 extends _ObjCBlockBase {
  ObjCBlock24._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock24.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ObjCObject> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock24_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock24.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock24_closureTrampoline)
                    .cast(),
                _ObjCBlock24_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ObjCObject> arg1)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ObjCObject> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

typedef NSItemProviderLoadHandler = ffi.Pointer<_ObjCBlock>;
void _ObjCBlock25_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    NSItemProviderCompletionHandler arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ObjCObject> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(
                  NSItemProviderCompletionHandler arg0,
                  ffi.Pointer<ObjCObject> arg1,
                  ffi.Pointer<ObjCObject> arg2)>>()
      .asFunction<
          void Function(
              NSItemProviderCompletionHandler arg0,
              ffi.Pointer<ObjCObject> arg1,
              ffi.Pointer<ObjCObject> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock25_closureRegistry = <int, Function>{};
int _ObjCBlock25_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock25_registerClosure(Function fn) {
  final id = ++_ObjCBlock25_closureRegistryIndex;
  _ObjCBlock25_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock25_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    NSItemProviderCompletionHandler arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ObjCObject> arg2) {
  return _ObjCBlock25_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock25 extends _ObjCBlockBase {
  ObjCBlock25._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock25.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      NSItemProviderCompletionHandler arg0,
                      ffi.Pointer<ObjCObject> arg1,
                      ffi.Pointer<ObjCObject> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                NSItemProviderCompletionHandler arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock25_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock25.fromFunction(
      AVFAudio lib,
      void Function(NSItemProviderCompletionHandler arg0,
              ffi.Pointer<ObjCObject> arg1, ffi.Pointer<ObjCObject> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                NSItemProviderCompletionHandler arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock25_closureTrampoline)
                    .cast(),
                _ObjCBlock25_registerClosure(fn)),
            lib);
  void call(NSItemProviderCompletionHandler arg0, ffi.Pointer<ObjCObject> arg1,
      ffi.Pointer<ObjCObject> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    NSItemProviderCompletionHandler arg0,
                    ffi.Pointer<ObjCObject> arg1,
                    ffi.Pointer<ObjCObject> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                NSItemProviderCompletionHandler arg0,
                ffi.Pointer<ObjCObject> arg1,
                ffi.Pointer<ObjCObject> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

typedef NSItemProviderCompletionHandler = ffi.Pointer<_ObjCBlock>;

class NSMutableString extends NSString {
  NSMutableString._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSMutableString] that points to the same underlying object as [other].
  static NSMutableString castFrom<T extends _ObjCWrapper>(T other) {
    return NSMutableString._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSMutableString] that wraps the given raw object pointer.
  static NSMutableString castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSMutableString._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSMutableString].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSMutableString1);
  }

  void replaceCharactersInRange_withString_(NSRange range, NSString? aString) {
    return _lib._objc_msgSend_603(
        _id,
        _lib._sel_replaceCharactersInRange_withString_1,
        range,
        aString?._id ?? ffi.nullptr);
  }

  void insertString_atIndex_(NSString? aString, int loc) {
    return _lib._objc_msgSend_604(_id, _lib._sel_insertString_atIndex_1,
        aString?._id ?? ffi.nullptr, loc);
  }

  void deleteCharactersInRange_(NSRange range) {
    return _lib._objc_msgSend_416(
        _id, _lib._sel_deleteCharactersInRange_1, range);
  }

  void appendString_(NSString? aString) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_appendString_1, aString?._id ?? ffi.nullptr);
  }

  void appendFormat_(NSString? format) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_appendFormat_1, format?._id ?? ffi.nullptr);
  }

  void setString_(NSString? aString) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_setString_1, aString?._id ?? ffi.nullptr);
  }

  int replaceOccurrencesOfString_withString_options_range_(NSString? target,
      NSString? replacement, int options, NSRange searchRange) {
    return _lib._objc_msgSend_605(
        _id,
        _lib._sel_replaceOccurrencesOfString_withString_options_range_1,
        target?._id ?? ffi.nullptr,
        replacement?._id ?? ffi.nullptr,
        options,
        searchRange);
  }

  bool applyTransform_reverse_range_updatedRange_(NSStringTransform transform,
      bool reverse, NSRange range, NSRangePointer resultingRange) {
    return _lib._objc_msgSend_606(
        _id,
        _lib._sel_applyTransform_reverse_range_updatedRange_1,
        transform,
        reverse,
        range,
        resultingRange);
  }

  NSMutableString initWithCapacity_(int capacity) {
    final _ret =
        _lib._objc_msgSend_607(_id, _lib._sel_initWithCapacity_1, capacity);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString stringWithCapacity_(AVFAudio _lib, int capacity) {
    final _ret = _lib._objc_msgSend_607(
        _lib._class_NSMutableString1, _lib._sel_stringWithCapacity_1, capacity);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static ffi.Pointer<NSStringEncoding> getAvailableStringEncodings(
      AVFAudio _lib) {
    return _lib._objc_msgSend_318(
        _lib._class_NSMutableString1, _lib._sel_availableStringEncodings1);
  }

  static NSString localizedNameOfStringEncoding_(AVFAudio _lib, int encoding) {
    final _ret = _lib._objc_msgSend_293(_lib._class_NSMutableString1,
        _lib._sel_localizedNameOfStringEncoding_1, encoding);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static int getDefaultCStringEncoding(AVFAudio _lib) {
    return _lib._objc_msgSend_10(
        _lib._class_NSMutableString1, _lib._sel_defaultCStringEncoding1);
  }

  static NSMutableString string(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableString1, _lib._sel_string1);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString stringWithString_(AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSMutableString1,
        _lib._sel_stringWithString_1, string?._id ?? ffi.nullptr);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString stringWithCharacters_length_(
      AVFAudio _lib, ffi.Pointer<unichar> characters, int length) {
    final _ret = _lib._objc_msgSend_331(_lib._class_NSMutableString1,
        _lib._sel_stringWithCharacters_length_1, characters, length);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString stringWithUTF8String_(
      AVFAudio _lib, ffi.Pointer<ffi.Char> nullTerminatedCString) {
    final _ret = _lib._objc_msgSend_332(_lib._class_NSMutableString1,
        _lib._sel_stringWithUTF8String_1, nullTerminatedCString);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString stringWithFormat_(AVFAudio _lib, NSString? format) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSMutableString1,
        _lib._sel_stringWithFormat_1, format?._id ?? ffi.nullptr);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString localizedStringWithFormat_(
      AVFAudio _lib, NSString? format) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSMutableString1,
        _lib._sel_localizedStringWithFormat_1, format?._id ?? ffi.nullptr);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString stringWithCString_encoding_(
      AVFAudio _lib, ffi.Pointer<ffi.Char> cString, int enc) {
    final _ret = _lib._objc_msgSend_339(_lib._class_NSMutableString1,
        _lib._sel_stringWithCString_encoding_1, cString, enc);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString stringWithContentsOfURL_encoding_error_(AVFAudio _lib,
      NSURL? url, int enc, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_340(
        _lib._class_NSMutableString1,
        _lib._sel_stringWithContentsOfURL_encoding_error_1,
        url?._id ?? ffi.nullptr,
        enc,
        error);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString stringWithContentsOfFile_encoding_error_(AVFAudio _lib,
      NSString? path, int enc, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_341(
        _lib._class_NSMutableString1,
        _lib._sel_stringWithContentsOfFile_encoding_error_1,
        path?._id ?? ffi.nullptr,
        enc,
        error);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString stringWithContentsOfURL_usedEncoding_error_(
      AVFAudio _lib,
      NSURL? url,
      ffi.Pointer<NSStringEncoding> enc,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_342(
        _lib._class_NSMutableString1,
        _lib._sel_stringWithContentsOfURL_usedEncoding_error_1,
        url?._id ?? ffi.nullptr,
        enc,
        error);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString stringWithContentsOfFile_usedEncoding_error_(
      AVFAudio _lib,
      NSString? path,
      ffi.Pointer<NSStringEncoding> enc,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_343(
        _lib._class_NSMutableString1,
        _lib._sel_stringWithContentsOfFile_usedEncoding_error_1,
        path?._id ?? ffi.nullptr,
        enc,
        error);
    return NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  static int
      stringEncodingForData_encodingOptions_convertedString_usedLossyConversion_(
          AVFAudio _lib,
          NSData? data,
          NSDictionary? opts,
          ffi.Pointer<ffi.Pointer<ObjCObject>> string,
          ffi.Pointer<ffi.Bool> usedLossyConversion) {
    return _lib._objc_msgSend_344(
        _lib._class_NSMutableString1,
        _lib._sel_stringEncodingForData_encodingOptions_convertedString_usedLossyConversion_1,
        data?._id ?? ffi.nullptr,
        opts?._id ?? ffi.nullptr,
        string,
        usedLossyConversion);
  }

  static NSObject stringWithContentsOfFile_(AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSMutableString1,
        _lib._sel_stringWithContentsOfFile_1, path?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject stringWithContentsOfURL_(AVFAudio _lib, NSURL? url) {
    final _ret = _lib._objc_msgSend_226(_lib._class_NSMutableString1,
        _lib._sel_stringWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject stringWithCString_length_(
      AVFAudio _lib, ffi.Pointer<ffi.Char> bytes, int length) {
    final _ret = _lib._objc_msgSend_339(_lib._class_NSMutableString1,
        _lib._sel_stringWithCString_length_1, bytes, length);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject stringWithCString_(
      AVFAudio _lib, ffi.Pointer<ffi.Char> bytes) {
    final _ret = _lib._objc_msgSend_332(
        _lib._class_NSMutableString1, _lib._sel_stringWithCString_1, bytes);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSString pathWithComponents_(AVFAudio _lib, NSArray? components) {
    final _ret = _lib._objc_msgSend_350(_lib._class_NSMutableString1,
        _lib._sel_pathWithComponents_1, components?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableString new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableString1, _lib._sel_new1);
    return NSMutableString._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableString alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableString1, _lib._sel_alloc1);
    return NSMutableString._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSMutableString1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSMutableString1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSMutableString1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMutableString1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSMutableString1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSMutableString1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSMutableString1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSMutableString1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableString1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSNotification extends NSObject {
  NSNotification._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSNotification] that points to the same underlying object as [other].
  static NSNotification castFrom<T extends _ObjCWrapper>(T other) {
    return NSNotification._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSNotification] that wraps the given raw object pointer.
  static NSNotification castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSNotification._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSNotification].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSNotification1);
  }

  NSNotificationName get name {
    return _lib._objc_msgSend_20(_id, _lib._sel_name1);
  }

  NSObject get object {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_object1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get userInfo {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_userInfo1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSNotification initWithName_object_userInfo_(
      NSNotificationName name, NSObject object, NSDictionary? userInfo) {
    final _ret = _lib._objc_msgSend_608(
        _id,
        _lib._sel_initWithName_object_userInfo_1,
        name,
        object._id,
        userInfo?._id ?? ffi.nullptr);
    return NSNotification._(_ret, _lib, retain: true, release: true);
  }

  NSNotification initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSNotification._(_ret, _lib, retain: true, release: true);
  }

  static NSNotification notificationWithName_object_(
      AVFAudio _lib, NSNotificationName aName, NSObject anObject) {
    final _ret = _lib._objc_msgSend_157(_lib._class_NSNotification1,
        _lib._sel_notificationWithName_object_1, aName, anObject._id);
    return NSNotification._(_ret, _lib, retain: true, release: true);
  }

  static NSNotification notificationWithName_object_userInfo_(AVFAudio _lib,
      NSNotificationName aName, NSObject anObject, NSDictionary? aUserInfo) {
    final _ret = _lib._objc_msgSend_608(
        _lib._class_NSNotification1,
        _lib._sel_notificationWithName_object_userInfo_1,
        aName,
        anObject._id,
        aUserInfo?._id ?? ffi.nullptr);
    return NSNotification._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSNotification init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSNotification._(_ret, _lib, retain: true, release: true);
  }

  static NSNotification new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSNotification1, _lib._sel_new1);
    return NSNotification._(_ret, _lib, retain: false, release: true);
  }

  static NSNotification alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSNotification1, _lib._sel_alloc1);
    return NSNotification._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSNotification1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSNotification1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSNotification1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSNotification1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSNotification1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSNotification1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSNotification1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSNotification1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSNotification1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSNotificationName = ffi.Pointer<ObjCObject>;

class NSBundle extends NSObject {
  NSBundle._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSBundle] that points to the same underlying object as [other].
  static NSBundle castFrom<T extends _ObjCWrapper>(T other) {
    return NSBundle._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSBundle] that wraps the given raw object pointer.
  static NSBundle castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSBundle._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSBundle].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSBundle1);
  }

  static NSBundle? getMainBundle(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_609(_lib._class_NSBundle1, _lib._sel_mainBundle1);
    return _ret.address == 0
        ? null
        : NSBundle._(_ret, _lib, retain: true, release: true);
  }

  static NSBundle bundleWithPath_(AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSBundle1,
        _lib._sel_bundleWithPath_1, path?._id ?? ffi.nullptr);
    return NSBundle._(_ret, _lib, retain: true, release: true);
  }

  NSBundle initWithPath_(NSString? path) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithPath_1, path?._id ?? ffi.nullptr);
    return NSBundle._(_ret, _lib, retain: true, release: true);
  }

  static NSBundle bundleWithURL_(AVFAudio _lib, NSURL? url) {
    final _ret = _lib._objc_msgSend_226(_lib._class_NSBundle1,
        _lib._sel_bundleWithURL_1, url?._id ?? ffi.nullptr);
    return NSBundle._(_ret, _lib, retain: true, release: true);
  }

  NSBundle initWithURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_226(
        _id, _lib._sel_initWithURL_1, url?._id ?? ffi.nullptr);
    return NSBundle._(_ret, _lib, retain: true, release: true);
  }

  static NSBundle bundleForClass_(AVFAudio _lib, NSObject aClass) {
    final _ret = _lib._objc_msgSend_610(
        _lib._class_NSBundle1, _lib._sel_bundleForClass_1, aClass._id);
    return NSBundle._(_ret, _lib, retain: true, release: true);
  }

  static NSBundle bundleWithIdentifier_(AVFAudio _lib, NSString? identifier) {
    final _ret = _lib._objc_msgSend_611(_lib._class_NSBundle1,
        _lib._sel_bundleWithIdentifier_1, identifier?._id ?? ffi.nullptr);
    return NSBundle._(_ret, _lib, retain: true, release: true);
  }

  static NSArray? getAllBundles(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_80(_lib._class_NSBundle1, _lib._sel_allBundles1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray? getAllFrameworks(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_80(_lib._class_NSBundle1, _lib._sel_allFrameworks1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  bool load() {
    return _lib._objc_msgSend_12(_id, _lib._sel_load1);
  }

  bool get loaded {
    return _lib._objc_msgSend_12(_id, _lib._sel_isLoaded1);
  }

  bool unload() {
    return _lib._objc_msgSend_12(_id, _lib._sel_unload1);
  }

  bool preflightAndReturnError_(ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_219(
        _id, _lib._sel_preflightAndReturnError_1, error);
  }

  bool loadAndReturnError_(ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_219(_id, _lib._sel_loadAndReturnError_1, error);
  }

  NSURL? get bundleURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_bundleURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get resourceURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_resourceURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get executableURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_executableURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL URLForAuxiliaryExecutable_(NSString? executableName) {
    final _ret = _lib._objc_msgSend_34(
        _id,
        _lib._sel_URLForAuxiliaryExecutable_1,
        executableName?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get privateFrameworksURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_privateFrameworksURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get sharedFrameworksURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_sharedFrameworksURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get sharedSupportURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_sharedSupportURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get builtInPlugInsURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_builtInPlugInsURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get appStoreReceiptURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_appStoreReceiptURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSString? get bundlePath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_bundlePath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get resourcePath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_resourcePath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get executablePath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_executablePath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString pathForAuxiliaryExecutable_(NSString? executableName) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_pathForAuxiliaryExecutable_1,
        executableName?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get privateFrameworksPath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_privateFrameworksPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get sharedFrameworksPath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_sharedFrameworksPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get sharedSupportPath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_sharedSupportPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get builtInPlugInsPath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_builtInPlugInsPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSURL URLForResource_withExtension_subdirectory_inBundleWithURL_(
      AVFAudio _lib,
      NSString? name,
      NSString? ext,
      NSString? subpath,
      NSURL? bundleURL) {
    final _ret = _lib._objc_msgSend_612(
        _lib._class_NSBundle1,
        _lib._sel_URLForResource_withExtension_subdirectory_inBundleWithURL_1,
        name?._id ?? ffi.nullptr,
        ext?._id ?? ffi.nullptr,
        subpath?._id ?? ffi.nullptr,
        bundleURL?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  static NSArray URLsForResourcesWithExtension_subdirectory_inBundleWithURL_(
      AVFAudio _lib, NSString? ext, NSString? subpath, NSURL? bundleURL) {
    final _ret = _lib._objc_msgSend_613(
        _lib._class_NSBundle1,
        _lib._sel_URLsForResourcesWithExtension_subdirectory_inBundleWithURL_1,
        ext?._id ?? ffi.nullptr,
        subpath?._id ?? ffi.nullptr,
        bundleURL?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSURL URLForResource_withExtension_(NSString? name, NSString? ext) {
    final _ret = _lib._objc_msgSend_614(
        _id,
        _lib._sel_URLForResource_withExtension_1,
        name?._id ?? ffi.nullptr,
        ext?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL URLForResource_withExtension_subdirectory_(
      NSString? name, NSString? ext, NSString? subpath) {
    final _ret = _lib._objc_msgSend_615(
        _id,
        _lib._sel_URLForResource_withExtension_subdirectory_1,
        name?._id ?? ffi.nullptr,
        ext?._id ?? ffi.nullptr,
        subpath?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSURL URLForResource_withExtension_subdirectory_localization_(NSString? name,
      NSString? ext, NSString? subpath, NSString? localizationName) {
    final _ret = _lib._objc_msgSend_616(
        _id,
        _lib._sel_URLForResource_withExtension_subdirectory_localization_1,
        name?._id ?? ffi.nullptr,
        ext?._id ?? ffi.nullptr,
        subpath?._id ?? ffi.nullptr,
        localizationName?._id ?? ffi.nullptr);
    return NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSArray URLsForResourcesWithExtension_subdirectory_(
      NSString? ext, NSString? subpath) {
    final _ret = _lib._objc_msgSend_617(
        _id,
        _lib._sel_URLsForResourcesWithExtension_subdirectory_1,
        ext?._id ?? ffi.nullptr,
        subpath?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray URLsForResourcesWithExtension_subdirectory_localization_(
      NSString? ext, NSString? subpath, NSString? localizationName) {
    final _ret = _lib._objc_msgSend_618(
        _id,
        _lib._sel_URLsForResourcesWithExtension_subdirectory_localization_1,
        ext?._id ?? ffi.nullptr,
        subpath?._id ?? ffi.nullptr,
        localizationName?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSString pathForResource_ofType_inDirectory_(
      AVFAudio _lib, NSString? name, NSString? ext, NSString? bundlePath) {
    final _ret = _lib._objc_msgSend_619(
        _lib._class_NSBundle1,
        _lib._sel_pathForResource_ofType_inDirectory_1,
        name?._id ?? ffi.nullptr,
        ext?._id ?? ffi.nullptr,
        bundlePath?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSArray pathsForResourcesOfType_inDirectory_(
      AVFAudio _lib, NSString? ext, NSString? bundlePath) {
    final _ret = _lib._objc_msgSend_617(
        _lib._class_NSBundle1,
        _lib._sel_pathsForResourcesOfType_inDirectory_1,
        ext?._id ?? ffi.nullptr,
        bundlePath?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString pathForResource_ofType_(NSString? name, NSString? ext) {
    final _ret = _lib._objc_msgSend_324(_id, _lib._sel_pathForResource_ofType_1,
        name?._id ?? ffi.nullptr, ext?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString pathForResource_ofType_inDirectory_forLocalization_(NSString? name,
      NSString? ext, NSString? subpath, NSString? localizationName) {
    final _ret = _lib._objc_msgSend_620(
        _id,
        _lib._sel_pathForResource_ofType_inDirectory_forLocalization_1,
        name?._id ?? ffi.nullptr,
        ext?._id ?? ffi.nullptr,
        subpath?._id ?? ffi.nullptr,
        localizationName?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray pathsForResourcesOfType_inDirectory_forLocalization_(
      NSString? ext, NSString? subpath, NSString? localizationName) {
    final _ret = _lib._objc_msgSend_618(
        _id,
        _lib._sel_pathsForResourcesOfType_inDirectory_forLocalization_1,
        ext?._id ?? ffi.nullptr,
        subpath?._id ?? ffi.nullptr,
        localizationName?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString localizedStringForKey_value_table_(
      NSString? key, NSString? value, NSString? tableName) {
    final _ret = _lib._objc_msgSend_619(
        _id,
        _lib._sel_localizedStringForKey_value_table_1,
        key?._id ?? ffi.nullptr,
        value?._id ?? ffi.nullptr,
        tableName?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSAttributedString localizedAttributedStringForKey_value_table_(
      NSString? key, NSString? value, NSString? tableName) {
    final _ret = _lib._objc_msgSend_641(
        _id,
        _lib._sel_localizedAttributedStringForKey_value_table_1,
        key?._id ?? ffi.nullptr,
        value?._id ?? ffi.nullptr,
        tableName?._id ?? ffi.nullptr);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get bundleIdentifier {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_bundleIdentifier1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get infoDictionary {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_infoDictionary1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get localizedInfoDictionary {
    final _ret =
        _lib._objc_msgSend_164(_id, _lib._sel_localizedInfoDictionary1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSObject objectForInfoDictionaryKey_(NSString? key) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_objectForInfoDictionaryKey_1, key?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject classNamed_(NSString? className) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_classNamed_1, className?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject get principalClass {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_principalClass1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get preferredLocalizations {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_preferredLocalizations1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get localizations {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_localizations1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString? get developmentLocalization {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_developmentLocalization1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSArray preferredLocalizationsFromArray_(
      AVFAudio _lib, NSArray? localizationsArray) {
    final _ret = _lib._objc_msgSend_63(
        _lib._class_NSBundle1,
        _lib._sel_preferredLocalizationsFromArray_1,
        localizationsArray?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSArray preferredLocalizationsFromArray_forPreferences_(
      AVFAudio _lib, NSArray? localizationsArray, NSArray? preferencesArray) {
    final _ret = _lib._objc_msgSend_642(
        _lib._class_NSBundle1,
        _lib._sel_preferredLocalizationsFromArray_forPreferences_1,
        localizationsArray?._id ?? ffi.nullptr,
        preferencesArray?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get executableArchitectures {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_executableArchitectures1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  void setPreservationPriority_forTags_(double priority, NSSet? tags) {
    return _lib._objc_msgSend_643(
        _id,
        _lib._sel_setPreservationPriority_forTags_1,
        priority,
        tags?._id ?? ffi.nullptr);
  }

  double preservationPriorityForTag_(NSString? tag) {
    return _lib._objc_msgSend_269(
        _id, _lib._sel_preservationPriorityForTag_1, tag?._id ?? ffi.nullptr);
  }

  static NSBundle new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSBundle1, _lib._sel_new1);
    return NSBundle._(_ret, _lib, retain: false, release: true);
  }

  static NSBundle alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSBundle1, _lib._sel_alloc1);
    return NSBundle._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSBundle1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSBundle1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSBundle1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSBundle1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSBundle1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSBundle1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSBundle1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSBundle1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSBundle1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSAttributedString extends NSObject {
  NSAttributedString._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSAttributedString] that points to the same underlying object as [other].
  static NSAttributedString castFrom<T extends _ObjCWrapper>(T other) {
    return NSAttributedString._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSAttributedString] that wraps the given raw object pointer.
  static NSAttributedString castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSAttributedString._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSAttributedString].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSAttributedString1);
  }

  NSString? get string {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_string1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary attributesAtIndex_effectiveRange_(
      int location, NSRangePointer range) {
    final _ret = _lib._objc_msgSend_621(
        _id, _lib._sel_attributesAtIndex_effectiveRange_1, location, range);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  int get length {
    return _lib._objc_msgSend_10(_id, _lib._sel_length1);
  }

  NSObject attribute_atIndex_effectiveRange_(
      NSAttributedStringKey attrName, int location, NSRangePointer range) {
    final _ret = _lib._objc_msgSend_622(
        _id,
        _lib._sel_attribute_atIndex_effectiveRange_1,
        attrName,
        location,
        range);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSAttributedString attributedSubstringFromRange_(NSRange range) {
    final _ret = _lib._objc_msgSend_623(
        _id, _lib._sel_attributedSubstringFromRange_1, range);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary attributesAtIndex_longestEffectiveRange_inRange_(
      int location, NSRangePointer range, NSRange rangeLimit) {
    final _ret = _lib._objc_msgSend_624(
        _id,
        _lib._sel_attributesAtIndex_longestEffectiveRange_inRange_1,
        location,
        range,
        rangeLimit);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSObject attribute_atIndex_longestEffectiveRange_inRange_(
      NSAttributedStringKey attrName,
      int location,
      NSRangePointer range,
      NSRange rangeLimit) {
    final _ret = _lib._objc_msgSend_625(
        _id,
        _lib._sel_attribute_atIndex_longestEffectiveRange_inRange_1,
        attrName,
        location,
        range,
        rangeLimit);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  bool isEqualToAttributedString_(NSAttributedString? other) {
    return _lib._objc_msgSend_626(
        _id, _lib._sel_isEqualToAttributedString_1, other?._id ?? ffi.nullptr);
  }

  NSAttributedString initWithString_(NSString? str) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithString_1, str?._id ?? ffi.nullptr);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  NSAttributedString initWithString_attributes_(
      NSString? str, NSDictionary? attrs) {
    final _ret = _lib._objc_msgSend_352(
        _id,
        _lib._sel_initWithString_attributes_1,
        str?._id ?? ffi.nullptr,
        attrs?._id ?? ffi.nullptr);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  NSAttributedString initWithAttributedString_(NSAttributedString? attrStr) {
    final _ret = _lib._objc_msgSend_627(
        _id, _lib._sel_initWithAttributedString_1, attrStr?._id ?? ffi.nullptr);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  void enumerateAttributesInRange_options_usingBlock_(
      NSRange enumerationRange, int opts, ObjCBlock26 block) {
    return _lib._objc_msgSend_628(
        _id,
        _lib._sel_enumerateAttributesInRange_options_usingBlock_1,
        enumerationRange,
        opts,
        block._id);
  }

  void enumerateAttribute_inRange_options_usingBlock_(
      NSAttributedStringKey attrName,
      NSRange enumerationRange,
      int opts,
      ObjCBlock27 block) {
    return _lib._objc_msgSend_629(
        _id,
        _lib._sel_enumerateAttribute_inRange_options_usingBlock_1,
        attrName,
        enumerationRange,
        opts,
        block._id);
  }

  NSAttributedString initWithContentsOfMarkdownFileAtURL_options_baseURL_error_(
      NSURL? markdownFile,
      NSAttributedStringMarkdownParsingOptions? options,
      NSURL? baseURL,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_634(
        _id,
        _lib._sel_initWithContentsOfMarkdownFileAtURL_options_baseURL_error_1,
        markdownFile?._id ?? ffi.nullptr,
        options?._id ?? ffi.nullptr,
        baseURL?._id ?? ffi.nullptr,
        error);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  NSAttributedString initWithMarkdown_options_baseURL_error_(
      NSData? markdown,
      NSAttributedStringMarkdownParsingOptions? options,
      NSURL? baseURL,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_635(
        _id,
        _lib._sel_initWithMarkdown_options_baseURL_error_1,
        markdown?._id ?? ffi.nullptr,
        options?._id ?? ffi.nullptr,
        baseURL?._id ?? ffi.nullptr,
        error);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  NSAttributedString initWithMarkdownString_options_baseURL_error_(
      NSString? markdownString,
      NSAttributedStringMarkdownParsingOptions? options,
      NSURL? baseURL,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_636(
        _id,
        _lib._sel_initWithMarkdownString_options_baseURL_error_1,
        markdownString?._id ?? ffi.nullptr,
        options?._id ?? ffi.nullptr,
        baseURL?._id ?? ffi.nullptr,
        error);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  NSAttributedString initWithFormat_options_locale_(
      NSAttributedString? format, int options, NSLocale? locale) {
    final _ret = _lib._objc_msgSend_637(
        _id,
        _lib._sel_initWithFormat_options_locale_1,
        format?._id ?? ffi.nullptr,
        options,
        locale?._id ?? ffi.nullptr);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  NSAttributedString initWithFormat_options_locale_arguments_(
      NSAttributedString? format,
      int options,
      NSLocale? locale,
      ffi.Pointer<__va_list_tag> arguments) {
    final _ret = _lib._objc_msgSend_638(
        _id,
        _lib._sel_initWithFormat_options_locale_arguments_1,
        format?._id ?? ffi.nullptr,
        options,
        locale?._id ?? ffi.nullptr,
        arguments);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  static NSAttributedString localizedAttributedStringWithFormat_(
      AVFAudio _lib, NSAttributedString? format) {
    final _ret = _lib._objc_msgSend_627(
        _lib._class_NSAttributedString1,
        _lib._sel_localizedAttributedStringWithFormat_1,
        format?._id ?? ffi.nullptr);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  static NSAttributedString localizedAttributedStringWithFormat_options_(
      AVFAudio _lib, NSAttributedString? format, int options) {
    final _ret = _lib._objc_msgSend_639(
        _lib._class_NSAttributedString1,
        _lib._sel_localizedAttributedStringWithFormat_options_1,
        format?._id ?? ffi.nullptr,
        options);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  NSAttributedString attributedStringByInflectingString() {
    final _ret = _lib._objc_msgSend_640(
        _id, _lib._sel_attributedStringByInflectingString1);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  static NSAttributedString new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSAttributedString1, _lib._sel_new1);
    return NSAttributedString._(_ret, _lib, retain: false, release: true);
  }

  static NSAttributedString alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSAttributedString1, _lib._sel_alloc1);
    return NSAttributedString._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSAttributedString1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSAttributedString1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSAttributedString1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSAttributedString1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSAttributedString1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSAttributedString1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSAttributedString1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSAttributedString1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSAttributedString1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSAttributedStringKey = ffi.Pointer<ObjCObject>;

abstract class NSAttributedStringEnumerationOptions {
  static const int NSAttributedStringEnumerationReverse = 2;
  static const int
      NSAttributedStringEnumerationLongestEffectiveRangeNotRequired = 1048576;
}

void _ObjCBlock26_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, NSRange arg1, ffi.Pointer<ffi.Bool> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0, NSRange arg1,
                  ffi.Pointer<ffi.Bool> arg2)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0, NSRange arg1,
              ffi.Pointer<ffi.Bool> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock26_closureRegistry = <int, Function>{};
int _ObjCBlock26_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock26_registerClosure(Function fn) {
  final id = ++_ObjCBlock26_closureRegistryIndex;
  _ObjCBlock26_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock26_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, NSRange arg1, ffi.Pointer<ffi.Bool> arg2) {
  return _ObjCBlock26_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock26 extends _ObjCBlockBase {
  ObjCBlock26._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock26.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0, NSRange arg1,
                      ffi.Pointer<ffi.Bool> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                NSRange arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock26_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock26.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, NSRange arg1,
              ffi.Pointer<ffi.Bool> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                NSRange arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock26_closureTrampoline)
                    .cast(),
                _ObjCBlock26_registerClosure(fn)),
            lib);
  void call(
      ffi.Pointer<ObjCObject> arg0, NSRange arg1, ffi.Pointer<ffi.Bool> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    NSRange arg1,
                    ffi.Pointer<ffi.Bool> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                NSRange arg1,
                ffi.Pointer<ffi.Bool> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

void _ObjCBlock27_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, NSRange arg1, ffi.Pointer<ffi.Bool> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0, NSRange arg1,
                  ffi.Pointer<ffi.Bool> arg2)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0, NSRange arg1,
              ffi.Pointer<ffi.Bool> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock27_closureRegistry = <int, Function>{};
int _ObjCBlock27_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock27_registerClosure(Function fn) {
  final id = ++_ObjCBlock27_closureRegistryIndex;
  _ObjCBlock27_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock27_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, NSRange arg1, ffi.Pointer<ffi.Bool> arg2) {
  return _ObjCBlock27_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock27 extends _ObjCBlockBase {
  ObjCBlock27._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock27.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0, NSRange arg1,
                      ffi.Pointer<ffi.Bool> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                NSRange arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock27_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock27.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, NSRange arg1,
              ffi.Pointer<ffi.Bool> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                NSRange arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock27_closureTrampoline)
                    .cast(),
                _ObjCBlock27_registerClosure(fn)),
            lib);
  void call(
      ffi.Pointer<ObjCObject> arg0, NSRange arg1, ffi.Pointer<ffi.Bool> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    NSRange arg1,
                    ffi.Pointer<ffi.Bool> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                NSRange arg1,
                ffi.Pointer<ffi.Bool> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSAttributedStringMarkdownParsingOptions extends NSObject {
  NSAttributedStringMarkdownParsingOptions._(
      ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSAttributedStringMarkdownParsingOptions] that points to the same underlying object as [other].
  static NSAttributedStringMarkdownParsingOptions
      castFrom<T extends _ObjCWrapper>(T other) {
    return NSAttributedStringMarkdownParsingOptions._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSAttributedStringMarkdownParsingOptions] that wraps the given raw object pointer.
  static NSAttributedStringMarkdownParsingOptions castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSAttributedStringMarkdownParsingOptions._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSAttributedStringMarkdownParsingOptions].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSAttributedStringMarkdownParsingOptions1);
  }

  @override
  NSAttributedStringMarkdownParsingOptions init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSAttributedStringMarkdownParsingOptions._(_ret, _lib,
        retain: true, release: true);
  }

  bool get allowsExtendedAttributes {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsExtendedAttributes1);
  }

  set allowsExtendedAttributes(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setAllowsExtendedAttributes_1, value);
  }

  int get interpretedSyntax {
    return _lib._objc_msgSend_630(_id, _lib._sel_interpretedSyntax1);
  }

  set interpretedSyntax(int value) {
    _lib._objc_msgSend_631(_id, _lib._sel_setInterpretedSyntax_1, value);
  }

  int get failurePolicy {
    return _lib._objc_msgSend_632(_id, _lib._sel_failurePolicy1);
  }

  set failurePolicy(int value) {
    _lib._objc_msgSend_633(_id, _lib._sel_setFailurePolicy_1, value);
  }

  NSString? get languageCode {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_languageCode1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set languageCode(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setLanguageCode_1, value?._id ?? ffi.nullptr);
  }

  static NSAttributedStringMarkdownParsingOptions new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSAttributedStringMarkdownParsingOptions1, _lib._sel_new1);
    return NSAttributedStringMarkdownParsingOptions._(_ret, _lib,
        retain: false, release: true);
  }

  static NSAttributedStringMarkdownParsingOptions alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSAttributedStringMarkdownParsingOptions1,
        _lib._sel_alloc1);
    return NSAttributedStringMarkdownParsingOptions._(_ret, _lib,
        retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSAttributedStringMarkdownParsingOptions1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(
        _lib._class_NSAttributedStringMarkdownParsingOptions1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1,
        aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSAttributedStringMarkdownParsingOptions1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSAttributedStringMarkdownParsingOptions1,
        _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSAttributedStringMarkdownParsingOptions1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSAttributedStringMarkdownParsingOptions1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSAttributedStringMarkdownParsingOptions1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSAttributedStringMarkdownParsingOptions1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSAttributedStringMarkdownParsingOptions1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSAttributedStringMarkdownInterpretedSyntax {
  static const int NSAttributedStringMarkdownInterpretedSyntaxFull = 0;
  static const int NSAttributedStringMarkdownInterpretedSyntaxInlineOnly = 1;
  static const int
      NSAttributedStringMarkdownInterpretedSyntaxInlineOnlyPreservingWhitespace =
      2;
}

abstract class NSAttributedStringMarkdownParsingFailurePolicy {
  static const int NSAttributedStringMarkdownParsingFailureReturnError = 0;
  static const int
      NSAttributedStringMarkdownParsingFailureReturnPartiallyParsedIfPossible =
      1;
}

abstract class NSAttributedStringFormattingOptions {
  static const int
      NSAttributedStringFormattingInsertArgumentAttributesWithoutMerging = 1;
  static const int NSAttributedStringFormattingApplyReplacementIndexAttribute =
      2;
}

class NSMutableAttributedString extends NSAttributedString {
  NSMutableAttributedString._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSMutableAttributedString] that points to the same underlying object as [other].
  static NSMutableAttributedString castFrom<T extends _ObjCWrapper>(T other) {
    return NSMutableAttributedString._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSMutableAttributedString] that wraps the given raw object pointer.
  static NSMutableAttributedString castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSMutableAttributedString._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSMutableAttributedString].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSMutableAttributedString1);
  }

  void replaceCharactersInRange_withString_(NSRange range, NSString? str) {
    return _lib._objc_msgSend_603(
        _id,
        _lib._sel_replaceCharactersInRange_withString_1,
        range,
        str?._id ?? ffi.nullptr);
  }

  void setAttributes_range_(NSDictionary? attrs, NSRange range) {
    return _lib._objc_msgSend_644(
        _id, _lib._sel_setAttributes_range_1, attrs?._id ?? ffi.nullptr, range);
  }

  NSMutableString? get mutableString {
    final _ret = _lib._objc_msgSend_645(_id, _lib._sel_mutableString1);
    return _ret.address == 0
        ? null
        : NSMutableString._(_ret, _lib, retain: true, release: true);
  }

  void addAttribute_value_range_(
      NSAttributedStringKey name, NSObject value, NSRange range) {
    return _lib._objc_msgSend_646(
        _id, _lib._sel_addAttribute_value_range_1, name, value._id, range);
  }

  void addAttributes_range_(NSDictionary? attrs, NSRange range) {
    return _lib._objc_msgSend_644(
        _id, _lib._sel_addAttributes_range_1, attrs?._id ?? ffi.nullptr, range);
  }

  void removeAttribute_range_(NSAttributedStringKey name, NSRange range) {
    return _lib._objc_msgSend_647(
        _id, _lib._sel_removeAttribute_range_1, name, range);
  }

  void replaceCharactersInRange_withAttributedString_(
      NSRange range, NSAttributedString? attrString) {
    return _lib._objc_msgSend_648(
        _id,
        _lib._sel_replaceCharactersInRange_withAttributedString_1,
        range,
        attrString?._id ?? ffi.nullptr);
  }

  void insertAttributedString_atIndex_(
      NSAttributedString? attrString, int loc) {
    return _lib._objc_msgSend_649(
        _id,
        _lib._sel_insertAttributedString_atIndex_1,
        attrString?._id ?? ffi.nullptr,
        loc);
  }

  void appendAttributedString_(NSAttributedString? attrString) {
    return _lib._objc_msgSend_650(_id, _lib._sel_appendAttributedString_1,
        attrString?._id ?? ffi.nullptr);
  }

  void deleteCharactersInRange_(NSRange range) {
    return _lib._objc_msgSend_416(
        _id, _lib._sel_deleteCharactersInRange_1, range);
  }

  void setAttributedString_(NSAttributedString? attrString) {
    return _lib._objc_msgSend_650(
        _id, _lib._sel_setAttributedString_1, attrString?._id ?? ffi.nullptr);
  }

  void beginEditing() {
    return _lib._objc_msgSend_1(_id, _lib._sel_beginEditing1);
  }

  void endEditing() {
    return _lib._objc_msgSend_1(_id, _lib._sel_endEditing1);
  }

  void appendLocalizedFormat_(NSAttributedString? format) {
    return _lib._objc_msgSend_650(
        _id, _lib._sel_appendLocalizedFormat_1, format?._id ?? ffi.nullptr);
  }

  static NSMutableAttributedString localizedAttributedStringWithFormat_(
      AVFAudio _lib, NSAttributedString? format) {
    final _ret = _lib._objc_msgSend_627(
        _lib._class_NSMutableAttributedString1,
        _lib._sel_localizedAttributedStringWithFormat_1,
        format?._id ?? ffi.nullptr);
    return NSMutableAttributedString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableAttributedString localizedAttributedStringWithFormat_options_(
      AVFAudio _lib, NSAttributedString? format, int options) {
    final _ret = _lib._objc_msgSend_639(
        _lib._class_NSMutableAttributedString1,
        _lib._sel_localizedAttributedStringWithFormat_options_1,
        format?._id ?? ffi.nullptr,
        options);
    return NSMutableAttributedString._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableAttributedString new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableAttributedString1, _lib._sel_new1);
    return NSMutableAttributedString._(_ret, _lib,
        retain: false, release: true);
  }

  static NSMutableAttributedString alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableAttributedString1, _lib._sel_alloc1);
    return NSMutableAttributedString._(_ret, _lib,
        retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSMutableAttributedString1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSMutableAttributedString1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSMutableAttributedString1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMutableAttributedString1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSMutableAttributedString1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSMutableAttributedString1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSMutableAttributedString1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSMutableAttributedString1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSMutableAttributedString1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSDateFormatter extends NSFormatter {
  NSDateFormatter._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSDateFormatter] that points to the same underlying object as [other].
  static NSDateFormatter castFrom<T extends _ObjCWrapper>(T other) {
    return NSDateFormatter._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSDateFormatter] that wraps the given raw object pointer.
  static NSDateFormatter castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSDateFormatter._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSDateFormatter].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSDateFormatter1);
  }

  int get formattingContext {
    return _lib._objc_msgSend_655(_id, _lib._sel_formattingContext1);
  }

  set formattingContext(int value) {
    _lib._objc_msgSend_656(_id, _lib._sel_setFormattingContext_1, value);
  }

  bool getObjectValue_forString_range_error_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> obj,
      NSString? string,
      ffi.Pointer<NSRange> rangep,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_657(
        _id,
        _lib._sel_getObjectValue_forString_range_error_1,
        obj,
        string?._id ?? ffi.nullptr,
        rangep,
        error);
  }

  NSString stringFromDate_(NSDate? date) {
    final _ret = _lib._objc_msgSend_161(
        _id, _lib._sel_stringFromDate_1, date?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSDate dateFromString_(NSString? string) {
    final _ret = _lib._objc_msgSend_496(
        _id, _lib._sel_dateFromString_1, string?._id ?? ffi.nullptr);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  static NSString localizedStringFromDate_dateStyle_timeStyle_(
      AVFAudio _lib, NSDate? date, int dstyle, int tstyle) {
    final _ret = _lib._objc_msgSend_658(
        _lib._class_NSDateFormatter1,
        _lib._sel_localizedStringFromDate_dateStyle_timeStyle_1,
        date?._id ?? ffi.nullptr,
        dstyle,
        tstyle);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString dateFormatFromTemplate_options_locale_(
      AVFAudio _lib, NSString? tmplate, int opts, NSLocale? locale) {
    final _ret = _lib._objc_msgSend_659(
        _lib._class_NSDateFormatter1,
        _lib._sel_dateFormatFromTemplate_options_locale_1,
        tmplate?._id ?? ffi.nullptr,
        opts,
        locale?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static int getDefaultFormatterBehavior(AVFAudio _lib) {
    return _lib._objc_msgSend_660(
        _lib._class_NSDateFormatter1, _lib._sel_defaultFormatterBehavior1);
  }

  static void setDefaultFormatterBehavior(AVFAudio _lib, int value) {
    _lib._objc_msgSend_661(_lib._class_NSDateFormatter1,
        _lib._sel_setDefaultFormatterBehavior_1, value);
  }

  void setLocalizedDateFormatFromTemplate_(NSString? dateFormatTemplate) {
    return _lib._objc_msgSend_186(
        _id,
        _lib._sel_setLocalizedDateFormatFromTemplate_1,
        dateFormatTemplate?._id ?? ffi.nullptr);
  }

  NSString? get dateFormat {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_dateFormat1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set dateFormat(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setDateFormat_1, value?._id ?? ffi.nullptr);
  }

  int get dateStyle {
    return _lib._objc_msgSend_662(_id, _lib._sel_dateStyle1);
  }

  set dateStyle(int value) {
    _lib._objc_msgSend_663(_id, _lib._sel_setDateStyle_1, value);
  }

  int get timeStyle {
    return _lib._objc_msgSend_662(_id, _lib._sel_timeStyle1);
  }

  set timeStyle(int value) {
    _lib._objc_msgSend_663(_id, _lib._sel_setTimeStyle_1, value);
  }

  NSLocale? get locale {
    final _ret = _lib._objc_msgSend_176(_id, _lib._sel_locale1);
    return _ret.address == 0
        ? null
        : NSLocale._(_ret, _lib, retain: true, release: true);
  }

  set locale(NSLocale? value) {
    _lib._objc_msgSend_664(
        _id, _lib._sel_setLocale_1, value?._id ?? ffi.nullptr);
  }

  bool get generatesCalendarDates {
    return _lib._objc_msgSend_12(_id, _lib._sel_generatesCalendarDates1);
  }

  set generatesCalendarDates(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setGeneratesCalendarDates_1, value);
  }

  int get formatterBehavior {
    return _lib._objc_msgSend_660(_id, _lib._sel_formatterBehavior1);
  }

  set formatterBehavior(int value) {
    _lib._objc_msgSend_661(_id, _lib._sel_setFormatterBehavior_1, value);
  }

  NSTimeZone? get timeZone {
    final _ret = _lib._objc_msgSend_162(_id, _lib._sel_timeZone1);
    return _ret.address == 0
        ? null
        : NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  set timeZone(NSTimeZone? value) {
    _lib._objc_msgSend_163(
        _id, _lib._sel_setTimeZone_1, value?._id ?? ffi.nullptr);
  }

  NSCalendar? get calendar {
    final _ret = _lib._objc_msgSend_665(_id, _lib._sel_calendar1);
    return _ret.address == 0
        ? null
        : NSCalendar._(_ret, _lib, retain: true, release: true);
  }

  set calendar(NSCalendar? value) {
    _lib._objc_msgSend_671(
        _id, _lib._sel_setCalendar_1, value?._id ?? ffi.nullptr);
  }

  bool get lenient {
    return _lib._objc_msgSend_12(_id, _lib._sel_isLenient1);
  }

  set lenient(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setLenient_1, value);
  }

  NSDate? get twoDigitStartDate {
    final _ret = _lib._objc_msgSend_156(_id, _lib._sel_twoDigitStartDate1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  set twoDigitStartDate(NSDate? value) {
    _lib._objc_msgSend_493(
        _id, _lib._sel_setTwoDigitStartDate_1, value?._id ?? ffi.nullptr);
  }

  NSDate? get defaultDate {
    final _ret = _lib._objc_msgSend_156(_id, _lib._sel_defaultDate1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  set defaultDate(NSDate? value) {
    _lib._objc_msgSend_493(
        _id, _lib._sel_setDefaultDate_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get eraSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_eraSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set eraSymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setEraSymbols_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get monthSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_monthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set monthSymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setMonthSymbols_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get shortMonthSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_shortMonthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set shortMonthSymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setShortMonthSymbols_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get weekdaySymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_weekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set weekdaySymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setWeekdaySymbols_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get shortWeekdaySymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_shortWeekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set shortWeekdaySymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setShortWeekdaySymbols_1, value?._id ?? ffi.nullptr);
  }

  NSString? get AMSymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_AMSymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set AMSymbol(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setAMSymbol_1, value?._id ?? ffi.nullptr);
  }

  NSString? get PMSymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_PMSymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set PMSymbol(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPMSymbol_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get longEraSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_longEraSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set longEraSymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setLongEraSymbols_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get veryShortMonthSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_veryShortMonthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set veryShortMonthSymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setVeryShortMonthSymbols_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get standaloneMonthSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_standaloneMonthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set standaloneMonthSymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setStandaloneMonthSymbols_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get shortStandaloneMonthSymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_shortStandaloneMonthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set shortStandaloneMonthSymbols(NSArray? value) {
    _lib._objc_msgSend_696(_id, _lib._sel_setShortStandaloneMonthSymbols_1,
        value?._id ?? ffi.nullptr);
  }

  NSArray? get veryShortStandaloneMonthSymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_veryShortStandaloneMonthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set veryShortStandaloneMonthSymbols(NSArray? value) {
    _lib._objc_msgSend_696(_id, _lib._sel_setVeryShortStandaloneMonthSymbols_1,
        value?._id ?? ffi.nullptr);
  }

  NSArray? get veryShortWeekdaySymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_veryShortWeekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set veryShortWeekdaySymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setVeryShortWeekdaySymbols_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get standaloneWeekdaySymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_standaloneWeekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set standaloneWeekdaySymbols(NSArray? value) {
    _lib._objc_msgSend_696(_id, _lib._sel_setStandaloneWeekdaySymbols_1,
        value?._id ?? ffi.nullptr);
  }

  NSArray? get shortStandaloneWeekdaySymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_shortStandaloneWeekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set shortStandaloneWeekdaySymbols(NSArray? value) {
    _lib._objc_msgSend_696(_id, _lib._sel_setShortStandaloneWeekdaySymbols_1,
        value?._id ?? ffi.nullptr);
  }

  NSArray? get veryShortStandaloneWeekdaySymbols {
    final _ret = _lib._objc_msgSend_80(
        _id, _lib._sel_veryShortStandaloneWeekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set veryShortStandaloneWeekdaySymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id,
        _lib._sel_setVeryShortStandaloneWeekdaySymbols_1,
        value?._id ?? ffi.nullptr);
  }

  NSArray? get quarterSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_quarterSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set quarterSymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setQuarterSymbols_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get shortQuarterSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_shortQuarterSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set shortQuarterSymbols(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setShortQuarterSymbols_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get standaloneQuarterSymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_standaloneQuarterSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set standaloneQuarterSymbols(NSArray? value) {
    _lib._objc_msgSend_696(_id, _lib._sel_setStandaloneQuarterSymbols_1,
        value?._id ?? ffi.nullptr);
  }

  NSArray? get shortStandaloneQuarterSymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_shortStandaloneQuarterSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set shortStandaloneQuarterSymbols(NSArray? value) {
    _lib._objc_msgSend_696(_id, _lib._sel_setShortStandaloneQuarterSymbols_1,
        value?._id ?? ffi.nullptr);
  }

  NSDate? get gregorianStartDate {
    final _ret = _lib._objc_msgSend_156(_id, _lib._sel_gregorianStartDate1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  set gregorianStartDate(NSDate? value) {
    _lib._objc_msgSend_493(
        _id, _lib._sel_setGregorianStartDate_1, value?._id ?? ffi.nullptr);
  }

  bool get doesRelativeDateFormatting {
    return _lib._objc_msgSend_12(_id, _lib._sel_doesRelativeDateFormatting1);
  }

  set doesRelativeDateFormatting(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setDoesRelativeDateFormatting_1, value);
  }

  NSObject initWithDateFormat_allowNaturalLanguage_(
      NSString? format, bool flag) {
    final _ret = _lib._objc_msgSend_29(
        _id,
        _lib._sel_initWithDateFormat_allowNaturalLanguage_1,
        format?._id ?? ffi.nullptr,
        flag);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  bool allowsNaturalLanguage() {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsNaturalLanguage1);
  }

  static NSDateFormatter new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSDateFormatter1, _lib._sel_new1);
    return NSDateFormatter._(_ret, _lib, retain: false, release: true);
  }

  static NSDateFormatter alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSDateFormatter1, _lib._sel_alloc1);
    return NSDateFormatter._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSDateFormatter1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSDateFormatter1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSDateFormatter1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSDateFormatter1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSDateFormatter1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSDateFormatter1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSDateFormatter1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSDateFormatter1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSDateFormatter1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSFormatter extends NSObject {
  NSFormatter._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSFormatter] that points to the same underlying object as [other].
  static NSFormatter castFrom<T extends _ObjCWrapper>(T other) {
    return NSFormatter._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSFormatter] that wraps the given raw object pointer.
  static NSFormatter castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSFormatter._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSFormatter].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSFormatter1);
  }

  NSString stringForObjectValue_(NSObject obj) {
    final _ret =
        _lib._objc_msgSend_65(_id, _lib._sel_stringForObjectValue_1, obj._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSAttributedString attributedStringForObjectValue_withDefaultAttributes_(
      NSObject obj, NSDictionary? attrs) {
    final _ret = _lib._objc_msgSend_651(
        _id,
        _lib._sel_attributedStringForObjectValue_withDefaultAttributes_1,
        obj._id,
        attrs?._id ?? ffi.nullptr);
    return NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  NSString editingStringForObjectValue_(NSObject obj) {
    final _ret = _lib._objc_msgSend_65(
        _id, _lib._sel_editingStringForObjectValue_1, obj._id);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  bool getObjectValue_forString_errorDescription_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> obj,
      NSString? string,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_652(
        _id,
        _lib._sel_getObjectValue_forString_errorDescription_1,
        obj,
        string?._id ?? ffi.nullptr,
        error);
  }

  bool isPartialStringValid_newEditingString_errorDescription_(
      NSString? partialString,
      ffi.Pointer<ffi.Pointer<ObjCObject>> newString,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_653(
        _id,
        _lib._sel_isPartialStringValid_newEditingString_errorDescription_1,
        partialString?._id ?? ffi.nullptr,
        newString,
        error);
  }

  bool
      isPartialStringValid_proposedSelectedRange_originalString_originalSelectedRange_errorDescription_(
          ffi.Pointer<ffi.Pointer<ObjCObject>> partialStringPtr,
          NSRangePointer proposedSelRangePtr,
          NSString? origString,
          NSRange origSelRange,
          ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_654(
        _id,
        _lib._sel_isPartialStringValid_proposedSelectedRange_originalString_originalSelectedRange_errorDescription_1,
        partialStringPtr,
        proposedSelRangePtr,
        origString?._id ?? ffi.nullptr,
        origSelRange,
        error);
  }

  static NSFormatter new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSFormatter1, _lib._sel_new1);
    return NSFormatter._(_ret, _lib, retain: false, release: true);
  }

  static NSFormatter alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSFormatter1, _lib._sel_alloc1);
    return NSFormatter._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSFormatter1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSFormatter1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSFormatter1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSFormatter1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSFormatter1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSFormatter1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSFormatter1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSFormatter1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSFormatter1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSFormattingContext {
  static const int NSFormattingContextUnknown = 0;
  static const int NSFormattingContextDynamic = 1;
  static const int NSFormattingContextStandalone = 2;
  static const int NSFormattingContextListItem = 3;
  static const int NSFormattingContextBeginningOfSentence = 4;
  static const int NSFormattingContextMiddleOfSentence = 5;
}

abstract class NSDateFormatterStyle {
  static const int NSDateFormatterNoStyle = 0;
  static const int NSDateFormatterShortStyle = 1;
  static const int NSDateFormatterMediumStyle = 2;
  static const int NSDateFormatterLongStyle = 3;
  static const int NSDateFormatterFullStyle = 4;
}

abstract class NSDateFormatterBehavior {
  static const int NSDateFormatterBehaviorDefault = 0;
  static const int NSDateFormatterBehavior10_0 = 1000;
  static const int NSDateFormatterBehavior10_4 = 1040;
}

class NSCalendar extends NSObject {
  NSCalendar._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSCalendar] that points to the same underlying object as [other].
  static NSCalendar castFrom<T extends _ObjCWrapper>(T other) {
    return NSCalendar._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSCalendar] that wraps the given raw object pointer.
  static NSCalendar castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSCalendar._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSCalendar].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSCalendar1);
  }

  static NSCalendar? getCurrentCalendar(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_665(
        _lib._class_NSCalendar1, _lib._sel_currentCalendar1);
    return _ret.address == 0
        ? null
        : NSCalendar._(_ret, _lib, retain: true, release: true);
  }

  static NSCalendar? getAutoupdatingCurrentCalendar(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_665(
        _lib._class_NSCalendar1, _lib._sel_autoupdatingCurrentCalendar1);
    return _ret.address == 0
        ? null
        : NSCalendar._(_ret, _lib, retain: true, release: true);
  }

  static NSCalendar calendarWithIdentifier_(
      AVFAudio _lib, NSCalendarIdentifier calendarIdentifierConstant) {
    final _ret = _lib._objc_msgSend_666(_lib._class_NSCalendar1,
        _lib._sel_calendarWithIdentifier_1, calendarIdentifierConstant);
    return NSCalendar._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSCalendar init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSCalendar._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithCalendarIdentifier_(NSCalendarIdentifier ident) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithCalendarIdentifier_1, ident);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSCalendarIdentifier get calendarIdentifier {
    return _lib._objc_msgSend_20(_id, _lib._sel_calendarIdentifier1);
  }

  NSLocale? get locale {
    final _ret = _lib._objc_msgSend_176(_id, _lib._sel_locale1);
    return _ret.address == 0
        ? null
        : NSLocale._(_ret, _lib, retain: true, release: true);
  }

  set locale(NSLocale? value) {
    _lib._objc_msgSend_664(
        _id, _lib._sel_setLocale_1, value?._id ?? ffi.nullptr);
  }

  NSTimeZone? get timeZone {
    final _ret = _lib._objc_msgSend_162(_id, _lib._sel_timeZone1);
    return _ret.address == 0
        ? null
        : NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  set timeZone(NSTimeZone? value) {
    _lib._objc_msgSend_163(
        _id, _lib._sel_setTimeZone_1, value?._id ?? ffi.nullptr);
  }

  int get firstWeekday {
    return _lib._objc_msgSend_10(_id, _lib._sel_firstWeekday1);
  }

  set firstWeekday(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setFirstWeekday_1, value);
  }

  int get minimumDaysInFirstWeek {
    return _lib._objc_msgSend_10(_id, _lib._sel_minimumDaysInFirstWeek1);
  }

  set minimumDaysInFirstWeek(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setMinimumDaysInFirstWeek_1, value);
  }

  NSArray? get eraSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_eraSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get longEraSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_longEraSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get monthSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_monthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get shortMonthSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_shortMonthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get veryShortMonthSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_veryShortMonthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get standaloneMonthSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_standaloneMonthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get shortStandaloneMonthSymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_shortStandaloneMonthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get veryShortStandaloneMonthSymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_veryShortStandaloneMonthSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get weekdaySymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_weekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get shortWeekdaySymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_shortWeekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get veryShortWeekdaySymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_veryShortWeekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get standaloneWeekdaySymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_standaloneWeekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get shortStandaloneWeekdaySymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_shortStandaloneWeekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get veryShortStandaloneWeekdaySymbols {
    final _ret = _lib._objc_msgSend_80(
        _id, _lib._sel_veryShortStandaloneWeekdaySymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get quarterSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_quarterSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get shortQuarterSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_shortQuarterSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get standaloneQuarterSymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_standaloneQuarterSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get shortStandaloneQuarterSymbols {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_shortStandaloneQuarterSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString? get AMSymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_AMSymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get PMSymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_PMSymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSRange minimumRangeOfUnit_(int unit) {
    return _lib._objc_msgSend_667(_id, _lib._sel_minimumRangeOfUnit_1, unit);
  }

  NSRange maximumRangeOfUnit_(int unit) {
    return _lib._objc_msgSend_667(_id, _lib._sel_maximumRangeOfUnit_1, unit);
  }

  NSRange rangeOfUnit_inUnit_forDate_(int smaller, int larger, NSDate? date) {
    return _lib._objc_msgSend_668(_id, _lib._sel_rangeOfUnit_inUnit_forDate_1,
        smaller, larger, date?._id ?? ffi.nullptr);
  }

  int ordinalityOfUnit_inUnit_forDate_(int smaller, int larger, NSDate? date) {
    return _lib._objc_msgSend_669(
        _id,
        _lib._sel_ordinalityOfUnit_inUnit_forDate_1,
        smaller,
        larger,
        date?._id ?? ffi.nullptr);
  }

  bool rangeOfUnit_startDate_interval_forDate_(
      int unit,
      ffi.Pointer<ffi.Pointer<ObjCObject>> datep,
      ffi.Pointer<NSTimeInterval> tip,
      NSDate? date) {
    return _lib._objc_msgSend_670(
        _id,
        _lib._sel_rangeOfUnit_startDate_interval_forDate_1,
        unit,
        datep,
        tip,
        date?._id ?? ffi.nullptr);
  }

  NSDate dateFromComponents_(NSDateComponents? comps) {
    final _ret = _lib._objc_msgSend_675(
        _id, _lib._sel_dateFromComponents_1, comps?._id ?? ffi.nullptr);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDateComponents components_fromDate_(int unitFlags, NSDate? date) {
    final _ret = _lib._objc_msgSend_676(_id, _lib._sel_components_fromDate_1,
        unitFlags, date?._id ?? ffi.nullptr);
    return NSDateComponents._(_ret, _lib, retain: true, release: true);
  }

  NSDate dateByAddingComponents_toDate_options_(
      NSDateComponents? comps, NSDate? date, int opts) {
    final _ret = _lib._objc_msgSend_677(
        _id,
        _lib._sel_dateByAddingComponents_toDate_options_1,
        comps?._id ?? ffi.nullptr,
        date?._id ?? ffi.nullptr,
        opts);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDateComponents components_fromDate_toDate_options_(
      int unitFlags, NSDate? startingDate, NSDate? resultDate, int opts) {
    final _ret = _lib._objc_msgSend_678(
        _id,
        _lib._sel_components_fromDate_toDate_options_1,
        unitFlags,
        startingDate?._id ?? ffi.nullptr,
        resultDate?._id ?? ffi.nullptr,
        opts);
    return NSDateComponents._(_ret, _lib, retain: true, release: true);
  }

  void getEra_year_month_day_fromDate_(
      ffi.Pointer<NSInteger> eraValuePointer,
      ffi.Pointer<NSInteger> yearValuePointer,
      ffi.Pointer<NSInteger> monthValuePointer,
      ffi.Pointer<NSInteger> dayValuePointer,
      NSDate? date) {
    return _lib._objc_msgSend_679(
        _id,
        _lib._sel_getEra_year_month_day_fromDate_1,
        eraValuePointer,
        yearValuePointer,
        monthValuePointer,
        dayValuePointer,
        date?._id ?? ffi.nullptr);
  }

  void getEra_yearForWeekOfYear_weekOfYear_weekday_fromDate_(
      ffi.Pointer<NSInteger> eraValuePointer,
      ffi.Pointer<NSInteger> yearValuePointer,
      ffi.Pointer<NSInteger> weekValuePointer,
      ffi.Pointer<NSInteger> weekdayValuePointer,
      NSDate? date) {
    return _lib._objc_msgSend_679(
        _id,
        _lib._sel_getEra_yearForWeekOfYear_weekOfYear_weekday_fromDate_1,
        eraValuePointer,
        yearValuePointer,
        weekValuePointer,
        weekdayValuePointer,
        date?._id ?? ffi.nullptr);
  }

  void getHour_minute_second_nanosecond_fromDate_(
      ffi.Pointer<NSInteger> hourValuePointer,
      ffi.Pointer<NSInteger> minuteValuePointer,
      ffi.Pointer<NSInteger> secondValuePointer,
      ffi.Pointer<NSInteger> nanosecondValuePointer,
      NSDate? date) {
    return _lib._objc_msgSend_679(
        _id,
        _lib._sel_getHour_minute_second_nanosecond_fromDate_1,
        hourValuePointer,
        minuteValuePointer,
        secondValuePointer,
        nanosecondValuePointer,
        date?._id ?? ffi.nullptr);
  }

  int component_fromDate_(int unit, NSDate? date) {
    return _lib._objc_msgSend_680(
        _id, _lib._sel_component_fromDate_1, unit, date?._id ?? ffi.nullptr);
  }

  NSDate dateWithEra_year_month_day_hour_minute_second_nanosecond_(
      int eraValue,
      int yearValue,
      int monthValue,
      int dayValue,
      int hourValue,
      int minuteValue,
      int secondValue,
      int nanosecondValue) {
    final _ret = _lib._objc_msgSend_681(
        _id,
        _lib._sel_dateWithEra_year_month_day_hour_minute_second_nanosecond_1,
        eraValue,
        yearValue,
        monthValue,
        dayValue,
        hourValue,
        minuteValue,
        secondValue,
        nanosecondValue);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate
      dateWithEra_yearForWeekOfYear_weekOfYear_weekday_hour_minute_second_nanosecond_(
          int eraValue,
          int yearValue,
          int weekValue,
          int weekdayValue,
          int hourValue,
          int minuteValue,
          int secondValue,
          int nanosecondValue) {
    final _ret = _lib._objc_msgSend_681(
        _id,
        _lib._sel_dateWithEra_yearForWeekOfYear_weekOfYear_weekday_hour_minute_second_nanosecond_1,
        eraValue,
        yearValue,
        weekValue,
        weekdayValue,
        hourValue,
        minuteValue,
        secondValue,
        nanosecondValue);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate startOfDayForDate_(NSDate? date) {
    final _ret = _lib._objc_msgSend_152(
        _id, _lib._sel_startOfDayForDate_1, date?._id ?? ffi.nullptr);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDateComponents componentsInTimeZone_fromDate_(
      NSTimeZone? timezone, NSDate? date) {
    final _ret = _lib._objc_msgSend_682(
        _id,
        _lib._sel_componentsInTimeZone_fromDate_1,
        timezone?._id ?? ffi.nullptr,
        date?._id ?? ffi.nullptr);
    return NSDateComponents._(_ret, _lib, retain: true, release: true);
  }

  int compareDate_toDate_toUnitGranularity_(
      NSDate? date1, NSDate? date2, int unit) {
    return _lib._objc_msgSend_683(
        _id,
        _lib._sel_compareDate_toDate_toUnitGranularity_1,
        date1?._id ?? ffi.nullptr,
        date2?._id ?? ffi.nullptr,
        unit);
  }

  bool isDate_equalToDate_toUnitGranularity_(
      NSDate? date1, NSDate? date2, int unit) {
    return _lib._objc_msgSend_684(
        _id,
        _lib._sel_isDate_equalToDate_toUnitGranularity_1,
        date1?._id ?? ffi.nullptr,
        date2?._id ?? ffi.nullptr,
        unit);
  }

  bool isDate_inSameDayAsDate_(NSDate? date1, NSDate? date2) {
    return _lib._objc_msgSend_685(_id, _lib._sel_isDate_inSameDayAsDate_1,
        date1?._id ?? ffi.nullptr, date2?._id ?? ffi.nullptr);
  }

  bool isDateInToday_(NSDate? date) {
    return _lib._objc_msgSend_154(
        _id, _lib._sel_isDateInToday_1, date?._id ?? ffi.nullptr);
  }

  bool isDateInYesterday_(NSDate? date) {
    return _lib._objc_msgSend_154(
        _id, _lib._sel_isDateInYesterday_1, date?._id ?? ffi.nullptr);
  }

  bool isDateInTomorrow_(NSDate? date) {
    return _lib._objc_msgSend_154(
        _id, _lib._sel_isDateInTomorrow_1, date?._id ?? ffi.nullptr);
  }

  bool isDateInWeekend_(NSDate? date) {
    return _lib._objc_msgSend_154(
        _id, _lib._sel_isDateInWeekend_1, date?._id ?? ffi.nullptr);
  }

  bool rangeOfWeekendStartDate_interval_containingDate_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> datep,
      ffi.Pointer<NSTimeInterval> tip,
      NSDate? date) {
    return _lib._objc_msgSend_686(
        _id,
        _lib._sel_rangeOfWeekendStartDate_interval_containingDate_1,
        datep,
        tip,
        date?._id ?? ffi.nullptr);
  }

  bool nextWeekendStartDate_interval_options_afterDate_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> datep,
      ffi.Pointer<NSTimeInterval> tip,
      int options,
      NSDate? date) {
    return _lib._objc_msgSend_687(
        _id,
        _lib._sel_nextWeekendStartDate_interval_options_afterDate_1,
        datep,
        tip,
        options,
        date?._id ?? ffi.nullptr);
  }

  NSDateComponents components_fromDateComponents_toDateComponents_options_(
      int unitFlags,
      NSDateComponents? startingDateComp,
      NSDateComponents? resultDateComp,
      int options) {
    final _ret = _lib._objc_msgSend_688(
        _id,
        _lib._sel_components_fromDateComponents_toDateComponents_options_1,
        unitFlags,
        startingDateComp?._id ?? ffi.nullptr,
        resultDateComp?._id ?? ffi.nullptr,
        options);
    return NSDateComponents._(_ret, _lib, retain: true, release: true);
  }

  NSDate dateByAddingUnit_value_toDate_options_(
      int unit, int value, NSDate? date, int options) {
    final _ret = _lib._objc_msgSend_689(
        _id,
        _lib._sel_dateByAddingUnit_value_toDate_options_1,
        unit,
        value,
        date?._id ?? ffi.nullptr,
        options);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  void enumerateDatesStartingAfterDate_matchingComponents_options_usingBlock_(
      NSDate? start, NSDateComponents? comps, int opts, ObjCBlock28 block) {
    return _lib._objc_msgSend_690(
        _id,
        _lib._sel_enumerateDatesStartingAfterDate_matchingComponents_options_usingBlock_1,
        start?._id ?? ffi.nullptr,
        comps?._id ?? ffi.nullptr,
        opts,
        block._id);
  }

  NSDate nextDateAfterDate_matchingComponents_options_(
      NSDate? date, NSDateComponents? comps, int options) {
    final _ret = _lib._objc_msgSend_691(
        _id,
        _lib._sel_nextDateAfterDate_matchingComponents_options_1,
        date?._id ?? ffi.nullptr,
        comps?._id ?? ffi.nullptr,
        options);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate nextDateAfterDate_matchingUnit_value_options_(
      NSDate? date, int unit, int value, int options) {
    final _ret = _lib._objc_msgSend_692(
        _id,
        _lib._sel_nextDateAfterDate_matchingUnit_value_options_1,
        date?._id ?? ffi.nullptr,
        unit,
        value,
        options);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate nextDateAfterDate_matchingHour_minute_second_options_(NSDate? date,
      int hourValue, int minuteValue, int secondValue, int options) {
    final _ret = _lib._objc_msgSend_693(
        _id,
        _lib._sel_nextDateAfterDate_matchingHour_minute_second_options_1,
        date?._id ?? ffi.nullptr,
        hourValue,
        minuteValue,
        secondValue,
        options);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate dateBySettingUnit_value_ofDate_options_(
      int unit, int v, NSDate? date, int opts) {
    final _ret = _lib._objc_msgSend_689(
        _id,
        _lib._sel_dateBySettingUnit_value_ofDate_options_1,
        unit,
        v,
        date?._id ?? ffi.nullptr,
        opts);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSDate dateBySettingHour_minute_second_ofDate_options_(
      int h, int m, int s, NSDate? date, int opts) {
    final _ret = _lib._objc_msgSend_694(
        _id,
        _lib._sel_dateBySettingHour_minute_second_ofDate_options_1,
        h,
        m,
        s,
        date?._id ?? ffi.nullptr,
        opts);
    return NSDate._(_ret, _lib, retain: true, release: true);
  }

  bool date_matchesComponents_(NSDate? date, NSDateComponents? components) {
    return _lib._objc_msgSend_695(_id, _lib._sel_date_matchesComponents_1,
        date?._id ?? ffi.nullptr, components?._id ?? ffi.nullptr);
  }

  static NSCalendar new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSCalendar1, _lib._sel_new1);
    return NSCalendar._(_ret, _lib, retain: false, release: true);
  }

  static NSCalendar alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSCalendar1, _lib._sel_alloc1);
    return NSCalendar._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSCalendar1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSCalendar1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSCalendar1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSCalendar1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSCalendar1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSCalendar1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSCalendar1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSCalendar1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSCalendar1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSCalendarIdentifier = ffi.Pointer<ObjCObject>;

abstract class NSCalendarUnit {
  static const int NSCalendarUnitEra = 2;
  static const int NSCalendarUnitYear = 4;
  static const int NSCalendarUnitMonth = 8;
  static const int NSCalendarUnitDay = 16;
  static const int NSCalendarUnitHour = 32;
  static const int NSCalendarUnitMinute = 64;
  static const int NSCalendarUnitSecond = 128;
  static const int NSCalendarUnitWeekday = 512;
  static const int NSCalendarUnitWeekdayOrdinal = 1024;
  static const int NSCalendarUnitQuarter = 2048;
  static const int NSCalendarUnitWeekOfMonth = 4096;
  static const int NSCalendarUnitWeekOfYear = 8192;
  static const int NSCalendarUnitYearForWeekOfYear = 16384;
  static const int NSCalendarUnitNanosecond = 32768;
  static const int NSCalendarUnitCalendar = 1048576;
  static const int NSCalendarUnitTimeZone = 2097152;
  static const int NSEraCalendarUnit = 2;
  static const int NSYearCalendarUnit = 4;
  static const int NSMonthCalendarUnit = 8;
  static const int NSDayCalendarUnit = 16;
  static const int NSHourCalendarUnit = 32;
  static const int NSMinuteCalendarUnit = 64;
  static const int NSSecondCalendarUnit = 128;
  static const int NSWeekCalendarUnit = 256;
  static const int NSWeekdayCalendarUnit = 512;
  static const int NSWeekdayOrdinalCalendarUnit = 1024;
  static const int NSQuarterCalendarUnit = 2048;
  static const int NSWeekOfMonthCalendarUnit = 4096;
  static const int NSWeekOfYearCalendarUnit = 8192;
  static const int NSYearForWeekOfYearCalendarUnit = 16384;
  static const int NSCalendarCalendarUnit = 1048576;
  static const int NSTimeZoneCalendarUnit = 2097152;
}

class NSDateComponents extends NSObject {
  NSDateComponents._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSDateComponents] that points to the same underlying object as [other].
  static NSDateComponents castFrom<T extends _ObjCWrapper>(T other) {
    return NSDateComponents._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSDateComponents] that wraps the given raw object pointer.
  static NSDateComponents castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSDateComponents._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSDateComponents].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSDateComponents1);
  }

  NSCalendar? get calendar {
    final _ret = _lib._objc_msgSend_665(_id, _lib._sel_calendar1);
    return _ret.address == 0
        ? null
        : NSCalendar._(_ret, _lib, retain: true, release: true);
  }

  set calendar(NSCalendar? value) {
    _lib._objc_msgSend_671(
        _id, _lib._sel_setCalendar_1, value?._id ?? ffi.nullptr);
  }

  NSTimeZone? get timeZone {
    final _ret = _lib._objc_msgSend_162(_id, _lib._sel_timeZone1);
    return _ret.address == 0
        ? null
        : NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  set timeZone(NSTimeZone? value) {
    _lib._objc_msgSend_163(
        _id, _lib._sel_setTimeZone_1, value?._id ?? ffi.nullptr);
  }

  int get era {
    return _lib._objc_msgSend_78(_id, _lib._sel_era1);
  }

  set era(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setEra_1, value);
  }

  int get year {
    return _lib._objc_msgSend_78(_id, _lib._sel_year1);
  }

  set year(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setYear_1, value);
  }

  int get month {
    return _lib._objc_msgSend_78(_id, _lib._sel_month1);
  }

  set month(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setMonth_1, value);
  }

  int get day {
    return _lib._objc_msgSend_78(_id, _lib._sel_day1);
  }

  set day(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setDay_1, value);
  }

  int get hour {
    return _lib._objc_msgSend_78(_id, _lib._sel_hour1);
  }

  set hour(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setHour_1, value);
  }

  int get minute {
    return _lib._objc_msgSend_78(_id, _lib._sel_minute1);
  }

  set minute(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setMinute_1, value);
  }

  int get second {
    return _lib._objc_msgSend_78(_id, _lib._sel_second1);
  }

  set second(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setSecond_1, value);
  }

  int get nanosecond {
    return _lib._objc_msgSend_78(_id, _lib._sel_nanosecond1);
  }

  set nanosecond(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setNanosecond_1, value);
  }

  int get weekday {
    return _lib._objc_msgSend_78(_id, _lib._sel_weekday1);
  }

  set weekday(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setWeekday_1, value);
  }

  int get weekdayOrdinal {
    return _lib._objc_msgSend_78(_id, _lib._sel_weekdayOrdinal1);
  }

  set weekdayOrdinal(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setWeekdayOrdinal_1, value);
  }

  int get quarter {
    return _lib._objc_msgSend_78(_id, _lib._sel_quarter1);
  }

  set quarter(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setQuarter_1, value);
  }

  int get weekOfMonth {
    return _lib._objc_msgSend_78(_id, _lib._sel_weekOfMonth1);
  }

  set weekOfMonth(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setWeekOfMonth_1, value);
  }

  int get weekOfYear {
    return _lib._objc_msgSend_78(_id, _lib._sel_weekOfYear1);
  }

  set weekOfYear(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setWeekOfYear_1, value);
  }

  int get yearForWeekOfYear {
    return _lib._objc_msgSend_78(_id, _lib._sel_yearForWeekOfYear1);
  }

  set yearForWeekOfYear(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setYearForWeekOfYear_1, value);
  }

  bool get leapMonth {
    return _lib._objc_msgSend_12(_id, _lib._sel_isLeapMonth1);
  }

  set leapMonth(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setLeapMonth_1, value);
  }

  NSDate? get date {
    final _ret = _lib._objc_msgSend_156(_id, _lib._sel_date1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  int week() {
    return _lib._objc_msgSend_78(_id, _lib._sel_week1);
  }

  void setWeek_(int v) {
    return _lib._objc_msgSend_374(_id, _lib._sel_setWeek_1, v);
  }

  void setValue_forComponent_(int value, int unit) {
    return _lib._objc_msgSend_672(
        _id, _lib._sel_setValue_forComponent_1, value, unit);
  }

  int valueForComponent_(int unit) {
    return _lib._objc_msgSend_673(_id, _lib._sel_valueForComponent_1, unit);
  }

  bool get validDate {
    return _lib._objc_msgSend_12(_id, _lib._sel_isValidDate1);
  }

  bool isValidDateInCalendar_(NSCalendar? calendar) {
    return _lib._objc_msgSend_674(
        _id, _lib._sel_isValidDateInCalendar_1, calendar?._id ?? ffi.nullptr);
  }

  static NSDateComponents new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSDateComponents1, _lib._sel_new1);
    return NSDateComponents._(_ret, _lib, retain: false, release: true);
  }

  static NSDateComponents alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSDateComponents1, _lib._sel_alloc1);
    return NSDateComponents._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSDateComponents1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSDateComponents1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSDateComponents1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSDateComponents1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSDateComponents1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSDateComponents1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSDateComponents1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSDateComponents1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSDateComponents1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSCalendarOptions {
  static const int NSCalendarWrapComponents = 1;
  static const int NSCalendarMatchStrictly = 2;
  static const int NSCalendarSearchBackwards = 4;
  static const int NSCalendarMatchPreviousTimePreservingSmallerUnits = 256;
  static const int NSCalendarMatchNextTimePreservingSmallerUnits = 512;
  static const int NSCalendarMatchNextTime = 1024;
  static const int NSCalendarMatchFirst = 4096;
  static const int NSCalendarMatchLast = 8192;
}

void _ObjCBlock28_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, bool arg1, ffi.Pointer<ffi.Bool> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0, ffi.Bool arg1,
                  ffi.Pointer<ffi.Bool> arg2)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0, bool arg1,
              ffi.Pointer<ffi.Bool> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock28_closureRegistry = <int, Function>{};
int _ObjCBlock28_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock28_registerClosure(Function fn) {
  final id = ++_ObjCBlock28_closureRegistryIndex;
  _ObjCBlock28_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock28_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, bool arg1, ffi.Pointer<ffi.Bool> arg2) {
  return _ObjCBlock28_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock28 extends _ObjCBlockBase {
  ObjCBlock28._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock28.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0, ffi.Bool arg1,
                      ffi.Pointer<ffi.Bool> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Bool arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock28_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock28.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, bool arg1,
              ffi.Pointer<ffi.Bool> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Bool arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock28_closureTrampoline)
                    .cast(),
                _ObjCBlock28_registerClosure(fn)),
            lib);
  void call(
      ffi.Pointer<ObjCObject> arg0, bool arg1, ffi.Pointer<ffi.Bool> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Bool arg1,
                    ffi.Pointer<ffi.Bool> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                bool arg1,
                ffi.Pointer<ffi.Bool> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSNumberFormatter extends NSFormatter {
  NSNumberFormatter._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSNumberFormatter] that points to the same underlying object as [other].
  static NSNumberFormatter castFrom<T extends _ObjCWrapper>(T other) {
    return NSNumberFormatter._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSNumberFormatter] that wraps the given raw object pointer.
  static NSNumberFormatter castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSNumberFormatter._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSNumberFormatter].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSNumberFormatter1);
  }

  int get formattingContext {
    return _lib._objc_msgSend_655(_id, _lib._sel_formattingContext1);
  }

  set formattingContext(int value) {
    _lib._objc_msgSend_656(_id, _lib._sel_setFormattingContext_1, value);
  }

  bool getObjectValue_forString_range_error_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> obj,
      NSString? string,
      ffi.Pointer<NSRange> rangep,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_657(
        _id,
        _lib._sel_getObjectValue_forString_range_error_1,
        obj,
        string?._id ?? ffi.nullptr,
        rangep,
        error);
  }

  NSString stringFromNumber_(NSNumber? number) {
    final _ret = _lib._objc_msgSend_697(
        _id, _lib._sel_stringFromNumber_1, number?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSNumber numberFromString_(NSString? string) {
    final _ret = _lib._objc_msgSend_698(
        _id, _lib._sel_numberFromString_1, string?._id ?? ffi.nullptr);
    return NSNumber._(_ret, _lib, retain: true, release: true);
  }

  static NSString localizedStringFromNumber_numberStyle_(
      AVFAudio _lib, NSNumber? num, int nstyle) {
    final _ret = _lib._objc_msgSend_699(
        _lib._class_NSNumberFormatter1,
        _lib._sel_localizedStringFromNumber_numberStyle_1,
        num?._id ?? ffi.nullptr,
        nstyle);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static int defaultFormatterBehavior(AVFAudio _lib) {
    return _lib._objc_msgSend_700(
        _lib._class_NSNumberFormatter1, _lib._sel_defaultFormatterBehavior1);
  }

  static void setDefaultFormatterBehavior_(AVFAudio _lib, int behavior) {
    return _lib._objc_msgSend_701(_lib._class_NSNumberFormatter1,
        _lib._sel_setDefaultFormatterBehavior_1, behavior);
  }

  int get numberStyle {
    return _lib._objc_msgSend_702(_id, _lib._sel_numberStyle1);
  }

  set numberStyle(int value) {
    _lib._objc_msgSend_703(_id, _lib._sel_setNumberStyle_1, value);
  }

  NSLocale? get locale {
    final _ret = _lib._objc_msgSend_176(_id, _lib._sel_locale1);
    return _ret.address == 0
        ? null
        : NSLocale._(_ret, _lib, retain: true, release: true);
  }

  set locale(NSLocale? value) {
    _lib._objc_msgSend_664(
        _id, _lib._sel_setLocale_1, value?._id ?? ffi.nullptr);
  }

  bool get generatesDecimalNumbers {
    return _lib._objc_msgSend_12(_id, _lib._sel_generatesDecimalNumbers1);
  }

  set generatesDecimalNumbers(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setGeneratesDecimalNumbers_1, value);
  }

  int get formatterBehavior {
    return _lib._objc_msgSend_700(_id, _lib._sel_formatterBehavior1);
  }

  set formatterBehavior(int value) {
    _lib._objc_msgSend_704(_id, _lib._sel_setFormatterBehavior_1, value);
  }

  NSString? get negativeFormat {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_negativeFormat1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set negativeFormat(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setNegativeFormat_1, value?._id ?? ffi.nullptr);
  }

  NSDictionary? get textAttributesForNegativeValues {
    final _ret =
        _lib._objc_msgSend_164(_id, _lib._sel_textAttributesForNegativeValues1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set textAttributesForNegativeValues(NSDictionary? value) {
    _lib._objc_msgSend_165(_id, _lib._sel_setTextAttributesForNegativeValues_1,
        value?._id ?? ffi.nullptr);
  }

  NSString? get positiveFormat {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_positiveFormat1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set positiveFormat(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPositiveFormat_1, value?._id ?? ffi.nullptr);
  }

  NSDictionary? get textAttributesForPositiveValues {
    final _ret =
        _lib._objc_msgSend_164(_id, _lib._sel_textAttributesForPositiveValues1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set textAttributesForPositiveValues(NSDictionary? value) {
    _lib._objc_msgSend_165(_id, _lib._sel_setTextAttributesForPositiveValues_1,
        value?._id ?? ffi.nullptr);
  }

  bool get allowsFloats {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsFloats1);
  }

  set allowsFloats(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setAllowsFloats_1, value);
  }

  NSString? get decimalSeparator {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_decimalSeparator1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set decimalSeparator(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setDecimalSeparator_1, value?._id ?? ffi.nullptr);
  }

  bool get alwaysShowsDecimalSeparator {
    return _lib._objc_msgSend_12(_id, _lib._sel_alwaysShowsDecimalSeparator1);
  }

  set alwaysShowsDecimalSeparator(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setAlwaysShowsDecimalSeparator_1, value);
  }

  NSString? get currencyDecimalSeparator {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_currencyDecimalSeparator1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set currencyDecimalSeparator(NSString? value) {
    _lib._objc_msgSend_477(_id, _lib._sel_setCurrencyDecimalSeparator_1,
        value?._id ?? ffi.nullptr);
  }

  bool get usesGroupingSeparator {
    return _lib._objc_msgSend_12(_id, _lib._sel_usesGroupingSeparator1);
  }

  set usesGroupingSeparator(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setUsesGroupingSeparator_1, value);
  }

  NSString? get groupingSeparator {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_groupingSeparator1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set groupingSeparator(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setGroupingSeparator_1, value?._id ?? ffi.nullptr);
  }

  NSString? get zeroSymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_zeroSymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set zeroSymbol(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setZeroSymbol_1, value?._id ?? ffi.nullptr);
  }

  NSDictionary? get textAttributesForZero {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_textAttributesForZero1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set textAttributesForZero(NSDictionary? value) {
    _lib._objc_msgSend_165(
        _id, _lib._sel_setTextAttributesForZero_1, value?._id ?? ffi.nullptr);
  }

  NSString? get nilSymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_nilSymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set nilSymbol(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setNilSymbol_1, value?._id ?? ffi.nullptr);
  }

  NSDictionary? get textAttributesForNil {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_textAttributesForNil1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set textAttributesForNil(NSDictionary? value) {
    _lib._objc_msgSend_165(
        _id, _lib._sel_setTextAttributesForNil_1, value?._id ?? ffi.nullptr);
  }

  NSString? get notANumberSymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_notANumberSymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set notANumberSymbol(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setNotANumberSymbol_1, value?._id ?? ffi.nullptr);
  }

  NSDictionary? get textAttributesForNotANumber {
    final _ret =
        _lib._objc_msgSend_164(_id, _lib._sel_textAttributesForNotANumber1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set textAttributesForNotANumber(NSDictionary? value) {
    _lib._objc_msgSend_165(_id, _lib._sel_setTextAttributesForNotANumber_1,
        value?._id ?? ffi.nullptr);
  }

  NSString? get positiveInfinitySymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_positiveInfinitySymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set positiveInfinitySymbol(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPositiveInfinitySymbol_1, value?._id ?? ffi.nullptr);
  }

  NSDictionary? get textAttributesForPositiveInfinity {
    final _ret = _lib._objc_msgSend_164(
        _id, _lib._sel_textAttributesForPositiveInfinity1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set textAttributesForPositiveInfinity(NSDictionary? value) {
    _lib._objc_msgSend_165(
        _id,
        _lib._sel_setTextAttributesForPositiveInfinity_1,
        value?._id ?? ffi.nullptr);
  }

  NSString? get negativeInfinitySymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_negativeInfinitySymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set negativeInfinitySymbol(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setNegativeInfinitySymbol_1, value?._id ?? ffi.nullptr);
  }

  NSDictionary? get textAttributesForNegativeInfinity {
    final _ret = _lib._objc_msgSend_164(
        _id, _lib._sel_textAttributesForNegativeInfinity1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set textAttributesForNegativeInfinity(NSDictionary? value) {
    _lib._objc_msgSend_165(
        _id,
        _lib._sel_setTextAttributesForNegativeInfinity_1,
        value?._id ?? ffi.nullptr);
  }

  NSString? get positivePrefix {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_positivePrefix1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set positivePrefix(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPositivePrefix_1, value?._id ?? ffi.nullptr);
  }

  NSString? get positiveSuffix {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_positiveSuffix1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set positiveSuffix(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPositiveSuffix_1, value?._id ?? ffi.nullptr);
  }

  NSString? get negativePrefix {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_negativePrefix1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set negativePrefix(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setNegativePrefix_1, value?._id ?? ffi.nullptr);
  }

  NSString? get negativeSuffix {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_negativeSuffix1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set negativeSuffix(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setNegativeSuffix_1, value?._id ?? ffi.nullptr);
  }

  NSString? get currencyCode {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_currencyCode1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set currencyCode(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setCurrencyCode_1, value?._id ?? ffi.nullptr);
  }

  NSString? get currencySymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_currencySymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set currencySymbol(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setCurrencySymbol_1, value?._id ?? ffi.nullptr);
  }

  NSString? get internationalCurrencySymbol {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_internationalCurrencySymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set internationalCurrencySymbol(NSString? value) {
    _lib._objc_msgSend_477(_id, _lib._sel_setInternationalCurrencySymbol_1,
        value?._id ?? ffi.nullptr);
  }

  NSString? get percentSymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_percentSymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set percentSymbol(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPercentSymbol_1, value?._id ?? ffi.nullptr);
  }

  NSString? get perMillSymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_perMillSymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set perMillSymbol(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPerMillSymbol_1, value?._id ?? ffi.nullptr);
  }

  NSString? get minusSign {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_minusSign1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set minusSign(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setMinusSign_1, value?._id ?? ffi.nullptr);
  }

  NSString? get plusSign {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_plusSign1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set plusSign(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPlusSign_1, value?._id ?? ffi.nullptr);
  }

  NSString? get exponentSymbol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_exponentSymbol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set exponentSymbol(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setExponentSymbol_1, value?._id ?? ffi.nullptr);
  }

  int get groupingSize {
    return _lib._objc_msgSend_10(_id, _lib._sel_groupingSize1);
  }

  set groupingSize(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setGroupingSize_1, value);
  }

  int get secondaryGroupingSize {
    return _lib._objc_msgSend_10(_id, _lib._sel_secondaryGroupingSize1);
  }

  set secondaryGroupingSize(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setSecondaryGroupingSize_1, value);
  }

  NSNumber? get multiplier {
    final _ret = _lib._objc_msgSend_192(_id, _lib._sel_multiplier1);
    return _ret.address == 0
        ? null
        : NSNumber._(_ret, _lib, retain: true, release: true);
  }

  set multiplier(NSNumber? value) {
    _lib._objc_msgSend_705(
        _id, _lib._sel_setMultiplier_1, value?._id ?? ffi.nullptr);
  }

  int get formatWidth {
    return _lib._objc_msgSend_10(_id, _lib._sel_formatWidth1);
  }

  set formatWidth(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setFormatWidth_1, value);
  }

  NSString? get paddingCharacter {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_paddingCharacter1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set paddingCharacter(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPaddingCharacter_1, value?._id ?? ffi.nullptr);
  }

  int get paddingPosition {
    return _lib._objc_msgSend_706(_id, _lib._sel_paddingPosition1);
  }

  set paddingPosition(int value) {
    _lib._objc_msgSend_707(_id, _lib._sel_setPaddingPosition_1, value);
  }

  int get roundingMode {
    return _lib._objc_msgSend_708(_id, _lib._sel_roundingMode1);
  }

  set roundingMode(int value) {
    _lib._objc_msgSend_709(_id, _lib._sel_setRoundingMode_1, value);
  }

  NSNumber? get roundingIncrement {
    final _ret = _lib._objc_msgSend_192(_id, _lib._sel_roundingIncrement1);
    return _ret.address == 0
        ? null
        : NSNumber._(_ret, _lib, retain: true, release: true);
  }

  set roundingIncrement(NSNumber? value) {
    _lib._objc_msgSend_705(
        _id, _lib._sel_setRoundingIncrement_1, value?._id ?? ffi.nullptr);
  }

  int get minimumIntegerDigits {
    return _lib._objc_msgSend_10(_id, _lib._sel_minimumIntegerDigits1);
  }

  set minimumIntegerDigits(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setMinimumIntegerDigits_1, value);
  }

  int get maximumIntegerDigits {
    return _lib._objc_msgSend_10(_id, _lib._sel_maximumIntegerDigits1);
  }

  set maximumIntegerDigits(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setMaximumIntegerDigits_1, value);
  }

  int get minimumFractionDigits {
    return _lib._objc_msgSend_10(_id, _lib._sel_minimumFractionDigits1);
  }

  set minimumFractionDigits(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setMinimumFractionDigits_1, value);
  }

  int get maximumFractionDigits {
    return _lib._objc_msgSend_10(_id, _lib._sel_maximumFractionDigits1);
  }

  set maximumFractionDigits(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setMaximumFractionDigits_1, value);
  }

  NSNumber? get minimum {
    final _ret = _lib._objc_msgSend_192(_id, _lib._sel_minimum1);
    return _ret.address == 0
        ? null
        : NSNumber._(_ret, _lib, retain: true, release: true);
  }

  set minimum(NSNumber? value) {
    _lib._objc_msgSend_705(
        _id, _lib._sel_setMinimum_1, value?._id ?? ffi.nullptr);
  }

  NSNumber? get maximum {
    final _ret = _lib._objc_msgSend_192(_id, _lib._sel_maximum1);
    return _ret.address == 0
        ? null
        : NSNumber._(_ret, _lib, retain: true, release: true);
  }

  set maximum(NSNumber? value) {
    _lib._objc_msgSend_705(
        _id, _lib._sel_setMaximum_1, value?._id ?? ffi.nullptr);
  }

  NSString? get currencyGroupingSeparator {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_currencyGroupingSeparator1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set currencyGroupingSeparator(NSString? value) {
    _lib._objc_msgSend_477(_id, _lib._sel_setCurrencyGroupingSeparator_1,
        value?._id ?? ffi.nullptr);
  }

  bool get lenient {
    return _lib._objc_msgSend_12(_id, _lib._sel_isLenient1);
  }

  set lenient(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setLenient_1, value);
  }

  bool get usesSignificantDigits {
    return _lib._objc_msgSend_12(_id, _lib._sel_usesSignificantDigits1);
  }

  set usesSignificantDigits(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setUsesSignificantDigits_1, value);
  }

  int get minimumSignificantDigits {
    return _lib._objc_msgSend_10(_id, _lib._sel_minimumSignificantDigits1);
  }

  set minimumSignificantDigits(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setMinimumSignificantDigits_1, value);
  }

  int get maximumSignificantDigits {
    return _lib._objc_msgSend_10(_id, _lib._sel_maximumSignificantDigits1);
  }

  set maximumSignificantDigits(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setMaximumSignificantDigits_1, value);
  }

  bool get partialStringValidationEnabled {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_isPartialStringValidationEnabled1);
  }

  set partialStringValidationEnabled(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setPartialStringValidationEnabled_1, value);
  }

  bool get hasThousandSeparators {
    return _lib._objc_msgSend_12(_id, _lib._sel_hasThousandSeparators1);
  }

  set hasThousandSeparators(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setHasThousandSeparators_1, value);
  }

  NSString? get thousandSeparator {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_thousandSeparator1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set thousandSeparator(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setThousandSeparator_1, value?._id ?? ffi.nullptr);
  }

  bool get localizesFormat {
    return _lib._objc_msgSend_12(_id, _lib._sel_localizesFormat1);
  }

  set localizesFormat(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setLocalizesFormat_1, value);
  }

  NSString? get format {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_format1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set format(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setFormat_1, value?._id ?? ffi.nullptr);
  }

  NSAttributedString? get attributedStringForZero {
    final _ret =
        _lib._objc_msgSend_640(_id, _lib._sel_attributedStringForZero1);
    return _ret.address == 0
        ? null
        : NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  set attributedStringForZero(NSAttributedString? value) {
    _lib._objc_msgSend_710(
        _id, _lib._sel_setAttributedStringForZero_1, value?._id ?? ffi.nullptr);
  }

  NSAttributedString? get attributedStringForNil {
    final _ret = _lib._objc_msgSend_640(_id, _lib._sel_attributedStringForNil1);
    return _ret.address == 0
        ? null
        : NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  set attributedStringForNil(NSAttributedString? value) {
    _lib._objc_msgSend_710(
        _id, _lib._sel_setAttributedStringForNil_1, value?._id ?? ffi.nullptr);
  }

  NSAttributedString? get attributedStringForNotANumber {
    final _ret =
        _lib._objc_msgSend_640(_id, _lib._sel_attributedStringForNotANumber1);
    return _ret.address == 0
        ? null
        : NSAttributedString._(_ret, _lib, retain: true, release: true);
  }

  set attributedStringForNotANumber(NSAttributedString? value) {
    _lib._objc_msgSend_710(_id, _lib._sel_setAttributedStringForNotANumber_1,
        value?._id ?? ffi.nullptr);
  }

  NSDecimalNumberHandler? get roundingBehavior {
    final _ret = _lib._objc_msgSend_711(_id, _lib._sel_roundingBehavior1);
    return _ret.address == 0
        ? null
        : NSDecimalNumberHandler._(_ret, _lib, retain: true, release: true);
  }

  set roundingBehavior(NSDecimalNumberHandler? value) {
    _lib._objc_msgSend_713(
        _id, _lib._sel_setRoundingBehavior_1, value?._id ?? ffi.nullptr);
  }

  static NSNumberFormatter new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSNumberFormatter1, _lib._sel_new1);
    return NSNumberFormatter._(_ret, _lib, retain: false, release: true);
  }

  static NSNumberFormatter alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSNumberFormatter1, _lib._sel_alloc1);
    return NSNumberFormatter._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSNumberFormatter1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSNumberFormatter1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSNumberFormatter1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSNumberFormatter1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSNumberFormatter1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSNumberFormatter1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSNumberFormatter1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSNumberFormatter1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSNumberFormatter1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSNumberFormatterStyle {
  static const int NSNumberFormatterNoStyle = 0;
  static const int NSNumberFormatterDecimalStyle = 1;
  static const int NSNumberFormatterCurrencyStyle = 2;
  static const int NSNumberFormatterPercentStyle = 3;
  static const int NSNumberFormatterScientificStyle = 4;
  static const int NSNumberFormatterSpellOutStyle = 5;
  static const int NSNumberFormatterOrdinalStyle = 6;
  static const int NSNumberFormatterCurrencyISOCodeStyle = 8;
  static const int NSNumberFormatterCurrencyPluralStyle = 9;
  static const int NSNumberFormatterCurrencyAccountingStyle = 10;
}

abstract class NSNumberFormatterBehavior {
  static const int NSNumberFormatterBehaviorDefault = 0;
  static const int NSNumberFormatterBehavior10_0 = 1000;
  static const int NSNumberFormatterBehavior10_4 = 1040;
}

abstract class NSNumberFormatterPadPosition {
  static const int NSNumberFormatterPadBeforePrefix = 0;
  static const int NSNumberFormatterPadAfterPrefix = 1;
  static const int NSNumberFormatterPadBeforeSuffix = 2;
  static const int NSNumberFormatterPadAfterSuffix = 3;
}

abstract class NSNumberFormatterRoundingMode {
  static const int NSNumberFormatterRoundCeiling = 0;
  static const int NSNumberFormatterRoundFloor = 1;
  static const int NSNumberFormatterRoundDown = 2;
  static const int NSNumberFormatterRoundUp = 3;
  static const int NSNumberFormatterRoundHalfEven = 4;
  static const int NSNumberFormatterRoundHalfDown = 5;
  static const int NSNumberFormatterRoundHalfUp = 6;
}

class NSDecimalNumberHandler extends NSObject {
  NSDecimalNumberHandler._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSDecimalNumberHandler] that points to the same underlying object as [other].
  static NSDecimalNumberHandler castFrom<T extends _ObjCWrapper>(T other) {
    return NSDecimalNumberHandler._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSDecimalNumberHandler] that wraps the given raw object pointer.
  static NSDecimalNumberHandler castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSDecimalNumberHandler._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSDecimalNumberHandler].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSDecimalNumberHandler1);
  }

  static NSDecimalNumberHandler? getDefaultDecimalNumberHandler(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_711(_lib._class_NSDecimalNumberHandler1,
        _lib._sel_defaultDecimalNumberHandler1);
    return _ret.address == 0
        ? null
        : NSDecimalNumberHandler._(_ret, _lib, retain: true, release: true);
  }

  NSDecimalNumberHandler
      initWithRoundingMode_scale_raiseOnExactness_raiseOnOverflow_raiseOnUnderflow_raiseOnDivideByZero_(
          int roundingMode,
          int scale,
          bool exact,
          bool overflow,
          bool underflow,
          bool divideByZero) {
    final _ret = _lib._objc_msgSend_712(
        _id,
        _lib._sel_initWithRoundingMode_scale_raiseOnExactness_raiseOnOverflow_raiseOnUnderflow_raiseOnDivideByZero_1,
        roundingMode,
        scale,
        exact,
        overflow,
        underflow,
        divideByZero);
    return NSDecimalNumberHandler._(_ret, _lib, retain: true, release: true);
  }

  static NSDecimalNumberHandler
      decimalNumberHandlerWithRoundingMode_scale_raiseOnExactness_raiseOnOverflow_raiseOnUnderflow_raiseOnDivideByZero_(
          AVFAudio _lib,
          int roundingMode,
          int scale,
          bool exact,
          bool overflow,
          bool underflow,
          bool divideByZero) {
    final _ret = _lib._objc_msgSend_712(
        _lib._class_NSDecimalNumberHandler1,
        _lib._sel_decimalNumberHandlerWithRoundingMode_scale_raiseOnExactness_raiseOnOverflow_raiseOnUnderflow_raiseOnDivideByZero_1,
        roundingMode,
        scale,
        exact,
        overflow,
        underflow,
        divideByZero);
    return NSDecimalNumberHandler._(_ret, _lib, retain: true, release: true);
  }

  static NSDecimalNumberHandler new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSDecimalNumberHandler1, _lib._sel_new1);
    return NSDecimalNumberHandler._(_ret, _lib, retain: false, release: true);
  }

  static NSDecimalNumberHandler alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSDecimalNumberHandler1, _lib._sel_alloc1);
    return NSDecimalNumberHandler._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSDecimalNumberHandler1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSDecimalNumberHandler1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSDecimalNumberHandler1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSDecimalNumberHandler1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSDecimalNumberHandler1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSDecimalNumberHandler1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSDecimalNumberHandler1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSDecimalNumberHandler1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSDecimalNumberHandler1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSRoundingMode {
  static const int NSRoundPlain = 0;
  static const int NSRoundDown = 1;
  static const int NSRoundUp = 2;
  static const int NSRoundBankers = 3;
}

class NSScanner extends NSObject {
  NSScanner._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSScanner] that points to the same underlying object as [other].
  static NSScanner castFrom<T extends _ObjCWrapper>(T other) {
    return NSScanner._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSScanner] that wraps the given raw object pointer.
  static NSScanner castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSScanner._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSScanner].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSScanner1);
  }

  NSString? get string {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_string1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get scanLocation {
    return _lib._objc_msgSend_10(_id, _lib._sel_scanLocation1);
  }

  set scanLocation(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setScanLocation_1, value);
  }

  NSCharacterSet? get charactersToBeSkipped {
    final _ret = _lib._objc_msgSend_168(_id, _lib._sel_charactersToBeSkipped1);
    return _ret.address == 0
        ? null
        : NSCharacterSet._(_ret, _lib, retain: true, release: true);
  }

  set charactersToBeSkipped(NSCharacterSet? value) {
    _lib._objc_msgSend_714(
        _id, _lib._sel_setCharactersToBeSkipped_1, value?._id ?? ffi.nullptr);
  }

  bool get caseSensitive {
    return _lib._objc_msgSend_12(_id, _lib._sel_caseSensitive1);
  }

  set caseSensitive(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setCaseSensitive_1, value);
  }

  NSObject get locale {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_locale1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  set locale(NSObject value) {
    _lib._objc_msgSend_368(_id, _lib._sel_setLocale_1, value._id);
  }

  NSScanner initWithString_(NSString? string) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithString_1, string?._id ?? ffi.nullptr);
    return NSScanner._(_ret, _lib, retain: true, release: true);
  }

  bool scanInt_(ffi.Pointer<ffi.Int> result) {
    return _lib._objc_msgSend_715(_id, _lib._sel_scanInt_1, result);
  }

  bool scanInteger_(ffi.Pointer<NSInteger> result) {
    return _lib._objc_msgSend_716(_id, _lib._sel_scanInteger_1, result);
  }

  bool scanLongLong_(ffi.Pointer<ffi.LongLong> result) {
    return _lib._objc_msgSend_717(_id, _lib._sel_scanLongLong_1, result);
  }

  bool scanUnsignedLongLong_(ffi.Pointer<ffi.UnsignedLongLong> result) {
    return _lib._objc_msgSend_718(
        _id, _lib._sel_scanUnsignedLongLong_1, result);
  }

  bool scanFloat_(ffi.Pointer<ffi.Float> result) {
    return _lib._objc_msgSend_719(_id, _lib._sel_scanFloat_1, result);
  }

  bool scanDouble_(ffi.Pointer<ffi.Double> result) {
    return _lib._objc_msgSend_720(_id, _lib._sel_scanDouble_1, result);
  }

  bool scanHexInt_(ffi.Pointer<ffi.UnsignedInt> result) {
    return _lib._objc_msgSend_721(_id, _lib._sel_scanHexInt_1, result);
  }

  bool scanHexLongLong_(ffi.Pointer<ffi.UnsignedLongLong> result) {
    return _lib._objc_msgSend_718(_id, _lib._sel_scanHexLongLong_1, result);
  }

  bool scanHexFloat_(ffi.Pointer<ffi.Float> result) {
    return _lib._objc_msgSend_719(_id, _lib._sel_scanHexFloat_1, result);
  }

  bool scanHexDouble_(ffi.Pointer<ffi.Double> result) {
    return _lib._objc_msgSend_720(_id, _lib._sel_scanHexDouble_1, result);
  }

  bool scanString_intoString_(
      NSString? string, ffi.Pointer<ffi.Pointer<ObjCObject>> result) {
    return _lib._objc_msgSend_722(_id, _lib._sel_scanString_intoString_1,
        string?._id ?? ffi.nullptr, result);
  }

  bool scanCharactersFromSet_intoString_(
      NSCharacterSet? set, ffi.Pointer<ffi.Pointer<ObjCObject>> result) {
    return _lib._objc_msgSend_723(
        _id,
        _lib._sel_scanCharactersFromSet_intoString_1,
        set?._id ?? ffi.nullptr,
        result);
  }

  bool scanUpToString_intoString_(
      NSString? string, ffi.Pointer<ffi.Pointer<ObjCObject>> result) {
    return _lib._objc_msgSend_722(_id, _lib._sel_scanUpToString_intoString_1,
        string?._id ?? ffi.nullptr, result);
  }

  bool scanUpToCharactersFromSet_intoString_(
      NSCharacterSet? set, ffi.Pointer<ffi.Pointer<ObjCObject>> result) {
    return _lib._objc_msgSend_723(
        _id,
        _lib._sel_scanUpToCharactersFromSet_intoString_1,
        set?._id ?? ffi.nullptr,
        result);
  }

  bool get atEnd {
    return _lib._objc_msgSend_12(_id, _lib._sel_isAtEnd1);
  }

  static NSScanner scannerWithString_(AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSScanner1,
        _lib._sel_scannerWithString_1, string?._id ?? ffi.nullptr);
    return NSScanner._(_ret, _lib, retain: true, release: true);
  }

  static NSObject localizedScannerWithString_(AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSScanner1,
        _lib._sel_localizedScannerWithString_1, string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  bool scanDecimal_(ffi.Pointer<NSDecimal> dcm) {
    return _lib._objc_msgSend_724(_id, _lib._sel_scanDecimal_1, dcm);
  }

  static NSScanner new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSScanner1, _lib._sel_new1);
    return NSScanner._(_ret, _lib, retain: false, release: true);
  }

  static NSScanner alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSScanner1, _lib._sel_alloc1);
    return NSScanner._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSScanner1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSScanner1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSScanner1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSScanner1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSScanner1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSScanner1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSScanner1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSScanner1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSScanner1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

final class NSDecimal extends ffi.Opaque {}

class NSException extends NSObject {
  NSException._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSException] that points to the same underlying object as [other].
  static NSException castFrom<T extends _ObjCWrapper>(T other) {
    return NSException._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSException] that wraps the given raw object pointer.
  static NSException castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSException._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSException].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSException1);
  }

  static NSException exceptionWithName_reason_userInfo_(AVFAudio _lib,
      NSExceptionName name, NSString? reason, NSDictionary? userInfo) {
    final _ret = _lib._objc_msgSend_725(
        _lib._class_NSException1,
        _lib._sel_exceptionWithName_reason_userInfo_1,
        name,
        reason?._id ?? ffi.nullptr,
        userInfo?._id ?? ffi.nullptr);
    return NSException._(_ret, _lib, retain: true, release: true);
  }

  NSException initWithName_reason_userInfo_(
      NSExceptionName aName, NSString? aReason, NSDictionary? aUserInfo) {
    final _ret = _lib._objc_msgSend_551(
        _id,
        _lib._sel_initWithName_reason_userInfo_1,
        aName,
        aReason?._id ?? ffi.nullptr,
        aUserInfo?._id ?? ffi.nullptr);
    return NSException._(_ret, _lib, retain: true, release: true);
  }

  NSExceptionName get name {
    return _lib._objc_msgSend_20(_id, _lib._sel_name1);
  }

  NSString? get reason {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_reason1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get userInfo {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_userInfo1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get callStackReturnAddresses {
    final _ret =
        _lib._objc_msgSend_80(_id, _lib._sel_callStackReturnAddresses1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get callStackSymbols {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_callStackSymbols1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  void raise() {
    return _lib._objc_msgSend_1(_id, _lib._sel_raise1);
  }

  static void raise_format_(
      AVFAudio _lib, NSExceptionName name, NSString? format) {
    return _lib._objc_msgSend_483(_lib._class_NSException1,
        _lib._sel_raise_format_1, name, format?._id ?? ffi.nullptr);
  }

  static void raise_format_arguments_(AVFAudio _lib, NSExceptionName name,
      NSString? format, ffi.Pointer<__va_list_tag> argList) {
    return _lib._objc_msgSend_726(
        _lib._class_NSException1,
        _lib._sel_raise_format_arguments_1,
        name,
        format?._id ?? ffi.nullptr,
        argList);
  }

  static NSException new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSException1, _lib._sel_new1);
    return NSException._(_ret, _lib, retain: false, release: true);
  }

  static NSException alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSException1, _lib._sel_alloc1);
    return NSException._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSException1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSException1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSException1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSException1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSException1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSException1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSException1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSException1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSException1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSExceptionName = ffi.Pointer<ObjCObject>;

class NSFileHandle extends NSObject {
  NSFileHandle._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSFileHandle] that points to the same underlying object as [other].
  static NSFileHandle castFrom<T extends _ObjCWrapper>(T other) {
    return NSFileHandle._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSFileHandle] that wraps the given raw object pointer.
  static NSFileHandle castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSFileHandle._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSFileHandle].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSFileHandle1);
  }

  NSData? get availableData {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_availableData1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  NSFileHandle initWithFileDescriptor_closeOnDealloc_(int fd, bool closeopt) {
    final _ret = _lib._objc_msgSend_727(
        _id, _lib._sel_initWithFileDescriptor_closeOnDealloc_1, fd, closeopt);
    return NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  NSFileHandle initWithCoder_(NSCoder? coder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, coder?._id ?? ffi.nullptr);
    return NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  NSData readDataToEndOfFileAndReturnError_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_728(
        _id, _lib._sel_readDataToEndOfFileAndReturnError_1, error);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData readDataUpToLength_error_(
      int length, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_729(
        _id, _lib._sel_readDataUpToLength_error_1, length, error);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  bool writeData_error_(
      NSData? data, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_730(
        _id, _lib._sel_writeData_error_1, data?._id ?? ffi.nullptr, error);
  }

  bool getOffset_error_(ffi.Pointer<ffi.UnsignedLongLong> offsetInFile,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_731(
        _id, _lib._sel_getOffset_error_1, offsetInFile, error);
  }

  bool seekToEndReturningOffset_error_(
      ffi.Pointer<ffi.UnsignedLongLong> offsetInFile,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_731(
        _id, _lib._sel_seekToEndReturningOffset_error_1, offsetInFile, error);
  }

  bool seekToOffset_error_(
      int offset, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_732(
        _id, _lib._sel_seekToOffset_error_1, offset, error);
  }

  bool truncateAtOffset_error_(
      int offset, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_732(
        _id, _lib._sel_truncateAtOffset_error_1, offset, error);
  }

  bool synchronizeAndReturnError_(ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_219(
        _id, _lib._sel_synchronizeAndReturnError_1, error);
  }

  bool closeAndReturnError_(ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_219(_id, _lib._sel_closeAndReturnError_1, error);
  }

  static NSFileHandle? getFileHandleWithStandardInput(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_733(
        _lib._class_NSFileHandle1, _lib._sel_fileHandleWithStandardInput1);
    return _ret.address == 0
        ? null
        : NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  static NSFileHandle? getFileHandleWithStandardOutput(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_733(
        _lib._class_NSFileHandle1, _lib._sel_fileHandleWithStandardOutput1);
    return _ret.address == 0
        ? null
        : NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  static NSFileHandle? getFileHandleWithStandardError(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_733(
        _lib._class_NSFileHandle1, _lib._sel_fileHandleWithStandardError1);
    return _ret.address == 0
        ? null
        : NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  static NSFileHandle? getFileHandleWithNullDevice(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_733(
        _lib._class_NSFileHandle1, _lib._sel_fileHandleWithNullDevice1);
    return _ret.address == 0
        ? null
        : NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  static NSFileHandle fileHandleForReadingAtPath_(
      AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSFileHandle1,
        _lib._sel_fileHandleForReadingAtPath_1, path?._id ?? ffi.nullptr);
    return NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  static NSFileHandle fileHandleForWritingAtPath_(
      AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSFileHandle1,
        _lib._sel_fileHandleForWritingAtPath_1, path?._id ?? ffi.nullptr);
    return NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  static NSFileHandle fileHandleForUpdatingAtPath_(
      AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSFileHandle1,
        _lib._sel_fileHandleForUpdatingAtPath_1, path?._id ?? ffi.nullptr);
    return NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  static NSFileHandle fileHandleForReadingFromURL_error_(
      AVFAudio _lib, NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_734(
        _lib._class_NSFileHandle1,
        _lib._sel_fileHandleForReadingFromURL_error_1,
        url?._id ?? ffi.nullptr,
        error);
    return NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  static NSFileHandle fileHandleForWritingToURL_error_(
      AVFAudio _lib, NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_734(
        _lib._class_NSFileHandle1,
        _lib._sel_fileHandleForWritingToURL_error_1,
        url?._id ?? ffi.nullptr,
        error);
    return NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  static NSFileHandle fileHandleForUpdatingURL_error_(
      AVFAudio _lib, NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_734(
        _lib._class_NSFileHandle1,
        _lib._sel_fileHandleForUpdatingURL_error_1,
        url?._id ?? ffi.nullptr,
        error);
    return NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  void readInBackgroundAndNotifyForModes_(NSArray? modes) {
    return _lib._objc_msgSend_412(
        _id,
        _lib._sel_readInBackgroundAndNotifyForModes_1,
        modes?._id ?? ffi.nullptr);
  }

  void readInBackgroundAndNotify() {
    return _lib._objc_msgSend_1(_id, _lib._sel_readInBackgroundAndNotify1);
  }

  void readToEndOfFileInBackgroundAndNotifyForModes_(NSArray? modes) {
    return _lib._objc_msgSend_412(
        _id,
        _lib._sel_readToEndOfFileInBackgroundAndNotifyForModes_1,
        modes?._id ?? ffi.nullptr);
  }

  void readToEndOfFileInBackgroundAndNotify() {
    return _lib._objc_msgSend_1(
        _id, _lib._sel_readToEndOfFileInBackgroundAndNotify1);
  }

  void acceptConnectionInBackgroundAndNotifyForModes_(NSArray? modes) {
    return _lib._objc_msgSend_412(
        _id,
        _lib._sel_acceptConnectionInBackgroundAndNotifyForModes_1,
        modes?._id ?? ffi.nullptr);
  }

  void acceptConnectionInBackgroundAndNotify() {
    return _lib._objc_msgSend_1(
        _id, _lib._sel_acceptConnectionInBackgroundAndNotify1);
  }

  void waitForDataInBackgroundAndNotifyForModes_(NSArray? modes) {
    return _lib._objc_msgSend_412(
        _id,
        _lib._sel_waitForDataInBackgroundAndNotifyForModes_1,
        modes?._id ?? ffi.nullptr);
  }

  void waitForDataInBackgroundAndNotify() {
    return _lib._objc_msgSend_1(
        _id, _lib._sel_waitForDataInBackgroundAndNotify1);
  }

  ObjCBlock29 get readabilityHandler {
    final _ret = _lib._objc_msgSend_735(_id, _lib._sel_readabilityHandler1);
    return ObjCBlock29._(_ret, _lib);
  }

  set readabilityHandler(ObjCBlock29 value) {
    _lib._objc_msgSend_736(_id, _lib._sel_setReadabilityHandler_1, value._id);
  }

  ObjCBlock29 get writeabilityHandler {
    final _ret = _lib._objc_msgSend_735(_id, _lib._sel_writeabilityHandler1);
    return ObjCBlock29._(_ret, _lib);
  }

  set writeabilityHandler(ObjCBlock29 value) {
    _lib._objc_msgSend_736(_id, _lib._sel_setWriteabilityHandler_1, value._id);
  }

  NSFileHandle initWithFileDescriptor_(int fd) {
    final _ret =
        _lib._objc_msgSend_737(_id, _lib._sel_initWithFileDescriptor_1, fd);
    return NSFileHandle._(_ret, _lib, retain: true, release: true);
  }

  int get fileDescriptor {
    return _lib._objc_msgSend_213(_id, _lib._sel_fileDescriptor1);
  }

  NSData readDataToEndOfFile() {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_readDataToEndOfFile1);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData readDataOfLength_(int length) {
    final _ret =
        _lib._objc_msgSend_315(_id, _lib._sel_readDataOfLength_1, length);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  void writeData_(NSData? data) {
    return _lib._objc_msgSend_248(
        _id, _lib._sel_writeData_1, data?._id ?? ffi.nullptr);
  }

  int get offsetInFile {
    return _lib._objc_msgSend_148(_id, _lib._sel_offsetInFile1);
  }

  int seekToEndOfFile() {
    return _lib._objc_msgSend_148(_id, _lib._sel_seekToEndOfFile1);
  }

  void seekToFileOffset_(int offset) {
    return _lib._objc_msgSend_738(_id, _lib._sel_seekToFileOffset_1, offset);
  }

  void truncateFileAtOffset_(int offset) {
    return _lib._objc_msgSend_738(
        _id, _lib._sel_truncateFileAtOffset_1, offset);
  }

  void synchronizeFile() {
    return _lib._objc_msgSend_1(_id, _lib._sel_synchronizeFile1);
  }

  void closeFile() {
    return _lib._objc_msgSend_1(_id, _lib._sel_closeFile1);
  }

  static NSFileHandle new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSFileHandle1, _lib._sel_new1);
    return NSFileHandle._(_ret, _lib, retain: false, release: true);
  }

  static NSFileHandle alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSFileHandle1, _lib._sel_alloc1);
    return NSFileHandle._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSFileHandle1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSFileHandle1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSFileHandle1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSFileHandle1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSFileHandle1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSFileHandle1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSFileHandle1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSFileHandle1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSFileHandle1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

void _ObjCBlock29_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>()
      .asFunction<void Function(ffi.Pointer<ObjCObject> arg0)>()(arg0);
}

final _ObjCBlock29_closureRegistry = <int, Function>{};
int _ObjCBlock29_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock29_registerClosure(Function fn) {
  final id = ++_ObjCBlock29_closureRegistryIndex;
  _ObjCBlock29_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock29_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return _ObjCBlock29_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock29 extends _ObjCBlockBase {
  ObjCBlock29._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock29.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi
              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock29_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock29.fromFunction(
      AVFAudio lib, void Function(ffi.Pointer<ObjCObject> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock29_closureTrampoline)
                    .cast(),
                _ObjCBlock29_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSHTTPCookieStorage extends NSObject {
  NSHTTPCookieStorage._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSHTTPCookieStorage] that points to the same underlying object as [other].
  static NSHTTPCookieStorage castFrom<T extends _ObjCWrapper>(T other) {
    return NSHTTPCookieStorage._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSHTTPCookieStorage] that wraps the given raw object pointer.
  static NSHTTPCookieStorage castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSHTTPCookieStorage._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSHTTPCookieStorage].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSHTTPCookieStorage1);
  }

  static NSHTTPCookieStorage? getSharedHTTPCookieStorage(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_739(
        _lib._class_NSHTTPCookieStorage1, _lib._sel_sharedHTTPCookieStorage1);
    return _ret.address == 0
        ? null
        : NSHTTPCookieStorage._(_ret, _lib, retain: true, release: true);
  }

  static NSHTTPCookieStorage sharedCookieStorageForGroupContainerIdentifier_(
      AVFAudio _lib, NSString? identifier) {
    final _ret = _lib._objc_msgSend_740(
        _lib._class_NSHTTPCookieStorage1,
        _lib._sel_sharedCookieStorageForGroupContainerIdentifier_1,
        identifier?._id ?? ffi.nullptr);
    return NSHTTPCookieStorage._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get cookies {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_cookies1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  void setCookie_(NSHTTPCookie? cookie) {
    return _lib._objc_msgSend_743(
        _id, _lib._sel_setCookie_1, cookie?._id ?? ffi.nullptr);
  }

  void deleteCookie_(NSHTTPCookie? cookie) {
    return _lib._objc_msgSend_743(
        _id, _lib._sel_deleteCookie_1, cookie?._id ?? ffi.nullptr);
  }

  void removeCookiesSinceDate_(NSDate? date) {
    return _lib._objc_msgSend_472(
        _id, _lib._sel_removeCookiesSinceDate_1, date?._id ?? ffi.nullptr);
  }

  NSArray cookiesForURL_(NSURL? URL) {
    final _ret = _lib._objc_msgSend_120(
        _id, _lib._sel_cookiesForURL_1, URL?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  void setCookies_forURL_mainDocumentURL_(
      NSArray? cookies, NSURL? URL, NSURL? mainDocumentURL) {
    return _lib._objc_msgSend_744(
        _id,
        _lib._sel_setCookies_forURL_mainDocumentURL_1,
        cookies?._id ?? ffi.nullptr,
        URL?._id ?? ffi.nullptr,
        mainDocumentURL?._id ?? ffi.nullptr);
  }

  int get cookieAcceptPolicy {
    return _lib._objc_msgSend_745(_id, _lib._sel_cookieAcceptPolicy1);
  }

  set cookieAcceptPolicy(int value) {
    _lib._objc_msgSend_746(_id, _lib._sel_setCookieAcceptPolicy_1, value);
  }

  NSArray sortedCookiesUsingDescriptors_(NSArray? sortOrder) {
    final _ret = _lib._objc_msgSend_63(
        _id,
        _lib._sel_sortedCookiesUsingDescriptors_1,
        sortOrder?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  void storeCookies_forTask_(NSArray? cookies, NSURLSessionTask? task) {
    return _lib._objc_msgSend_766(_id, _lib._sel_storeCookies_forTask_1,
        cookies?._id ?? ffi.nullptr, task?._id ?? ffi.nullptr);
  }

  void getCookiesForTask_completionHandler_(
      NSURLSessionTask? task, ObjCBlock30 completionHandler) {
    return _lib._objc_msgSend_767(
        _id,
        _lib._sel_getCookiesForTask_completionHandler_1,
        task?._id ?? ffi.nullptr,
        completionHandler._id);
  }

  static NSHTTPCookieStorage new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSHTTPCookieStorage1, _lib._sel_new1);
    return NSHTTPCookieStorage._(_ret, _lib, retain: false, release: true);
  }

  static NSHTTPCookieStorage alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSHTTPCookieStorage1, _lib._sel_alloc1);
    return NSHTTPCookieStorage._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSHTTPCookieStorage1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSHTTPCookieStorage1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSHTTPCookieStorage1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSHTTPCookieStorage1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSHTTPCookieStorage1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSHTTPCookieStorage1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSHTTPCookieStorage1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSHTTPCookieStorage1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSHTTPCookieStorage1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSHTTPCookie extends NSObject {
  NSHTTPCookie._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSHTTPCookie] that points to the same underlying object as [other].
  static NSHTTPCookie castFrom<T extends _ObjCWrapper>(T other) {
    return NSHTTPCookie._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSHTTPCookie] that wraps the given raw object pointer.
  static NSHTTPCookie castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSHTTPCookie._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSHTTPCookie].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSHTTPCookie1);
  }

  NSHTTPCookie initWithProperties_(NSDictionary? properties) {
    final _ret = _lib._objc_msgSend_143(
        _id, _lib._sel_initWithProperties_1, properties?._id ?? ffi.nullptr);
    return NSHTTPCookie._(_ret, _lib, retain: true, release: true);
  }

  static NSHTTPCookie cookieWithProperties_(
      AVFAudio _lib, NSDictionary? properties) {
    final _ret = _lib._objc_msgSend_741(_lib._class_NSHTTPCookie1,
        _lib._sel_cookieWithProperties_1, properties?._id ?? ffi.nullptr);
    return NSHTTPCookie._(_ret, _lib, retain: true, release: true);
  }

  static NSDictionary requestHeaderFieldsWithCookies_(
      AVFAudio _lib, NSArray? cookies) {
    final _ret = _lib._objc_msgSend_443(
        _lib._class_NSHTTPCookie1,
        _lib._sel_requestHeaderFieldsWithCookies_1,
        cookies?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSArray cookiesWithResponseHeaderFields_forURL_(
      AVFAudio _lib, NSDictionary? headerFields, NSURL? URL) {
    final _ret = _lib._objc_msgSend_742(
        _lib._class_NSHTTPCookie1,
        _lib._sel_cookiesWithResponseHeaderFields_forURL_1,
        headerFields?._id ?? ffi.nullptr,
        URL?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get properties {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_properties1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  int get version {
    return _lib._objc_msgSend_10(_id, _lib._sel_version1);
  }

  NSString? get name {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_name1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get value {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_value1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSDate? get expiresDate {
    final _ret = _lib._objc_msgSend_156(_id, _lib._sel_expiresDate1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  bool get sessionOnly {
    return _lib._objc_msgSend_12(_id, _lib._sel_isSessionOnly1);
  }

  NSString? get domain {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_domain1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get path {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_path1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  bool get secure {
    return _lib._objc_msgSend_12(_id, _lib._sel_isSecure1);
  }

  bool get HTTPOnly {
    return _lib._objc_msgSend_12(_id, _lib._sel_isHTTPOnly1);
  }

  NSString? get comment {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_comment1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get commentURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_commentURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get portList {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_portList1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSHTTPCookieStringPolicy get sameSitePolicy {
    return _lib._objc_msgSend_20(_id, _lib._sel_sameSitePolicy1);
  }

  static NSHTTPCookie new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSHTTPCookie1, _lib._sel_new1);
    return NSHTTPCookie._(_ret, _lib, retain: false, release: true);
  }

  static NSHTTPCookie alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSHTTPCookie1, _lib._sel_alloc1);
    return NSHTTPCookie._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSHTTPCookie1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSHTTPCookie1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSHTTPCookie1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSHTTPCookie1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSHTTPCookie1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSHTTPCookie1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSHTTPCookie1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSHTTPCookie1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSHTTPCookie1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSHTTPCookieStringPolicy = ffi.Pointer<ObjCObject>;

abstract class NSHTTPCookieAcceptPolicy {
  static const int NSHTTPCookieAcceptPolicyAlways = 0;
  static const int NSHTTPCookieAcceptPolicyNever = 1;
  static const int NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain = 2;
}

class NSURLSessionTask extends NSObject {
  NSURLSessionTask._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLSessionTask] that points to the same underlying object as [other].
  static NSURLSessionTask castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLSessionTask._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLSessionTask] that wraps the given raw object pointer.
  static NSURLSessionTask castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLSessionTask._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLSessionTask].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLSessionTask1);
  }

  int get taskIdentifier {
    return _lib._objc_msgSend_10(_id, _lib._sel_taskIdentifier1);
  }

  NSURLRequest? get originalRequest {
    final _ret = _lib._objc_msgSend_761(_id, _lib._sel_originalRequest1);
    return _ret.address == 0
        ? null
        : NSURLRequest._(_ret, _lib, retain: true, release: true);
  }

  NSURLRequest? get currentRequest {
    final _ret = _lib._objc_msgSend_761(_id, _lib._sel_currentRequest1);
    return _ret.address == 0
        ? null
        : NSURLRequest._(_ret, _lib, retain: true, release: true);
  }

  NSURLResponse? get response {
    final _ret = _lib._objc_msgSend_763(_id, _lib._sel_response1);
    return _ret.address == 0
        ? null
        : NSURLResponse._(_ret, _lib, retain: true, release: true);
  }

  NSObject? get delegate {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_delegate1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  set delegate(NSObject? value) {
    _lib._objc_msgSend_368(
        _id, _lib._sel_setDelegate_1, value?._id ?? ffi.nullptr);
  }

  NSProgress? get progress {
    final _ret = _lib._objc_msgSend_577(_id, _lib._sel_progress1);
    return _ret.address == 0
        ? null
        : NSProgress._(_ret, _lib, retain: true, release: true);
  }

  NSDate? get earliestBeginDate {
    final _ret = _lib._objc_msgSend_156(_id, _lib._sel_earliestBeginDate1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  set earliestBeginDate(NSDate? value) {
    _lib._objc_msgSend_493(
        _id, _lib._sel_setEarliestBeginDate_1, value?._id ?? ffi.nullptr);
  }

  int get countOfBytesClientExpectsToSend {
    return _lib._objc_msgSend_584(
        _id, _lib._sel_countOfBytesClientExpectsToSend1);
  }

  set countOfBytesClientExpectsToSend(int value) {
    _lib._objc_msgSend_585(
        _id, _lib._sel_setCountOfBytesClientExpectsToSend_1, value);
  }

  int get countOfBytesClientExpectsToReceive {
    return _lib._objc_msgSend_584(
        _id, _lib._sel_countOfBytesClientExpectsToReceive1);
  }

  set countOfBytesClientExpectsToReceive(int value) {
    _lib._objc_msgSend_585(
        _id, _lib._sel_setCountOfBytesClientExpectsToReceive_1, value);
  }

  int get countOfBytesSent {
    return _lib._objc_msgSend_584(_id, _lib._sel_countOfBytesSent1);
  }

  int get countOfBytesReceived {
    return _lib._objc_msgSend_584(_id, _lib._sel_countOfBytesReceived1);
  }

  int get countOfBytesExpectedToSend {
    return _lib._objc_msgSend_584(_id, _lib._sel_countOfBytesExpectedToSend1);
  }

  int get countOfBytesExpectedToReceive {
    return _lib._objc_msgSend_584(
        _id, _lib._sel_countOfBytesExpectedToReceive1);
  }

  NSString? get taskDescription {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_taskDescription1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set taskDescription(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setTaskDescription_1, value?._id ?? ffi.nullptr);
  }

  void cancel() {
    return _lib._objc_msgSend_1(_id, _lib._sel_cancel1);
  }

  int get state {
    return _lib._objc_msgSend_764(_id, _lib._sel_state1);
  }

  NSError? get error {
    final _ret = _lib._objc_msgSend_283(_id, _lib._sel_error1);
    return _ret.address == 0
        ? null
        : NSError._(_ret, _lib, retain: true, release: true);
  }

  void suspend() {
    return _lib._objc_msgSend_1(_id, _lib._sel_suspend1);
  }

  void resume() {
    return _lib._objc_msgSend_1(_id, _lib._sel_resume1);
  }

  double get priority {
    return _lib._objc_msgSend_215(_id, _lib._sel_priority1);
  }

  set priority(double value) {
    _lib._objc_msgSend_765(_id, _lib._sel_setPriority_1, value);
  }

  bool get prefersIncrementalDelivery {
    return _lib._objc_msgSend_12(_id, _lib._sel_prefersIncrementalDelivery1);
  }

  set prefersIncrementalDelivery(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setPrefersIncrementalDelivery_1, value);
  }

  @override
  NSURLSessionTask init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSURLSessionTask._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSessionTask new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLSessionTask1, _lib._sel_new1);
    return NSURLSessionTask._(_ret, _lib, retain: false, release: true);
  }

  static NSURLSessionTask alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLSessionTask1, _lib._sel_alloc1);
    return NSURLSessionTask._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLSessionTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLSessionTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLSessionTask1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLSessionTask1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLSessionTask1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLSessionTask1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLSessionTask1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionTask1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionTask1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSURLRequest extends NSObject {
  NSURLRequest._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLRequest] that points to the same underlying object as [other].
  static NSURLRequest castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLRequest._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSURLRequest] that wraps the given raw object pointer.
  static NSURLRequest castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLRequest._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLRequest].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSURLRequest1);
  }

  static NSURLRequest requestWithURL_(AVFAudio _lib, NSURL? URL) {
    final _ret = _lib._objc_msgSend_226(_lib._class_NSURLRequest1,
        _lib._sel_requestWithURL_1, URL?._id ?? ffi.nullptr);
    return NSURLRequest._(_ret, _lib, retain: true, release: true);
  }

  static bool getSupportsSecureCoding(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLRequest1, _lib._sel_supportsSecureCoding1);
  }

  static NSURLRequest requestWithURL_cachePolicy_timeoutInterval_(
      AVFAudio _lib, NSURL? URL, int cachePolicy, double timeoutInterval) {
    final _ret = _lib._objc_msgSend_747(
        _lib._class_NSURLRequest1,
        _lib._sel_requestWithURL_cachePolicy_timeoutInterval_1,
        URL?._id ?? ffi.nullptr,
        cachePolicy,
        timeoutInterval);
    return NSURLRequest._(_ret, _lib, retain: true, release: true);
  }

  NSURLRequest initWithURL_(NSURL? URL) {
    final _ret = _lib._objc_msgSend_226(
        _id, _lib._sel_initWithURL_1, URL?._id ?? ffi.nullptr);
    return NSURLRequest._(_ret, _lib, retain: true, release: true);
  }

  NSURLRequest initWithURL_cachePolicy_timeoutInterval_(
      NSURL? URL, int cachePolicy, double timeoutInterval) {
    final _ret = _lib._objc_msgSend_747(
        _id,
        _lib._sel_initWithURL_cachePolicy_timeoutInterval_1,
        URL?._id ?? ffi.nullptr,
        cachePolicy,
        timeoutInterval);
    return NSURLRequest._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get URL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_URL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  int get cachePolicy {
    return _lib._objc_msgSend_748(_id, _lib._sel_cachePolicy1);
  }

  double get timeoutInterval {
    return _lib._objc_msgSend_149(_id, _lib._sel_timeoutInterval1);
  }

  NSURL? get mainDocumentURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_mainDocumentURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  int get networkServiceType {
    return _lib._objc_msgSend_749(_id, _lib._sel_networkServiceType1);
  }

  bool get allowsCellularAccess {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsCellularAccess1);
  }

  bool get allowsExpensiveNetworkAccess {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsExpensiveNetworkAccess1);
  }

  bool get allowsConstrainedNetworkAccess {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_allowsConstrainedNetworkAccess1);
  }

  bool get assumesHTTP3Capable {
    return _lib._objc_msgSend_12(_id, _lib._sel_assumesHTTP3Capable1);
  }

  int get attribution {
    return _lib._objc_msgSend_750(_id, _lib._sel_attribution1);
  }

  NSString? get HTTPMethod {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_HTTPMethod1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get allHTTPHeaderFields {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_allHTTPHeaderFields1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSString valueForHTTPHeaderField_(NSString? field) {
    final _ret = _lib._objc_msgSend_64(
        _id, _lib._sel_valueForHTTPHeaderField_1, field?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSData? get HTTPBody {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_HTTPBody1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  NSInputStream? get HTTPBodyStream {
    final _ret = _lib._objc_msgSend_760(_id, _lib._sel_HTTPBodyStream1);
    return _ret.address == 0
        ? null
        : NSInputStream._(_ret, _lib, retain: true, release: true);
  }

  bool get HTTPShouldHandleCookies {
    return _lib._objc_msgSend_12(_id, _lib._sel_HTTPShouldHandleCookies1);
  }

  bool get HTTPShouldUsePipelining {
    return _lib._objc_msgSend_12(_id, _lib._sel_HTTPShouldUsePipelining1);
  }

  static NSURLRequest new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLRequest1, _lib._sel_new1);
    return NSURLRequest._(_ret, _lib, retain: false, release: true);
  }

  static NSURLRequest alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLRequest1, _lib._sel_alloc1);
    return NSURLRequest._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLRequest1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLRequest1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLRequest1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLRequest1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLRequest1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLRequest1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLRequest1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSURLRequest1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLRequest1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSURLRequestCachePolicy {
  static const int NSURLRequestUseProtocolCachePolicy = 0;
  static const int NSURLRequestReloadIgnoringLocalCacheData = 1;
  static const int NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4;
  static const int NSURLRequestReloadIgnoringCacheData = 1;
  static const int NSURLRequestReturnCacheDataElseLoad = 2;
  static const int NSURLRequestReturnCacheDataDontLoad = 3;
  static const int NSURLRequestReloadRevalidatingCacheData = 5;
}

abstract class NSURLRequestNetworkServiceType {
  static const int NSURLNetworkServiceTypeDefault = 0;
  static const int NSURLNetworkServiceTypeVoIP = 1;
  static const int NSURLNetworkServiceTypeVideo = 2;
  static const int NSURLNetworkServiceTypeBackground = 3;
  static const int NSURLNetworkServiceTypeVoice = 4;
  static const int NSURLNetworkServiceTypeResponsiveData = 6;
  static const int NSURLNetworkServiceTypeAVStreaming = 8;
  static const int NSURLNetworkServiceTypeResponsiveAV = 9;
  static const int NSURLNetworkServiceTypeCallSignaling = 11;
}

abstract class NSURLRequestAttribution {
  static const int NSURLRequestAttributionDeveloper = 0;
  static const int NSURLRequestAttributionUser = 1;
}

class NSInputStream extends NSStream {
  NSInputStream._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSInputStream] that points to the same underlying object as [other].
  static NSInputStream castFrom<T extends _ObjCWrapper>(T other) {
    return NSInputStream._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSInputStream] that wraps the given raw object pointer.
  static NSInputStream castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSInputStream._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSInputStream].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSInputStream1);
  }

  int read_maxLength_(ffi.Pointer<ffi.Uint8> buffer, int len) {
    return _lib._objc_msgSend_752(_id, _lib._sel_read_maxLength_1, buffer, len);
  }

  bool getBuffer_length_(
      ffi.Pointer<ffi.Pointer<ffi.Uint8>> buffer, ffi.Pointer<NSUInteger> len) {
    return _lib._objc_msgSend_759(
        _id, _lib._sel_getBuffer_length_1, buffer, len);
  }

  bool get hasBytesAvailable {
    return _lib._objc_msgSend_12(_id, _lib._sel_hasBytesAvailable1);
  }

  NSInputStream initWithData_(NSData? data) {
    final _ret = _lib._objc_msgSend_242(
        _id, _lib._sel_initWithData_1, data?._id ?? ffi.nullptr);
    return NSInputStream._(_ret, _lib, retain: true, release: true);
  }

  NSInputStream initWithURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_226(
        _id, _lib._sel_initWithURL_1, url?._id ?? ffi.nullptr);
    return NSInputStream._(_ret, _lib, retain: true, release: true);
  }

  NSInputStream initWithFileAtPath_(NSString? path) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithFileAtPath_1, path?._id ?? ffi.nullptr);
    return NSInputStream._(_ret, _lib, retain: true, release: true);
  }

  static NSInputStream inputStreamWithData_(AVFAudio _lib, NSData? data) {
    final _ret = _lib._objc_msgSend_242(_lib._class_NSInputStream1,
        _lib._sel_inputStreamWithData_1, data?._id ?? ffi.nullptr);
    return NSInputStream._(_ret, _lib, retain: true, release: true);
  }

  static NSInputStream inputStreamWithFileAtPath_(
      AVFAudio _lib, NSString? path) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSInputStream1,
        _lib._sel_inputStreamWithFileAtPath_1, path?._id ?? ffi.nullptr);
    return NSInputStream._(_ret, _lib, retain: true, release: true);
  }

  static NSInputStream inputStreamWithURL_(AVFAudio _lib, NSURL? url) {
    final _ret = _lib._objc_msgSend_226(_lib._class_NSInputStream1,
        _lib._sel_inputStreamWithURL_1, url?._id ?? ffi.nullptr);
    return NSInputStream._(_ret, _lib, retain: true, release: true);
  }

  static void getStreamsToHostWithName_port_inputStream_outputStream_(
      AVFAudio _lib,
      NSString? hostname,
      int port,
      ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream) {
    return _lib._objc_msgSend_754(
        _lib._class_NSInputStream1,
        _lib._sel_getStreamsToHostWithName_port_inputStream_outputStream_1,
        hostname?._id ?? ffi.nullptr,
        port,
        inputStream,
        outputStream);
  }

  static void getStreamsToHost_port_inputStream_outputStream_(
      AVFAudio _lib,
      NSHost? host,
      int port,
      ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream) {
    return _lib._objc_msgSend_757(
        _lib._class_NSInputStream1,
        _lib._sel_getStreamsToHost_port_inputStream_outputStream_1,
        host?._id ?? ffi.nullptr,
        port,
        inputStream,
        outputStream);
  }

  static void getBoundStreamsWithBufferSize_inputStream_outputStream_(
      AVFAudio _lib,
      int bufferSize,
      ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream) {
    return _lib._objc_msgSend_758(
        _lib._class_NSInputStream1,
        _lib._sel_getBoundStreamsWithBufferSize_inputStream_outputStream_1,
        bufferSize,
        inputStream,
        outputStream);
  }

  static NSInputStream new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSInputStream1, _lib._sel_new1);
    return NSInputStream._(_ret, _lib, retain: false, release: true);
  }

  static NSInputStream alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSInputStream1, _lib._sel_alloc1);
    return NSInputStream._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSInputStream1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSInputStream1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSInputStream1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSInputStream1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSInputStream1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSInputStream1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSInputStream1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSInputStream1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSInputStream1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSStream extends NSObject {
  NSStream._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSStream] that points to the same underlying object as [other].
  static NSStream castFrom<T extends _ObjCWrapper>(T other) {
    return NSStream._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSStream] that wraps the given raw object pointer.
  static NSStream castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSStream._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSStream].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSStream1);
  }

  void open() {
    return _lib._objc_msgSend_1(_id, _lib._sel_open1);
  }

  void close() {
    return _lib._objc_msgSend_1(_id, _lib._sel_close1);
  }

  NSObject? get delegate {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_delegate1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  set delegate(NSObject? value) {
    _lib._objc_msgSend_368(
        _id, _lib._sel_setDelegate_1, value?._id ?? ffi.nullptr);
  }

  NSObject propertyForKey_(NSStreamPropertyKey key) {
    final _ret = _lib._objc_msgSend_30(_id, _lib._sel_propertyForKey_1, key);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  bool setProperty_forKey_(NSObject property, NSStreamPropertyKey key) {
    return _lib._objc_msgSend_225(
        _id, _lib._sel_setProperty_forKey_1, property._id, key);
  }

  void scheduleInRunLoop_forMode_(NSRunLoop? aRunLoop, NSRunLoopMode mode) {
    return _lib._objc_msgSend_501(_id, _lib._sel_scheduleInRunLoop_forMode_1,
        aRunLoop?._id ?? ffi.nullptr, mode);
  }

  void removeFromRunLoop_forMode_(NSRunLoop? aRunLoop, NSRunLoopMode mode) {
    return _lib._objc_msgSend_501(_id, _lib._sel_removeFromRunLoop_forMode_1,
        aRunLoop?._id ?? ffi.nullptr, mode);
  }

  int get streamStatus {
    return _lib._objc_msgSend_751(_id, _lib._sel_streamStatus1);
  }

  NSError? get streamError {
    final _ret = _lib._objc_msgSend_283(_id, _lib._sel_streamError1);
    return _ret.address == 0
        ? null
        : NSError._(_ret, _lib, retain: true, release: true);
  }

  static void getStreamsToHostWithName_port_inputStream_outputStream_(
      AVFAudio _lib,
      NSString? hostname,
      int port,
      ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream) {
    return _lib._objc_msgSend_754(
        _lib._class_NSStream1,
        _lib._sel_getStreamsToHostWithName_port_inputStream_outputStream_1,
        hostname?._id ?? ffi.nullptr,
        port,
        inputStream,
        outputStream);
  }

  static void getStreamsToHost_port_inputStream_outputStream_(
      AVFAudio _lib,
      NSHost? host,
      int port,
      ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream) {
    return _lib._objc_msgSend_757(
        _lib._class_NSStream1,
        _lib._sel_getStreamsToHost_port_inputStream_outputStream_1,
        host?._id ?? ffi.nullptr,
        port,
        inputStream,
        outputStream);
  }

  static void getBoundStreamsWithBufferSize_inputStream_outputStream_(
      AVFAudio _lib,
      int bufferSize,
      ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream) {
    return _lib._objc_msgSend_758(
        _lib._class_NSStream1,
        _lib._sel_getBoundStreamsWithBufferSize_inputStream_outputStream_1,
        bufferSize,
        inputStream,
        outputStream);
  }

  static NSStream new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSStream1, _lib._sel_new1);
    return NSStream._(_ret, _lib, retain: false, release: true);
  }

  static NSStream alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSStream1, _lib._sel_alloc1);
    return NSStream._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSStream1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSStream1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSStream1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSStream1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSStream1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSStream1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSStream1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSStream1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSStream1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef NSStreamPropertyKey = ffi.Pointer<ObjCObject>;

abstract class NSStreamStatus {
  static const int NSStreamStatusNotOpen = 0;
  static const int NSStreamStatusOpening = 1;
  static const int NSStreamStatusOpen = 2;
  static const int NSStreamStatusReading = 3;
  static const int NSStreamStatusWriting = 4;
  static const int NSStreamStatusAtEnd = 5;
  static const int NSStreamStatusClosed = 6;
  static const int NSStreamStatusError = 7;
}

class NSOutputStream extends NSStream {
  NSOutputStream._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSOutputStream] that points to the same underlying object as [other].
  static NSOutputStream castFrom<T extends _ObjCWrapper>(T other) {
    return NSOutputStream._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSOutputStream] that wraps the given raw object pointer.
  static NSOutputStream castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSOutputStream._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSOutputStream].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSOutputStream1);
  }

  int write_maxLength_(ffi.Pointer<ffi.Uint8> buffer, int len) {
    return _lib._objc_msgSend_752(
        _id, _lib._sel_write_maxLength_1, buffer, len);
  }

  bool get hasSpaceAvailable {
    return _lib._objc_msgSend_12(_id, _lib._sel_hasSpaceAvailable1);
  }

  NSOutputStream initToMemory() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_initToMemory1);
    return NSOutputStream._(_ret, _lib, retain: true, release: true);
  }

  NSOutputStream initToBuffer_capacity_(
      ffi.Pointer<ffi.Uint8> buffer, int capacity) {
    final _ret = _lib._objc_msgSend_753(
        _id, _lib._sel_initToBuffer_capacity_1, buffer, capacity);
    return NSOutputStream._(_ret, _lib, retain: true, release: true);
  }

  NSOutputStream initWithURL_append_(NSURL? url, bool shouldAppend) {
    final _ret = _lib._objc_msgSend_231(_id, _lib._sel_initWithURL_append_1,
        url?._id ?? ffi.nullptr, shouldAppend);
    return NSOutputStream._(_ret, _lib, retain: true, release: true);
  }

  NSOutputStream initToFileAtPath_append_(NSString? path, bool shouldAppend) {
    final _ret = _lib._objc_msgSend_29(_id, _lib._sel_initToFileAtPath_append_1,
        path?._id ?? ffi.nullptr, shouldAppend);
    return NSOutputStream._(_ret, _lib, retain: true, release: true);
  }

  static NSOutputStream outputStreamToMemory(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSOutputStream1, _lib._sel_outputStreamToMemory1);
    return NSOutputStream._(_ret, _lib, retain: true, release: true);
  }

  static NSOutputStream outputStreamToBuffer_capacity_(
      AVFAudio _lib, ffi.Pointer<ffi.Uint8> buffer, int capacity) {
    final _ret = _lib._objc_msgSend_753(_lib._class_NSOutputStream1,
        _lib._sel_outputStreamToBuffer_capacity_1, buffer, capacity);
    return NSOutputStream._(_ret, _lib, retain: true, release: true);
  }

  static NSOutputStream outputStreamToFileAtPath_append_(
      AVFAudio _lib, NSString? path, bool shouldAppend) {
    final _ret = _lib._objc_msgSend_29(
        _lib._class_NSOutputStream1,
        _lib._sel_outputStreamToFileAtPath_append_1,
        path?._id ?? ffi.nullptr,
        shouldAppend);
    return NSOutputStream._(_ret, _lib, retain: true, release: true);
  }

  static NSOutputStream outputStreamWithURL_append_(
      AVFAudio _lib, NSURL? url, bool shouldAppend) {
    final _ret = _lib._objc_msgSend_231(
        _lib._class_NSOutputStream1,
        _lib._sel_outputStreamWithURL_append_1,
        url?._id ?? ffi.nullptr,
        shouldAppend);
    return NSOutputStream._(_ret, _lib, retain: true, release: true);
  }

  static void getStreamsToHostWithName_port_inputStream_outputStream_(
      AVFAudio _lib,
      NSString? hostname,
      int port,
      ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream) {
    return _lib._objc_msgSend_754(
        _lib._class_NSOutputStream1,
        _lib._sel_getStreamsToHostWithName_port_inputStream_outputStream_1,
        hostname?._id ?? ffi.nullptr,
        port,
        inputStream,
        outputStream);
  }

  static void getStreamsToHost_port_inputStream_outputStream_(
      AVFAudio _lib,
      NSHost? host,
      int port,
      ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream) {
    return _lib._objc_msgSend_757(
        _lib._class_NSOutputStream1,
        _lib._sel_getStreamsToHost_port_inputStream_outputStream_1,
        host?._id ?? ffi.nullptr,
        port,
        inputStream,
        outputStream);
  }

  static void getBoundStreamsWithBufferSize_inputStream_outputStream_(
      AVFAudio _lib,
      int bufferSize,
      ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream) {
    return _lib._objc_msgSend_758(
        _lib._class_NSOutputStream1,
        _lib._sel_getBoundStreamsWithBufferSize_inputStream_outputStream_1,
        bufferSize,
        inputStream,
        outputStream);
  }

  static NSOutputStream new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSOutputStream1, _lib._sel_new1);
    return NSOutputStream._(_ret, _lib, retain: false, release: true);
  }

  static NSOutputStream alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSOutputStream1, _lib._sel_alloc1);
    return NSOutputStream._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSOutputStream1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSOutputStream1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSOutputStream1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSOutputStream1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSOutputStream1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSOutputStream1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSOutputStream1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSOutputStream1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSOutputStream1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSHost extends NSObject {
  NSHost._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSHost] that points to the same underlying object as [other].
  static NSHost castFrom<T extends _ObjCWrapper>(T other) {
    return NSHost._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSHost] that wraps the given raw object pointer.
  static NSHost castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSHost._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSHost].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSHost1);
  }

  static NSHost currentHost(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSHost1, _lib._sel_currentHost1);
    return NSHost._(_ret, _lib, retain: true, release: true);
  }

  static NSHost hostWithName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSHost1,
        _lib._sel_hostWithName_1, name?._id ?? ffi.nullptr);
    return NSHost._(_ret, _lib, retain: true, release: true);
  }

  static NSHost hostWithAddress_(AVFAudio _lib, NSString? address) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSHost1,
        _lib._sel_hostWithAddress_1, address?._id ?? ffi.nullptr);
    return NSHost._(_ret, _lib, retain: true, release: true);
  }

  bool isEqualToHost_(NSHost? aHost) {
    return _lib._objc_msgSend_755(
        _id, _lib._sel_isEqualToHost_1, aHost?._id ?? ffi.nullptr);
  }

  NSString? get name {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_name1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get names {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_names1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString? get address {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_address1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get addresses {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_addresses1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString? get localizedName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_localizedName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  static void setHostCacheEnabled_(AVFAudio _lib, bool flag) {
    return _lib._objc_msgSend_756(
        _lib._class_NSHost1, _lib._sel_setHostCacheEnabled_1, flag);
  }

  static bool isHostCacheEnabled(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSHost1, _lib._sel_isHostCacheEnabled1);
  }

  static void flushHostCache(AVFAudio _lib) {
    return _lib._objc_msgSend_1(_lib._class_NSHost1, _lib._sel_flushHostCache1);
  }

  static NSHost new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSHost1, _lib._sel_new1);
    return NSHost._(_ret, _lib, retain: false, release: true);
  }

  static NSHost alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSHost1, _lib._sel_alloc1);
    return NSHost._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSHost1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSHost1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSHost1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSHost1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSHost1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSHost1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSHost1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSHost1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSHost1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSURLResponse extends NSObject {
  NSURLResponse._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLResponse] that points to the same underlying object as [other].
  static NSURLResponse castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLResponse._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSURLResponse] that wraps the given raw object pointer.
  static NSURLResponse castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLResponse._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLResponse].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSURLResponse1);
  }

  NSURLResponse initWithURL_MIMEType_expectedContentLength_textEncodingName_(
      NSURL? URL, NSString? MIMEType, int length, NSString? name) {
    final _ret = _lib._objc_msgSend_762(
        _id,
        _lib._sel_initWithURL_MIMEType_expectedContentLength_textEncodingName_1,
        URL?._id ?? ffi.nullptr,
        MIMEType?._id ?? ffi.nullptr,
        length,
        name?._id ?? ffi.nullptr);
    return NSURLResponse._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get URL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_URL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSString? get MIMEType {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_MIMEType1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get expectedContentLength {
    return _lib._objc_msgSend_214(_id, _lib._sel_expectedContentLength1);
  }

  NSString? get textEncodingName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_textEncodingName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get suggestedFilename {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_suggestedFilename1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSURLResponse new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLResponse1, _lib._sel_new1);
    return NSURLResponse._(_ret, _lib, retain: false, release: true);
  }

  static NSURLResponse alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLResponse1, _lib._sel_alloc1);
    return NSURLResponse._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLResponse1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLResponse1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLResponse1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLResponse1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLResponse1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLResponse1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLResponse1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSURLResponse1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLResponse1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSURLSessionTaskState {
  static const int NSURLSessionTaskStateRunning = 0;
  static const int NSURLSessionTaskStateSuspended = 1;
  static const int NSURLSessionTaskStateCanceling = 2;
  static const int NSURLSessionTaskStateCompleted = 3;
}

void _ObjCBlock30_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>()
      .asFunction<void Function(ffi.Pointer<ObjCObject> arg0)>()(arg0);
}

final _ObjCBlock30_closureRegistry = <int, Function>{};
int _ObjCBlock30_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock30_registerClosure(Function fn) {
  final id = ++_ObjCBlock30_closureRegistryIndex;
  _ObjCBlock30_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock30_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return _ObjCBlock30_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock30 extends _ObjCBlockBase {
  ObjCBlock30._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock30.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi
              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock30_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock30.fromFunction(
      AVFAudio lib, void Function(ffi.Pointer<ObjCObject> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock30_closureTrampoline)
                    .cast(),
                _ObjCBlock30_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSIndexPath extends NSObject {
  NSIndexPath._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSIndexPath] that points to the same underlying object as [other].
  static NSIndexPath castFrom<T extends _ObjCWrapper>(T other) {
    return NSIndexPath._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSIndexPath] that wraps the given raw object pointer.
  static NSIndexPath castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSIndexPath._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSIndexPath].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSIndexPath1);
  }

  static NSIndexPath indexPathWithIndex_(AVFAudio _lib, int index) {
    final _ret = _lib._objc_msgSend_60(
        _lib._class_NSIndexPath1, _lib._sel_indexPathWithIndex_1, index);
    return NSIndexPath._(_ret, _lib, retain: true, release: true);
  }

  static NSIndexPath indexPathWithIndexes_length_(
      AVFAudio _lib, ffi.Pointer<NSUInteger> indexes, int length) {
    final _ret = _lib._objc_msgSend_768(_lib._class_NSIndexPath1,
        _lib._sel_indexPathWithIndexes_length_1, indexes, length);
    return NSIndexPath._(_ret, _lib, retain: true, release: true);
  }

  NSIndexPath initWithIndexes_length_(
      ffi.Pointer<NSUInteger> indexes, int length) {
    final _ret = _lib._objc_msgSend_768(
        _id, _lib._sel_initWithIndexes_length_1, indexes, length);
    return NSIndexPath._(_ret, _lib, retain: true, release: true);
  }

  NSIndexPath initWithIndex_(int index) {
    final _ret = _lib._objc_msgSend_60(_id, _lib._sel_initWithIndex_1, index);
    return NSIndexPath._(_ret, _lib, retain: true, release: true);
  }

  NSIndexPath indexPathByAddingIndex_(int index) {
    final _ret =
        _lib._objc_msgSend_769(_id, _lib._sel_indexPathByAddingIndex_1, index);
    return NSIndexPath._(_ret, _lib, retain: true, release: true);
  }

  NSIndexPath indexPathByRemovingLastIndex() {
    final _ret =
        _lib._objc_msgSend_770(_id, _lib._sel_indexPathByRemovingLastIndex1);
    return NSIndexPath._(_ret, _lib, retain: true, release: true);
  }

  int indexAtPosition_(int position) {
    return _lib._objc_msgSend_86(_id, _lib._sel_indexAtPosition_1, position);
  }

  int get length {
    return _lib._objc_msgSend_10(_id, _lib._sel_length1);
  }

  void getIndexes_range_(
      ffi.Pointer<NSUInteger> indexes, NSRange positionRange) {
    return _lib._objc_msgSend_771(
        _id, _lib._sel_getIndexes_range_1, indexes, positionRange);
  }

  int compare_(NSIndexPath? otherObject) {
    return _lib._objc_msgSend_772(
        _id, _lib._sel_compare_1, otherObject?._id ?? ffi.nullptr);
  }

  void getIndexes_(ffi.Pointer<NSUInteger> indexes) {
    return _lib._objc_msgSend_773(_id, _lib._sel_getIndexes_1, indexes);
  }

  static NSIndexPath new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSIndexPath1, _lib._sel_new1);
    return NSIndexPath._(_ret, _lib, retain: false, release: true);
  }

  static NSIndexPath alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSIndexPath1, _lib._sel_alloc1);
    return NSIndexPath._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSIndexPath1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSIndexPath1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSIndexPath1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSIndexPath1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSIndexPath1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSIndexPath1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSIndexPath1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSIndexPath1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSIndexPath1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSInflectionRule extends NSObject {
  NSInflectionRule._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSInflectionRule] that points to the same underlying object as [other].
  static NSInflectionRule castFrom<T extends _ObjCWrapper>(T other) {
    return NSInflectionRule._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSInflectionRule] that wraps the given raw object pointer.
  static NSInflectionRule castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSInflectionRule._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSInflectionRule].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSInflectionRule1);
  }

  @override
  NSObject init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSInflectionRule? getAutomaticRule(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_774(
        _lib._class_NSInflectionRule1, _lib._sel_automaticRule1);
    return _ret.address == 0
        ? null
        : NSInflectionRule._(_ret, _lib, retain: true, release: true);
  }

  static bool canInflectLanguage_(AVFAudio _lib, NSString? language) {
    return _lib._objc_msgSend_59(_lib._class_NSInflectionRule1,
        _lib._sel_canInflectLanguage_1, language?._id ?? ffi.nullptr);
  }

  static bool getCanInflectPreferredLocalization(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSInflectionRule1,
        _lib._sel_canInflectPreferredLocalization1);
  }

  static NSInflectionRule new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSInflectionRule1, _lib._sel_new1);
    return NSInflectionRule._(_ret, _lib, retain: false, release: true);
  }

  static NSInflectionRule alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSInflectionRule1, _lib._sel_alloc1);
    return NSInflectionRule._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSInflectionRule1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSInflectionRule1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSInflectionRule1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSInflectionRule1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSInflectionRule1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSInflectionRule1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSInflectionRule1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSInflectionRule1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSInflectionRule1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSMorphology extends NSObject {
  NSMorphology._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSMorphology] that points to the same underlying object as [other].
  static NSMorphology castFrom<T extends _ObjCWrapper>(T other) {
    return NSMorphology._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSMorphology] that wraps the given raw object pointer.
  static NSMorphology castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSMorphology._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSMorphology].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSMorphology1);
  }

  int get grammaticalGender {
    return _lib._objc_msgSend_775(_id, _lib._sel_grammaticalGender1);
  }

  set grammaticalGender(int value) {
    _lib._objc_msgSend_776(_id, _lib._sel_setGrammaticalGender_1, value);
  }

  int get partOfSpeech {
    return _lib._objc_msgSend_777(_id, _lib._sel_partOfSpeech1);
  }

  set partOfSpeech(int value) {
    _lib._objc_msgSend_778(_id, _lib._sel_setPartOfSpeech_1, value);
  }

  int get number {
    return _lib._objc_msgSend_779(_id, _lib._sel_number1);
  }

  set number(int value) {
    _lib._objc_msgSend_780(_id, _lib._sel_setNumber_1, value);
  }

  NSMorphologyCustomPronoun customPronounForLanguage_(NSString? language) {
    final _ret = _lib._objc_msgSend_781(_id,
        _lib._sel_customPronounForLanguage_1, language?._id ?? ffi.nullptr);
    return NSMorphologyCustomPronoun._(_ret, _lib, retain: true, release: true);
  }

  bool setCustomPronoun_forLanguage_error_(NSMorphologyCustomPronoun? features,
      NSString? language, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_782(
        _id,
        _lib._sel_setCustomPronoun_forLanguage_error_1,
        features?._id ?? ffi.nullptr,
        language?._id ?? ffi.nullptr,
        error);
  }

  bool get unspecified {
    return _lib._objc_msgSend_12(_id, _lib._sel_isUnspecified1);
  }

  static NSMorphology? getUserMorphology(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_783(
        _lib._class_NSMorphology1, _lib._sel_userMorphology1);
    return _ret.address == 0
        ? null
        : NSMorphology._(_ret, _lib, retain: true, release: true);
  }

  static NSMorphology new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMorphology1, _lib._sel_new1);
    return NSMorphology._(_ret, _lib, retain: false, release: true);
  }

  static NSMorphology alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMorphology1, _lib._sel_alloc1);
    return NSMorphology._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSMorphology1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSMorphology1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMorphology1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMorphology1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSMorphology1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSMorphology1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSMorphology1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSMorphology1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMorphology1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSGrammaticalGender {
  static const int NSGrammaticalGenderNotSet = 0;
  static const int NSGrammaticalGenderFeminine = 1;
  static const int NSGrammaticalGenderMasculine = 2;
  static const int NSGrammaticalGenderNeuter = 3;
}

abstract class NSGrammaticalPartOfSpeech {
  static const int NSGrammaticalPartOfSpeechNotSet = 0;
  static const int NSGrammaticalPartOfSpeechDeterminer = 1;
  static const int NSGrammaticalPartOfSpeechPronoun = 2;
  static const int NSGrammaticalPartOfSpeechLetter = 3;
  static const int NSGrammaticalPartOfSpeechAdverb = 4;
  static const int NSGrammaticalPartOfSpeechParticle = 5;
  static const int NSGrammaticalPartOfSpeechAdjective = 6;
  static const int NSGrammaticalPartOfSpeechAdposition = 7;
  static const int NSGrammaticalPartOfSpeechVerb = 8;
  static const int NSGrammaticalPartOfSpeechNoun = 9;
  static const int NSGrammaticalPartOfSpeechConjunction = 10;
  static const int NSGrammaticalPartOfSpeechNumeral = 11;
  static const int NSGrammaticalPartOfSpeechInterjection = 12;
  static const int NSGrammaticalPartOfSpeechPreposition = 13;
  static const int NSGrammaticalPartOfSpeechAbbreviation = 14;
}

abstract class NSGrammaticalNumber {
  static const int NSGrammaticalNumberNotSet = 0;
  static const int NSGrammaticalNumberSingular = 1;
  static const int NSGrammaticalNumberZero = 2;
  static const int NSGrammaticalNumberPlural = 3;
  static const int NSGrammaticalNumberPluralTwo = 4;
  static const int NSGrammaticalNumberPluralFew = 5;
  static const int NSGrammaticalNumberPluralMany = 6;
}

class NSMorphologyCustomPronoun extends NSObject {
  NSMorphologyCustomPronoun._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSMorphologyCustomPronoun] that points to the same underlying object as [other].
  static NSMorphologyCustomPronoun castFrom<T extends _ObjCWrapper>(T other) {
    return NSMorphologyCustomPronoun._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSMorphologyCustomPronoun] that wraps the given raw object pointer.
  static NSMorphologyCustomPronoun castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSMorphologyCustomPronoun._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSMorphologyCustomPronoun].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSMorphologyCustomPronoun1);
  }

  static bool isSupportedForLanguage_(AVFAudio _lib, NSString? language) {
    return _lib._objc_msgSend_59(_lib._class_NSMorphologyCustomPronoun1,
        _lib._sel_isSupportedForLanguage_1, language?._id ?? ffi.nullptr);
  }

  static NSArray requiredKeysForLanguage_(AVFAudio _lib, NSString? language) {
    final _ret = _lib._objc_msgSend_119(_lib._class_NSMorphologyCustomPronoun1,
        _lib._sel_requiredKeysForLanguage_1, language?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString? get subjectForm {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_subjectForm1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set subjectForm(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setSubjectForm_1, value?._id ?? ffi.nullptr);
  }

  NSString? get objectForm {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_objectForm1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set objectForm(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setObjectForm_1, value?._id ?? ffi.nullptr);
  }

  NSString? get possessiveForm {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_possessiveForm1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set possessiveForm(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPossessiveForm_1, value?._id ?? ffi.nullptr);
  }

  NSString? get possessiveAdjectiveForm {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_possessiveAdjectiveForm1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set possessiveAdjectiveForm(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPossessiveAdjectiveForm_1, value?._id ?? ffi.nullptr);
  }

  NSString? get reflexiveForm {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_reflexiveForm1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set reflexiveForm(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setReflexiveForm_1, value?._id ?? ffi.nullptr);
  }

  static NSMorphologyCustomPronoun new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMorphologyCustomPronoun1, _lib._sel_new1);
    return NSMorphologyCustomPronoun._(_ret, _lib,
        retain: false, release: true);
  }

  static NSMorphologyCustomPronoun alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMorphologyCustomPronoun1, _lib._sel_alloc1);
    return NSMorphologyCustomPronoun._(_ret, _lib,
        retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSMorphologyCustomPronoun1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSMorphologyCustomPronoun1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSMorphologyCustomPronoun1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMorphologyCustomPronoun1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSMorphologyCustomPronoun1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSMorphologyCustomPronoun1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSMorphologyCustomPronoun1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSMorphologyCustomPronoun1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSMorphologyCustomPronoun1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSOperationQueue extends NSObject {
  NSOperationQueue._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSOperationQueue] that points to the same underlying object as [other].
  static NSOperationQueue castFrom<T extends _ObjCWrapper>(T other) {
    return NSOperationQueue._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSOperationQueue] that wraps the given raw object pointer.
  static NSOperationQueue castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSOperationQueue._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSOperationQueue].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSOperationQueue1);
  }

  NSProgress? get progress {
    final _ret = _lib._objc_msgSend_577(_id, _lib._sel_progress1);
    return _ret.address == 0
        ? null
        : NSProgress._(_ret, _lib, retain: true, release: true);
  }

  void addOperation_(NSOperation? op) {
    return _lib._objc_msgSend_784(
        _id, _lib._sel_addOperation_1, op?._id ?? ffi.nullptr);
  }

  void addOperations_waitUntilFinished_(NSArray? ops, bool wait) {
    return _lib._objc_msgSend_787(
        _id,
        _lib._sel_addOperations_waitUntilFinished_1,
        ops?._id ?? ffi.nullptr,
        wait);
  }

  void addOperationWithBlock_(ObjCBlock16 block) {
    return _lib._objc_msgSend_465(
        _id, _lib._sel_addOperationWithBlock_1, block._id);
  }

  void addBarrierBlock_(ObjCBlock16 barrier) {
    return _lib._objc_msgSend_465(
        _id, _lib._sel_addBarrierBlock_1, barrier._id);
  }

  int get maxConcurrentOperationCount {
    return _lib._objc_msgSend_78(_id, _lib._sel_maxConcurrentOperationCount1);
  }

  set maxConcurrentOperationCount(int value) {
    _lib._objc_msgSend_558(
        _id, _lib._sel_setMaxConcurrentOperationCount_1, value);
  }

  bool get suspended {
    return _lib._objc_msgSend_12(_id, _lib._sel_isSuspended1);
  }

  set suspended(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setSuspended_1, value);
  }

  NSString? get name {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_name1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set name(NSString? value) {
    _lib._objc_msgSend_477(_id, _lib._sel_setName_1, value?._id ?? ffi.nullptr);
  }

  int get qualityOfService {
    return _lib._objc_msgSend_475(_id, _lib._sel_qualityOfService1);
  }

  set qualityOfService(int value) {
    _lib._objc_msgSend_476(_id, _lib._sel_setQualityOfService_1, value);
  }

  dispatch_queue_t get underlyingQueue {
    return _lib._objc_msgSend_788(_id, _lib._sel_underlyingQueue1);
  }

  set underlyingQueue(dispatch_queue_t value) {
    _lib._objc_msgSend_789(_id, _lib._sel_setUnderlyingQueue_1, value);
  }

  void cancelAllOperations() {
    return _lib._objc_msgSend_1(_id, _lib._sel_cancelAllOperations1);
  }

  void waitUntilAllOperationsAreFinished() {
    return _lib._objc_msgSend_1(
        _id, _lib._sel_waitUntilAllOperationsAreFinished1);
  }

  static NSOperationQueue? getCurrentQueue(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_790(
        _lib._class_NSOperationQueue1, _lib._sel_currentQueue1);
    return _ret.address == 0
        ? null
        : NSOperationQueue._(_ret, _lib, retain: true, release: true);
  }

  static NSOperationQueue? getMainQueue(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_790(
        _lib._class_NSOperationQueue1, _lib._sel_mainQueue1);
    return _ret.address == 0
        ? null
        : NSOperationQueue._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get operations {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_operations1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  int get operationCount {
    return _lib._objc_msgSend_10(_id, _lib._sel_operationCount1);
  }

  static NSOperationQueue new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSOperationQueue1, _lib._sel_new1);
    return NSOperationQueue._(_ret, _lib, retain: false, release: true);
  }

  static NSOperationQueue alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSOperationQueue1, _lib._sel_alloc1);
    return NSOperationQueue._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSOperationQueue1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSOperationQueue1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSOperationQueue1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSOperationQueue1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSOperationQueue1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSOperationQueue1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSOperationQueue1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSOperationQueue1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSOperationQueue1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSOperation extends NSObject {
  NSOperation._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSOperation] that points to the same underlying object as [other].
  static NSOperation castFrom<T extends _ObjCWrapper>(T other) {
    return NSOperation._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSOperation] that wraps the given raw object pointer.
  static NSOperation castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSOperation._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSOperation].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSOperation1);
  }

  void start() {
    return _lib._objc_msgSend_1(_id, _lib._sel_start1);
  }

  void main() {
    return _lib._objc_msgSend_1(_id, _lib._sel_main1);
  }

  bool get cancelled {
    return _lib._objc_msgSend_12(_id, _lib._sel_isCancelled1);
  }

  void cancel() {
    return _lib._objc_msgSend_1(_id, _lib._sel_cancel1);
  }

  bool get executing {
    return _lib._objc_msgSend_12(_id, _lib._sel_isExecuting1);
  }

  bool get finished {
    return _lib._objc_msgSend_12(_id, _lib._sel_isFinished1);
  }

  bool get concurrent {
    return _lib._objc_msgSend_12(_id, _lib._sel_isConcurrent1);
  }

  bool get asynchronous {
    return _lib._objc_msgSend_12(_id, _lib._sel_isAsynchronous1);
  }

  bool get ready {
    return _lib._objc_msgSend_12(_id, _lib._sel_isReady1);
  }

  void addDependency_(NSOperation? op) {
    return _lib._objc_msgSend_784(
        _id, _lib._sel_addDependency_1, op?._id ?? ffi.nullptr);
  }

  void removeDependency_(NSOperation? op) {
    return _lib._objc_msgSend_784(
        _id, _lib._sel_removeDependency_1, op?._id ?? ffi.nullptr);
  }

  NSArray? get dependencies {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_dependencies1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  int get queuePriority {
    return _lib._objc_msgSend_785(_id, _lib._sel_queuePriority1);
  }

  set queuePriority(int value) {
    _lib._objc_msgSend_786(_id, _lib._sel_setQueuePriority_1, value);
  }

  ObjCBlock16 get completionBlock {
    final _ret = _lib._objc_msgSend_586(_id, _lib._sel_completionBlock1);
    return ObjCBlock16._(_ret, _lib);
  }

  set completionBlock(ObjCBlock16 value) {
    _lib._objc_msgSend_587(_id, _lib._sel_setCompletionBlock_1, value._id);
  }

  void waitUntilFinished() {
    return _lib._objc_msgSend_1(_id, _lib._sel_waitUntilFinished1);
  }

  double get threadPriority {
    return _lib._objc_msgSend_149(_id, _lib._sel_threadPriority1);
  }

  set threadPriority(double value) {
    _lib._objc_msgSend_474(_id, _lib._sel_setThreadPriority_1, value);
  }

  int get qualityOfService {
    return _lib._objc_msgSend_475(_id, _lib._sel_qualityOfService1);
  }

  set qualityOfService(int value) {
    _lib._objc_msgSend_476(_id, _lib._sel_setQualityOfService_1, value);
  }

  NSString? get name {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_name1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set name(NSString? value) {
    _lib._objc_msgSend_477(_id, _lib._sel_setName_1, value?._id ?? ffi.nullptr);
  }

  static NSOperation new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSOperation1, _lib._sel_new1);
    return NSOperation._(_ret, _lib, retain: false, release: true);
  }

  static NSOperation alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSOperation1, _lib._sel_alloc1);
    return NSOperation._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSOperation1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSOperation1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSOperation1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSOperation1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSOperation1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSOperation1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSOperation1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSOperation1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSOperation1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSOperationQueuePriority {
  static const int NSOperationQueuePriorityVeryLow = -8;
  static const int NSOperationQueuePriorityLow = -4;
  static const int NSOperationQueuePriorityNormal = 0;
  static const int NSOperationQueuePriorityHigh = 4;
  static const int NSOperationQueuePriorityVeryHigh = 8;
}

typedef dispatch_queue_t = ffi.Pointer<ObjCObject>;

class NSPointerArray extends NSObject {
  NSPointerArray._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSPointerArray] that points to the same underlying object as [other].
  static NSPointerArray castFrom<T extends _ObjCWrapper>(T other) {
    return NSPointerArray._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSPointerArray] that wraps the given raw object pointer.
  static NSPointerArray castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSPointerArray._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSPointerArray].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSPointerArray1);
  }

  NSPointerArray initWithOptions_(int options) {
    final _ret =
        _lib._objc_msgSend_791(_id, _lib._sel_initWithOptions_1, options);
    return NSPointerArray._(_ret, _lib, retain: true, release: true);
  }

  NSPointerArray initWithPointerFunctions_(NSPointerFunctions? functions) {
    final _ret = _lib._objc_msgSend_805(_id,
        _lib._sel_initWithPointerFunctions_1, functions?._id ?? ffi.nullptr);
    return NSPointerArray._(_ret, _lib, retain: true, release: true);
  }

  static NSPointerArray pointerArrayWithOptions_(AVFAudio _lib, int options) {
    final _ret = _lib._objc_msgSend_806(_lib._class_NSPointerArray1,
        _lib._sel_pointerArrayWithOptions_1, options);
    return NSPointerArray._(_ret, _lib, retain: true, release: true);
  }

  static NSPointerArray pointerArrayWithPointerFunctions_(
      AVFAudio _lib, NSPointerFunctions? functions) {
    final _ret = _lib._objc_msgSend_807(
        _lib._class_NSPointerArray1,
        _lib._sel_pointerArrayWithPointerFunctions_1,
        functions?._id ?? ffi.nullptr);
    return NSPointerArray._(_ret, _lib, retain: true, release: true);
  }

  NSPointerFunctions? get pointerFunctions {
    final _ret = _lib._objc_msgSend_808(_id, _lib._sel_pointerFunctions1);
    return _ret.address == 0
        ? null
        : NSPointerFunctions._(_ret, _lib, retain: true, release: true);
  }

  ffi.Pointer<ffi.Void> pointerAtIndex_(int index) {
    return _lib._objc_msgSend_809(_id, _lib._sel_pointerAtIndex_1, index);
  }

  void addPointer_(ffi.Pointer<ffi.Void> pointer) {
    return _lib._objc_msgSend_47(_id, _lib._sel_addPointer_1, pointer);
  }

  void removePointerAtIndex_(int index) {
    return _lib._objc_msgSend_410(_id, _lib._sel_removePointerAtIndex_1, index);
  }

  void insertPointer_atIndex_(ffi.Pointer<ffi.Void> item, int index) {
    return _lib._objc_msgSend_21(
        _id, _lib._sel_insertPointer_atIndex_1, item, index);
  }

  void replacePointerAtIndex_withPointer_(
      int index, ffi.Pointer<ffi.Void> item) {
    return _lib._objc_msgSend_810(
        _id, _lib._sel_replacePointerAtIndex_withPointer_1, index, item);
  }

  void compact() {
    return _lib._objc_msgSend_1(_id, _lib._sel_compact1);
  }

  int get count {
    return _lib._objc_msgSend_10(_id, _lib._sel_count1);
  }

  set count(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setCount_1, value);
  }

  static NSObject pointerArrayWithStrongObjects(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSPointerArray1, _lib._sel_pointerArrayWithStrongObjects1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject pointerArrayWithWeakObjects(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSPointerArray1, _lib._sel_pointerArrayWithWeakObjects1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSPointerArray strongObjectsPointerArray(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_811(
        _lib._class_NSPointerArray1, _lib._sel_strongObjectsPointerArray1);
    return NSPointerArray._(_ret, _lib, retain: true, release: true);
  }

  static NSPointerArray weakObjectsPointerArray(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_811(
        _lib._class_NSPointerArray1, _lib._sel_weakObjectsPointerArray1);
    return NSPointerArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get allObjects {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_allObjects1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSPointerArray new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSPointerArray1, _lib._sel_new1);
    return NSPointerArray._(_ret, _lib, retain: false, release: true);
  }

  static NSPointerArray alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSPointerArray1, _lib._sel_alloc1);
    return NSPointerArray._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSPointerArray1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSPointerArray1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSPointerArray1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSPointerArray1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSPointerArray1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSPointerArray1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSPointerArray1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSPointerArray1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSPointerArray1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSPointerFunctionsOptions {
  static const int NSPointerFunctionsStrongMemory = 0;
  static const int NSPointerFunctionsZeroingWeakMemory = 1;
  static const int NSPointerFunctionsOpaqueMemory = 2;
  static const int NSPointerFunctionsMallocMemory = 3;
  static const int NSPointerFunctionsMachVirtualMemory = 4;
  static const int NSPointerFunctionsWeakMemory = 5;
  static const int NSPointerFunctionsObjectPersonality = 0;
  static const int NSPointerFunctionsOpaquePersonality = 256;
  static const int NSPointerFunctionsObjectPointerPersonality = 512;
  static const int NSPointerFunctionsCStringPersonality = 768;
  static const int NSPointerFunctionsStructPersonality = 1024;
  static const int NSPointerFunctionsIntegerPersonality = 1280;
  static const int NSPointerFunctionsCopyIn = 65536;
}

class NSPointerFunctions extends NSObject {
  NSPointerFunctions._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSPointerFunctions] that points to the same underlying object as [other].
  static NSPointerFunctions castFrom<T extends _ObjCWrapper>(T other) {
    return NSPointerFunctions._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSPointerFunctions] that wraps the given raw object pointer.
  static NSPointerFunctions castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSPointerFunctions._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSPointerFunctions].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSPointerFunctions1);
  }

  NSPointerFunctions initWithOptions_(int options) {
    final _ret =
        _lib._objc_msgSend_791(_id, _lib._sel_initWithOptions_1, options);
    return NSPointerFunctions._(_ret, _lib, retain: true, release: true);
  }

  static NSPointerFunctions pointerFunctionsWithOptions_(
      AVFAudio _lib, int options) {
    final _ret = _lib._objc_msgSend_792(_lib._class_NSPointerFunctions1,
        _lib._sel_pointerFunctionsWithOptions_1, options);
    return NSPointerFunctions._(_ret, _lib, retain: true, release: true);
  }

  ffi.Pointer<
          ffi.NativeFunction<
              NSUInteger Function(
                  ffi.Pointer<ffi.Void>,
                  ffi.Pointer<
                      ffi.NativeFunction<
                          NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
      get hashFunction {
    return _lib._objc_msgSend_793(_id, _lib._sel_hashFunction1);
  }

  set hashFunction(
      ffi.Pointer<
              ffi.NativeFunction<
                  NSUInteger Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
          value) {
    _lib._objc_msgSend_794(_id, _lib._sel_setHashFunction_1, value);
  }

  ffi.Pointer<
          ffi.NativeFunction<
              ffi.Bool Function(
                  ffi.Pointer<ffi.Void>,
                  ffi.Pointer<ffi.Void>,
                  ffi.Pointer<
                      ffi.NativeFunction<
                          NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
      get isEqualFunction {
    return _lib._objc_msgSend_795(_id, _lib._sel_isEqualFunction1);
  }

  set isEqualFunction(
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Bool Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
          value) {
    _lib._objc_msgSend_796(_id, _lib._sel_setIsEqualFunction_1, value);
  }

  ffi.Pointer<ffi.NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>
      get sizeFunction {
    return _lib._objc_msgSend_797(_id, _lib._sel_sizeFunction1);
  }

  set sizeFunction(
      ffi.Pointer<
              ffi.NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>
          value) {
    _lib._objc_msgSend_798(_id, _lib._sel_setSizeFunction_1, value);
  }

  ffi.Pointer<
          ffi.NativeFunction<
              ffi.Pointer<ObjCObject> Function(ffi.Pointer<ffi.Void>)>>
      get descriptionFunction {
    return _lib._objc_msgSend_799(_id, _lib._sel_descriptionFunction1);
  }

  set descriptionFunction(
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Pointer<ObjCObject> Function(ffi.Pointer<ffi.Void>)>>
          value) {
    _lib._objc_msgSend_800(_id, _lib._sel_setDescriptionFunction_1, value);
  }

  ffi.Pointer<
          ffi.NativeFunction<
              ffi.Void Function(
                  ffi.Pointer<ffi.Void>,
                  ffi.Pointer<
                      ffi.NativeFunction<
                          NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
      get relinquishFunction {
    return _lib._objc_msgSend_801(_id, _lib._sel_relinquishFunction1);
  }

  set relinquishFunction(
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>>
          value) {
    _lib._objc_msgSend_802(_id, _lib._sel_setRelinquishFunction_1, value);
  }

  ffi.Pointer<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Void> Function(
              ffi.Pointer<ffi.Void>,
              ffi.Pointer<
                  ffi
                  .NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
              ffi.Bool)>> get acquireFunction {
    return _lib._objc_msgSend_803(_id, _lib._sel_acquireFunction1);
  }

  set acquireFunction(
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Pointer<ffi.Void> Function(
                      ffi.Pointer<ffi.Void>,
                      ffi.Pointer<
                          ffi.NativeFunction<
                              NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
                      ffi.Bool)>>
          value) {
    _lib._objc_msgSend_804(_id, _lib._sel_setAcquireFunction_1, value);
  }

  bool get usesStrongWriteBarrier {
    return _lib._objc_msgSend_12(_id, _lib._sel_usesStrongWriteBarrier1);
  }

  set usesStrongWriteBarrier(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setUsesStrongWriteBarrier_1, value);
  }

  bool get usesWeakReadAndWriteBarriers {
    return _lib._objc_msgSend_12(_id, _lib._sel_usesWeakReadAndWriteBarriers1);
  }

  set usesWeakReadAndWriteBarriers(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setUsesWeakReadAndWriteBarriers_1, value);
  }

  static NSPointerFunctions new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSPointerFunctions1, _lib._sel_new1);
    return NSPointerFunctions._(_ret, _lib, retain: false, release: true);
  }

  static NSPointerFunctions alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSPointerFunctions1, _lib._sel_alloc1);
    return NSPointerFunctions._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSPointerFunctions1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSPointerFunctions1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSPointerFunctions1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSPointerFunctions1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSPointerFunctions1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSPointerFunctions1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSPointerFunctions1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSPointerFunctions1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSPointerFunctions1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSProcessInfo extends NSObject {
  NSProcessInfo._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSProcessInfo] that points to the same underlying object as [other].
  static NSProcessInfo castFrom<T extends _ObjCWrapper>(T other) {
    return NSProcessInfo._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSProcessInfo] that wraps the given raw object pointer.
  static NSProcessInfo castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSProcessInfo._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSProcessInfo].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSProcessInfo1);
  }

  static NSProcessInfo? getProcessInfo(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_812(
        _lib._class_NSProcessInfo1, _lib._sel_processInfo1);
    return _ret.address == 0
        ? null
        : NSProcessInfo._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get environment {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_environment1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get arguments {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_arguments1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSString? get hostName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_hostName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get processName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_processName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set processName(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setProcessName_1, value?._id ?? ffi.nullptr);
  }

  int get processIdentifier {
    return _lib._objc_msgSend_213(_id, _lib._sel_processIdentifier1);
  }

  NSString? get globallyUniqueString {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_globallyUniqueString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int operatingSystem() {
    return _lib._objc_msgSend_10(_id, _lib._sel_operatingSystem1);
  }

  NSString operatingSystemName() {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_operatingSystemName1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get operatingSystemVersionString {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_operatingSystemVersionString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSOperatingSystemVersion get operatingSystemVersion {
    return _lib._objc_msgSend_813(_id, _lib._sel_operatingSystemVersion1);
  }

  int get processorCount {
    return _lib._objc_msgSend_10(_id, _lib._sel_processorCount1);
  }

  int get activeProcessorCount {
    return _lib._objc_msgSend_10(_id, _lib._sel_activeProcessorCount1);
  }

  int get physicalMemory {
    return _lib._objc_msgSend_148(_id, _lib._sel_physicalMemory1);
  }

  bool isOperatingSystemAtLeastVersion_(NSOperatingSystemVersion version) {
    return _lib._objc_msgSend_814(
        _id, _lib._sel_isOperatingSystemAtLeastVersion_1, version);
  }

  double get systemUptime {
    return _lib._objc_msgSend_149(_id, _lib._sel_systemUptime1);
  }

  void disableSuddenTermination() {
    return _lib._objc_msgSend_1(_id, _lib._sel_disableSuddenTermination1);
  }

  void enableSuddenTermination() {
    return _lib._objc_msgSend_1(_id, _lib._sel_enableSuddenTermination1);
  }

  void disableAutomaticTermination_(NSString? reason) {
    return _lib._objc_msgSend_186(_id, _lib._sel_disableAutomaticTermination_1,
        reason?._id ?? ffi.nullptr);
  }

  void enableAutomaticTermination_(NSString? reason) {
    return _lib._objc_msgSend_186(_id, _lib._sel_enableAutomaticTermination_1,
        reason?._id ?? ffi.nullptr);
  }

  bool get automaticTerminationSupportEnabled {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_automaticTerminationSupportEnabled1);
  }

  set automaticTerminationSupportEnabled(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setAutomaticTerminationSupportEnabled_1, value);
  }

  NSObject beginActivityWithOptions_reason_(int options, NSString? reason) {
    final _ret = _lib._objc_msgSend_815(
        _id,
        _lib._sel_beginActivityWithOptions_reason_1,
        options,
        reason?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  void endActivity_(NSObject? activity) {
    return _lib._objc_msgSend_15(
        _id, _lib._sel_endActivity_1, activity?._id ?? ffi.nullptr);
  }

  void performActivityWithOptions_reason_usingBlock_(
      int options, NSString? reason, ObjCBlock16 block) {
    return _lib._objc_msgSend_816(
        _id,
        _lib._sel_performActivityWithOptions_reason_usingBlock_1,
        options,
        reason?._id ?? ffi.nullptr,
        block._id);
  }

  void performExpiringActivityWithReason_usingBlock_(
      NSString? reason, ObjCBlock31 block) {
    return _lib._objc_msgSend_817(
        _id,
        _lib._sel_performExpiringActivityWithReason_usingBlock_1,
        reason?._id ?? ffi.nullptr,
        block._id);
  }

  NSString? get userName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_userName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get fullUserName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_fullUserName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get thermalState {
    return _lib._objc_msgSend_818(_id, _lib._sel_thermalState1);
  }

  bool get lowPowerModeEnabled {
    return _lib._objc_msgSend_12(_id, _lib._sel_isLowPowerModeEnabled1);
  }

  bool get macCatalystApp {
    return _lib._objc_msgSend_12(_id, _lib._sel_isMacCatalystApp1);
  }

  bool get iOSAppOnMac {
    return _lib._objc_msgSend_12(_id, _lib._sel_isiOSAppOnMac1);
  }

  static NSProcessInfo new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSProcessInfo1, _lib._sel_new1);
    return NSProcessInfo._(_ret, _lib, retain: false, release: true);
  }

  static NSProcessInfo alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSProcessInfo1, _lib._sel_alloc1);
    return NSProcessInfo._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSProcessInfo1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSProcessInfo1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSProcessInfo1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSProcessInfo1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSProcessInfo1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSProcessInfo1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSProcessInfo1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSProcessInfo1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSProcessInfo1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

final class NSOperatingSystemVersion extends ffi.Struct {
  @NSInteger()
  external int majorVersion;

  @NSInteger()
  external int minorVersion;

  @NSInteger()
  external int patchVersion;
}

abstract class NSActivityOptions {
  static const int NSActivityIdleDisplaySleepDisabled = 1099511627776;
  static const int NSActivityIdleSystemSleepDisabled = 1048576;
  static const int NSActivitySuddenTerminationDisabled = 16384;
  static const int NSActivityAutomaticTerminationDisabled = 32768;
  static const int NSActivityUserInitiated = 16777215;
  static const int NSActivityUserInitiatedAllowingIdleSystemSleep = 15728639;
  static const int NSActivityBackground = 255;
  static const int NSActivityLatencyCritical = 1095216660480;
}

void _ObjCBlock31_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block, bool arg0) {
  return block.ref.target
      .cast<ffi.NativeFunction<ffi.Void Function(ffi.Bool arg0)>>()
      .asFunction<void Function(bool arg0)>()(arg0);
}

final _ObjCBlock31_closureRegistry = <int, Function>{};
int _ObjCBlock31_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock31_registerClosure(Function fn) {
  final id = ++_ObjCBlock31_closureRegistryIndex;
  _ObjCBlock31_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock31_closureTrampoline(ffi.Pointer<_ObjCBlock> block, bool arg0) {
  return _ObjCBlock31_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock31 extends _ObjCBlockBase {
  ObjCBlock31._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock31.fromFunctionPointer(AVFAudio lib,
      ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool arg0)>> ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                        ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                            ffi.Bool arg0)>(_ObjCBlock31_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock31.fromFunction(AVFAudio lib, void Function(bool arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                        ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                            ffi.Bool arg0)>(_ObjCBlock31_closureTrampoline)
                    .cast(),
                _ObjCBlock31_registerClosure(fn)),
            lib);
  void call(bool arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block, ffi.Bool arg0)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block, bool arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

abstract class NSProcessInfoThermalState {
  static const int NSProcessInfoThermalStateNominal = 0;
  static const int NSProcessInfoThermalStateFair = 1;
  static const int NSProcessInfoThermalStateSerious = 2;
  static const int NSProcessInfoThermalStateCritical = 3;
}

class NSTextCheckingResult extends NSObject {
  NSTextCheckingResult._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSTextCheckingResult] that points to the same underlying object as [other].
  static NSTextCheckingResult castFrom<T extends _ObjCWrapper>(T other) {
    return NSTextCheckingResult._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSTextCheckingResult] that wraps the given raw object pointer.
  static NSTextCheckingResult castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSTextCheckingResult._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSTextCheckingResult].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSTextCheckingResult1);
  }

  int get resultType {
    return _lib._objc_msgSend_819(_id, _lib._sel_resultType1);
  }

  NSRange get range {
    return _lib._objc_msgSend_49(_id, _lib._sel_range1);
  }

  NSOrthography? get orthography {
    final _ret = _lib._objc_msgSend_820(_id, _lib._sel_orthography1);
    return _ret.address == 0
        ? null
        : NSOrthography._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get grammarDetails {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_grammarDetails1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSDate? get date {
    final _ret = _lib._objc_msgSend_156(_id, _lib._sel_date1);
    return _ret.address == 0
        ? null
        : NSDate._(_ret, _lib, retain: true, release: true);
  }

  NSTimeZone? get timeZone {
    final _ret = _lib._objc_msgSend_162(_id, _lib._sel_timeZone1);
    return _ret.address == 0
        ? null
        : NSTimeZone._(_ret, _lib, retain: true, release: true);
  }

  double get duration {
    return _lib._objc_msgSend_149(_id, _lib._sel_duration1);
  }

  NSDictionary? get components {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_components1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get URL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_URL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSString? get replacementString {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_replacementString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get alternativeStrings {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_alternativeStrings1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSRegularExpression? get regularExpression {
    final _ret = _lib._objc_msgSend_832(_id, _lib._sel_regularExpression1);
    return _ret.address == 0
        ? null
        : NSRegularExpression._(_ret, _lib, retain: true, release: true);
  }

  NSString? get phoneNumber {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_phoneNumber1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get numberOfRanges {
    return _lib._objc_msgSend_10(_id, _lib._sel_numberOfRanges1);
  }

  NSRange rangeAtIndex_(int idx) {
    return _lib._objc_msgSend_308(_id, _lib._sel_rangeAtIndex_1, idx);
  }

  NSRange rangeWithName_(NSString? name) {
    return _lib._objc_msgSend_301(
        _id, _lib._sel_rangeWithName_1, name?._id ?? ffi.nullptr);
  }

  NSTextCheckingResult resultByAdjustingRangesWithOffset_(int offset) {
    final _ret = _lib._objc_msgSend_833(
        _id, _lib._sel_resultByAdjustingRangesWithOffset_1, offset);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get addressComponents {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_addressComponents1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult orthographyCheckingResultWithRange_orthography_(
      AVFAudio _lib, NSRange range, NSOrthography? orthography) {
    final _ret = _lib._objc_msgSend_834(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_orthographyCheckingResultWithRange_orthography_1,
        range,
        orthography?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult spellCheckingResultWithRange_(
      AVFAudio _lib, NSRange range) {
    final _ret = _lib._objc_msgSend_835(_lib._class_NSTextCheckingResult1,
        _lib._sel_spellCheckingResultWithRange_1, range);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult grammarCheckingResultWithRange_details_(
      AVFAudio _lib, NSRange range, NSArray? details) {
    final _ret = _lib._objc_msgSend_836(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_grammarCheckingResultWithRange_details_1,
        range,
        details?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult dateCheckingResultWithRange_date_(
      AVFAudio _lib, NSRange range, NSDate? date) {
    final _ret = _lib._objc_msgSend_837(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_dateCheckingResultWithRange_date_1,
        range,
        date?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult
      dateCheckingResultWithRange_date_timeZone_duration_(AVFAudio _lib,
          NSRange range, NSDate? date, NSTimeZone? timeZone, double duration) {
    final _ret = _lib._objc_msgSend_838(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_dateCheckingResultWithRange_date_timeZone_duration_1,
        range,
        date?._id ?? ffi.nullptr,
        timeZone?._id ?? ffi.nullptr,
        duration);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult addressCheckingResultWithRange_components_(
      AVFAudio _lib, NSRange range, NSDictionary? components) {
    final _ret = _lib._objc_msgSend_839(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_addressCheckingResultWithRange_components_1,
        range,
        components?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult linkCheckingResultWithRange_URL_(
      AVFAudio _lib, NSRange range, NSURL? url) {
    final _ret = _lib._objc_msgSend_840(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_linkCheckingResultWithRange_URL_1,
        range,
        url?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult quoteCheckingResultWithRange_replacementString_(
      AVFAudio _lib, NSRange range, NSString? replacementString) {
    final _ret = _lib._objc_msgSend_841(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_quoteCheckingResultWithRange_replacementString_1,
        range,
        replacementString?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult dashCheckingResultWithRange_replacementString_(
      AVFAudio _lib, NSRange range, NSString? replacementString) {
    final _ret = _lib._objc_msgSend_841(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_dashCheckingResultWithRange_replacementString_1,
        range,
        replacementString?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult
      replacementCheckingResultWithRange_replacementString_(
          AVFAudio _lib, NSRange range, NSString? replacementString) {
    final _ret = _lib._objc_msgSend_841(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_replacementCheckingResultWithRange_replacementString_1,
        range,
        replacementString?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult
      correctionCheckingResultWithRange_replacementString_(
          AVFAudio _lib, NSRange range, NSString? replacementString) {
    final _ret = _lib._objc_msgSend_841(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_correctionCheckingResultWithRange_replacementString_1,
        range,
        replacementString?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult
      correctionCheckingResultWithRange_replacementString_alternativeStrings_(
          AVFAudio _lib,
          NSRange range,
          NSString? replacementString,
          NSArray? alternativeStrings) {
    final _ret = _lib._objc_msgSend_842(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_correctionCheckingResultWithRange_replacementString_alternativeStrings_1,
        range,
        replacementString?._id ?? ffi.nullptr,
        alternativeStrings?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult
      regularExpressionCheckingResultWithRanges_count_regularExpression_(
          AVFAudio _lib,
          NSRangePointer ranges,
          int count,
          NSRegularExpression? regularExpression) {
    final _ret = _lib._objc_msgSend_843(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_regularExpressionCheckingResultWithRanges_count_regularExpression_1,
        ranges,
        count,
        regularExpression?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult phoneNumberCheckingResultWithRange_phoneNumber_(
      AVFAudio _lib, NSRange range, NSString? phoneNumber) {
    final _ret = _lib._objc_msgSend_841(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_phoneNumberCheckingResultWithRange_phoneNumber_1,
        range,
        phoneNumber?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult
      transitInformationCheckingResultWithRange_components_(
          AVFAudio _lib, NSRange range, NSDictionary? components) {
    final _ret = _lib._objc_msgSend_839(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_transitInformationCheckingResultWithRange_components_1,
        range,
        components?._id ?? ffi.nullptr);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  static NSTextCheckingResult new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSTextCheckingResult1, _lib._sel_new1);
    return NSTextCheckingResult._(_ret, _lib, retain: false, release: true);
  }

  static NSTextCheckingResult alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSTextCheckingResult1, _lib._sel_alloc1);
    return NSTextCheckingResult._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSTextCheckingResult1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSTextCheckingResult1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSTextCheckingResult1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSTextCheckingResult1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSTextCheckingResult1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSTextCheckingResult1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSTextCheckingType {
  static const int NSTextCheckingTypeOrthography = 1;
  static const int NSTextCheckingTypeSpelling = 2;
  static const int NSTextCheckingTypeGrammar = 4;
  static const int NSTextCheckingTypeDate = 8;
  static const int NSTextCheckingTypeAddress = 16;
  static const int NSTextCheckingTypeLink = 32;
  static const int NSTextCheckingTypeQuote = 64;
  static const int NSTextCheckingTypeDash = 128;
  static const int NSTextCheckingTypeReplacement = 256;
  static const int NSTextCheckingTypeCorrection = 512;
  static const int NSTextCheckingTypeRegularExpression = 1024;
  static const int NSTextCheckingTypePhoneNumber = 2048;
  static const int NSTextCheckingTypeTransitInformation = 4096;
}

class NSRegularExpression extends NSObject {
  NSRegularExpression._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSRegularExpression] that points to the same underlying object as [other].
  static NSRegularExpression castFrom<T extends _ObjCWrapper>(T other) {
    return NSRegularExpression._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSRegularExpression] that wraps the given raw object pointer.
  static NSRegularExpression castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSRegularExpression._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSRegularExpression].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSRegularExpression1);
  }

  static NSRegularExpression regularExpressionWithPattern_options_error_(
      AVFAudio _lib,
      NSString? pattern,
      int options,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_821(
        _lib._class_NSRegularExpression1,
        _lib._sel_regularExpressionWithPattern_options_error_1,
        pattern?._id ?? ffi.nullptr,
        options,
        error);
    return NSRegularExpression._(_ret, _lib, retain: true, release: true);
  }

  NSRegularExpression initWithPattern_options_error_(NSString? pattern,
      int options, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_822(
        _id,
        _lib._sel_initWithPattern_options_error_1,
        pattern?._id ?? ffi.nullptr,
        options,
        error);
    return NSRegularExpression._(_ret, _lib, retain: true, release: true);
  }

  NSString? get pattern {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_pattern1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get options {
    return _lib._objc_msgSend_823(_id, _lib._sel_options1);
  }

  int get numberOfCaptureGroups {
    return _lib._objc_msgSend_10(_id, _lib._sel_numberOfCaptureGroups1);
  }

  static NSString escapedPatternForString_(AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSRegularExpression1,
        _lib._sel_escapedPatternForString_1, string?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  void enumerateMatchesInString_options_range_usingBlock_(
      NSString? string, int options, NSRange range, ObjCBlock32 block) {
    return _lib._objc_msgSend_824(
        _id,
        _lib._sel_enumerateMatchesInString_options_range_usingBlock_1,
        string?._id ?? ffi.nullptr,
        options,
        range,
        block._id);
  }

  NSArray matchesInString_options_range_(
      NSString? string, int options, NSRange range) {
    final _ret = _lib._objc_msgSend_825(
        _id,
        _lib._sel_matchesInString_options_range_1,
        string?._id ?? ffi.nullptr,
        options,
        range);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  int numberOfMatchesInString_options_range_(
      NSString? string, int options, NSRange range) {
    return _lib._objc_msgSend_826(
        _id,
        _lib._sel_numberOfMatchesInString_options_range_1,
        string?._id ?? ffi.nullptr,
        options,
        range);
  }

  NSTextCheckingResult firstMatchInString_options_range_(
      NSString? string, int options, NSRange range) {
    final _ret = _lib._objc_msgSend_827(
        _id,
        _lib._sel_firstMatchInString_options_range_1,
        string?._id ?? ffi.nullptr,
        options,
        range);
    return NSTextCheckingResult._(_ret, _lib, retain: true, release: true);
  }

  NSRange rangeOfFirstMatchInString_options_range_(
      NSString? string, int options, NSRange range) {
    return _lib._objc_msgSend_828(
        _id,
        _lib._sel_rangeOfFirstMatchInString_options_range_1,
        string?._id ?? ffi.nullptr,
        options,
        range);
  }

  NSString stringByReplacingMatchesInString_options_range_withTemplate_(
      NSString? string, int options, NSRange range, NSString? templ) {
    final _ret = _lib._objc_msgSend_829(
        _id,
        _lib._sel_stringByReplacingMatchesInString_options_range_withTemplate_1,
        string?._id ?? ffi.nullptr,
        options,
        range,
        templ?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  int replaceMatchesInString_options_range_withTemplate_(
      NSMutableString? string, int options, NSRange range, NSString? templ) {
    return _lib._objc_msgSend_830(
        _id,
        _lib._sel_replaceMatchesInString_options_range_withTemplate_1,
        string?._id ?? ffi.nullptr,
        options,
        range,
        templ?._id ?? ffi.nullptr);
  }

  NSString replacementStringForResult_inString_offset_template_(
      NSTextCheckingResult? result,
      NSString? string,
      int offset,
      NSString? templ) {
    final _ret = _lib._objc_msgSend_831(
        _id,
        _lib._sel_replacementStringForResult_inString_offset_template_1,
        result?._id ?? ffi.nullptr,
        string?._id ?? ffi.nullptr,
        offset,
        templ?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString escapedTemplateForString_(AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSRegularExpression1,
        _lib._sel_escapedTemplateForString_1, string?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSRegularExpression new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSRegularExpression1, _lib._sel_new1);
    return NSRegularExpression._(_ret, _lib, retain: false, release: true);
  }

  static NSRegularExpression alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSRegularExpression1, _lib._sel_alloc1);
    return NSRegularExpression._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSRegularExpression1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSRegularExpression1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSRegularExpression1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSRegularExpression1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSRegularExpression1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSRegularExpression1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSRegularExpression1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSRegularExpression1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSRegularExpression1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSRegularExpressionOptions {
  static const int NSRegularExpressionCaseInsensitive = 1;
  static const int NSRegularExpressionAllowCommentsAndWhitespace = 2;
  static const int NSRegularExpressionIgnoreMetacharacters = 4;
  static const int NSRegularExpressionDotMatchesLineSeparators = 8;
  static const int NSRegularExpressionAnchorsMatchLines = 16;
  static const int NSRegularExpressionUseUnixLineSeparators = 32;
  static const int NSRegularExpressionUseUnicodeWordBoundaries = 64;
}

abstract class NSMatchingOptions {
  static const int NSMatchingReportProgress = 1;
  static const int NSMatchingReportCompletion = 2;
  static const int NSMatchingAnchored = 4;
  static const int NSMatchingWithTransparentBounds = 8;
  static const int NSMatchingWithoutAnchoringBounds = 16;
}

void _ObjCBlock32_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, int arg1, ffi.Pointer<ffi.Bool> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0, ffi.Int32 arg1,
                  ffi.Pointer<ffi.Bool> arg2)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0, int arg1,
              ffi.Pointer<ffi.Bool> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock32_closureRegistry = <int, Function>{};
int _ObjCBlock32_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock32_registerClosure(Function fn) {
  final id = ++_ObjCBlock32_closureRegistryIndex;
  _ObjCBlock32_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock32_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, int arg1, ffi.Pointer<ffi.Bool> arg2) {
  return _ObjCBlock32_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock32 extends _ObjCBlockBase {
  ObjCBlock32._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock32.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                      ffi.Int32 arg1, ffi.Pointer<ffi.Bool> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Int32 arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock32_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock32.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, int arg1,
              ffi.Pointer<ffi.Bool> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Int32 arg1,
                                ffi.Pointer<ffi.Bool> arg2)>(
                        _ObjCBlock32_closureTrampoline)
                    .cast(),
                _ObjCBlock32_registerClosure(fn)),
            lib);
  void call(
      ffi.Pointer<ObjCObject> arg0, int arg1, ffi.Pointer<ffi.Bool> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Int32 arg1,
                    ffi.Pointer<ffi.Bool> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                int arg1,
                ffi.Pointer<ffi.Bool> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

abstract class NSMatchingFlags {
  static const int NSMatchingProgress = 1;
  static const int NSMatchingCompleted = 2;
  static const int NSMatchingHitEnd = 4;
  static const int NSMatchingRequiredEnd = 8;
  static const int NSMatchingInternalError = 16;
}

class NSURLCache extends NSObject {
  NSURLCache._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLCache] that points to the same underlying object as [other].
  static NSURLCache castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLCache._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSURLCache] that wraps the given raw object pointer.
  static NSURLCache castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLCache._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLCache].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSURLCache1);
  }

  static NSURLCache? getSharedURLCache(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_844(
        _lib._class_NSURLCache1, _lib._sel_sharedURLCache1);
    return _ret.address == 0
        ? null
        : NSURLCache._(_ret, _lib, retain: true, release: true);
  }

  static void setSharedURLCache(AVFAudio _lib, NSURLCache? value) {
    _lib._objc_msgSend_845(_lib._class_NSURLCache1,
        _lib._sel_setSharedURLCache_1, value?._id ?? ffi.nullptr);
  }

  NSURLCache initWithMemoryCapacity_diskCapacity_diskPath_(
      int memoryCapacity, int diskCapacity, NSString? path) {
    final _ret = _lib._objc_msgSend_846(
        _id,
        _lib._sel_initWithMemoryCapacity_diskCapacity_diskPath_1,
        memoryCapacity,
        diskCapacity,
        path?._id ?? ffi.nullptr);
    return NSURLCache._(_ret, _lib, retain: true, release: true);
  }

  NSURLCache initWithMemoryCapacity_diskCapacity_directoryURL_(
      int memoryCapacity, int diskCapacity, NSURL? directoryURL) {
    final _ret = _lib._objc_msgSend_847(
        _id,
        _lib._sel_initWithMemoryCapacity_diskCapacity_directoryURL_1,
        memoryCapacity,
        diskCapacity,
        directoryURL?._id ?? ffi.nullptr);
    return NSURLCache._(_ret, _lib, retain: true, release: true);
  }

  NSCachedURLResponse cachedResponseForRequest_(NSURLRequest? request) {
    final _ret = _lib._objc_msgSend_851(
        _id, _lib._sel_cachedResponseForRequest_1, request?._id ?? ffi.nullptr);
    return NSCachedURLResponse._(_ret, _lib, retain: true, release: true);
  }

  void storeCachedResponse_forRequest_(
      NSCachedURLResponse? cachedResponse, NSURLRequest? request) {
    return _lib._objc_msgSend_852(
        _id,
        _lib._sel_storeCachedResponse_forRequest_1,
        cachedResponse?._id ?? ffi.nullptr,
        request?._id ?? ffi.nullptr);
  }

  void removeCachedResponseForRequest_(NSURLRequest? request) {
    return _lib._objc_msgSend_853(
        _id,
        _lib._sel_removeCachedResponseForRequest_1,
        request?._id ?? ffi.nullptr);
  }

  void removeAllCachedResponses() {
    return _lib._objc_msgSend_1(_id, _lib._sel_removeAllCachedResponses1);
  }

  void removeCachedResponsesSinceDate_(NSDate? date) {
    return _lib._objc_msgSend_472(_id,
        _lib._sel_removeCachedResponsesSinceDate_1, date?._id ?? ffi.nullptr);
  }

  int get memoryCapacity {
    return _lib._objc_msgSend_10(_id, _lib._sel_memoryCapacity1);
  }

  set memoryCapacity(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setMemoryCapacity_1, value);
  }

  int get diskCapacity {
    return _lib._objc_msgSend_10(_id, _lib._sel_diskCapacity1);
  }

  set diskCapacity(int value) {
    _lib._objc_msgSend_451(_id, _lib._sel_setDiskCapacity_1, value);
  }

  int get currentMemoryUsage {
    return _lib._objc_msgSend_10(_id, _lib._sel_currentMemoryUsage1);
  }

  int get currentDiskUsage {
    return _lib._objc_msgSend_10(_id, _lib._sel_currentDiskUsage1);
  }

  void storeCachedResponse_forDataTask_(
      NSCachedURLResponse? cachedResponse, NSURLSessionDataTask? dataTask) {
    return _lib._objc_msgSend_854(
        _id,
        _lib._sel_storeCachedResponse_forDataTask_1,
        cachedResponse?._id ?? ffi.nullptr,
        dataTask?._id ?? ffi.nullptr);
  }

  void getCachedResponseForDataTask_completionHandler_(
      NSURLSessionDataTask? dataTask, ObjCBlock33 completionHandler) {
    return _lib._objc_msgSend_855(
        _id,
        _lib._sel_getCachedResponseForDataTask_completionHandler_1,
        dataTask?._id ?? ffi.nullptr,
        completionHandler._id);
  }

  void removeCachedResponseForDataTask_(NSURLSessionDataTask? dataTask) {
    return _lib._objc_msgSend_856(
        _id,
        _lib._sel_removeCachedResponseForDataTask_1,
        dataTask?._id ?? ffi.nullptr);
  }

  static NSURLCache new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSURLCache1, _lib._sel_new1);
    return NSURLCache._(_ret, _lib, retain: false, release: true);
  }

  static NSURLCache alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLCache1, _lib._sel_alloc1);
    return NSURLCache._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLCache1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLCache1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLCache1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLCache1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLCache1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLCache1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLCache1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSURLCache1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLCache1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSCachedURLResponse extends NSObject {
  NSCachedURLResponse._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSCachedURLResponse] that points to the same underlying object as [other].
  static NSCachedURLResponse castFrom<T extends _ObjCWrapper>(T other) {
    return NSCachedURLResponse._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSCachedURLResponse] that wraps the given raw object pointer.
  static NSCachedURLResponse castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSCachedURLResponse._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSCachedURLResponse].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSCachedURLResponse1);
  }

  NSCachedURLResponse initWithResponse_data_(
      NSURLResponse? response, NSData? data) {
    final _ret = _lib._objc_msgSend_848(_id, _lib._sel_initWithResponse_data_1,
        response?._id ?? ffi.nullptr, data?._id ?? ffi.nullptr);
    return NSCachedURLResponse._(_ret, _lib, retain: true, release: true);
  }

  NSCachedURLResponse initWithResponse_data_userInfo_storagePolicy_(
      NSURLResponse? response,
      NSData? data,
      NSDictionary? userInfo,
      int storagePolicy) {
    final _ret = _lib._objc_msgSend_849(
        _id,
        _lib._sel_initWithResponse_data_userInfo_storagePolicy_1,
        response?._id ?? ffi.nullptr,
        data?._id ?? ffi.nullptr,
        userInfo?._id ?? ffi.nullptr,
        storagePolicy);
    return NSCachedURLResponse._(_ret, _lib, retain: true, release: true);
  }

  NSURLResponse? get response {
    final _ret = _lib._objc_msgSend_763(_id, _lib._sel_response1);
    return _ret.address == 0
        ? null
        : NSURLResponse._(_ret, _lib, retain: true, release: true);
  }

  NSData? get data {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_data1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get userInfo {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_userInfo1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  int get storagePolicy {
    return _lib._objc_msgSend_850(_id, _lib._sel_storagePolicy1);
  }

  static NSCachedURLResponse new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSCachedURLResponse1, _lib._sel_new1);
    return NSCachedURLResponse._(_ret, _lib, retain: false, release: true);
  }

  static NSCachedURLResponse alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSCachedURLResponse1, _lib._sel_alloc1);
    return NSCachedURLResponse._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSCachedURLResponse1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSCachedURLResponse1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSCachedURLResponse1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSCachedURLResponse1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSCachedURLResponse1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSCachedURLResponse1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSCachedURLResponse1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSCachedURLResponse1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSCachedURLResponse1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSURLCacheStoragePolicy {
  static const int NSURLCacheStorageAllowed = 0;
  static const int NSURLCacheStorageAllowedInMemoryOnly = 1;
  static const int NSURLCacheStorageNotAllowed = 2;
}

class NSURLSessionDataTask extends NSURLSessionTask {
  NSURLSessionDataTask._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLSessionDataTask] that points to the same underlying object as [other].
  static NSURLSessionDataTask castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLSessionDataTask._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLSessionDataTask] that wraps the given raw object pointer.
  static NSURLSessionDataTask castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLSessionDataTask._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLSessionDataTask].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLSessionDataTask1);
  }

  @override
  NSURLSessionDataTask init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSURLSessionDataTask._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSessionDataTask new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLSessionDataTask1, _lib._sel_new1);
    return NSURLSessionDataTask._(_ret, _lib, retain: false, release: true);
  }

  static NSURLSessionDataTask alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionDataTask1, _lib._sel_alloc1);
    return NSURLSessionDataTask._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLSessionDataTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLSessionDataTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLSessionDataTask1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLSessionDataTask1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLSessionDataTask1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLSessionDataTask1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLSessionDataTask1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionDataTask1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionDataTask1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

void _ObjCBlock33_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>()
      .asFunction<void Function(ffi.Pointer<ObjCObject> arg0)>()(arg0);
}

final _ObjCBlock33_closureRegistry = <int, Function>{};
int _ObjCBlock33_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock33_registerClosure(Function fn) {
  final id = ++_ObjCBlock33_closureRegistryIndex;
  _ObjCBlock33_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock33_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return _ObjCBlock33_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock33 extends _ObjCBlockBase {
  ObjCBlock33._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock33.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi
              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock33_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock33.fromFunction(
      AVFAudio lib, void Function(ffi.Pointer<ObjCObject> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock33_closureTrampoline)
                    .cast(),
                _ObjCBlock33_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSURLConnection extends NSObject {
  NSURLConnection._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLConnection] that points to the same underlying object as [other].
  static NSURLConnection castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLConnection._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLConnection] that wraps the given raw object pointer.
  static NSURLConnection castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLConnection._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLConnection].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLConnection1);
  }

  NSURLConnection initWithRequest_delegate_startImmediately_(
      NSURLRequest? request, NSObject delegate, bool startImmediately) {
    final _ret = _lib._objc_msgSend_857(
        _id,
        _lib._sel_initWithRequest_delegate_startImmediately_1,
        request?._id ?? ffi.nullptr,
        delegate._id,
        startImmediately);
    return NSURLConnection._(_ret, _lib, retain: true, release: true);
  }

  NSURLConnection initWithRequest_delegate_(
      NSURLRequest? request, NSObject delegate) {
    final _ret = _lib._objc_msgSend_858(
        _id,
        _lib._sel_initWithRequest_delegate_1,
        request?._id ?? ffi.nullptr,
        delegate._id);
    return NSURLConnection._(_ret, _lib, retain: true, release: true);
  }

  static NSURLConnection connectionWithRequest_delegate_(
      AVFAudio _lib, NSURLRequest? request, NSObject delegate) {
    final _ret = _lib._objc_msgSend_859(
        _lib._class_NSURLConnection1,
        _lib._sel_connectionWithRequest_delegate_1,
        request?._id ?? ffi.nullptr,
        delegate._id);
    return NSURLConnection._(_ret, _lib, retain: true, release: true);
  }

  NSURLRequest? get originalRequest {
    final _ret = _lib._objc_msgSend_761(_id, _lib._sel_originalRequest1);
    return _ret.address == 0
        ? null
        : NSURLRequest._(_ret, _lib, retain: true, release: true);
  }

  NSURLRequest? get currentRequest {
    final _ret = _lib._objc_msgSend_761(_id, _lib._sel_currentRequest1);
    return _ret.address == 0
        ? null
        : NSURLRequest._(_ret, _lib, retain: true, release: true);
  }

  void start() {
    return _lib._objc_msgSend_1(_id, _lib._sel_start1);
  }

  void cancel() {
    return _lib._objc_msgSend_1(_id, _lib._sel_cancel1);
  }

  void scheduleInRunLoop_forMode_(NSRunLoop? aRunLoop, NSRunLoopMode mode) {
    return _lib._objc_msgSend_501(_id, _lib._sel_scheduleInRunLoop_forMode_1,
        aRunLoop?._id ?? ffi.nullptr, mode);
  }

  void unscheduleFromRunLoop_forMode_(NSRunLoop? aRunLoop, NSRunLoopMode mode) {
    return _lib._objc_msgSend_501(
        _id,
        _lib._sel_unscheduleFromRunLoop_forMode_1,
        aRunLoop?._id ?? ffi.nullptr,
        mode);
  }

  void setDelegateQueue_(NSOperationQueue? queue) {
    return _lib._objc_msgSend_860(
        _id, _lib._sel_setDelegateQueue_1, queue?._id ?? ffi.nullptr);
  }

  static bool canHandleRequest_(AVFAudio _lib, NSURLRequest? request) {
    return _lib._objc_msgSend_861(_lib._class_NSURLConnection1,
        _lib._sel_canHandleRequest_1, request?._id ?? ffi.nullptr);
  }

  static NSData sendSynchronousRequest_returningResponse_error_(
      AVFAudio _lib,
      NSURLRequest? request,
      ffi.Pointer<ffi.Pointer<ObjCObject>> response,
      ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_862(
        _lib._class_NSURLConnection1,
        _lib._sel_sendSynchronousRequest_returningResponse_error_1,
        request?._id ?? ffi.nullptr,
        response,
        error);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  static void sendAsynchronousRequest_queue_completionHandler_(AVFAudio _lib,
      NSURLRequest? request, NSOperationQueue? queue, ObjCBlock34 handler) {
    return _lib._objc_msgSend_863(
        _lib._class_NSURLConnection1,
        _lib._sel_sendAsynchronousRequest_queue_completionHandler_1,
        request?._id ?? ffi.nullptr,
        queue?._id ?? ffi.nullptr,
        handler._id);
  }

  static NSURLConnection new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLConnection1, _lib._sel_new1);
    return NSURLConnection._(_ret, _lib, retain: false, release: true);
  }

  static NSURLConnection alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLConnection1, _lib._sel_alloc1);
    return NSURLConnection._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLConnection1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLConnection1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLConnection1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLConnection1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLConnection1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLConnection1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLConnection1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLConnection1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLConnection1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

void _ObjCBlock34_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ObjCObject> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(
                  ffi.Pointer<ObjCObject> arg0,
                  ffi.Pointer<ObjCObject> arg1,
                  ffi.Pointer<ObjCObject> arg2)>>()
      .asFunction<
          void Function(
              ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ObjCObject> arg1,
              ffi.Pointer<ObjCObject> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock34_closureRegistry = <int, Function>{};
int _ObjCBlock34_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock34_registerClosure(Function fn) {
  final id = ++_ObjCBlock34_closureRegistryIndex;
  _ObjCBlock34_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock34_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ObjCObject> arg2) {
  return _ObjCBlock34_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock34 extends _ObjCBlockBase {
  ObjCBlock34._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock34.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ObjCObject> arg1,
                      ffi.Pointer<ObjCObject> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock34_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock34.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1,
              ffi.Pointer<ObjCObject> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock34_closureTrampoline)
                    .cast(),
                _ObjCBlock34_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1,
      ffi.Pointer<ObjCObject> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ObjCObject> arg1,
                    ffi.Pointer<ObjCObject> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ObjCObject> arg1,
                ffi.Pointer<ObjCObject> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSURLCredential extends NSObject {
  NSURLCredential._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLCredential] that points to the same underlying object as [other].
  static NSURLCredential castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLCredential._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLCredential] that wraps the given raw object pointer.
  static NSURLCredential castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLCredential._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLCredential].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLCredential1);
  }

  int get persistence {
    return _lib._objc_msgSend_864(_id, _lib._sel_persistence1);
  }

  NSURLCredential initWithUser_password_persistence_(
      NSString? user, NSString? password, int persistence) {
    final _ret = _lib._objc_msgSend_865(
        _id,
        _lib._sel_initWithUser_password_persistence_1,
        user?._id ?? ffi.nullptr,
        password?._id ?? ffi.nullptr,
        persistence);
    return NSURLCredential._(_ret, _lib, retain: true, release: true);
  }

  static NSURLCredential credentialWithUser_password_persistence_(
      AVFAudio _lib, NSString? user, NSString? password, int persistence) {
    final _ret = _lib._objc_msgSend_866(
        _lib._class_NSURLCredential1,
        _lib._sel_credentialWithUser_password_persistence_1,
        user?._id ?? ffi.nullptr,
        password?._id ?? ffi.nullptr,
        persistence);
    return NSURLCredential._(_ret, _lib, retain: true, release: true);
  }

  NSString? get user {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_user1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get password {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_password1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  bool get hasPassword {
    return _lib._objc_msgSend_12(_id, _lib._sel_hasPassword1);
  }

  NSURLCredential initWithIdentity_certificates_persistence_(
      SecIdentityRef identity, NSArray? certArray, int persistence) {
    final _ret = _lib._objc_msgSend_867(
        _id,
        _lib._sel_initWithIdentity_certificates_persistence_1,
        identity,
        certArray?._id ?? ffi.nullptr,
        persistence);
    return NSURLCredential._(_ret, _lib, retain: true, release: true);
  }

  static NSURLCredential credentialWithIdentity_certificates_persistence_(
      AVFAudio _lib,
      SecIdentityRef identity,
      NSArray? certArray,
      int persistence) {
    final _ret = _lib._objc_msgSend_868(
        _lib._class_NSURLCredential1,
        _lib._sel_credentialWithIdentity_certificates_persistence_1,
        identity,
        certArray?._id ?? ffi.nullptr,
        persistence);
    return NSURLCredential._(_ret, _lib, retain: true, release: true);
  }

  SecIdentityRef get identity {
    return _lib._objc_msgSend_869(_id, _lib._sel_identity1);
  }

  NSArray? get certificates {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_certificates1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSURLCredential initWithTrust_(SecTrustRef trust) {
    final _ret = _lib._objc_msgSend_870(_id, _lib._sel_initWithTrust_1, trust);
    return NSURLCredential._(_ret, _lib, retain: true, release: true);
  }

  static NSURLCredential credentialForTrust_(AVFAudio _lib, SecTrustRef trust) {
    final _ret = _lib._objc_msgSend_871(
        _lib._class_NSURLCredential1, _lib._sel_credentialForTrust_1, trust);
    return NSURLCredential._(_ret, _lib, retain: true, release: true);
  }

  static NSURLCredential new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLCredential1, _lib._sel_new1);
    return NSURLCredential._(_ret, _lib, retain: false, release: true);
  }

  static NSURLCredential alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLCredential1, _lib._sel_alloc1);
    return NSURLCredential._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLCredential1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLCredential1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLCredential1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLCredential1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLCredential1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLCredential1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLCredential1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLCredential1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLCredential1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSURLCredentialPersistence {
  static const int NSURLCredentialPersistenceNone = 0;
  static const int NSURLCredentialPersistenceForSession = 1;
  static const int NSURLCredentialPersistencePermanent = 2;
  static const int NSURLCredentialPersistenceSynchronizable = 3;
}

typedef SecIdentityRef = ffi.Pointer<__SecIdentity>;

final class __SecIdentity extends ffi.Opaque {}

typedef SecTrustRef = ffi.Pointer<__SecTrust>;

final class __SecTrust extends ffi.Opaque {}

class NSURLProtectionSpace extends NSObject {
  NSURLProtectionSpace._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLProtectionSpace] that points to the same underlying object as [other].
  static NSURLProtectionSpace castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLProtectionSpace._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLProtectionSpace] that wraps the given raw object pointer.
  static NSURLProtectionSpace castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLProtectionSpace._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLProtectionSpace].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLProtectionSpace1);
  }

  NSURLProtectionSpace initWithHost_port_protocol_realm_authenticationMethod_(
      NSString? host,
      int port,
      NSString? protocol,
      NSString? realm,
      NSString? authenticationMethod) {
    final _ret = _lib._objc_msgSend_872(
        _id,
        _lib._sel_initWithHost_port_protocol_realm_authenticationMethod_1,
        host?._id ?? ffi.nullptr,
        port,
        protocol?._id ?? ffi.nullptr,
        realm?._id ?? ffi.nullptr,
        authenticationMethod?._id ?? ffi.nullptr);
    return NSURLProtectionSpace._(_ret, _lib, retain: true, release: true);
  }

  NSURLProtectionSpace initWithProxyHost_port_type_realm_authenticationMethod_(
      NSString? host,
      int port,
      NSString? type,
      NSString? realm,
      NSString? authenticationMethod) {
    final _ret = _lib._objc_msgSend_872(
        _id,
        _lib._sel_initWithProxyHost_port_type_realm_authenticationMethod_1,
        host?._id ?? ffi.nullptr,
        port,
        type?._id ?? ffi.nullptr,
        realm?._id ?? ffi.nullptr,
        authenticationMethod?._id ?? ffi.nullptr);
    return NSURLProtectionSpace._(_ret, _lib, retain: true, release: true);
  }

  NSString? get realm {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_realm1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  bool get receivesCredentialSecurely {
    return _lib._objc_msgSend_12(_id, _lib._sel_receivesCredentialSecurely1);
  }

  bool get isProxy {
    return _lib._objc_msgSend_12(_id, _lib._sel_isProxy1);
  }

  NSString? get host {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_host1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get port {
    return _lib._objc_msgSend_78(_id, _lib._sel_port1);
  }

  NSString? get proxyType {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_proxyType1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get protocol {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_protocol1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get authenticationMethod {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_authenticationMethod1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get distinguishedNames {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_distinguishedNames1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  SecTrustRef get serverTrust {
    return _lib._objc_msgSend_873(_id, _lib._sel_serverTrust1);
  }

  static NSURLProtectionSpace new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLProtectionSpace1, _lib._sel_new1);
    return NSURLProtectionSpace._(_ret, _lib, retain: false, release: true);
  }

  static NSURLProtectionSpace alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLProtectionSpace1, _lib._sel_alloc1);
    return NSURLProtectionSpace._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLProtectionSpace1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLProtectionSpace1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLProtectionSpace1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLProtectionSpace1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLProtectionSpace1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLProtectionSpace1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLProtectionSpace1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLProtectionSpace1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLProtectionSpace1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSURLCredentialStorage extends NSObject {
  NSURLCredentialStorage._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLCredentialStorage] that points to the same underlying object as [other].
  static NSURLCredentialStorage castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLCredentialStorage._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLCredentialStorage] that wraps the given raw object pointer.
  static NSURLCredentialStorage castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLCredentialStorage._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLCredentialStorage].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLCredentialStorage1);
  }

  static NSURLCredentialStorage? getSharedCredentialStorage(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_874(_lib._class_NSURLCredentialStorage1,
        _lib._sel_sharedCredentialStorage1);
    return _ret.address == 0
        ? null
        : NSURLCredentialStorage._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary credentialsForProtectionSpace_(NSURLProtectionSpace? space) {
    final _ret = _lib._objc_msgSend_875(_id,
        _lib._sel_credentialsForProtectionSpace_1, space?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSDictionary? get allCredentials {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_allCredentials1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  void setCredential_forProtectionSpace_(
      NSURLCredential? credential, NSURLProtectionSpace? space) {
    return _lib._objc_msgSend_876(
        _id,
        _lib._sel_setCredential_forProtectionSpace_1,
        credential?._id ?? ffi.nullptr,
        space?._id ?? ffi.nullptr);
  }

  void removeCredential_forProtectionSpace_(
      NSURLCredential? credential, NSURLProtectionSpace? space) {
    return _lib._objc_msgSend_876(
        _id,
        _lib._sel_removeCredential_forProtectionSpace_1,
        credential?._id ?? ffi.nullptr,
        space?._id ?? ffi.nullptr);
  }

  void removeCredential_forProtectionSpace_options_(NSURLCredential? credential,
      NSURLProtectionSpace? space, NSDictionary? options) {
    return _lib._objc_msgSend_877(
        _id,
        _lib._sel_removeCredential_forProtectionSpace_options_1,
        credential?._id ?? ffi.nullptr,
        space?._id ?? ffi.nullptr,
        options?._id ?? ffi.nullptr);
  }

  NSURLCredential defaultCredentialForProtectionSpace_(
      NSURLProtectionSpace? space) {
    final _ret = _lib._objc_msgSend_878(
        _id,
        _lib._sel_defaultCredentialForProtectionSpace_1,
        space?._id ?? ffi.nullptr);
    return NSURLCredential._(_ret, _lib, retain: true, release: true);
  }

  void setDefaultCredential_forProtectionSpace_(
      NSURLCredential? credential, NSURLProtectionSpace? space) {
    return _lib._objc_msgSend_876(
        _id,
        _lib._sel_setDefaultCredential_forProtectionSpace_1,
        credential?._id ?? ffi.nullptr,
        space?._id ?? ffi.nullptr);
  }

  void getCredentialsForProtectionSpace_task_completionHandler_(
      NSURLProtectionSpace? protectionSpace,
      NSURLSessionTask? task,
      ObjCBlock35 completionHandler) {
    return _lib._objc_msgSend_879(
        _id,
        _lib._sel_getCredentialsForProtectionSpace_task_completionHandler_1,
        protectionSpace?._id ?? ffi.nullptr,
        task?._id ?? ffi.nullptr,
        completionHandler._id);
  }

  void setCredential_forProtectionSpace_task_(NSURLCredential? credential,
      NSURLProtectionSpace? protectionSpace, NSURLSessionTask? task) {
    return _lib._objc_msgSend_880(
        _id,
        _lib._sel_setCredential_forProtectionSpace_task_1,
        credential?._id ?? ffi.nullptr,
        protectionSpace?._id ?? ffi.nullptr,
        task?._id ?? ffi.nullptr);
  }

  void removeCredential_forProtectionSpace_options_task_(
      NSURLCredential? credential,
      NSURLProtectionSpace? protectionSpace,
      NSDictionary? options,
      NSURLSessionTask? task) {
    return _lib._objc_msgSend_881(
        _id,
        _lib._sel_removeCredential_forProtectionSpace_options_task_1,
        credential?._id ?? ffi.nullptr,
        protectionSpace?._id ?? ffi.nullptr,
        options?._id ?? ffi.nullptr,
        task?._id ?? ffi.nullptr);
  }

  void getDefaultCredentialForProtectionSpace_task_completionHandler_(
      NSURLProtectionSpace? space,
      NSURLSessionTask? task,
      ObjCBlock36 completionHandler) {
    return _lib._objc_msgSend_882(
        _id,
        _lib._sel_getDefaultCredentialForProtectionSpace_task_completionHandler_1,
        space?._id ?? ffi.nullptr,
        task?._id ?? ffi.nullptr,
        completionHandler._id);
  }

  void setDefaultCredential_forProtectionSpace_task_(
      NSURLCredential? credential,
      NSURLProtectionSpace? protectionSpace,
      NSURLSessionTask? task) {
    return _lib._objc_msgSend_880(
        _id,
        _lib._sel_setDefaultCredential_forProtectionSpace_task_1,
        credential?._id ?? ffi.nullptr,
        protectionSpace?._id ?? ffi.nullptr,
        task?._id ?? ffi.nullptr);
  }

  static NSURLCredentialStorage new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLCredentialStorage1, _lib._sel_new1);
    return NSURLCredentialStorage._(_ret, _lib, retain: false, release: true);
  }

  static NSURLCredentialStorage alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLCredentialStorage1, _lib._sel_alloc1);
    return NSURLCredentialStorage._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLCredentialStorage1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLCredentialStorage1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLCredentialStorage1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLCredentialStorage1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLCredentialStorage1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLCredentialStorage1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLCredentialStorage1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLCredentialStorage1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSURLCredentialStorage1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

void _ObjCBlock35_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>()
      .asFunction<void Function(ffi.Pointer<ObjCObject> arg0)>()(arg0);
}

final _ObjCBlock35_closureRegistry = <int, Function>{};
int _ObjCBlock35_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock35_registerClosure(Function fn) {
  final id = ++_ObjCBlock35_closureRegistryIndex;
  _ObjCBlock35_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock35_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return _ObjCBlock35_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock35 extends _ObjCBlockBase {
  ObjCBlock35._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock35.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi
              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock35_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock35.fromFunction(
      AVFAudio lib, void Function(ffi.Pointer<ObjCObject> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock35_closureTrampoline)
                    .cast(),
                _ObjCBlock35_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

void _ObjCBlock36_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>()
      .asFunction<void Function(ffi.Pointer<ObjCObject> arg0)>()(arg0);
}

final _ObjCBlock36_closureRegistry = <int, Function>{};
int _ObjCBlock36_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock36_registerClosure(Function fn) {
  final id = ++_ObjCBlock36_closureRegistryIndex;
  _ObjCBlock36_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock36_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return _ObjCBlock36_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock36 extends _ObjCBlockBase {
  ObjCBlock36._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock36.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi
              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock36_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock36.fromFunction(
      AVFAudio lib, void Function(ffi.Pointer<ObjCObject> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock36_closureTrampoline)
                    .cast(),
                _ObjCBlock36_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSURLProtocol extends NSObject {
  NSURLProtocol._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLProtocol] that points to the same underlying object as [other].
  static NSURLProtocol castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLProtocol._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSURLProtocol] that wraps the given raw object pointer.
  static NSURLProtocol castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLProtocol._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLProtocol].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSURLProtocol1);
  }

  NSURLProtocol initWithRequest_cachedResponse_client_(NSURLRequest? request,
      NSCachedURLResponse? cachedResponse, NSObject? client) {
    final _ret = _lib._objc_msgSend_883(
        _id,
        _lib._sel_initWithRequest_cachedResponse_client_1,
        request?._id ?? ffi.nullptr,
        cachedResponse?._id ?? ffi.nullptr,
        client?._id ?? ffi.nullptr);
    return NSURLProtocol._(_ret, _lib, retain: true, release: true);
  }

  NSObject? get client {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_client1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSURLRequest? get request {
    final _ret = _lib._objc_msgSend_761(_id, _lib._sel_request1);
    return _ret.address == 0
        ? null
        : NSURLRequest._(_ret, _lib, retain: true, release: true);
  }

  NSCachedURLResponse? get cachedResponse {
    final _ret = _lib._objc_msgSend_884(_id, _lib._sel_cachedResponse1);
    return _ret.address == 0
        ? null
        : NSCachedURLResponse._(_ret, _lib, retain: true, release: true);
  }

  static bool canInitWithRequest_(AVFAudio _lib, NSURLRequest? request) {
    return _lib._objc_msgSend_861(_lib._class_NSURLProtocol1,
        _lib._sel_canInitWithRequest_1, request?._id ?? ffi.nullptr);
  }

  static NSURLRequest canonicalRequestForRequest_(
      AVFAudio _lib, NSURLRequest? request) {
    final _ret = _lib._objc_msgSend_885(_lib._class_NSURLProtocol1,
        _lib._sel_canonicalRequestForRequest_1, request?._id ?? ffi.nullptr);
    return NSURLRequest._(_ret, _lib, retain: true, release: true);
  }

  static bool requestIsCacheEquivalent_toRequest_(
      AVFAudio _lib, NSURLRequest? a, NSURLRequest? b) {
    return _lib._objc_msgSend_886(
        _lib._class_NSURLProtocol1,
        _lib._sel_requestIsCacheEquivalent_toRequest_1,
        a?._id ?? ffi.nullptr,
        b?._id ?? ffi.nullptr);
  }

  void startLoading() {
    return _lib._objc_msgSend_1(_id, _lib._sel_startLoading1);
  }

  void stopLoading() {
    return _lib._objc_msgSend_1(_id, _lib._sel_stopLoading1);
  }

  static NSObject propertyForKey_inRequest_(
      AVFAudio _lib, NSString? key, NSURLRequest? request) {
    final _ret = _lib._objc_msgSend_887(
        _lib._class_NSURLProtocol1,
        _lib._sel_propertyForKey_inRequest_1,
        key?._id ?? ffi.nullptr,
        request?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static void setProperty_forKey_inRequest_(AVFAudio _lib, NSObject value,
      NSString? key, NSMutableURLRequest? request) {
    return _lib._objc_msgSend_894(
        _lib._class_NSURLProtocol1,
        _lib._sel_setProperty_forKey_inRequest_1,
        value._id,
        key?._id ?? ffi.nullptr,
        request?._id ?? ffi.nullptr);
  }

  static void removePropertyForKey_inRequest_(
      AVFAudio _lib, NSString? key, NSMutableURLRequest? request) {
    return _lib._objc_msgSend_895(
        _lib._class_NSURLProtocol1,
        _lib._sel_removePropertyForKey_inRequest_1,
        key?._id ?? ffi.nullptr,
        request?._id ?? ffi.nullptr);
  }

  static bool registerClass_(AVFAudio _lib, NSObject protocolClass) {
    return _lib._objc_msgSend_0(_lib._class_NSURLProtocol1,
        _lib._sel_registerClass_1, protocolClass._id);
  }

  static void unregisterClass_(AVFAudio _lib, NSObject protocolClass) {
    return _lib._objc_msgSend_15(_lib._class_NSURLProtocol1,
        _lib._sel_unregisterClass_1, protocolClass._id);
  }

  static bool canInitWithTask_(AVFAudio _lib, NSURLSessionTask? task) {
    return _lib._objc_msgSend_896(_lib._class_NSURLProtocol1,
        _lib._sel_canInitWithTask_1, task?._id ?? ffi.nullptr);
  }

  NSURLProtocol initWithTask_cachedResponse_client_(NSURLSessionTask? task,
      NSCachedURLResponse? cachedResponse, NSObject? client) {
    final _ret = _lib._objc_msgSend_897(
        _id,
        _lib._sel_initWithTask_cachedResponse_client_1,
        task?._id ?? ffi.nullptr,
        cachedResponse?._id ?? ffi.nullptr,
        client?._id ?? ffi.nullptr);
    return NSURLProtocol._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionTask? get task {
    final _ret = _lib._objc_msgSend_898(_id, _lib._sel_task1);
    return _ret.address == 0
        ? null
        : NSURLSessionTask._(_ret, _lib, retain: true, release: true);
  }

  static NSURLProtocol new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLProtocol1, _lib._sel_new1);
    return NSURLProtocol._(_ret, _lib, retain: false, release: true);
  }

  static NSURLProtocol alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLProtocol1, _lib._sel_alloc1);
    return NSURLProtocol._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLProtocol1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLProtocol1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLProtocol1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLProtocol1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLProtocol1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLProtocol1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLProtocol1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSURLProtocol1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLProtocol1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSMutableURLRequest extends NSURLRequest {
  NSMutableURLRequest._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSMutableURLRequest] that points to the same underlying object as [other].
  static NSMutableURLRequest castFrom<T extends _ObjCWrapper>(T other) {
    return NSMutableURLRequest._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSMutableURLRequest] that wraps the given raw object pointer.
  static NSMutableURLRequest castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSMutableURLRequest._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSMutableURLRequest].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSMutableURLRequest1);
  }

  @override
  NSURL? get URL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_URL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  set URL(NSURL? value) {
    _lib._objc_msgSend_888(_id, _lib._sel_setURL_1, value?._id ?? ffi.nullptr);
  }

  @override
  int get cachePolicy {
    return _lib._objc_msgSend_748(_id, _lib._sel_cachePolicy1);
  }

  set cachePolicy(int value) {
    _lib._objc_msgSend_889(_id, _lib._sel_setCachePolicy_1, value);
  }

  @override
  double get timeoutInterval {
    return _lib._objc_msgSend_149(_id, _lib._sel_timeoutInterval1);
  }

  set timeoutInterval(double value) {
    _lib._objc_msgSend_474(_id, _lib._sel_setTimeoutInterval_1, value);
  }

  @override
  NSURL? get mainDocumentURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_mainDocumentURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  set mainDocumentURL(NSURL? value) {
    _lib._objc_msgSend_888(
        _id, _lib._sel_setMainDocumentURL_1, value?._id ?? ffi.nullptr);
  }

  @override
  int get networkServiceType {
    return _lib._objc_msgSend_749(_id, _lib._sel_networkServiceType1);
  }

  set networkServiceType(int value) {
    _lib._objc_msgSend_890(_id, _lib._sel_setNetworkServiceType_1, value);
  }

  @override
  bool get allowsCellularAccess {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsCellularAccess1);
  }

  set allowsCellularAccess(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setAllowsCellularAccess_1, value);
  }

  @override
  bool get allowsExpensiveNetworkAccess {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsExpensiveNetworkAccess1);
  }

  set allowsExpensiveNetworkAccess(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setAllowsExpensiveNetworkAccess_1, value);
  }

  @override
  bool get allowsConstrainedNetworkAccess {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_allowsConstrainedNetworkAccess1);
  }

  set allowsConstrainedNetworkAccess(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setAllowsConstrainedNetworkAccess_1, value);
  }

  @override
  bool get assumesHTTP3Capable {
    return _lib._objc_msgSend_12(_id, _lib._sel_assumesHTTP3Capable1);
  }

  set assumesHTTP3Capable(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setAssumesHTTP3Capable_1, value);
  }

  @override
  int get attribution {
    return _lib._objc_msgSend_750(_id, _lib._sel_attribution1);
  }

  set attribution(int value) {
    _lib._objc_msgSend_891(_id, _lib._sel_setAttribution_1, value);
  }

  @override
  NSString? get HTTPMethod {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_HTTPMethod1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set HTTPMethod(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setHTTPMethod_1, value?._id ?? ffi.nullptr);
  }

  @override
  NSDictionary? get allHTTPHeaderFields {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_allHTTPHeaderFields1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set allHTTPHeaderFields(NSDictionary? value) {
    _lib._objc_msgSend_165(
        _id, _lib._sel_setAllHTTPHeaderFields_1, value?._id ?? ffi.nullptr);
  }

  void setValue_forHTTPHeaderField_(NSString? value, NSString? field) {
    return _lib._objc_msgSend_483(_id, _lib._sel_setValue_forHTTPHeaderField_1,
        value?._id ?? ffi.nullptr, field?._id ?? ffi.nullptr);
  }

  void addValue_forHTTPHeaderField_(NSString? value, NSString? field) {
    return _lib._objc_msgSend_483(_id, _lib._sel_addValue_forHTTPHeaderField_1,
        value?._id ?? ffi.nullptr, field?._id ?? ffi.nullptr);
  }

  @override
  NSData? get HTTPBody {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_HTTPBody1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  set HTTPBody(NSData? value) {
    _lib._objc_msgSend_892(
        _id, _lib._sel_setHTTPBody_1, value?._id ?? ffi.nullptr);
  }

  @override
  NSInputStream? get HTTPBodyStream {
    final _ret = _lib._objc_msgSend_760(_id, _lib._sel_HTTPBodyStream1);
    return _ret.address == 0
        ? null
        : NSInputStream._(_ret, _lib, retain: true, release: true);
  }

  set HTTPBodyStream(NSInputStream? value) {
    _lib._objc_msgSend_893(
        _id, _lib._sel_setHTTPBodyStream_1, value?._id ?? ffi.nullptr);
  }

  @override
  bool get HTTPShouldHandleCookies {
    return _lib._objc_msgSend_12(_id, _lib._sel_HTTPShouldHandleCookies1);
  }

  set HTTPShouldHandleCookies(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setHTTPShouldHandleCookies_1, value);
  }

  @override
  bool get HTTPShouldUsePipelining {
    return _lib._objc_msgSend_12(_id, _lib._sel_HTTPShouldUsePipelining1);
  }

  set HTTPShouldUsePipelining(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setHTTPShouldUsePipelining_1, value);
  }

  static NSMutableURLRequest requestWithURL_(AVFAudio _lib, NSURL? URL) {
    final _ret = _lib._objc_msgSend_226(_lib._class_NSMutableURLRequest1,
        _lib._sel_requestWithURL_1, URL?._id ?? ffi.nullptr);
    return NSMutableURLRequest._(_ret, _lib, retain: true, release: true);
  }

  static bool getSupportsSecureCoding(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMutableURLRequest1, _lib._sel_supportsSecureCoding1);
  }

  static NSMutableURLRequest requestWithURL_cachePolicy_timeoutInterval_(
      AVFAudio _lib, NSURL? URL, int cachePolicy, double timeoutInterval) {
    final _ret = _lib._objc_msgSend_747(
        _lib._class_NSMutableURLRequest1,
        _lib._sel_requestWithURL_cachePolicy_timeoutInterval_1,
        URL?._id ?? ffi.nullptr,
        cachePolicy,
        timeoutInterval);
    return NSMutableURLRequest._(_ret, _lib, retain: true, release: true);
  }

  static NSMutableURLRequest new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSMutableURLRequest1, _lib._sel_new1);
    return NSMutableURLRequest._(_ret, _lib, retain: false, release: true);
  }

  static NSMutableURLRequest alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableURLRequest1, _lib._sel_alloc1);
    return NSMutableURLRequest._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSMutableURLRequest1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSMutableURLRequest1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSMutableURLRequest1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSMutableURLRequest1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSMutableURLRequest1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSMutableURLRequest1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSMutableURLRequest1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSMutableURLRequest1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSMutableURLRequest1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSXMLParser extends NSObject {
  NSXMLParser._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSXMLParser] that points to the same underlying object as [other].
  static NSXMLParser castFrom<T extends _ObjCWrapper>(T other) {
    return NSXMLParser._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSXMLParser] that wraps the given raw object pointer.
  static NSXMLParser castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSXMLParser._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSXMLParser].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSXMLParser1);
  }

  NSXMLParser initWithContentsOfURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_226(
        _id, _lib._sel_initWithContentsOfURL_1, url?._id ?? ffi.nullptr);
    return NSXMLParser._(_ret, _lib, retain: true, release: true);
  }

  NSXMLParser initWithData_(NSData? data) {
    final _ret = _lib._objc_msgSend_242(
        _id, _lib._sel_initWithData_1, data?._id ?? ffi.nullptr);
    return NSXMLParser._(_ret, _lib, retain: true, release: true);
  }

  NSXMLParser initWithStream_(NSInputStream? stream) {
    final _ret = _lib._objc_msgSend_899(
        _id, _lib._sel_initWithStream_1, stream?._id ?? ffi.nullptr);
    return NSXMLParser._(_ret, _lib, retain: true, release: true);
  }

  NSObject? get delegate {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_delegate1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  set delegate(NSObject? value) {
    _lib._objc_msgSend_368(
        _id, _lib._sel_setDelegate_1, value?._id ?? ffi.nullptr);
  }

  bool get shouldProcessNamespaces {
    return _lib._objc_msgSend_12(_id, _lib._sel_shouldProcessNamespaces1);
  }

  set shouldProcessNamespaces(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setShouldProcessNamespaces_1, value);
  }

  bool get shouldReportNamespacePrefixes {
    return _lib._objc_msgSend_12(_id, _lib._sel_shouldReportNamespacePrefixes1);
  }

  set shouldReportNamespacePrefixes(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setShouldReportNamespacePrefixes_1, value);
  }

  int get externalEntityResolvingPolicy {
    return _lib._objc_msgSend_900(
        _id, _lib._sel_externalEntityResolvingPolicy1);
  }

  set externalEntityResolvingPolicy(int value) {
    _lib._objc_msgSend_901(
        _id, _lib._sel_setExternalEntityResolvingPolicy_1, value);
  }

  NSSet? get allowedExternalEntityURLs {
    final _ret =
        _lib._objc_msgSend_280(_id, _lib._sel_allowedExternalEntityURLs1);
    return _ret.address == 0
        ? null
        : NSSet._(_ret, _lib, retain: true, release: true);
  }

  set allowedExternalEntityURLs(NSSet? value) {
    _lib._objc_msgSend_902(_id, _lib._sel_setAllowedExternalEntityURLs_1,
        value?._id ?? ffi.nullptr);
  }

  bool parse() {
    return _lib._objc_msgSend_12(_id, _lib._sel_parse1);
  }

  void abortParsing() {
    return _lib._objc_msgSend_1(_id, _lib._sel_abortParsing1);
  }

  NSError? get parserError {
    final _ret = _lib._objc_msgSend_283(_id, _lib._sel_parserError1);
    return _ret.address == 0
        ? null
        : NSError._(_ret, _lib, retain: true, release: true);
  }

  bool get shouldResolveExternalEntities {
    return _lib._objc_msgSend_12(_id, _lib._sel_shouldResolveExternalEntities1);
  }

  set shouldResolveExternalEntities(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setShouldResolveExternalEntities_1, value);
  }

  NSString? get publicID {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_publicID1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get systemID {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_systemID1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get lineNumber {
    return _lib._objc_msgSend_78(_id, _lib._sel_lineNumber1);
  }

  int get columnNumber {
    return _lib._objc_msgSend_78(_id, _lib._sel_columnNumber1);
  }

  static NSXMLParser new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSXMLParser1, _lib._sel_new1);
    return NSXMLParser._(_ret, _lib, retain: false, release: true);
  }

  static NSXMLParser alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLParser1, _lib._sel_alloc1);
    return NSXMLParser._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSXMLParser1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSXMLParser1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLParser1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLParser1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSXMLParser1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSXMLParser1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSXMLParser1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSXMLParser1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSXMLParser1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSXMLParserExternalEntityResolvingPolicy {
  static const int NSXMLParserResolveExternalEntitiesNever = 0;
  static const int NSXMLParserResolveExternalEntitiesNoNetwork = 1;
  static const int NSXMLParserResolveExternalEntitiesSameOriginOnly = 2;
  static const int NSXMLParserResolveExternalEntitiesAlways = 3;
}

class NSFileWrapper extends NSObject {
  NSFileWrapper._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSFileWrapper] that points to the same underlying object as [other].
  static NSFileWrapper castFrom<T extends _ObjCWrapper>(T other) {
    return NSFileWrapper._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSFileWrapper] that wraps the given raw object pointer.
  static NSFileWrapper castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSFileWrapper._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSFileWrapper].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSFileWrapper1);
  }

  NSFileWrapper initWithURL_options_error_(
      NSURL? url, int options, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    final _ret = _lib._objc_msgSend_903(
        _id,
        _lib._sel_initWithURL_options_error_1,
        url?._id ?? ffi.nullptr,
        options,
        outError);
    return NSFileWrapper._(_ret, _lib, retain: true, release: true);
  }

  NSFileWrapper initDirectoryWithFileWrappers_(
      NSDictionary? childrenByPreferredName) {
    final _ret = _lib._objc_msgSend_143(
        _id,
        _lib._sel_initDirectoryWithFileWrappers_1,
        childrenByPreferredName?._id ?? ffi.nullptr);
    return NSFileWrapper._(_ret, _lib, retain: true, release: true);
  }

  NSFileWrapper initRegularFileWithContents_(NSData? contents) {
    final _ret = _lib._objc_msgSend_242(_id,
        _lib._sel_initRegularFileWithContents_1, contents?._id ?? ffi.nullptr);
    return NSFileWrapper._(_ret, _lib, retain: true, release: true);
  }

  NSFileWrapper initSymbolicLinkWithDestinationURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_226(
        _id,
        _lib._sel_initSymbolicLinkWithDestinationURL_1,
        url?._id ?? ffi.nullptr);
    return NSFileWrapper._(_ret, _lib, retain: true, release: true);
  }

  NSFileWrapper initWithSerializedRepresentation_(
      NSData? serializeRepresentation) {
    final _ret = _lib._objc_msgSend_242(
        _id,
        _lib._sel_initWithSerializedRepresentation_1,
        serializeRepresentation?._id ?? ffi.nullptr);
    return NSFileWrapper._(_ret, _lib, retain: true, release: true);
  }

  NSFileWrapper initWithCoder_(NSCoder? inCoder) {
    final _ret = _lib._objc_msgSend_42(
        _id, _lib._sel_initWithCoder_1, inCoder?._id ?? ffi.nullptr);
    return NSFileWrapper._(_ret, _lib, retain: true, release: true);
  }

  bool get directory {
    return _lib._objc_msgSend_12(_id, _lib._sel_isDirectory1);
  }

  bool get regularFile {
    return _lib._objc_msgSend_12(_id, _lib._sel_isRegularFile1);
  }

  bool get symbolicLink {
    return _lib._objc_msgSend_12(_id, _lib._sel_isSymbolicLink1);
  }

  NSString? get preferredFilename {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_preferredFilename1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set preferredFilename(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPreferredFilename_1, value?._id ?? ffi.nullptr);
  }

  NSString? get filename {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_filename1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set filename(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setFilename_1, value?._id ?? ffi.nullptr);
  }

  NSDictionary? get fileAttributes {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_fileAttributes1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set fileAttributes(NSDictionary? value) {
    _lib._objc_msgSend_165(
        _id, _lib._sel_setFileAttributes_1, value?._id ?? ffi.nullptr);
  }

  bool matchesContentsOfURL_(NSURL? url) {
    return _lib._objc_msgSend_229(
        _id, _lib._sel_matchesContentsOfURL_1, url?._id ?? ffi.nullptr);
  }

  bool readFromURL_options_error_(
      NSURL? url, int options, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_904(_id, _lib._sel_readFromURL_options_error_1,
        url?._id ?? ffi.nullptr, options, outError);
  }

  bool writeToURL_options_originalContentsURL_error_(
      NSURL? url,
      int options,
      NSURL? originalContentsURL,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_905(
        _id,
        _lib._sel_writeToURL_options_originalContentsURL_error_1,
        url?._id ?? ffi.nullptr,
        options,
        originalContentsURL?._id ?? ffi.nullptr,
        outError);
  }

  NSData? get serializedRepresentation {
    final _ret =
        _lib._objc_msgSend_39(_id, _lib._sel_serializedRepresentation1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  NSString addFileWrapper_(NSFileWrapper? child) {
    final _ret = _lib._objc_msgSend_906(
        _id, _lib._sel_addFileWrapper_1, child?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString addRegularFileWithContents_preferredFilename_(
      NSData? data, NSString? fileName) {
    final _ret = _lib._objc_msgSend_907(
        _id,
        _lib._sel_addRegularFileWithContents_preferredFilename_1,
        data?._id ?? ffi.nullptr,
        fileName?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  void removeFileWrapper_(NSFileWrapper? child) {
    return _lib._objc_msgSend_908(
        _id, _lib._sel_removeFileWrapper_1, child?._id ?? ffi.nullptr);
  }

  NSDictionary? get fileWrappers {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_fileWrappers1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  NSString keyForFileWrapper_(NSFileWrapper? child) {
    final _ret = _lib._objc_msgSend_906(
        _id, _lib._sel_keyForFileWrapper_1, child?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSData? get regularFileContents {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_regularFileContents1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get symbolicLinkDestinationURL {
    final _ret =
        _lib._objc_msgSend_40(_id, _lib._sel_symbolicLinkDestinationURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSObject initWithPath_(NSString? path) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithPath_1, path?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject initSymbolicLinkWithDestination_(NSString? path) {
    final _ret = _lib._objc_msgSend_30(_id,
        _lib._sel_initSymbolicLinkWithDestination_1, path?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  bool needsToBeUpdatedFromPath_(NSString? path) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_needsToBeUpdatedFromPath_1, path?._id ?? ffi.nullptr);
  }

  bool updateFromPath_(NSString? path) {
    return _lib._objc_msgSend_59(
        _id, _lib._sel_updateFromPath_1, path?._id ?? ffi.nullptr);
  }

  bool writeToFile_atomically_updateFilenames_(
      NSString? path, bool atomicFlag, bool updateFilenamesFlag) {
    return _lib._objc_msgSend_909(
        _id,
        _lib._sel_writeToFile_atomically_updateFilenames_1,
        path?._id ?? ffi.nullptr,
        atomicFlag,
        updateFilenamesFlag);
  }

  NSString addFileWithPath_(NSString? path) {
    final _ret = _lib._objc_msgSend_64(
        _id, _lib._sel_addFileWithPath_1, path?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString addSymbolicLinkWithDestination_preferredFilename_(
      NSString? path, NSString? filename) {
    final _ret = _lib._objc_msgSend_324(
        _id,
        _lib._sel_addSymbolicLinkWithDestination_preferredFilename_1,
        path?._id ?? ffi.nullptr,
        filename?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString symbolicLinkDestination() {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_symbolicLinkDestination1);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSFileWrapper new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSFileWrapper1, _lib._sel_new1);
    return NSFileWrapper._(_ret, _lib, retain: false, release: true);
  }

  static NSFileWrapper alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSFileWrapper1, _lib._sel_alloc1);
    return NSFileWrapper._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSFileWrapper1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSFileWrapper1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSFileWrapper1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSFileWrapper1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSFileWrapper1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSFileWrapper1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSFileWrapper1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSFileWrapper1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSFileWrapper1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSFileWrapperReadingOptions {
  static const int NSFileWrapperReadingImmediate = 1;
  static const int NSFileWrapperReadingWithoutMapping = 2;
}

abstract class NSFileWrapperWritingOptions {
  static const int NSFileWrapperWritingAtomic = 1;
  static const int NSFileWrapperWritingWithNameUpdating = 2;
}

class NSURLSession extends NSObject {
  NSURLSession._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLSession] that points to the same underlying object as [other].
  static NSURLSession castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLSession._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSURLSession] that wraps the given raw object pointer.
  static NSURLSession castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLSession._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLSession].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSURLSession1);
  }

  static NSURLSession? getSharedSession(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_910(
        _lib._class_NSURLSession1, _lib._sel_sharedSession1);
    return _ret.address == 0
        ? null
        : NSURLSession._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSession sessionWithConfiguration_(
      AVFAudio _lib, NSURLSessionConfiguration? configuration) {
    final _ret = _lib._objc_msgSend_921(
        _lib._class_NSURLSession1,
        _lib._sel_sessionWithConfiguration_1,
        configuration?._id ?? ffi.nullptr);
    return NSURLSession._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSession sessionWithConfiguration_delegate_delegateQueue_(
      AVFAudio _lib,
      NSURLSessionConfiguration? configuration,
      NSObject? delegate,
      NSOperationQueue? queue) {
    final _ret = _lib._objc_msgSend_922(
        _lib._class_NSURLSession1,
        _lib._sel_sessionWithConfiguration_delegate_delegateQueue_1,
        configuration?._id ?? ffi.nullptr,
        delegate?._id ?? ffi.nullptr,
        queue?._id ?? ffi.nullptr);
    return NSURLSession._(_ret, _lib, retain: true, release: true);
  }

  NSOperationQueue? get delegateQueue {
    final _ret = _lib._objc_msgSend_790(_id, _lib._sel_delegateQueue1);
    return _ret.address == 0
        ? null
        : NSOperationQueue._(_ret, _lib, retain: true, release: true);
  }

  NSObject? get delegate {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_delegate1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionConfiguration? get configuration {
    final _ret = _lib._objc_msgSend_911(_id, _lib._sel_configuration1);
    return _ret.address == 0
        ? null
        : NSURLSessionConfiguration._(_ret, _lib, retain: true, release: true);
  }

  NSString? get sessionDescription {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_sessionDescription1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set sessionDescription(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setSessionDescription_1, value?._id ?? ffi.nullptr);
  }

  void finishTasksAndInvalidate() {
    return _lib._objc_msgSend_1(_id, _lib._sel_finishTasksAndInvalidate1);
  }

  void invalidateAndCancel() {
    return _lib._objc_msgSend_1(_id, _lib._sel_invalidateAndCancel1);
  }

  void resetWithCompletionHandler_(ObjCBlock16 completionHandler) {
    return _lib._objc_msgSend_465(
        _id, _lib._sel_resetWithCompletionHandler_1, completionHandler._id);
  }

  void flushWithCompletionHandler_(ObjCBlock16 completionHandler) {
    return _lib._objc_msgSend_465(
        _id, _lib._sel_flushWithCompletionHandler_1, completionHandler._id);
  }

  void getTasksWithCompletionHandler_(ObjCBlock37 completionHandler) {
    return _lib._objc_msgSend_923(
        _id, _lib._sel_getTasksWithCompletionHandler_1, completionHandler._id);
  }

  void getAllTasksWithCompletionHandler_(ObjCBlock30 completionHandler) {
    return _lib._objc_msgSend_924(_id,
        _lib._sel_getAllTasksWithCompletionHandler_1, completionHandler._id);
  }

  NSURLSessionDataTask dataTaskWithRequest_(NSURLRequest? request) {
    final _ret = _lib._objc_msgSend_925(
        _id, _lib._sel_dataTaskWithRequest_1, request?._id ?? ffi.nullptr);
    return NSURLSessionDataTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionDataTask dataTaskWithURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_926(
        _id, _lib._sel_dataTaskWithURL_1, url?._id ?? ffi.nullptr);
    return NSURLSessionDataTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionUploadTask uploadTaskWithRequest_fromFile_(
      NSURLRequest? request, NSURL? fileURL) {
    final _ret = _lib._objc_msgSend_927(
        _id,
        _lib._sel_uploadTaskWithRequest_fromFile_1,
        request?._id ?? ffi.nullptr,
        fileURL?._id ?? ffi.nullptr);
    return NSURLSessionUploadTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionUploadTask uploadTaskWithRequest_fromData_(
      NSURLRequest? request, NSData? bodyData) {
    final _ret = _lib._objc_msgSend_928(
        _id,
        _lib._sel_uploadTaskWithRequest_fromData_1,
        request?._id ?? ffi.nullptr,
        bodyData?._id ?? ffi.nullptr);
    return NSURLSessionUploadTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionUploadTask uploadTaskWithStreamedRequest_(NSURLRequest? request) {
    final _ret = _lib._objc_msgSend_929(_id,
        _lib._sel_uploadTaskWithStreamedRequest_1, request?._id ?? ffi.nullptr);
    return NSURLSessionUploadTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionDownloadTask downloadTaskWithRequest_(NSURLRequest? request) {
    final _ret = _lib._objc_msgSend_931(
        _id, _lib._sel_downloadTaskWithRequest_1, request?._id ?? ffi.nullptr);
    return NSURLSessionDownloadTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionDownloadTask downloadTaskWithURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_932(
        _id, _lib._sel_downloadTaskWithURL_1, url?._id ?? ffi.nullptr);
    return NSURLSessionDownloadTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionDownloadTask downloadTaskWithResumeData_(NSData? resumeData) {
    final _ret = _lib._objc_msgSend_933(_id,
        _lib._sel_downloadTaskWithResumeData_1, resumeData?._id ?? ffi.nullptr);
    return NSURLSessionDownloadTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionStreamTask streamTaskWithHostName_port_(
      NSString? hostname, int port) {
    final _ret = _lib._objc_msgSend_936(
        _id,
        _lib._sel_streamTaskWithHostName_port_1,
        hostname?._id ?? ffi.nullptr,
        port);
    return NSURLSessionStreamTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionStreamTask streamTaskWithNetService_(NSNetService? service) {
    final _ret = _lib._objc_msgSend_942(
        _id, _lib._sel_streamTaskWithNetService_1, service?._id ?? ffi.nullptr);
    return NSURLSessionStreamTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionWebSocketTask webSocketTaskWithURL_(NSURL? url) {
    final _ret = _lib._objc_msgSend_949(
        _id, _lib._sel_webSocketTaskWithURL_1, url?._id ?? ffi.nullptr);
    return NSURLSessionWebSocketTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionWebSocketTask webSocketTaskWithURL_protocols_(
      NSURL? url, NSArray? protocols) {
    final _ret = _lib._objc_msgSend_950(
        _id,
        _lib._sel_webSocketTaskWithURL_protocols_1,
        url?._id ?? ffi.nullptr,
        protocols?._id ?? ffi.nullptr);
    return NSURLSessionWebSocketTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionWebSocketTask webSocketTaskWithRequest_(NSURLRequest? request) {
    final _ret = _lib._objc_msgSend_951(
        _id, _lib._sel_webSocketTaskWithRequest_1, request?._id ?? ffi.nullptr);
    return NSURLSessionWebSocketTask._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSURLSession init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSURLSession._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSession new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLSession1, _lib._sel_new1);
    return NSURLSession._(_ret, _lib, retain: false, release: true);
  }

  NSURLSessionDataTask dataTaskWithRequest_completionHandler_(
      NSURLRequest? request, ObjCBlock41 completionHandler) {
    final _ret = _lib._objc_msgSend_952(
        _id,
        _lib._sel_dataTaskWithRequest_completionHandler_1,
        request?._id ?? ffi.nullptr,
        completionHandler._id);
    return NSURLSessionDataTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionDataTask dataTaskWithURL_completionHandler_(
      NSURL? url, ObjCBlock41 completionHandler) {
    final _ret = _lib._objc_msgSend_953(
        _id,
        _lib._sel_dataTaskWithURL_completionHandler_1,
        url?._id ?? ffi.nullptr,
        completionHandler._id);
    return NSURLSessionDataTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionUploadTask uploadTaskWithRequest_fromFile_completionHandler_(
      NSURLRequest? request, NSURL? fileURL, ObjCBlock41 completionHandler) {
    final _ret = _lib._objc_msgSend_954(
        _id,
        _lib._sel_uploadTaskWithRequest_fromFile_completionHandler_1,
        request?._id ?? ffi.nullptr,
        fileURL?._id ?? ffi.nullptr,
        completionHandler._id);
    return NSURLSessionUploadTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionUploadTask uploadTaskWithRequest_fromData_completionHandler_(
      NSURLRequest? request, NSData? bodyData, ObjCBlock41 completionHandler) {
    final _ret = _lib._objc_msgSend_955(
        _id,
        _lib._sel_uploadTaskWithRequest_fromData_completionHandler_1,
        request?._id ?? ffi.nullptr,
        bodyData?._id ?? ffi.nullptr,
        completionHandler._id);
    return NSURLSessionUploadTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionDownloadTask downloadTaskWithRequest_completionHandler_(
      NSURLRequest? request, ObjCBlock42 completionHandler) {
    final _ret = _lib._objc_msgSend_956(
        _id,
        _lib._sel_downloadTaskWithRequest_completionHandler_1,
        request?._id ?? ffi.nullptr,
        completionHandler._id);
    return NSURLSessionDownloadTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionDownloadTask downloadTaskWithURL_completionHandler_(
      NSURL? url, ObjCBlock42 completionHandler) {
    final _ret = _lib._objc_msgSend_957(
        _id,
        _lib._sel_downloadTaskWithURL_completionHandler_1,
        url?._id ?? ffi.nullptr,
        completionHandler._id);
    return NSURLSessionDownloadTask._(_ret, _lib, retain: true, release: true);
  }

  NSURLSessionDownloadTask downloadTaskWithResumeData_completionHandler_(
      NSData? resumeData, ObjCBlock42 completionHandler) {
    final _ret = _lib._objc_msgSend_958(
        _id,
        _lib._sel_downloadTaskWithResumeData_completionHandler_1,
        resumeData?._id ?? ffi.nullptr,
        completionHandler._id);
    return NSURLSessionDownloadTask._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSession alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSURLSession1, _lib._sel_alloc1);
    return NSURLSession._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLSession1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLSession1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLSession1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLSession1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLSession1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLSession1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLSession1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSURLSession1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSession1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSURLSessionConfiguration extends NSObject {
  NSURLSessionConfiguration._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLSessionConfiguration] that points to the same underlying object as [other].
  static NSURLSessionConfiguration castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLSessionConfiguration._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLSessionConfiguration] that wraps the given raw object pointer.
  static NSURLSessionConfiguration castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLSessionConfiguration._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLSessionConfiguration].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLSessionConfiguration1);
  }

  static NSURLSessionConfiguration? getDefaultSessionConfiguration(
      AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_911(_lib._class_NSURLSessionConfiguration1,
        _lib._sel_defaultSessionConfiguration1);
    return _ret.address == 0
        ? null
        : NSURLSessionConfiguration._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSessionConfiguration? getEphemeralSessionConfiguration(
      AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_911(_lib._class_NSURLSessionConfiguration1,
        _lib._sel_ephemeralSessionConfiguration1);
    return _ret.address == 0
        ? null
        : NSURLSessionConfiguration._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSessionConfiguration
      backgroundSessionConfigurationWithIdentifier_(
          AVFAudio _lib, NSString? identifier) {
    final _ret = _lib._objc_msgSend_912(
        _lib._class_NSURLSessionConfiguration1,
        _lib._sel_backgroundSessionConfigurationWithIdentifier_1,
        identifier?._id ?? ffi.nullptr);
    return NSURLSessionConfiguration._(_ret, _lib, retain: true, release: true);
  }

  NSString? get identifier {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_identifier1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  int get requestCachePolicy {
    return _lib._objc_msgSend_748(_id, _lib._sel_requestCachePolicy1);
  }

  set requestCachePolicy(int value) {
    _lib._objc_msgSend_889(_id, _lib._sel_setRequestCachePolicy_1, value);
  }

  double get timeoutIntervalForRequest {
    return _lib._objc_msgSend_149(_id, _lib._sel_timeoutIntervalForRequest1);
  }

  set timeoutIntervalForRequest(double value) {
    _lib._objc_msgSend_474(
        _id, _lib._sel_setTimeoutIntervalForRequest_1, value);
  }

  double get timeoutIntervalForResource {
    return _lib._objc_msgSend_149(_id, _lib._sel_timeoutIntervalForResource1);
  }

  set timeoutIntervalForResource(double value) {
    _lib._objc_msgSend_474(
        _id, _lib._sel_setTimeoutIntervalForResource_1, value);
  }

  int get networkServiceType {
    return _lib._objc_msgSend_749(_id, _lib._sel_networkServiceType1);
  }

  set networkServiceType(int value) {
    _lib._objc_msgSend_890(_id, _lib._sel_setNetworkServiceType_1, value);
  }

  bool get allowsCellularAccess {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsCellularAccess1);
  }

  set allowsCellularAccess(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setAllowsCellularAccess_1, value);
  }

  bool get allowsExpensiveNetworkAccess {
    return _lib._objc_msgSend_12(_id, _lib._sel_allowsExpensiveNetworkAccess1);
  }

  set allowsExpensiveNetworkAccess(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setAllowsExpensiveNetworkAccess_1, value);
  }

  bool get allowsConstrainedNetworkAccess {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_allowsConstrainedNetworkAccess1);
  }

  set allowsConstrainedNetworkAccess(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setAllowsConstrainedNetworkAccess_1, value);
  }

  bool get waitsForConnectivity {
    return _lib._objc_msgSend_12(_id, _lib._sel_waitsForConnectivity1);
  }

  set waitsForConnectivity(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setWaitsForConnectivity_1, value);
  }

  bool get discretionary {
    return _lib._objc_msgSend_12(_id, _lib._sel_isDiscretionary1);
  }

  set discretionary(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setDiscretionary_1, value);
  }

  NSString? get sharedContainerIdentifier {
    final _ret =
        _lib._objc_msgSend_20(_id, _lib._sel_sharedContainerIdentifier1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set sharedContainerIdentifier(NSString? value) {
    _lib._objc_msgSend_477(_id, _lib._sel_setSharedContainerIdentifier_1,
        value?._id ?? ffi.nullptr);
  }

  bool get sessionSendsLaunchEvents {
    return _lib._objc_msgSend_12(_id, _lib._sel_sessionSendsLaunchEvents1);
  }

  set sessionSendsLaunchEvents(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setSessionSendsLaunchEvents_1, value);
  }

  NSDictionary? get connectionProxyDictionary {
    final _ret =
        _lib._objc_msgSend_164(_id, _lib._sel_connectionProxyDictionary1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set connectionProxyDictionary(NSDictionary? value) {
    _lib._objc_msgSend_165(_id, _lib._sel_setConnectionProxyDictionary_1,
        value?._id ?? ffi.nullptr);
  }

  int get TLSMinimumSupportedProtocol {
    return _lib._objc_msgSend_913(_id, _lib._sel_TLSMinimumSupportedProtocol1);
  }

  set TLSMinimumSupportedProtocol(int value) {
    _lib._objc_msgSend_914(
        _id, _lib._sel_setTLSMinimumSupportedProtocol_1, value);
  }

  int get TLSMaximumSupportedProtocol {
    return _lib._objc_msgSend_913(_id, _lib._sel_TLSMaximumSupportedProtocol1);
  }

  set TLSMaximumSupportedProtocol(int value) {
    _lib._objc_msgSend_914(
        _id, _lib._sel_setTLSMaximumSupportedProtocol_1, value);
  }

  int get TLSMinimumSupportedProtocolVersion {
    return _lib._objc_msgSend_915(
        _id, _lib._sel_TLSMinimumSupportedProtocolVersion1);
  }

  set TLSMinimumSupportedProtocolVersion(int value) {
    _lib._objc_msgSend_916(
        _id, _lib._sel_setTLSMinimumSupportedProtocolVersion_1, value);
  }

  int get TLSMaximumSupportedProtocolVersion {
    return _lib._objc_msgSend_915(
        _id, _lib._sel_TLSMaximumSupportedProtocolVersion1);
  }

  set TLSMaximumSupportedProtocolVersion(int value) {
    _lib._objc_msgSend_916(
        _id, _lib._sel_setTLSMaximumSupportedProtocolVersion_1, value);
  }

  bool get HTTPShouldUsePipelining {
    return _lib._objc_msgSend_12(_id, _lib._sel_HTTPShouldUsePipelining1);
  }

  set HTTPShouldUsePipelining(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setHTTPShouldUsePipelining_1, value);
  }

  bool get HTTPShouldSetCookies {
    return _lib._objc_msgSend_12(_id, _lib._sel_HTTPShouldSetCookies1);
  }

  set HTTPShouldSetCookies(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setHTTPShouldSetCookies_1, value);
  }

  int get HTTPCookieAcceptPolicy {
    return _lib._objc_msgSend_745(_id, _lib._sel_HTTPCookieAcceptPolicy1);
  }

  set HTTPCookieAcceptPolicy(int value) {
    _lib._objc_msgSend_746(_id, _lib._sel_setHTTPCookieAcceptPolicy_1, value);
  }

  NSDictionary? get HTTPAdditionalHeaders {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_HTTPAdditionalHeaders1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set HTTPAdditionalHeaders(NSDictionary? value) {
    _lib._objc_msgSend_165(
        _id, _lib._sel_setHTTPAdditionalHeaders_1, value?._id ?? ffi.nullptr);
  }

  int get HTTPMaximumConnectionsPerHost {
    return _lib._objc_msgSend_78(_id, _lib._sel_HTTPMaximumConnectionsPerHost1);
  }

  set HTTPMaximumConnectionsPerHost(int value) {
    _lib._objc_msgSend_558(
        _id, _lib._sel_setHTTPMaximumConnectionsPerHost_1, value);
  }

  NSHTTPCookieStorage? get HTTPCookieStorage {
    final _ret = _lib._objc_msgSend_739(_id, _lib._sel_HTTPCookieStorage1);
    return _ret.address == 0
        ? null
        : NSHTTPCookieStorage._(_ret, _lib, retain: true, release: true);
  }

  set HTTPCookieStorage(NSHTTPCookieStorage? value) {
    _lib._objc_msgSend_917(
        _id, _lib._sel_setHTTPCookieStorage_1, value?._id ?? ffi.nullptr);
  }

  NSURLCredentialStorage? get URLCredentialStorage {
    final _ret = _lib._objc_msgSend_874(_id, _lib._sel_URLCredentialStorage1);
    return _ret.address == 0
        ? null
        : NSURLCredentialStorage._(_ret, _lib, retain: true, release: true);
  }

  set URLCredentialStorage(NSURLCredentialStorage? value) {
    _lib._objc_msgSend_918(
        _id, _lib._sel_setURLCredentialStorage_1, value?._id ?? ffi.nullptr);
  }

  NSURLCache? get URLCache {
    final _ret = _lib._objc_msgSend_844(_id, _lib._sel_URLCache1);
    return _ret.address == 0
        ? null
        : NSURLCache._(_ret, _lib, retain: true, release: true);
  }

  set URLCache(NSURLCache? value) {
    _lib._objc_msgSend_845(
        _id, _lib._sel_setURLCache_1, value?._id ?? ffi.nullptr);
  }

  bool get shouldUseExtendedBackgroundIdleMode {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_shouldUseExtendedBackgroundIdleMode1);
  }

  set shouldUseExtendedBackgroundIdleMode(bool value) {
    _lib._objc_msgSend_460(
        _id, _lib._sel_setShouldUseExtendedBackgroundIdleMode_1, value);
  }

  NSArray? get protocolClasses {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_protocolClasses1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set protocolClasses(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setProtocolClasses_1, value?._id ?? ffi.nullptr);
  }

  int get multipathServiceType {
    return _lib._objc_msgSend_919(_id, _lib._sel_multipathServiceType1);
  }

  set multipathServiceType(int value) {
    _lib._objc_msgSend_920(_id, _lib._sel_setMultipathServiceType_1, value);
  }

  @override
  NSURLSessionConfiguration init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSURLSessionConfiguration._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSessionConfiguration new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionConfiguration1, _lib._sel_new1);
    return NSURLSessionConfiguration._(_ret, _lib,
        retain: false, release: true);
  }

  static NSURLSessionConfiguration backgroundSessionConfiguration_(
      AVFAudio _lib, NSString? identifier) {
    final _ret = _lib._objc_msgSend_912(
        _lib._class_NSURLSessionConfiguration1,
        _lib._sel_backgroundSessionConfiguration_1,
        identifier?._id ?? ffi.nullptr);
    return NSURLSessionConfiguration._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSessionConfiguration alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionConfiguration1, _lib._sel_alloc1);
    return NSURLSessionConfiguration._(_ret, _lib,
        retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLSessionConfiguration1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLSessionConfiguration1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLSessionConfiguration1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLSessionConfiguration1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLSessionConfiguration1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLSessionConfiguration1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLSessionConfiguration1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionConfiguration1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSURLSessionConfiguration1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class SSLProtocol {
  static const int kSSLProtocolUnknown = 0;
  static const int kTLSProtocol1 = 4;
  static const int kTLSProtocol11 = 7;
  static const int kTLSProtocol12 = 8;
  static const int kDTLSProtocol1 = 9;
  static const int kTLSProtocol13 = 10;
  static const int kDTLSProtocol12 = 11;
  static const int kTLSProtocolMaxSupported = 999;
  static const int kSSLProtocol2 = 1;
  static const int kSSLProtocol3 = 2;
  static const int kSSLProtocol3Only = 3;
  static const int kTLSProtocol1Only = 5;
  static const int kSSLProtocolAll = 6;
}

abstract class tls_protocol_version_t {
  static const int tls_protocol_version_TLSv10 = 769;
  static const int tls_protocol_version_TLSv11 = 770;
  static const int tls_protocol_version_TLSv12 = 771;
  static const int tls_protocol_version_TLSv13 = 772;
  static const int tls_protocol_version_DTLSv10 = -257;
  static const int tls_protocol_version_DTLSv12 = -259;
}

abstract class NSURLSessionMultipathServiceType {
  static const int NSURLSessionMultipathServiceTypeNone = 0;
  static const int NSURLSessionMultipathServiceTypeHandover = 1;
  static const int NSURLSessionMultipathServiceTypeInteractive = 2;
  static const int NSURLSessionMultipathServiceTypeAggregate = 3;
}

void _ObjCBlock37_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ObjCObject> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(
                  ffi.Pointer<ObjCObject> arg0,
                  ffi.Pointer<ObjCObject> arg1,
                  ffi.Pointer<ObjCObject> arg2)>>()
      .asFunction<
          void Function(
              ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ObjCObject> arg1,
              ffi.Pointer<ObjCObject> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock37_closureRegistry = <int, Function>{};
int _ObjCBlock37_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock37_registerClosure(Function fn) {
  final id = ++_ObjCBlock37_closureRegistryIndex;
  _ObjCBlock37_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock37_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ObjCObject> arg2) {
  return _ObjCBlock37_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock37 extends _ObjCBlockBase {
  ObjCBlock37._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock37.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ObjCObject> arg1,
                      ffi.Pointer<ObjCObject> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock37_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock37.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1,
              ffi.Pointer<ObjCObject> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock37_closureTrampoline)
                    .cast(),
                _ObjCBlock37_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1,
      ffi.Pointer<ObjCObject> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ObjCObject> arg1,
                    ffi.Pointer<ObjCObject> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ObjCObject> arg1,
                ffi.Pointer<ObjCObject> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSURLSessionUploadTask extends NSURLSessionDataTask {
  NSURLSessionUploadTask._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLSessionUploadTask] that points to the same underlying object as [other].
  static NSURLSessionUploadTask castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLSessionUploadTask._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLSessionUploadTask] that wraps the given raw object pointer.
  static NSURLSessionUploadTask castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLSessionUploadTask._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLSessionUploadTask].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLSessionUploadTask1);
  }

  @override
  NSURLSessionUploadTask init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSURLSessionUploadTask._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSessionUploadTask new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionUploadTask1, _lib._sel_new1);
    return NSURLSessionUploadTask._(_ret, _lib, retain: false, release: true);
  }

  static NSURLSessionUploadTask alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionUploadTask1, _lib._sel_alloc1);
    return NSURLSessionUploadTask._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLSessionUploadTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLSessionUploadTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLSessionUploadTask1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLSessionUploadTask1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLSessionUploadTask1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLSessionUploadTask1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLSessionUploadTask1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionUploadTask1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSURLSessionUploadTask1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSURLSessionDownloadTask extends NSURLSessionTask {
  NSURLSessionDownloadTask._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLSessionDownloadTask] that points to the same underlying object as [other].
  static NSURLSessionDownloadTask castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLSessionDownloadTask._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLSessionDownloadTask] that wraps the given raw object pointer.
  static NSURLSessionDownloadTask castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLSessionDownloadTask._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLSessionDownloadTask].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLSessionDownloadTask1);
  }

  void cancelByProducingResumeData_(ObjCBlock38 completionHandler) {
    return _lib._objc_msgSend_930(
        _id, _lib._sel_cancelByProducingResumeData_1, completionHandler._id);
  }

  @override
  NSURLSessionDownloadTask init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSURLSessionDownloadTask._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSessionDownloadTask new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionDownloadTask1, _lib._sel_new1);
    return NSURLSessionDownloadTask._(_ret, _lib, retain: false, release: true);
  }

  static NSURLSessionDownloadTask alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionDownloadTask1, _lib._sel_alloc1);
    return NSURLSessionDownloadTask._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLSessionDownloadTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLSessionDownloadTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLSessionDownloadTask1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLSessionDownloadTask1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLSessionDownloadTask1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLSessionDownloadTask1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLSessionDownloadTask1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionDownloadTask1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSURLSessionDownloadTask1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

void _ObjCBlock38_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>()
      .asFunction<void Function(ffi.Pointer<ObjCObject> arg0)>()(arg0);
}

final _ObjCBlock38_closureRegistry = <int, Function>{};
int _ObjCBlock38_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock38_registerClosure(Function fn) {
  final id = ++_ObjCBlock38_closureRegistryIndex;
  _ObjCBlock38_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock38_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return _ObjCBlock38_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock38 extends _ObjCBlockBase {
  ObjCBlock38._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock38.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi
              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock38_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock38.fromFunction(
      AVFAudio lib, void Function(ffi.Pointer<ObjCObject> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock38_closureTrampoline)
                    .cast(),
                _ObjCBlock38_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSURLSessionStreamTask extends NSURLSessionTask {
  NSURLSessionStreamTask._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLSessionStreamTask] that points to the same underlying object as [other].
  static NSURLSessionStreamTask castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLSessionStreamTask._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLSessionStreamTask] that wraps the given raw object pointer.
  static NSURLSessionStreamTask castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLSessionStreamTask._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLSessionStreamTask].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLSessionStreamTask1);
  }

  void readDataOfMinLength_maxLength_timeout_completionHandler_(int minBytes,
      int maxBytes, double timeout, ObjCBlock39 completionHandler) {
    return _lib._objc_msgSend_934(
        _id,
        _lib._sel_readDataOfMinLength_maxLength_timeout_completionHandler_1,
        minBytes,
        maxBytes,
        timeout,
        completionHandler._id);
  }

  void writeData_timeout_completionHandler_(
      NSData? data, double timeout, ObjCBlock15 completionHandler) {
    return _lib._objc_msgSend_935(
        _id,
        _lib._sel_writeData_timeout_completionHandler_1,
        data?._id ?? ffi.nullptr,
        timeout,
        completionHandler._id);
  }

  void captureStreams() {
    return _lib._objc_msgSend_1(_id, _lib._sel_captureStreams1);
  }

  void closeWrite() {
    return _lib._objc_msgSend_1(_id, _lib._sel_closeWrite1);
  }

  void closeRead() {
    return _lib._objc_msgSend_1(_id, _lib._sel_closeRead1);
  }

  void startSecureConnection() {
    return _lib._objc_msgSend_1(_id, _lib._sel_startSecureConnection1);
  }

  void stopSecureConnection() {
    return _lib._objc_msgSend_1(_id, _lib._sel_stopSecureConnection1);
  }

  @override
  NSURLSessionStreamTask init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSURLSessionStreamTask._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSessionStreamTask new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionStreamTask1, _lib._sel_new1);
    return NSURLSessionStreamTask._(_ret, _lib, retain: false, release: true);
  }

  static NSURLSessionStreamTask alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionStreamTask1, _lib._sel_alloc1);
    return NSURLSessionStreamTask._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLSessionStreamTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLSessionStreamTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLSessionStreamTask1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLSessionStreamTask1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLSessionStreamTask1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLSessionStreamTask1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLSessionStreamTask1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionStreamTask1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSURLSessionStreamTask1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

void _ObjCBlock39_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, bool arg1, ffi.Pointer<ObjCObject> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0, ffi.Bool arg1,
                  ffi.Pointer<ObjCObject> arg2)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0, bool arg1,
              ffi.Pointer<ObjCObject> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock39_closureRegistry = <int, Function>{};
int _ObjCBlock39_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock39_registerClosure(Function fn) {
  final id = ++_ObjCBlock39_closureRegistryIndex;
  _ObjCBlock39_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock39_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, bool arg1, ffi.Pointer<ObjCObject> arg2) {
  return _ObjCBlock39_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock39 extends _ObjCBlockBase {
  ObjCBlock39._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock39.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0, ffi.Bool arg1,
                      ffi.Pointer<ObjCObject> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Bool arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock39_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock39.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, bool arg1,
              ffi.Pointer<ObjCObject> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Bool arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock39_closureTrampoline)
                    .cast(),
                _ObjCBlock39_registerClosure(fn)),
            lib);
  void call(
      ffi.Pointer<ObjCObject> arg0, bool arg1, ffi.Pointer<ObjCObject> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Bool arg1,
                    ffi.Pointer<ObjCObject> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                bool arg1,
                ffi.Pointer<ObjCObject> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSNetService extends NSObject {
  NSNetService._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSNetService] that points to the same underlying object as [other].
  static NSNetService castFrom<T extends _ObjCWrapper>(T other) {
    return NSNetService._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSNetService] that wraps the given raw object pointer.
  static NSNetService castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSNetService._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSNetService].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSNetService1);
  }

  NSNetService initWithDomain_type_name_port_(
      NSString? domain, NSString? type, NSString? name, int port) {
    final _ret = _lib._objc_msgSend_937(
        _id,
        _lib._sel_initWithDomain_type_name_port_1,
        domain?._id ?? ffi.nullptr,
        type?._id ?? ffi.nullptr,
        name?._id ?? ffi.nullptr,
        port);
    return NSNetService._(_ret, _lib, retain: true, release: true);
  }

  NSNetService initWithDomain_type_name_(
      NSString? domain, NSString? type, NSString? name) {
    final _ret = _lib._objc_msgSend_26(
        _id,
        _lib._sel_initWithDomain_type_name_1,
        domain?._id ?? ffi.nullptr,
        type?._id ?? ffi.nullptr,
        name?._id ?? ffi.nullptr);
    return NSNetService._(_ret, _lib, retain: true, release: true);
  }

  void scheduleInRunLoop_forMode_(NSRunLoop? aRunLoop, NSRunLoopMode mode) {
    return _lib._objc_msgSend_501(_id, _lib._sel_scheduleInRunLoop_forMode_1,
        aRunLoop?._id ?? ffi.nullptr, mode);
  }

  void removeFromRunLoop_forMode_(NSRunLoop? aRunLoop, NSRunLoopMode mode) {
    return _lib._objc_msgSend_501(_id, _lib._sel_removeFromRunLoop_forMode_1,
        aRunLoop?._id ?? ffi.nullptr, mode);
  }

  NSObject? get delegate {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_delegate1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  set delegate(NSObject? value) {
    _lib._objc_msgSend_368(
        _id, _lib._sel_setDelegate_1, value?._id ?? ffi.nullptr);
  }

  bool get includesPeerToPeer {
    return _lib._objc_msgSend_12(_id, _lib._sel_includesPeerToPeer1);
  }

  set includesPeerToPeer(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setIncludesPeerToPeer_1, value);
  }

  NSString? get name {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_name1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get type {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_type1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get domain {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_domain1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get hostName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_hostName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get addresses {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_addresses1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  int get port {
    return _lib._objc_msgSend_78(_id, _lib._sel_port1);
  }

  void publish() {
    return _lib._objc_msgSend_1(_id, _lib._sel_publish1);
  }

  void publishWithOptions_(int options) {
    return _lib._objc_msgSend_938(_id, _lib._sel_publishWithOptions_1, options);
  }

  void resolve() {
    return _lib._objc_msgSend_1(_id, _lib._sel_resolve1);
  }

  void stop() {
    return _lib._objc_msgSend_1(_id, _lib._sel_stop1);
  }

  static NSDictionary dictionaryFromTXTRecordData_(
      AVFAudio _lib, NSData? txtData) {
    final _ret = _lib._objc_msgSend_939(_lib._class_NSNetService1,
        _lib._sel_dictionaryFromTXTRecordData_1, txtData?._id ?? ffi.nullptr);
    return NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  static NSData dataFromTXTRecordDictionary_(
      AVFAudio _lib, NSDictionary? txtDictionary) {
    final _ret = _lib._objc_msgSend_940(
        _lib._class_NSNetService1,
        _lib._sel_dataFromTXTRecordDictionary_1,
        txtDictionary?._id ?? ffi.nullptr);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  void resolveWithTimeout_(double timeout) {
    return _lib._objc_msgSend_473(_id, _lib._sel_resolveWithTimeout_1, timeout);
  }

  bool getInputStream_outputStream_(
      ffi.Pointer<ffi.Pointer<ObjCObject>> inputStream,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outputStream) {
    return _lib._objc_msgSend_941(_id, _lib._sel_getInputStream_outputStream_1,
        inputStream, outputStream);
  }

  bool setTXTRecordData_(NSData? recordData) {
    return _lib._objc_msgSend_23(
        _id, _lib._sel_setTXTRecordData_1, recordData?._id ?? ffi.nullptr);
  }

  NSData TXTRecordData() {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_TXTRecordData1);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  void startMonitoring() {
    return _lib._objc_msgSend_1(_id, _lib._sel_startMonitoring1);
  }

  void stopMonitoring() {
    return _lib._objc_msgSend_1(_id, _lib._sel_stopMonitoring1);
  }

  static NSNetService new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSNetService1, _lib._sel_new1);
    return NSNetService._(_ret, _lib, retain: false, release: true);
  }

  static NSNetService alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSNetService1, _lib._sel_alloc1);
    return NSNetService._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSNetService1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSNetService1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSNetService1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSNetService1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSNetService1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSNetService1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSNetService1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSNetService1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSNetService1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSNetServiceOptions {
  static const int NSNetServiceNoAutoRename = 1;
  static const int NSNetServiceListenForConnections = 2;
}

class NSURLSessionWebSocketTask extends NSURLSessionTask {
  NSURLSessionWebSocketTask._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLSessionWebSocketTask] that points to the same underlying object as [other].
  static NSURLSessionWebSocketTask castFrom<T extends _ObjCWrapper>(T other) {
    return NSURLSessionWebSocketTask._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLSessionWebSocketTask] that wraps the given raw object pointer.
  static NSURLSessionWebSocketTask castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLSessionWebSocketTask._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLSessionWebSocketTask].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLSessionWebSocketTask1);
  }

  void sendMessage_completionHandler_(
      NSURLSessionWebSocketMessage? message, ObjCBlock15 completionHandler) {
    return _lib._objc_msgSend_944(
        _id,
        _lib._sel_sendMessage_completionHandler_1,
        message?._id ?? ffi.nullptr,
        completionHandler._id);
  }

  void receiveMessageWithCompletionHandler_(ObjCBlock40 completionHandler) {
    return _lib._objc_msgSend_945(_id,
        _lib._sel_receiveMessageWithCompletionHandler_1, completionHandler._id);
  }

  void sendPingWithPongReceiveHandler_(ObjCBlock15 pongReceiveHandler) {
    return _lib._objc_msgSend_946(_id,
        _lib._sel_sendPingWithPongReceiveHandler_1, pongReceiveHandler._id);
  }

  void cancelWithCloseCode_reason_(int closeCode, NSData? reason) {
    return _lib._objc_msgSend_947(_id, _lib._sel_cancelWithCloseCode_reason_1,
        closeCode, reason?._id ?? ffi.nullptr);
  }

  int get maximumMessageSize {
    return _lib._objc_msgSend_78(_id, _lib._sel_maximumMessageSize1);
  }

  set maximumMessageSize(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setMaximumMessageSize_1, value);
  }

  int get closeCode {
    return _lib._objc_msgSend_948(_id, _lib._sel_closeCode1);
  }

  NSData? get closeReason {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_closeReason1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSURLSessionWebSocketTask init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSURLSessionWebSocketTask._(_ret, _lib, retain: true, release: true);
  }

  static NSURLSessionWebSocketTask new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionWebSocketTask1, _lib._sel_new1);
    return NSURLSessionWebSocketTask._(_ret, _lib,
        retain: false, release: true);
  }

  static NSURLSessionWebSocketTask alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionWebSocketTask1, _lib._sel_alloc1);
    return NSURLSessionWebSocketTask._(_ret, _lib,
        retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLSessionWebSocketTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLSessionWebSocketTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLSessionWebSocketTask1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSURLSessionWebSocketTask1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLSessionWebSocketTask1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLSessionWebSocketTask1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLSessionWebSocketTask1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionWebSocketTask1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSURLSessionWebSocketTask1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSURLSessionWebSocketMessage extends NSObject {
  NSURLSessionWebSocketMessage._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSURLSessionWebSocketMessage] that points to the same underlying object as [other].
  static NSURLSessionWebSocketMessage castFrom<T extends _ObjCWrapper>(
      T other) {
    return NSURLSessionWebSocketMessage._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSURLSessionWebSocketMessage] that wraps the given raw object pointer.
  static NSURLSessionWebSocketMessage castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSURLSessionWebSocketMessage._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSURLSessionWebSocketMessage].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSURLSessionWebSocketMessage1);
  }

  NSURLSessionWebSocketMessage initWithData_(NSData? data) {
    final _ret = _lib._objc_msgSend_242(
        _id, _lib._sel_initWithData_1, data?._id ?? ffi.nullptr);
    return NSURLSessionWebSocketMessage._(_ret, _lib,
        retain: true, release: true);
  }

  NSURLSessionWebSocketMessage initWithString_(NSString? string) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithString_1, string?._id ?? ffi.nullptr);
    return NSURLSessionWebSocketMessage._(_ret, _lib,
        retain: true, release: true);
  }

  int get type {
    return _lib._objc_msgSend_943(_id, _lib._sel_type1);
  }

  NSData? get data {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_data1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  NSString? get string {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_string1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSURLSessionWebSocketMessage init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSURLSessionWebSocketMessage._(_ret, _lib,
        retain: true, release: true);
  }

  static NSURLSessionWebSocketMessage new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionWebSocketMessage1, _lib._sel_new1);
    return NSURLSessionWebSocketMessage._(_ret, _lib,
        retain: false, release: true);
  }

  static NSURLSessionWebSocketMessage alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSURLSessionWebSocketMessage1, _lib._sel_alloc1);
    return NSURLSessionWebSocketMessage._(_ret, _lib,
        retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSURLSessionWebSocketMessage1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSURLSessionWebSocketMessage1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLSessionWebSocketMessage1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_NSURLSessionWebSocketMessage1,
        _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSURLSessionWebSocketMessage1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSURLSessionWebSocketMessage1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSURLSessionWebSocketMessage1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSURLSessionWebSocketMessage1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSURLSessionWebSocketMessage1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSURLSessionWebSocketMessageType {
  static const int NSURLSessionWebSocketMessageTypeData = 0;
  static const int NSURLSessionWebSocketMessageTypeString = 1;
}

void _ObjCBlock40_fnPtrTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                  ffi.Pointer<ObjCObject> arg1)>>()
      .asFunction<
          void Function(ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ObjCObject> arg1)>()(arg0, arg1);
}

final _ObjCBlock40_closureRegistry = <int, Function>{};
int _ObjCBlock40_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock40_registerClosure(Function fn) {
  final id = ++_ObjCBlock40_closureRegistryIndex;
  _ObjCBlock40_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock40_closureTrampoline(ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
  return _ObjCBlock40_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock40 extends _ObjCBlockBase {
  ObjCBlock40._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock40.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ObjCObject> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock40_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock40.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock40_closureTrampoline)
                    .cast(),
                _ObjCBlock40_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ObjCObject> arg1)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ObjCObject> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

abstract class NSURLSessionWebSocketCloseCode {
  static const int NSURLSessionWebSocketCloseCodeInvalid = 0;
  static const int NSURLSessionWebSocketCloseCodeNormalClosure = 1000;
  static const int NSURLSessionWebSocketCloseCodeGoingAway = 1001;
  static const int NSURLSessionWebSocketCloseCodeProtocolError = 1002;
  static const int NSURLSessionWebSocketCloseCodeUnsupportedData = 1003;
  static const int NSURLSessionWebSocketCloseCodeNoStatusReceived = 1005;
  static const int NSURLSessionWebSocketCloseCodeAbnormalClosure = 1006;
  static const int NSURLSessionWebSocketCloseCodeInvalidFramePayloadData = 1007;
  static const int NSURLSessionWebSocketCloseCodePolicyViolation = 1008;
  static const int NSURLSessionWebSocketCloseCodeMessageTooBig = 1009;
  static const int NSURLSessionWebSocketCloseCodeMandatoryExtensionMissing =
      1010;
  static const int NSURLSessionWebSocketCloseCodeInternalServerError = 1011;
  static const int NSURLSessionWebSocketCloseCodeTLSHandshakeFailure = 1015;
}

void _ObjCBlock41_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ObjCObject> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(
                  ffi.Pointer<ObjCObject> arg0,
                  ffi.Pointer<ObjCObject> arg1,
                  ffi.Pointer<ObjCObject> arg2)>>()
      .asFunction<
          void Function(
              ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ObjCObject> arg1,
              ffi.Pointer<ObjCObject> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock41_closureRegistry = <int, Function>{};
int _ObjCBlock41_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock41_registerClosure(Function fn) {
  final id = ++_ObjCBlock41_closureRegistryIndex;
  _ObjCBlock41_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock41_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ObjCObject> arg2) {
  return _ObjCBlock41_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock41 extends _ObjCBlockBase {
  ObjCBlock41._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock41.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ObjCObject> arg1,
                      ffi.Pointer<ObjCObject> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock41_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock41.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1,
              ffi.Pointer<ObjCObject> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock41_closureTrampoline)
                    .cast(),
                _ObjCBlock41_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1,
      ffi.Pointer<ObjCObject> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ObjCObject> arg1,
                    ffi.Pointer<ObjCObject> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ObjCObject> arg1,
                ffi.Pointer<ObjCObject> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

void _ObjCBlock42_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ObjCObject> arg2) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(
                  ffi.Pointer<ObjCObject> arg0,
                  ffi.Pointer<ObjCObject> arg1,
                  ffi.Pointer<ObjCObject> arg2)>>()
      .asFunction<
          void Function(
              ffi.Pointer<ObjCObject> arg0,
              ffi.Pointer<ObjCObject> arg1,
              ffi.Pointer<ObjCObject> arg2)>()(arg0, arg1, arg2);
}

final _ObjCBlock42_closureRegistry = <int, Function>{};
int _ObjCBlock42_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock42_registerClosure(Function fn) {
  final id = ++_ObjCBlock42_closureRegistryIndex;
  _ObjCBlock42_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock42_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block,
    ffi.Pointer<ObjCObject> arg0,
    ffi.Pointer<ObjCObject> arg1,
    ffi.Pointer<ObjCObject> arg2) {
  return _ObjCBlock42_closureRegistry[block.ref.target.address]!(
      arg0, arg1, arg2);
}

class ObjCBlock42 extends _ObjCBlockBase {
  ObjCBlock42._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock42.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      ffi.Pointer<ObjCObject> arg0,
                      ffi.Pointer<ObjCObject> arg1,
                      ffi.Pointer<ObjCObject> arg2)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock42_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock42.fromFunction(
      AVFAudio lib,
      void Function(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1,
              ffi.Pointer<ObjCObject> arg2)
          fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(
                                ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0,
                                ffi.Pointer<ObjCObject> arg1,
                                ffi.Pointer<ObjCObject> arg2)>(
                        _ObjCBlock42_closureTrampoline)
                    .cast(),
                _ObjCBlock42_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0, ffi.Pointer<ObjCObject> arg1,
      ffi.Pointer<ObjCObject> arg2) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(
                    ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0,
                    ffi.Pointer<ObjCObject> arg1,
                    ffi.Pointer<ObjCObject> arg2)>>()
        .asFunction<
            void Function(
                ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0,
                ffi.Pointer<ObjCObject> arg1,
                ffi.Pointer<ObjCObject> arg2)>()(_id, arg0, arg1, arg2);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSProtocolChecker extends NSProxy {
  NSProtocolChecker._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSProtocolChecker] that points to the same underlying object as [other].
  static NSProtocolChecker castFrom<T extends _ObjCWrapper>(T other) {
    return NSProtocolChecker._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [NSProtocolChecker] that wraps the given raw object pointer.
  static NSProtocolChecker castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSProtocolChecker._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSProtocolChecker].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_NSProtocolChecker1);
  }

  Protocol? get protocol {
    final _ret = _lib._objc_msgSend_959(_id, _lib._sel_protocol1);
    return _ret.address == 0
        ? null
        : Protocol._(_ret, _lib, retain: true, release: true);
  }

  NSObject? get target {
    final _ret = _lib._objc_msgSend_788(_id, _lib._sel_target1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSProtocolChecker protocolCheckerWithTarget_protocol_(
      AVFAudio _lib, NSObject? anObject, Protocol? aProtocol) {
    final _ret = _lib._objc_msgSend_960(
        _lib._class_NSProtocolChecker1,
        _lib._sel_protocolCheckerWithTarget_protocol_1,
        anObject?._id ?? ffi.nullptr,
        aProtocol?._id ?? ffi.nullptr);
    return NSProtocolChecker._(_ret, _lib, retain: true, release: true);
  }

  NSProtocolChecker initWithTarget_protocol_(
      NSObject? anObject, Protocol? aProtocol) {
    final _ret = _lib._objc_msgSend_960(
        _id,
        _lib._sel_initWithTarget_protocol_1,
        anObject?._id ?? ffi.nullptr,
        aProtocol?._id ?? ffi.nullptr);
    return NSProtocolChecker._(_ret, _lib, retain: true, release: true);
  }

  static NSObject alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSProtocolChecker1, _lib._sel_alloc1);
    return NSObject._(_ret, _lib, retain: false, release: true);
  }

  static bool respondsToSelector_(
      AVFAudio _lib, ffi.Pointer<ObjCSel> aSelector) {
    return _lib._objc_msgSend_4(_lib._class_NSProtocolChecker1,
        _lib._sel_respondsToSelector_1, aSelector);
  }
}

class NSTask extends NSObject {
  NSTask._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSTask] that points to the same underlying object as [other].
  static NSTask castFrom<T extends _ObjCWrapper>(T other) {
    return NSTask._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSTask] that wraps the given raw object pointer.
  static NSTask castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSTask._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSTask].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSTask1);
  }

  @override
  NSTask init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSTask._(_ret, _lib, retain: true, release: true);
  }

  NSURL? get executableURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_executableURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  set executableURL(NSURL? value) {
    _lib._objc_msgSend_888(
        _id, _lib._sel_setExecutableURL_1, value?._id ?? ffi.nullptr);
  }

  NSArray? get arguments {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_arguments1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set arguments(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setArguments_1, value?._id ?? ffi.nullptr);
  }

  NSDictionary? get environment {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_environment1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  set environment(NSDictionary? value) {
    _lib._objc_msgSend_165(
        _id, _lib._sel_setEnvironment_1, value?._id ?? ffi.nullptr);
  }

  NSURL? get currentDirectoryURL {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_currentDirectoryURL1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  set currentDirectoryURL(NSURL? value) {
    _lib._objc_msgSend_888(
        _id, _lib._sel_setCurrentDirectoryURL_1, value?._id ?? ffi.nullptr);
  }

  NSObject get standardInput {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_standardInput1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  set standardInput(NSObject value) {
    _lib._objc_msgSend_368(_id, _lib._sel_setStandardInput_1, value._id);
  }

  NSObject get standardOutput {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_standardOutput1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  set standardOutput(NSObject value) {
    _lib._objc_msgSend_368(_id, _lib._sel_setStandardOutput_1, value._id);
  }

  NSObject get standardError {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_standardError1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  set standardError(NSObject value) {
    _lib._objc_msgSend_368(_id, _lib._sel_setStandardError_1, value._id);
  }

  bool launchAndReturnError_(ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_219(_id, _lib._sel_launchAndReturnError_1, error);
  }

  void interrupt() {
    return _lib._objc_msgSend_1(_id, _lib._sel_interrupt1);
  }

  void terminate() {
    return _lib._objc_msgSend_1(_id, _lib._sel_terminate1);
  }

  bool suspend() {
    return _lib._objc_msgSend_12(_id, _lib._sel_suspend1);
  }

  bool resume() {
    return _lib._objc_msgSend_12(_id, _lib._sel_resume1);
  }

  int get processIdentifier {
    return _lib._objc_msgSend_213(_id, _lib._sel_processIdentifier1);
  }

  bool get running {
    return _lib._objc_msgSend_12(_id, _lib._sel_isRunning1);
  }

  int get terminationStatus {
    return _lib._objc_msgSend_213(_id, _lib._sel_terminationStatus1);
  }

  int get terminationReason {
    return _lib._objc_msgSend_961(_id, _lib._sel_terminationReason1);
  }

  ObjCBlock43 get terminationHandler {
    final _ret = _lib._objc_msgSend_962(_id, _lib._sel_terminationHandler1);
    return ObjCBlock43._(_ret, _lib);
  }

  set terminationHandler(ObjCBlock43 value) {
    _lib._objc_msgSend_963(_id, _lib._sel_setTerminationHandler_1, value._id);
  }

  int get qualityOfService {
    return _lib._objc_msgSend_475(_id, _lib._sel_qualityOfService1);
  }

  set qualityOfService(int value) {
    _lib._objc_msgSend_476(_id, _lib._sel_setQualityOfService_1, value);
  }

  static NSTask
      launchedTaskWithExecutableURL_arguments_error_terminationHandler_(
          AVFAudio _lib,
          NSURL? url,
          NSArray? arguments,
          ffi.Pointer<ffi.Pointer<ObjCObject>> error,
          ObjCBlock43 terminationHandler) {
    final _ret = _lib._objc_msgSend_964(
        _lib._class_NSTask1,
        _lib._sel_launchedTaskWithExecutableURL_arguments_error_terminationHandler_1,
        url?._id ?? ffi.nullptr,
        arguments?._id ?? ffi.nullptr,
        error,
        terminationHandler._id);
    return NSTask._(_ret, _lib, retain: true, release: true);
  }

  void waitUntilExit() {
    return _lib._objc_msgSend_1(_id, _lib._sel_waitUntilExit1);
  }

  NSString? get launchPath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_launchPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set launchPath(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setLaunchPath_1, value?._id ?? ffi.nullptr);
  }

  NSString? get currentDirectoryPath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_currentDirectoryPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set currentDirectoryPath(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setCurrentDirectoryPath_1, value?._id ?? ffi.nullptr);
  }

  void launch() {
    return _lib._objc_msgSend_1(_id, _lib._sel_launch1);
  }

  static NSTask launchedTaskWithLaunchPath_arguments_(
      AVFAudio _lib, NSString? path, NSArray? arguments) {
    final _ret = _lib._objc_msgSend_965(
        _lib._class_NSTask1,
        _lib._sel_launchedTaskWithLaunchPath_arguments_1,
        path?._id ?? ffi.nullptr,
        arguments?._id ?? ffi.nullptr);
    return NSTask._(_ret, _lib, retain: true, release: true);
  }

  static NSTask new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSTask1, _lib._sel_new1);
    return NSTask._(_ret, _lib, retain: false, release: true);
  }

  static NSTask alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSTask1, _lib._sel_alloc1);
    return NSTask._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSTask1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSTask1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSTask1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSTask1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSTask1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSTask1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSTask1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSTask1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSTaskTerminationReason {
  static const int NSTaskTerminationReasonExit = 1;
  static const int NSTaskTerminationReasonUncaughtSignal = 2;
}

void _ObjCBlock43_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>()
      .asFunction<void Function(ffi.Pointer<ObjCObject> arg0)>()(arg0);
}

final _ObjCBlock43_closureRegistry = <int, Function>{};
int _ObjCBlock43_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock43_registerClosure(Function fn) {
  final id = ++_ObjCBlock43_closureRegistryIndex;
  _ObjCBlock43_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock43_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, ffi.Pointer<ObjCObject> arg0) {
  return _ObjCBlock43_closureRegistry[block.ref.target.address]!(arg0);
}

class ObjCBlock43 extends _ObjCBlockBase {
  ObjCBlock43._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock43.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi
              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock43_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock43.fromFunction(
      AVFAudio lib, void Function(ffi.Pointer<ObjCObject> arg0) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Pointer<ObjCObject> arg0)>(
                        _ObjCBlock43_closureTrampoline)
                    .cast(),
                _ObjCBlock43_registerClosure(fn)),
            lib);
  void call(ffi.Pointer<ObjCObject> arg0) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                    ffi.Pointer<ObjCObject> arg0)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block,
                ffi.Pointer<ObjCObject> arg0)>()(_id, arg0);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

class NSXMLElement extends NSXMLNode {
  NSXMLElement._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSXMLElement] that points to the same underlying object as [other].
  static NSXMLElement castFrom<T extends _ObjCWrapper>(T other) {
    return NSXMLElement._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSXMLElement] that wraps the given raw object pointer.
  static NSXMLElement castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSXMLElement._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSXMLElement].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSXMLElement1);
  }

  NSXMLElement initWithName_(NSString? name) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithName_1, name?._id ?? ffi.nullptr);
    return NSXMLElement._(_ret, _lib, retain: true, release: true);
  }

  NSXMLElement initWithName_URI_(NSString? name, NSString? URI) {
    final _ret = _lib._objc_msgSend_159(_id, _lib._sel_initWithName_URI_1,
        name?._id ?? ffi.nullptr, URI?._id ?? ffi.nullptr);
    return NSXMLElement._(_ret, _lib, retain: true, release: true);
  }

  NSXMLElement initWithName_stringValue_(NSString? name, NSString? string) {
    final _ret = _lib._objc_msgSend_159(
        _id,
        _lib._sel_initWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        string?._id ?? ffi.nullptr);
    return NSXMLElement._(_ret, _lib, retain: true, release: true);
  }

  NSXMLElement initWithXMLString_error_(
      NSString? string, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_264(_id,
        _lib._sel_initWithXMLString_error_1, string?._id ?? ffi.nullptr, error);
    return NSXMLElement._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSXMLElement initWithKind_options_(int kind, int options) {
    final _ret = _lib._objc_msgSend_967(
        _id, _lib._sel_initWithKind_options_1, kind, options);
    return NSXMLElement._(_ret, _lib, retain: true, release: true);
  }

  NSArray elementsForName_(NSString? name) {
    final _ret = _lib._objc_msgSend_119(
        _id, _lib._sel_elementsForName_1, name?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray elementsForLocalName_URI_(NSString? localName, NSString? URI) {
    final _ret = _lib._objc_msgSend_617(
        _id,
        _lib._sel_elementsForLocalName_URI_1,
        localName?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  void addAttribute_(NSXMLNode? attribute) {
    return _lib._objc_msgSend_979(
        _id, _lib._sel_addAttribute_1, attribute?._id ?? ffi.nullptr);
  }

  void removeAttributeForName_(NSString? name) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_removeAttributeForName_1, name?._id ?? ffi.nullptr);
  }

  NSArray? get attributes {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_attributes1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set attributes(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setAttributes_1, value?._id ?? ffi.nullptr);
  }

  void setAttributesWithDictionary_(NSDictionary? attributes) {
    return _lib._objc_msgSend_444(_id, _lib._sel_setAttributesWithDictionary_1,
        attributes?._id ?? ffi.nullptr);
  }

  NSXMLNode attributeForName_(NSString? name) {
    final _ret = _lib._objc_msgSend_983(
        _id, _lib._sel_attributeForName_1, name?._id ?? ffi.nullptr);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  NSXMLNode attributeForLocalName_URI_(NSString? localName, NSString? URI) {
    final _ret = _lib._objc_msgSend_1000(
        _id,
        _lib._sel_attributeForLocalName_URI_1,
        localName?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  void addNamespace_(NSXMLNode? aNamespace) {
    return _lib._objc_msgSend_979(
        _id, _lib._sel_addNamespace_1, aNamespace?._id ?? ffi.nullptr);
  }

  void removeNamespaceForPrefix_(NSString? name) {
    return _lib._objc_msgSend_186(
        _id, _lib._sel_removeNamespaceForPrefix_1, name?._id ?? ffi.nullptr);
  }

  NSArray? get namespaces {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_namespaces1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set namespaces(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setNamespaces_1, value?._id ?? ffi.nullptr);
  }

  NSXMLNode namespaceForPrefix_(NSString? name) {
    final _ret = _lib._objc_msgSend_983(
        _id, _lib._sel_namespaceForPrefix_1, name?._id ?? ffi.nullptr);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  NSXMLNode resolveNamespaceForName_(NSString? name) {
    final _ret = _lib._objc_msgSend_983(
        _id, _lib._sel_resolveNamespaceForName_1, name?._id ?? ffi.nullptr);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  NSString resolvePrefixForNamespaceURI_(NSString? namespaceURI) {
    final _ret = _lib._objc_msgSend_64(
        _id,
        _lib._sel_resolvePrefixForNamespaceURI_1,
        namespaceURI?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  void insertChild_atIndex_(NSXMLNode? child, int index) {
    return _lib._objc_msgSend_977(
        _id, _lib._sel_insertChild_atIndex_1, child?._id ?? ffi.nullptr, index);
  }

  void insertChildren_atIndex_(NSArray? children, int index) {
    return _lib._objc_msgSend_978(_id, _lib._sel_insertChildren_atIndex_1,
        children?._id ?? ffi.nullptr, index);
  }

  void removeChildAtIndex_(int index) {
    return _lib._objc_msgSend_410(_id, _lib._sel_removeChildAtIndex_1, index);
  }

  void setChildren_(NSArray? children) {
    return _lib._objc_msgSend_412(
        _id, _lib._sel_setChildren_1, children?._id ?? ffi.nullptr);
  }

  void addChild_(NSXMLNode? child) {
    return _lib._objc_msgSend_979(
        _id, _lib._sel_addChild_1, child?._id ?? ffi.nullptr);
  }

  void replaceChildAtIndex_withNode_(int index, NSXMLNode? node) {
    return _lib._objc_msgSend_980(_id, _lib._sel_replaceChildAtIndex_withNode_1,
        index, node?._id ?? ffi.nullptr);
  }

  void normalizeAdjacentTextNodesPreservingCDATA_(bool preserve) {
    return _lib._objc_msgSend_756(
        _id, _lib._sel_normalizeAdjacentTextNodesPreservingCDATA_1, preserve);
  }

  void setAttributesAsDictionary_(NSDictionary? attributes) {
    return _lib._objc_msgSend_444(_id, _lib._sel_setAttributesAsDictionary_1,
        attributes?._id ?? ffi.nullptr);
  }

  static NSObject document(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLElement1, _lib._sel_document1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject documentWithRootElement_(
      AVFAudio _lib, NSXMLElement? element) {
    final _ret = _lib._objc_msgSend_968(_lib._class_NSXMLElement1,
        _lib._sel_documentWithRootElement_1, element?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLElement1,
        _lib._sel_elementWithName_1, name?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_URI_(
      AVFAudio _lib, NSString? name, NSString? URI) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLElement1,
        _lib._sel_elementWithName_URI_1,
        name?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? string) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLElement1,
        _lib._sel_elementWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_children_attributes_(
      AVFAudio _lib, NSString? name, NSArray? children, NSArray? attributes) {
    final _ret = _lib._objc_msgSend_969(
        _lib._class_NSXMLElement1,
        _lib._sel_elementWithName_children_attributes_1,
        name?._id ?? ffi.nullptr,
        children?._id ?? ffi.nullptr,
        attributes?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject attributeWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLElement1,
        _lib._sel_attributeWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject attributeWithName_URI_stringValue_(
      AVFAudio _lib, NSString? name, NSString? URI, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_26(
        _lib._class_NSXMLElement1,
        _lib._sel_attributeWithName_URI_stringValue_1,
        name?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject namespaceWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLElement1,
        _lib._sel_namespaceWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject processingInstructionWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLElement1,
        _lib._sel_processingInstructionWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject commentWithStringValue_(
      AVFAudio _lib, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLElement1,
        _lib._sel_commentWithStringValue_1, stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject textWithStringValue_(AVFAudio _lib, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLElement1,
        _lib._sel_textWithStringValue_1, stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject DTDNodeWithXMLString_(AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLElement1,
        _lib._sel_DTDNodeWithXMLString_1, string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSString localNameForName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSXMLElement1,
        _lib._sel_localNameForName_1, name?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString prefixForName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSXMLElement1,
        _lib._sel_prefixForName_1, name?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSXMLNode predefinedNamespaceForPrefix_(
      AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_983(_lib._class_NSXMLElement1,
        _lib._sel_predefinedNamespaceForPrefix_1, name?._id ?? ffi.nullptr);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  static NSXMLElement new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLElement1, _lib._sel_new1);
    return NSXMLElement._(_ret, _lib, retain: false, release: true);
  }

  static NSXMLElement alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLElement1, _lib._sel_alloc1);
    return NSXMLElement._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSXMLElement1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSXMLElement1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLElement1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLElement1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSXMLElement1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSXMLElement1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSXMLElement1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSXMLElement1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSXMLElement1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSXMLNode extends NSObject {
  NSXMLNode._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSXMLNode] that points to the same underlying object as [other].
  static NSXMLNode castFrom<T extends _ObjCWrapper>(T other) {
    return NSXMLNode._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSXMLNode] that wraps the given raw object pointer.
  static NSXMLNode castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSXMLNode._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSXMLNode].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSXMLNode1);
  }

  @override
  NSXMLNode init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  NSXMLNode initWithKind_(int kind) {
    final _ret = _lib._objc_msgSend_966(_id, _lib._sel_initWithKind_1, kind);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  NSXMLNode initWithKind_options_(int kind, int options) {
    final _ret = _lib._objc_msgSend_967(
        _id, _lib._sel_initWithKind_options_1, kind, options);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  static NSObject document(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLNode1, _lib._sel_document1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject documentWithRootElement_(
      AVFAudio _lib, NSXMLElement? element) {
    final _ret = _lib._objc_msgSend_968(_lib._class_NSXMLNode1,
        _lib._sel_documentWithRootElement_1, element?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLNode1,
        _lib._sel_elementWithName_1, name?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_URI_(
      AVFAudio _lib, NSString? name, NSString? URI) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLNode1,
        _lib._sel_elementWithName_URI_1,
        name?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? string) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLNode1,
        _lib._sel_elementWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_children_attributes_(
      AVFAudio _lib, NSString? name, NSArray? children, NSArray? attributes) {
    final _ret = _lib._objc_msgSend_969(
        _lib._class_NSXMLNode1,
        _lib._sel_elementWithName_children_attributes_1,
        name?._id ?? ffi.nullptr,
        children?._id ?? ffi.nullptr,
        attributes?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject attributeWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLNode1,
        _lib._sel_attributeWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject attributeWithName_URI_stringValue_(
      AVFAudio _lib, NSString? name, NSString? URI, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_26(
        _lib._class_NSXMLNode1,
        _lib._sel_attributeWithName_URI_stringValue_1,
        name?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject namespaceWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLNode1,
        _lib._sel_namespaceWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject processingInstructionWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLNode1,
        _lib._sel_processingInstructionWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject commentWithStringValue_(
      AVFAudio _lib, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLNode1,
        _lib._sel_commentWithStringValue_1, stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject textWithStringValue_(AVFAudio _lib, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLNode1,
        _lib._sel_textWithStringValue_1, stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject DTDNodeWithXMLString_(AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLNode1,
        _lib._sel_DTDNodeWithXMLString_1, string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  int get kind {
    return _lib._objc_msgSend_970(_id, _lib._sel_kind1);
  }

  NSString? get name {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_name1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set name(NSString? value) {
    _lib._objc_msgSend_477(_id, _lib._sel_setName_1, value?._id ?? ffi.nullptr);
  }

  NSObject get objectValue {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_objectValue1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  set objectValue(NSObject value) {
    _lib._objc_msgSend_368(_id, _lib._sel_setObjectValue_1, value._id);
  }

  NSString? get stringValue {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_stringValue1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set stringValue(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setStringValue_1, value?._id ?? ffi.nullptr);
  }

  void setStringValue_resolvingEntities_(NSString? string, bool resolve) {
    return _lib._objc_msgSend_971(
        _id,
        _lib._sel_setStringValue_resolvingEntities_1,
        string?._id ?? ffi.nullptr,
        resolve);
  }

  int get index {
    return _lib._objc_msgSend_10(_id, _lib._sel_index1);
  }

  int get level {
    return _lib._objc_msgSend_10(_id, _lib._sel_level1);
  }

  NSXMLDocument? get rootDocument {
    final _ret = _lib._objc_msgSend_994(_id, _lib._sel_rootDocument1);
    return _ret.address == 0
        ? null
        : NSXMLDocument._(_ret, _lib, retain: true, release: true);
  }

  NSXMLNode? get parent {
    final _ret = _lib._objc_msgSend_995(_id, _lib._sel_parent1);
    return _ret.address == 0
        ? null
        : NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  int get childCount {
    return _lib._objc_msgSend_10(_id, _lib._sel_childCount1);
  }

  NSArray? get children {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_children1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSXMLNode childAtIndex_(int index) {
    final _ret = _lib._objc_msgSend_996(_id, _lib._sel_childAtIndex_1, index);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  NSXMLNode? get previousSibling {
    final _ret = _lib._objc_msgSend_995(_id, _lib._sel_previousSibling1);
    return _ret.address == 0
        ? null
        : NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  NSXMLNode? get nextSibling {
    final _ret = _lib._objc_msgSend_995(_id, _lib._sel_nextSibling1);
    return _ret.address == 0
        ? null
        : NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  NSXMLNode? get previousNode {
    final _ret = _lib._objc_msgSend_995(_id, _lib._sel_previousNode1);
    return _ret.address == 0
        ? null
        : NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  NSXMLNode? get nextNode {
    final _ret = _lib._objc_msgSend_995(_id, _lib._sel_nextNode1);
    return _ret.address == 0
        ? null
        : NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  void detach() {
    return _lib._objc_msgSend_1(_id, _lib._sel_detach1);
  }

  NSString? get XPath {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_XPath1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get localName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_localName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get prefix {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_prefix1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get URI {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_URI1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set URI(NSString? value) {
    _lib._objc_msgSend_477(_id, _lib._sel_setURI_1, value?._id ?? ffi.nullptr);
  }

  static NSString localNameForName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSXMLNode1,
        _lib._sel_localNameForName_1, name?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString prefixForName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSXMLNode1,
        _lib._sel_prefixForName_1, name?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSXMLNode predefinedNamespaceForPrefix_(
      AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_983(_lib._class_NSXMLNode1,
        _lib._sel_predefinedNamespaceForPrefix_1, name?._id ?? ffi.nullptr);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  NSString? get description {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_description1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get XMLString {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_XMLString1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString XMLStringWithOptions_(int options) {
    final _ret =
        _lib._objc_msgSend_997(_id, _lib._sel_XMLStringWithOptions_1, options);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString canonicalXMLStringPreservingComments_(bool comments) {
    final _ret = _lib._objc_msgSend_998(
        _id, _lib._sel_canonicalXMLStringPreservingComments_1, comments);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  NSArray nodesForXPath_error_(
      NSString? xpath, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_394(
        _id, _lib._sel_nodesForXPath_error_1, xpath?._id ?? ffi.nullptr, error);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray objectsForXQuery_constants_error_(NSString? xquery,
      NSDictionary? constants, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_999(
        _id,
        _lib._sel_objectsForXQuery_constants_error_1,
        xquery?._id ?? ffi.nullptr,
        constants?._id ?? ffi.nullptr,
        error);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray objectsForXQuery_error_(
      NSString? xquery, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_394(_id, _lib._sel_objectsForXQuery_error_1,
        xquery?._id ?? ffi.nullptr, error);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSXMLNode new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSXMLNode1, _lib._sel_new1);
    return NSXMLNode._(_ret, _lib, retain: false, release: true);
  }

  static NSXMLNode alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSXMLNode1, _lib._sel_alloc1);
    return NSXMLNode._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSXMLNode1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSXMLNode1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLNode1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLNode1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSXMLNode1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSXMLNode1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSXMLNode1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSXMLNode1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSXMLNode1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSXMLNodeKind {
  static const int NSXMLInvalidKind = 0;
  static const int NSXMLDocumentKind = 1;
  static const int NSXMLElementKind = 2;
  static const int NSXMLAttributeKind = 3;
  static const int NSXMLNamespaceKind = 4;
  static const int NSXMLProcessingInstructionKind = 5;
  static const int NSXMLCommentKind = 6;
  static const int NSXMLTextKind = 7;
  static const int NSXMLDTDKind = 8;
  static const int NSXMLEntityDeclarationKind = 9;
  static const int NSXMLAttributeDeclarationKind = 10;
  static const int NSXMLElementDeclarationKind = 11;
  static const int NSXMLNotationDeclarationKind = 12;
}

abstract class NSXMLNodeOptions {
  static const int NSXMLNodeOptionsNone = 0;
  static const int NSXMLNodeIsCDATA = 1;
  static const int NSXMLNodeExpandEmptyElement = 2;
  static const int NSXMLNodeCompactEmptyElement = 4;
  static const int NSXMLNodeUseSingleQuotes = 8;
  static const int NSXMLNodeUseDoubleQuotes = 16;
  static const int NSXMLNodeNeverEscapeContents = 32;
  static const int NSXMLDocumentTidyHTML = 512;
  static const int NSXMLDocumentTidyXML = 1024;
  static const int NSXMLDocumentValidate = 8192;
  static const int NSXMLNodeLoadExternalEntitiesAlways = 16384;
  static const int NSXMLNodeLoadExternalEntitiesSameOriginOnly = 32768;
  static const int NSXMLNodeLoadExternalEntitiesNever = 524288;
  static const int NSXMLDocumentXInclude = 65536;
  static const int NSXMLNodePrettyPrint = 131072;
  static const int NSXMLDocumentIncludeContentTypeDeclaration = 262144;
  static const int NSXMLNodePreserveNamespaceOrder = 1048576;
  static const int NSXMLNodePreserveAttributeOrder = 2097152;
  static const int NSXMLNodePreserveEntities = 4194304;
  static const int NSXMLNodePreservePrefixes = 8388608;
  static const int NSXMLNodePreserveCDATA = 16777216;
  static const int NSXMLNodePreserveWhitespace = 33554432;
  static const int NSXMLNodePreserveDTD = 67108864;
  static const int NSXMLNodePreserveCharacterReferences = 134217728;
  static const int NSXMLNodePromoteSignificantWhitespace = 268435456;
  static const int NSXMLNodePreserveEmptyElements = 6;
  static const int NSXMLNodePreserveQuotes = 24;
  static const int NSXMLNodePreserveAll = 4293918750;
}

class NSXMLDocument extends NSXMLNode {
  NSXMLDocument._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSXMLDocument] that points to the same underlying object as [other].
  static NSXMLDocument castFrom<T extends _ObjCWrapper>(T other) {
    return NSXMLDocument._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSXMLDocument] that wraps the given raw object pointer.
  static NSXMLDocument castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSXMLDocument._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSXMLDocument].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSXMLDocument1);
  }

  @override
  NSXMLDocument init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSXMLDocument._(_ret, _lib, retain: true, release: true);
  }

  NSXMLDocument initWithXMLString_options_error_(
      NSString? string, int mask, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_972(
        _id,
        _lib._sel_initWithXMLString_options_error_1,
        string?._id ?? ffi.nullptr,
        mask,
        error);
    return NSXMLDocument._(_ret, _lib, retain: true, release: true);
  }

  NSXMLDocument initWithContentsOfURL_options_error_(
      NSURL? url, int mask, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_973(
        _id,
        _lib._sel_initWithContentsOfURL_options_error_1,
        url?._id ?? ffi.nullptr,
        mask,
        error);
    return NSXMLDocument._(_ret, _lib, retain: true, release: true);
  }

  NSXMLDocument initWithData_options_error_(
      NSData? data, int mask, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_974(
        _id,
        _lib._sel_initWithData_options_error_1,
        data?._id ?? ffi.nullptr,
        mask,
        error);
    return NSXMLDocument._(_ret, _lib, retain: true, release: true);
  }

  NSXMLDocument initWithRootElement_(NSXMLElement? element) {
    final _ret = _lib._objc_msgSend_968(
        _id, _lib._sel_initWithRootElement_1, element?._id ?? ffi.nullptr);
    return NSXMLDocument._(_ret, _lib, retain: true, release: true);
  }

  static NSObject replacementClassForClass_(AVFAudio _lib, NSObject cls) {
    final _ret = _lib._objc_msgSend_16(_lib._class_NSXMLDocument1,
        _lib._sel_replacementClassForClass_1, cls._id);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSString? get characterEncoding {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_characterEncoding1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set characterEncoding(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setCharacterEncoding_1, value?._id ?? ffi.nullptr);
  }

  NSString? get version {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_version1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set version(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setVersion_1, value?._id ?? ffi.nullptr);
  }

  bool get standalone {
    return _lib._objc_msgSend_12(_id, _lib._sel_isStandalone1);
  }

  set standalone(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setStandalone_1, value);
  }

  int get documentContentKind {
    return _lib._objc_msgSend_975(_id, _lib._sel_documentContentKind1);
  }

  set documentContentKind(int value) {
    _lib._objc_msgSend_976(_id, _lib._sel_setDocumentContentKind_1, value);
  }

  NSString? get MIMEType {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_MIMEType1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set MIMEType(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setMIMEType_1, value?._id ?? ffi.nullptr);
  }

  NSXMLDTD? get DTD {
    final _ret = _lib._objc_msgSend_986(_id, _lib._sel_DTD1);
    return _ret.address == 0
        ? null
        : NSXMLDTD._(_ret, _lib, retain: true, release: true);
  }

  set DTD(NSXMLDTD? value) {
    _lib._objc_msgSend_987(_id, _lib._sel_setDTD_1, value?._id ?? ffi.nullptr);
  }

  void setRootElement_(NSXMLElement? root) {
    return _lib._objc_msgSend_988(
        _id, _lib._sel_setRootElement_1, root?._id ?? ffi.nullptr);
  }

  NSXMLElement rootElement() {
    final _ret = _lib._objc_msgSend_989(_id, _lib._sel_rootElement1);
    return NSXMLElement._(_ret, _lib, retain: true, release: true);
  }

  void insertChild_atIndex_(NSXMLNode? child, int index) {
    return _lib._objc_msgSend_977(
        _id, _lib._sel_insertChild_atIndex_1, child?._id ?? ffi.nullptr, index);
  }

  void insertChildren_atIndex_(NSArray? children, int index) {
    return _lib._objc_msgSend_978(_id, _lib._sel_insertChildren_atIndex_1,
        children?._id ?? ffi.nullptr, index);
  }

  void removeChildAtIndex_(int index) {
    return _lib._objc_msgSend_410(_id, _lib._sel_removeChildAtIndex_1, index);
  }

  void setChildren_(NSArray? children) {
    return _lib._objc_msgSend_412(
        _id, _lib._sel_setChildren_1, children?._id ?? ffi.nullptr);
  }

  void addChild_(NSXMLNode? child) {
    return _lib._objc_msgSend_979(
        _id, _lib._sel_addChild_1, child?._id ?? ffi.nullptr);
  }

  void replaceChildAtIndex_withNode_(int index, NSXMLNode? node) {
    return _lib._objc_msgSend_980(_id, _lib._sel_replaceChildAtIndex_withNode_1,
        index, node?._id ?? ffi.nullptr);
  }

  NSData? get XMLData {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_XMLData1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  NSData XMLDataWithOptions_(int options) {
    final _ret =
        _lib._objc_msgSend_990(_id, _lib._sel_XMLDataWithOptions_1, options);
    return NSData._(_ret, _lib, retain: true, release: true);
  }

  NSObject objectByApplyingXSLT_arguments_error_(NSData? xslt,
      NSDictionary? arguments, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_991(
        _id,
        _lib._sel_objectByApplyingXSLT_arguments_error_1,
        xslt?._id ?? ffi.nullptr,
        arguments?._id ?? ffi.nullptr,
        error);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject objectByApplyingXSLTString_arguments_error_(NSString? xslt,
      NSDictionary? arguments, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_992(
        _id,
        _lib._sel_objectByApplyingXSLTString_arguments_error_1,
        xslt?._id ?? ffi.nullptr,
        arguments?._id ?? ffi.nullptr,
        error);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  NSObject objectByApplyingXSLTAtURL_arguments_error_(NSURL? xsltURL,
      NSDictionary? argument, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_993(
        _id,
        _lib._sel_objectByApplyingXSLTAtURL_arguments_error_1,
        xsltURL?._id ?? ffi.nullptr,
        argument?._id ?? ffi.nullptr,
        error);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  bool validateAndReturnError_(ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    return _lib._objc_msgSend_219(
        _id, _lib._sel_validateAndReturnError_1, error);
  }

  static NSObject document(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLDocument1, _lib._sel_document1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject documentWithRootElement_(
      AVFAudio _lib, NSXMLElement? element) {
    final _ret = _lib._objc_msgSend_968(_lib._class_NSXMLDocument1,
        _lib._sel_documentWithRootElement_1, element?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDocument1,
        _lib._sel_elementWithName_1, name?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_URI_(
      AVFAudio _lib, NSString? name, NSString? URI) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDocument1,
        _lib._sel_elementWithName_URI_1,
        name?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? string) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDocument1,
        _lib._sel_elementWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_children_attributes_(
      AVFAudio _lib, NSString? name, NSArray? children, NSArray? attributes) {
    final _ret = _lib._objc_msgSend_969(
        _lib._class_NSXMLDocument1,
        _lib._sel_elementWithName_children_attributes_1,
        name?._id ?? ffi.nullptr,
        children?._id ?? ffi.nullptr,
        attributes?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject attributeWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDocument1,
        _lib._sel_attributeWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject attributeWithName_URI_stringValue_(
      AVFAudio _lib, NSString? name, NSString? URI, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_26(
        _lib._class_NSXMLDocument1,
        _lib._sel_attributeWithName_URI_stringValue_1,
        name?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject namespaceWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDocument1,
        _lib._sel_namespaceWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject processingInstructionWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDocument1,
        _lib._sel_processingInstructionWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject commentWithStringValue_(
      AVFAudio _lib, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDocument1,
        _lib._sel_commentWithStringValue_1, stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject textWithStringValue_(AVFAudio _lib, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDocument1,
        _lib._sel_textWithStringValue_1, stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject DTDNodeWithXMLString_(AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDocument1,
        _lib._sel_DTDNodeWithXMLString_1, string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSString localNameForName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSXMLDocument1,
        _lib._sel_localNameForName_1, name?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString prefixForName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSXMLDocument1,
        _lib._sel_prefixForName_1, name?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSXMLNode predefinedNamespaceForPrefix_(
      AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_983(_lib._class_NSXMLDocument1,
        _lib._sel_predefinedNamespaceForPrefix_1, name?._id ?? ffi.nullptr);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  static NSXMLDocument new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLDocument1, _lib._sel_new1);
    return NSXMLDocument._(_ret, _lib, retain: false, release: true);
  }

  static NSXMLDocument alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLDocument1, _lib._sel_alloc1);
    return NSXMLDocument._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSXMLDocument1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSXMLDocument1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLDocument1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLDocument1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSXMLDocument1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSXMLDocument1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSXMLDocument1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSXMLDocument1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSXMLDocument1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSXMLDocumentContentKind {
  static const int NSXMLDocumentXMLKind = 0;
  static const int NSXMLDocumentXHTMLKind = 1;
  static const int NSXMLDocumentHTMLKind = 2;
  static const int NSXMLDocumentTextKind = 3;
}

class NSXMLDTD extends NSXMLNode {
  NSXMLDTD._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSXMLDTD] that points to the same underlying object as [other].
  static NSXMLDTD castFrom<T extends _ObjCWrapper>(T other) {
    return NSXMLDTD._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSXMLDTD] that wraps the given raw object pointer.
  static NSXMLDTD castFromPointer(AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSXMLDTD._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSXMLDTD].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSXMLDTD1);
  }

  @override
  NSXMLDTD init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSXMLDTD._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSXMLDTD initWithKind_options_(int kind, int options) {
    final _ret = _lib._objc_msgSend_967(
        _id, _lib._sel_initWithKind_options_1, kind, options);
    return NSXMLDTD._(_ret, _lib, retain: true, release: true);
  }

  NSXMLDTD initWithContentsOfURL_options_error_(
      NSURL? url, int mask, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_973(
        _id,
        _lib._sel_initWithContentsOfURL_options_error_1,
        url?._id ?? ffi.nullptr,
        mask,
        error);
    return NSXMLDTD._(_ret, _lib, retain: true, release: true);
  }

  NSXMLDTD initWithData_options_error_(
      NSData? data, int mask, ffi.Pointer<ffi.Pointer<ObjCObject>> error) {
    final _ret = _lib._objc_msgSend_974(
        _id,
        _lib._sel_initWithData_options_error_1,
        data?._id ?? ffi.nullptr,
        mask,
        error);
    return NSXMLDTD._(_ret, _lib, retain: true, release: true);
  }

  NSString? get publicID {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_publicID1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set publicID(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPublicID_1, value?._id ?? ffi.nullptr);
  }

  NSString? get systemID {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_systemID1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set systemID(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setSystemID_1, value?._id ?? ffi.nullptr);
  }

  void insertChild_atIndex_(NSXMLNode? child, int index) {
    return _lib._objc_msgSend_977(
        _id, _lib._sel_insertChild_atIndex_1, child?._id ?? ffi.nullptr, index);
  }

  void insertChildren_atIndex_(NSArray? children, int index) {
    return _lib._objc_msgSend_978(_id, _lib._sel_insertChildren_atIndex_1,
        children?._id ?? ffi.nullptr, index);
  }

  void removeChildAtIndex_(int index) {
    return _lib._objc_msgSend_410(_id, _lib._sel_removeChildAtIndex_1, index);
  }

  void setChildren_(NSArray? children) {
    return _lib._objc_msgSend_412(
        _id, _lib._sel_setChildren_1, children?._id ?? ffi.nullptr);
  }

  void addChild_(NSXMLNode? child) {
    return _lib._objc_msgSend_979(
        _id, _lib._sel_addChild_1, child?._id ?? ffi.nullptr);
  }

  void replaceChildAtIndex_withNode_(int index, NSXMLNode? node) {
    return _lib._objc_msgSend_980(_id, _lib._sel_replaceChildAtIndex_withNode_1,
        index, node?._id ?? ffi.nullptr);
  }

  NSXMLDTDNode entityDeclarationForName_(NSString? name) {
    final _ret = _lib._objc_msgSend_984(
        _id, _lib._sel_entityDeclarationForName_1, name?._id ?? ffi.nullptr);
    return NSXMLDTDNode._(_ret, _lib, retain: true, release: true);
  }

  NSXMLDTDNode notationDeclarationForName_(NSString? name) {
    final _ret = _lib._objc_msgSend_984(
        _id, _lib._sel_notationDeclarationForName_1, name?._id ?? ffi.nullptr);
    return NSXMLDTDNode._(_ret, _lib, retain: true, release: true);
  }

  NSXMLDTDNode elementDeclarationForName_(NSString? name) {
    final _ret = _lib._objc_msgSend_984(
        _id, _lib._sel_elementDeclarationForName_1, name?._id ?? ffi.nullptr);
    return NSXMLDTDNode._(_ret, _lib, retain: true, release: true);
  }

  NSXMLDTDNode attributeDeclarationForName_elementName_(
      NSString? name, NSString? elementName) {
    final _ret = _lib._objc_msgSend_985(
        _id,
        _lib._sel_attributeDeclarationForName_elementName_1,
        name?._id ?? ffi.nullptr,
        elementName?._id ?? ffi.nullptr);
    return NSXMLDTDNode._(_ret, _lib, retain: true, release: true);
  }

  static NSXMLDTDNode predefinedEntityDeclarationForName_(
      AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_984(
        _lib._class_NSXMLDTD1,
        _lib._sel_predefinedEntityDeclarationForName_1,
        name?._id ?? ffi.nullptr);
    return NSXMLDTDNode._(_ret, _lib, retain: true, release: true);
  }

  static NSObject document(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLDTD1, _lib._sel_document1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject documentWithRootElement_(
      AVFAudio _lib, NSXMLElement? element) {
    final _ret = _lib._objc_msgSend_968(_lib._class_NSXMLDTD1,
        _lib._sel_documentWithRootElement_1, element?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDTD1,
        _lib._sel_elementWithName_1, name?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_URI_(
      AVFAudio _lib, NSString? name, NSString? URI) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDTD1,
        _lib._sel_elementWithName_URI_1,
        name?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? string) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDTD1,
        _lib._sel_elementWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_children_attributes_(
      AVFAudio _lib, NSString? name, NSArray? children, NSArray? attributes) {
    final _ret = _lib._objc_msgSend_969(
        _lib._class_NSXMLDTD1,
        _lib._sel_elementWithName_children_attributes_1,
        name?._id ?? ffi.nullptr,
        children?._id ?? ffi.nullptr,
        attributes?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject attributeWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDTD1,
        _lib._sel_attributeWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject attributeWithName_URI_stringValue_(
      AVFAudio _lib, NSString? name, NSString? URI, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_26(
        _lib._class_NSXMLDTD1,
        _lib._sel_attributeWithName_URI_stringValue_1,
        name?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject namespaceWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDTD1,
        _lib._sel_namespaceWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject processingInstructionWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDTD1,
        _lib._sel_processingInstructionWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject commentWithStringValue_(
      AVFAudio _lib, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDTD1,
        _lib._sel_commentWithStringValue_1, stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject textWithStringValue_(AVFAudio _lib, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDTD1,
        _lib._sel_textWithStringValue_1, stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject DTDNodeWithXMLString_(AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDTD1,
        _lib._sel_DTDNodeWithXMLString_1, string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSString localNameForName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSXMLDTD1,
        _lib._sel_localNameForName_1, name?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString prefixForName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSXMLDTD1,
        _lib._sel_prefixForName_1, name?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSXMLNode predefinedNamespaceForPrefix_(
      AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_983(_lib._class_NSXMLDTD1,
        _lib._sel_predefinedNamespaceForPrefix_1, name?._id ?? ffi.nullptr);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  static NSXMLDTD new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSXMLDTD1, _lib._sel_new1);
    return NSXMLDTD._(_ret, _lib, retain: false, release: true);
  }

  static NSXMLDTD alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(_lib._class_NSXMLDTD1, _lib._sel_alloc1);
    return NSXMLDTD._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSXMLDTD1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSXMLDTD1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLDTD1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLDTD1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSXMLDTD1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSXMLDTD1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSXMLDTD1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSXMLDTD1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSXMLDTD1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class NSXMLDTDNode extends NSXMLNode {
  NSXMLDTDNode._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [NSXMLDTDNode] that points to the same underlying object as [other].
  static NSXMLDTDNode castFrom<T extends _ObjCWrapper>(T other) {
    return NSXMLDTDNode._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [NSXMLDTDNode] that wraps the given raw object pointer.
  static NSXMLDTDNode castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return NSXMLDTDNode._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [NSXMLDTDNode].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_NSXMLDTDNode1);
  }

  NSXMLDTDNode initWithXMLString_(NSString? string) {
    final _ret = _lib._objc_msgSend_30(
        _id, _lib._sel_initWithXMLString_1, string?._id ?? ffi.nullptr);
    return NSXMLDTDNode._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSXMLDTDNode initWithKind_options_(int kind, int options) {
    final _ret = _lib._objc_msgSend_967(
        _id, _lib._sel_initWithKind_options_1, kind, options);
    return NSXMLDTDNode._(_ret, _lib, retain: true, release: true);
  }

  @override
  NSXMLDTDNode init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return NSXMLDTDNode._(_ret, _lib, retain: true, release: true);
  }

  int get DTDKind {
    return _lib._objc_msgSend_981(_id, _lib._sel_DTDKind1);
  }

  set DTDKind(int value) {
    _lib._objc_msgSend_982(_id, _lib._sel_setDTDKind_1, value);
  }

  bool get external1 {
    return _lib._objc_msgSend_12(_id, _lib._sel_isExternal1);
  }

  NSString? get publicID {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_publicID1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set publicID(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setPublicID_1, value?._id ?? ffi.nullptr);
  }

  NSString? get systemID {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_systemID1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set systemID(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setSystemID_1, value?._id ?? ffi.nullptr);
  }

  NSString? get notationName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_notationName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set notationName(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setNotationName_1, value?._id ?? ffi.nullptr);
  }

  static NSObject document(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLDTDNode1, _lib._sel_document1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject documentWithRootElement_(
      AVFAudio _lib, NSXMLElement? element) {
    final _ret = _lib._objc_msgSend_968(_lib._class_NSXMLDTDNode1,
        _lib._sel_documentWithRootElement_1, element?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDTDNode1,
        _lib._sel_elementWithName_1, name?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_URI_(
      AVFAudio _lib, NSString? name, NSString? URI) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDTDNode1,
        _lib._sel_elementWithName_URI_1,
        name?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? string) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDTDNode1,
        _lib._sel_elementWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject elementWithName_children_attributes_(
      AVFAudio _lib, NSString? name, NSArray? children, NSArray? attributes) {
    final _ret = _lib._objc_msgSend_969(
        _lib._class_NSXMLDTDNode1,
        _lib._sel_elementWithName_children_attributes_1,
        name?._id ?? ffi.nullptr,
        children?._id ?? ffi.nullptr,
        attributes?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject attributeWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDTDNode1,
        _lib._sel_attributeWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject attributeWithName_URI_stringValue_(
      AVFAudio _lib, NSString? name, NSString? URI, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_26(
        _lib._class_NSXMLDTDNode1,
        _lib._sel_attributeWithName_URI_stringValue_1,
        name?._id ?? ffi.nullptr,
        URI?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject namespaceWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDTDNode1,
        _lib._sel_namespaceWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject processingInstructionWithName_stringValue_(
      AVFAudio _lib, NSString? name, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_159(
        _lib._class_NSXMLDTDNode1,
        _lib._sel_processingInstructionWithName_stringValue_1,
        name?._id ?? ffi.nullptr,
        stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject commentWithStringValue_(
      AVFAudio _lib, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDTDNode1,
        _lib._sel_commentWithStringValue_1, stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject textWithStringValue_(AVFAudio _lib, NSString? stringValue) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDTDNode1,
        _lib._sel_textWithStringValue_1, stringValue?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSObject DTDNodeWithXMLString_(AVFAudio _lib, NSString? string) {
    final _ret = _lib._objc_msgSend_30(_lib._class_NSXMLDTDNode1,
        _lib._sel_DTDNodeWithXMLString_1, string?._id ?? ffi.nullptr);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }

  static NSString localNameForName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSXMLDTDNode1,
        _lib._sel_localNameForName_1, name?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSString prefixForName_(AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_64(_lib._class_NSXMLDTDNode1,
        _lib._sel_prefixForName_1, name?._id ?? ffi.nullptr);
    return NSString._(_ret, _lib, retain: true, release: true);
  }

  static NSXMLNode predefinedNamespaceForPrefix_(
      AVFAudio _lib, NSString? name) {
    final _ret = _lib._objc_msgSend_983(_lib._class_NSXMLDTDNode1,
        _lib._sel_predefinedNamespaceForPrefix_1, name?._id ?? ffi.nullptr);
    return NSXMLNode._(_ret, _lib, retain: true, release: true);
  }

  static NSXMLDTDNode new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLDTDNode1, _lib._sel_new1);
    return NSXMLDTDNode._(_ret, _lib, retain: false, release: true);
  }

  static NSXMLDTDNode alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_NSXMLDTDNode1, _lib._sel_alloc1);
    return NSXMLDTDNode._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_NSXMLDTDNode1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_NSXMLDTDNode1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLDTDNode1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_NSXMLDTDNode1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_NSXMLDTDNode1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_NSXMLDTDNode1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_NSXMLDTDNode1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_NSXMLDTDNode1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_NSXMLDTDNode1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class NSXMLDTDNodeKind {
  static const int NSXMLEntityGeneralKind = 1;
  static const int NSXMLEntityParsedKind = 2;
  static const int NSXMLEntityUnparsedKind = 3;
  static const int NSXMLEntityParameterKind = 4;
  static const int NSXMLEntityPredefined = 5;
  static const int NSXMLAttributeCDATAKind = 6;
  static const int NSXMLAttributeIDKind = 7;
  static const int NSXMLAttributeIDRefKind = 8;
  static const int NSXMLAttributeIDRefsKind = 9;
  static const int NSXMLAttributeEntityKind = 10;
  static const int NSXMLAttributeEntitiesKind = 11;
  static const int NSXMLAttributeNMTokenKind = 12;
  static const int NSXMLAttributeNMTokensKind = 13;
  static const int NSXMLAttributeEnumerationKind = 14;
  static const int NSXMLAttributeNotationKind = 15;
  static const int NSXMLElementDeclarationUndefinedKind = 16;
  static const int NSXMLElementDeclarationEmptyKind = 17;
  static const int NSXMLElementDeclarationAnyKind = 18;
  static const int NSXMLElementDeclarationMixedKind = 19;
  static const int NSXMLElementDeclarationElementKind = 20;
}

class AVAudioSession extends NSObject {
  AVAudioSession._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [AVAudioSession] that points to the same underlying object as [other].
  static AVAudioSession castFrom<T extends _ObjCWrapper>(T other) {
    return AVAudioSession._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [AVAudioSession] that wraps the given raw object pointer.
  static AVAudioSession castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return AVAudioSession._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [AVAudioSession].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_AVAudioSession1);
  }

  static AVAudioSession sharedInstance(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_1001(
        _lib._class_AVAudioSession1, _lib._sel_sharedInstance1);
    return AVAudioSession._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get availableCategories {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_availableCategories1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  bool setCategory_error_(AVAudioSessionCategory category,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_398(
        _id, _lib._sel_setCategory_error_1, category, outError);
  }

  bool setCategory_withOptions_error_(AVAudioSessionCategory category,
      int options, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1002(_id,
        _lib._sel_setCategory_withOptions_error_1, category, options, outError);
  }

  bool setCategory_mode_options_error_(
      AVAudioSessionCategory category,
      AVAudioSessionMode mode,
      int options,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1003(
        _id,
        _lib._sel_setCategory_mode_options_error_1,
        category,
        mode,
        options,
        outError);
  }

  bool setCategory_mode_routeSharingPolicy_options_error_(
      AVAudioSessionCategory category,
      AVAudioSessionMode mode,
      int policy,
      int options,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1004(
        _id,
        _lib._sel_setCategory_mode_routeSharingPolicy_options_error_1,
        category,
        mode,
        policy,
        options,
        outError);
  }

  AVAudioSessionCategory get category {
    return _lib._objc_msgSend_20(_id, _lib._sel_category1);
  }

  int get categoryOptions {
    return _lib._objc_msgSend_1005(_id, _lib._sel_categoryOptions1);
  }

  int get routeSharingPolicy {
    return _lib._objc_msgSend_1006(_id, _lib._sel_routeSharingPolicy1);
  }

  NSArray? get availableModes {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_availableModes1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  bool setMode_error_(
      AVAudioSessionMode mode, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_398(
        _id, _lib._sel_setMode_error_1, mode, outError);
  }

  AVAudioSessionMode get mode {
    return _lib._objc_msgSend_20(_id, _lib._sel_mode1);
  }

  bool setAllowHapticsAndSystemSoundsDuringRecording_error_(
      bool inValue, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1007(
        _id,
        _lib._sel_setAllowHapticsAndSystemSoundsDuringRecording_error_1,
        inValue,
        outError);
  }

  bool get allowHapticsAndSystemSoundsDuringRecording {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_allowHapticsAndSystemSoundsDuringRecording1);
  }

  int get recordPermission {
    return _lib._objc_msgSend_1008(_id, _lib._sel_recordPermission1);
  }

  void requestRecordPermission_(ObjCBlock31 response) {
    return _lib._objc_msgSend_1009(
        _id, _lib._sel_requestRecordPermission_1, response._id);
  }

  bool overrideOutputAudioPort_error_(
      int portOverride, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1010(
        _id, _lib._sel_overrideOutputAudioPort_error_1, portOverride, outError);
  }

  bool setPreferredInput_error_(AVAudioSessionPortDescription? inPort,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1013(_id, _lib._sel_setPreferredInput_error_1,
        inPort?._id ?? ffi.nullptr, outError);
  }

  AVAudioSessionPortDescription? get preferredInput {
    final _ret = _lib._objc_msgSend_1014(_id, _lib._sel_preferredInput1);
    return _ret.address == 0
        ? null
        : AVAudioSessionPortDescription._(_ret, _lib,
            retain: true, release: true);
  }

  bool setPrefersNoInterruptionsFromSystemAlerts_error_(
      bool inValue, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1007(
        _id,
        _lib._sel_setPrefersNoInterruptionsFromSystemAlerts_error_1,
        inValue,
        outError);
  }

  bool get prefersNoInterruptionsFromSystemAlerts {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_prefersNoInterruptionsFromSystemAlerts1);
  }

  bool setActive_error_(
      bool active, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1007(
        _id, _lib._sel_setActive_error_1, active, outError);
  }

  bool setActive_withOptions_error_(
      bool active, int options, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1015(_id, _lib._sel_setActive_withOptions_error_1,
        active, options, outError);
  }

  void activateWithOptions_completionHandler_(
      int options, ObjCBlock44 handler) {
    return _lib._objc_msgSend_1016(
        _id,
        _lib._sel_activateWithOptions_completionHandler_1,
        options,
        handler._id);
  }

  bool setPreferredSampleRate_error_(
      double sampleRate, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1017(
        _id, _lib._sel_setPreferredSampleRate_error_1, sampleRate, outError);
  }

  double get preferredSampleRate {
    return _lib._objc_msgSend_149(_id, _lib._sel_preferredSampleRate1);
  }

  bool setPreferredIOBufferDuration_error_(
      double duration, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1017(_id,
        _lib._sel_setPreferredIOBufferDuration_error_1, duration, outError);
  }

  double get preferredIOBufferDuration {
    return _lib._objc_msgSend_149(_id, _lib._sel_preferredIOBufferDuration1);
  }

  bool setPreferredInputNumberOfChannels_error_(
      int count, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1018(_id,
        _lib._sel_setPreferredInputNumberOfChannels_error_1, count, outError);
  }

  int get preferredInputNumberOfChannels {
    return _lib._objc_msgSend_78(
        _id, _lib._sel_preferredInputNumberOfChannels1);
  }

  bool setPreferredOutputNumberOfChannels_error_(
      int count, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1018(_id,
        _lib._sel_setPreferredOutputNumberOfChannels_error_1, count, outError);
  }

  int get preferredOutputNumberOfChannels {
    return _lib._objc_msgSend_78(
        _id, _lib._sel_preferredOutputNumberOfChannels1);
  }

  bool setPreferredInputOrientation_error_(
      int orientation, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1019(_id,
        _lib._sel_setPreferredInputOrientation_error_1, orientation, outError);
  }

  int get preferredInputOrientation {
    return _lib._objc_msgSend_1020(_id, _lib._sel_preferredInputOrientation1);
  }

  int get inputOrientation {
    return _lib._objc_msgSend_1020(_id, _lib._sel_inputOrientation1);
  }

  int get maximumInputNumberOfChannels {
    return _lib._objc_msgSend_78(_id, _lib._sel_maximumInputNumberOfChannels1);
  }

  int get maximumOutputNumberOfChannels {
    return _lib._objc_msgSend_78(_id, _lib._sel_maximumOutputNumberOfChannels1);
  }

  bool setInputGain_error_(
      double gain, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1021(
        _id, _lib._sel_setInputGain_error_1, gain, outError);
  }

  double get inputGain {
    return _lib._objc_msgSend_215(_id, _lib._sel_inputGain1);
  }

  bool get inputGainSettable {
    return _lib._objc_msgSend_12(_id, _lib._sel_isInputGainSettable1);
  }

  bool get inputAvailable {
    return _lib._objc_msgSend_12(_id, _lib._sel_isInputAvailable1);
  }

  NSArray? get inputDataSources {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_inputDataSources1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  AVAudioSessionDataSourceDescription? get inputDataSource {
    final _ret = _lib._objc_msgSend_1011(_id, _lib._sel_inputDataSource1);
    return _ret.address == 0
        ? null
        : AVAudioSessionDataSourceDescription._(_ret, _lib,
            retain: true, release: true);
  }

  bool setInputDataSource_error_(
      AVAudioSessionDataSourceDescription? dataSource,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1012(_id, _lib._sel_setInputDataSource_error_1,
        dataSource?._id ?? ffi.nullptr, outError);
  }

  NSArray? get outputDataSources {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_outputDataSources1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  AVAudioSessionDataSourceDescription? get outputDataSource {
    final _ret = _lib._objc_msgSend_1011(_id, _lib._sel_outputDataSource1);
    return _ret.address == 0
        ? null
        : AVAudioSessionDataSourceDescription._(_ret, _lib,
            retain: true, release: true);
  }

  bool setOutputDataSource_error_(
      AVAudioSessionDataSourceDescription? dataSource,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1012(_id, _lib._sel_setOutputDataSource_error_1,
        dataSource?._id ?? ffi.nullptr, outError);
  }

  double get sampleRate {
    return _lib._objc_msgSend_149(_id, _lib._sel_sampleRate1);
  }

  int get inputNumberOfChannels {
    return _lib._objc_msgSend_78(_id, _lib._sel_inputNumberOfChannels1);
  }

  int get outputNumberOfChannels {
    return _lib._objc_msgSend_78(_id, _lib._sel_outputNumberOfChannels1);
  }

  double get inputLatency {
    return _lib._objc_msgSend_149(_id, _lib._sel_inputLatency1);
  }

  double get outputLatency {
    return _lib._objc_msgSend_149(_id, _lib._sel_outputLatency1);
  }

  double get IOBufferDuration {
    return _lib._objc_msgSend_149(_id, _lib._sel_IOBufferDuration1);
  }

  bool get otherAudioPlaying {
    return _lib._objc_msgSend_12(_id, _lib._sel_isOtherAudioPlaying1);
  }

  bool get secondaryAudioShouldBeSilencedHint {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_secondaryAudioShouldBeSilencedHint1);
  }

  double get outputVolume {
    return _lib._objc_msgSend_215(_id, _lib._sel_outputVolume1);
  }

  int get promptStyle {
    return _lib._objc_msgSend_1022(_id, _lib._sel_promptStyle1);
  }

  NSArray? get availableInputs {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_availableInputs1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  AVAudioSessionRouteDescription? get currentRoute {
    final _ret = _lib._objc_msgSend_1023(_id, _lib._sel_currentRoute1);
    return _ret.address == 0
        ? null
        : AVAudioSessionRouteDescription._(_ret, _lib,
            retain: true, release: true);
  }

  bool setAggregatedIOPreference_error_(
      int inIOType, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1024(
        _id, _lib._sel_setAggregatedIOPreference_error_1, inIOType, outError);
  }

  bool setSupportsMultichannelContent_error_(
      bool inValue, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1007(_id,
        _lib._sel_setSupportsMultichannelContent_error_1, inValue, outError);
  }

  bool get supportsMultichannelContent {
    return _lib._objc_msgSend_12(_id, _lib._sel_supportsMultichannelContent1);
  }

  NSObject? get delegate {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_delegate1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  set delegate(NSObject? value) {
    _lib._objc_msgSend_368(
        _id, _lib._sel_setDelegate_1, value?._id ?? ffi.nullptr);
  }

  @override
  AVAudioSession init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return AVAudioSession._(_ret, _lib, retain: true, release: true);
  }

  bool setActive_withFlags_error_(
      bool active, int flags, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1025(
        _id, _lib._sel_setActive_withFlags_error_1, active, flags, outError);
  }

  bool get inputIsAvailable {
    return _lib._objc_msgSend_12(_id, _lib._sel_inputIsAvailable1);
  }

  double get currentHardwareSampleRate {
    return _lib._objc_msgSend_149(_id, _lib._sel_currentHardwareSampleRate1);
  }

  int get currentHardwareInputNumberOfChannels {
    return _lib._objc_msgSend_78(
        _id, _lib._sel_currentHardwareInputNumberOfChannels1);
  }

  int get currentHardwareOutputNumberOfChannels {
    return _lib._objc_msgSend_78(
        _id, _lib._sel_currentHardwareOutputNumberOfChannels1);
  }

  bool setPreferredHardwareSampleRate_error_(
      double sampleRate, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1017(_id,
        _lib._sel_setPreferredHardwareSampleRate_error_1, sampleRate, outError);
  }

  double get preferredHardwareSampleRate {
    return _lib._objc_msgSend_149(_id, _lib._sel_preferredHardwareSampleRate1);
  }

  static AVAudioSession new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_AVAudioSession1, _lib._sel_new1);
    return AVAudioSession._(_ret, _lib, retain: false, release: true);
  }

  static AVAudioSession alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_AVAudioSession1, _lib._sel_alloc1);
    return AVAudioSession._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_AVAudioSession1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_AVAudioSession1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_AVAudioSession1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_AVAudioSession1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_AVAudioSession1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_AVAudioSession1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_AVAudioSession1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_AVAudioSession1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioSession1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef AVAudioSessionCategory = ffi.Pointer<ObjCObject>;

abstract class AVAudioSessionCategoryOptions {
  static const int AVAudioSessionCategoryOptionMixWithOthers = 1;
  static const int AVAudioSessionCategoryOptionDuckOthers = 2;
  static const int AVAudioSessionCategoryOptionAllowBluetooth = 4;
  static const int AVAudioSessionCategoryOptionDefaultToSpeaker = 8;
  static const int
      AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers = 17;
  static const int AVAudioSessionCategoryOptionAllowBluetoothA2DP = 32;
  static const int AVAudioSessionCategoryOptionAllowAirPlay = 64;
  static const int
      AVAudioSessionCategoryOptionOverrideMutedMicrophoneInterruption = 128;
}

typedef AVAudioSessionMode = ffi.Pointer<ObjCObject>;

abstract class AVAudioSessionRouteSharingPolicy {
  static const int AVAudioSessionRouteSharingPolicyDefault = 0;
  static const int AVAudioSessionRouteSharingPolicyLongFormAudio = 1;
  static const int AVAudioSessionRouteSharingPolicyLongForm = 1;
  static const int AVAudioSessionRouteSharingPolicyIndependent = 2;
  static const int AVAudioSessionRouteSharingPolicyLongFormVideo = 3;
}

abstract class AVAudioSessionRecordPermission {
  static const int AVAudioSessionRecordPermissionUndetermined = 1970168948;
  static const int AVAudioSessionRecordPermissionDenied = 1684369017;
  static const int AVAudioSessionRecordPermissionGranted = 1735552628;
}

abstract class AVAudioSessionPortOverride {
  static const int AVAudioSessionPortOverrideNone = 0;
  static const int AVAudioSessionPortOverrideSpeaker = 1936747378;
}

class AVAudioSessionPortDescription extends NSObject {
  AVAudioSessionPortDescription._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [AVAudioSessionPortDescription] that points to the same underlying object as [other].
  static AVAudioSessionPortDescription castFrom<T extends _ObjCWrapper>(
      T other) {
    return AVAudioSessionPortDescription._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [AVAudioSessionPortDescription] that wraps the given raw object pointer.
  static AVAudioSessionPortDescription castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return AVAudioSessionPortDescription._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [AVAudioSessionPortDescription].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_AVAudioSessionPortDescription1);
  }

  AVAudioSessionPort get portType {
    return _lib._objc_msgSend_20(_id, _lib._sel_portType1);
  }

  NSString? get portName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_portName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  NSString? get UID {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_UID1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  bool get hasHardwareVoiceCallProcessing {
    return _lib._objc_msgSend_12(
        _id, _lib._sel_hasHardwareVoiceCallProcessing1);
  }

  bool get spatialAudioEnabled {
    return _lib._objc_msgSend_12(_id, _lib._sel_isSpatialAudioEnabled1);
  }

  NSArray? get channels {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_channels1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get dataSources {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_dataSources1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  AVAudioSessionDataSourceDescription? get selectedDataSource {
    final _ret = _lib._objc_msgSend_1011(_id, _lib._sel_selectedDataSource1);
    return _ret.address == 0
        ? null
        : AVAudioSessionDataSourceDescription._(_ret, _lib,
            retain: true, release: true);
  }

  AVAudioSessionDataSourceDescription? get preferredDataSource {
    final _ret = _lib._objc_msgSend_1011(_id, _lib._sel_preferredDataSource1);
    return _ret.address == 0
        ? null
        : AVAudioSessionDataSourceDescription._(_ret, _lib,
            retain: true, release: true);
  }

  bool setPreferredDataSource_error_(
      AVAudioSessionDataSourceDescription? dataSource,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_1012(
        _id,
        _lib._sel_setPreferredDataSource_error_1,
        dataSource?._id ?? ffi.nullptr,
        outError);
  }

  static AVAudioSessionPortDescription new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioSessionPortDescription1, _lib._sel_new1);
    return AVAudioSessionPortDescription._(_ret, _lib,
        retain: false, release: true);
  }

  static AVAudioSessionPortDescription alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioSessionPortDescription1, _lib._sel_alloc1);
    return AVAudioSessionPortDescription._(_ret, _lib,
        retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_AVAudioSessionPortDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_AVAudioSessionPortDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_AVAudioSessionPortDescription1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_AVAudioSessionPortDescription1,
        _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_AVAudioSessionPortDescription1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_AVAudioSessionPortDescription1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_AVAudioSessionPortDescription1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_AVAudioSessionPortDescription1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioSessionPortDescription1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef AVAudioSessionPort = ffi.Pointer<ObjCObject>;

class AVAudioSessionDataSourceDescription extends NSObject {
  AVAudioSessionDataSourceDescription._(
      ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [AVAudioSessionDataSourceDescription] that points to the same underlying object as [other].
  static AVAudioSessionDataSourceDescription castFrom<T extends _ObjCWrapper>(
      T other) {
    return AVAudioSessionDataSourceDescription._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [AVAudioSessionDataSourceDescription] that wraps the given raw object pointer.
  static AVAudioSessionDataSourceDescription castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return AVAudioSessionDataSourceDescription._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [AVAudioSessionDataSourceDescription].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_AVAudioSessionDataSourceDescription1);
  }

  NSNumber? get dataSourceID {
    final _ret = _lib._objc_msgSend_192(_id, _lib._sel_dataSourceID1);
    return _ret.address == 0
        ? null
        : NSNumber._(_ret, _lib, retain: true, release: true);
  }

  NSString? get dataSourceName {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_dataSourceName1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  AVAudioSessionLocation get location {
    return _lib._objc_msgSend_20(_id, _lib._sel_location1);
  }

  AVAudioSessionOrientation get orientation {
    return _lib._objc_msgSend_20(_id, _lib._sel_orientation1);
  }

  NSArray? get supportedPolarPatterns {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_supportedPolarPatterns1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  AVAudioSessionPolarPattern get selectedPolarPattern {
    return _lib._objc_msgSend_20(_id, _lib._sel_selectedPolarPattern1);
  }

  AVAudioSessionPolarPattern get preferredPolarPattern {
    return _lib._objc_msgSend_20(_id, _lib._sel_preferredPolarPattern1);
  }

  bool setPreferredPolarPattern_error_(AVAudioSessionPolarPattern pattern,
      ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    return _lib._objc_msgSend_398(
        _id, _lib._sel_setPreferredPolarPattern_error_1, pattern, outError);
  }

  static AVAudioSessionDataSourceDescription new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioSessionDataSourceDescription1, _lib._sel_new1);
    return AVAudioSessionDataSourceDescription._(_ret, _lib,
        retain: false, release: true);
  }

  static AVAudioSessionDataSourceDescription alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioSessionDataSourceDescription1, _lib._sel_alloc1);
    return AVAudioSessionDataSourceDescription._(_ret, _lib,
        retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_AVAudioSessionDataSourceDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(
        _lib._class_AVAudioSessionDataSourceDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1,
        aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_AVAudioSessionDataSourceDescription1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_AVAudioSessionDataSourceDescription1,
        _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_AVAudioSessionDataSourceDescription1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_AVAudioSessionDataSourceDescription1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_AVAudioSessionDataSourceDescription1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_AVAudioSessionDataSourceDescription1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioSessionDataSourceDescription1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef AVAudioSessionLocation = ffi.Pointer<ObjCObject>;
typedef AVAudioSessionOrientation = ffi.Pointer<ObjCObject>;
typedef AVAudioSessionPolarPattern = ffi.Pointer<ObjCObject>;

abstract class AVAudioSessionSetActiveOptions {
  static const int AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation = 1;
}

abstract class AVAudioSessionActivationOptions {
  static const int AVAudioSessionActivationOptionNone = 0;
}

void _ObjCBlock44_fnPtrTrampoline(
    ffi.Pointer<_ObjCBlock> block, bool arg0, ffi.Pointer<ObjCObject> arg1) {
  return block.ref.target
      .cast<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Bool arg0, ffi.Pointer<ObjCObject> arg1)>>()
      .asFunction<
          void Function(bool arg0, ffi.Pointer<ObjCObject> arg1)>()(arg0, arg1);
}

final _ObjCBlock44_closureRegistry = <int, Function>{};
int _ObjCBlock44_closureRegistryIndex = 0;
ffi.Pointer<ffi.Void> _ObjCBlock44_registerClosure(Function fn) {
  final id = ++_ObjCBlock44_closureRegistryIndex;
  _ObjCBlock44_closureRegistry[id] = fn;
  return ffi.Pointer<ffi.Void>.fromAddress(id);
}

void _ObjCBlock44_closureTrampoline(
    ffi.Pointer<_ObjCBlock> block, bool arg0, ffi.Pointer<ObjCObject> arg1) {
  return _ObjCBlock44_closureRegistry[block.ref.target.address]!(arg0, arg1);
}

class ObjCBlock44 extends _ObjCBlockBase {
  ObjCBlock44._(ffi.Pointer<_ObjCBlock> id, AVFAudio lib)
      : super._(id, lib, retain: false, release: true);

  /// Creates a block from a C function pointer.
  ObjCBlock44.fromFunctionPointer(
      AVFAudio lib,
      ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Void Function(
                      ffi.Bool arg0, ffi.Pointer<ObjCObject> arg1)>>
          ptr)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Bool arg0, ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock44_fnPtrTrampoline)
                    .cast(),
                ptr.cast()),
            lib);

  /// Creates a block from a Dart function.
  ObjCBlock44.fromFunction(
      AVFAudio lib, void Function(bool arg0, ffi.Pointer<ObjCObject> arg1) fn)
      : this._(
            lib._newBlock1(
                ffi.Pointer.fromFunction<
                            ffi.Void Function(ffi.Pointer<_ObjCBlock> block,
                                ffi.Bool arg0, ffi.Pointer<ObjCObject> arg1)>(
                        _ObjCBlock44_closureTrampoline)
                    .cast(),
                _ObjCBlock44_registerClosure(fn)),
            lib);
  void call(bool arg0, ffi.Pointer<ObjCObject> arg1) {
    return _id.ref.invoke
        .cast<
            ffi.NativeFunction<
                ffi.Void Function(ffi.Pointer<_ObjCBlock> block, ffi.Bool arg0,
                    ffi.Pointer<ObjCObject> arg1)>>()
        .asFunction<
            void Function(ffi.Pointer<_ObjCBlock> block, bool arg0,
                ffi.Pointer<ObjCObject> arg1)>()(_id, arg0, arg1);
  }

  ffi.Pointer<_ObjCBlock> get pointer => _id;
}

abstract class AVAudioStereoOrientation {
  static const int AVAudioStereoOrientationNone = 0;
  static const int AVAudioStereoOrientationPortrait = 1;
  static const int AVAudioStereoOrientationPortraitUpsideDown = 2;
  static const int AVAudioStereoOrientationLandscapeRight = 3;
  static const int AVAudioStereoOrientationLandscapeLeft = 4;
}

abstract class AVAudioSessionPromptStyle {
  static const int AVAudioSessionPromptStyleNone = 1852796517;
  static const int AVAudioSessionPromptStyleShort = 1936224884;
  static const int AVAudioSessionPromptStyleNormal = 1852992876;
}

class AVAudioSessionRouteDescription extends NSObject {
  AVAudioSessionRouteDescription._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [AVAudioSessionRouteDescription] that points to the same underlying object as [other].
  static AVAudioSessionRouteDescription castFrom<T extends _ObjCWrapper>(
      T other) {
    return AVAudioSessionRouteDescription._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [AVAudioSessionRouteDescription] that wraps the given raw object pointer.
  static AVAudioSessionRouteDescription castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return AVAudioSessionRouteDescription._(other, lib,
        retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [AVAudioSessionRouteDescription].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_AVAudioSessionRouteDescription1);
  }

  NSArray? get inputs {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_inputs1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  NSArray? get outputs {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_outputs1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  static AVAudioSessionRouteDescription new1(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioSessionRouteDescription1, _lib._sel_new1);
    return AVAudioSessionRouteDescription._(_ret, _lib,
        retain: false, release: true);
  }

  static AVAudioSessionRouteDescription alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioSessionRouteDescription1, _lib._sel_alloc1);
    return AVAudioSessionRouteDescription._(_ret, _lib,
        retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_AVAudioSessionRouteDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_AVAudioSessionRouteDescription1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_AVAudioSessionRouteDescription1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_AVAudioSessionRouteDescription1,
        _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_AVAudioSessionRouteDescription1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_AVAudioSessionRouteDescription1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_AVAudioSessionRouteDescription1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_AVAudioSessionRouteDescription1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioSessionRouteDescription1,
        _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

abstract class AVAudioSessionIOType {
  static const int AVAudioSessionIOTypeNotSpecified = 0;
  static const int AVAudioSessionIOTypeAggregated = 1;
}

class AVAudioPlayer extends NSObject {
  AVAudioPlayer._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [AVAudioPlayer] that points to the same underlying object as [other].
  static AVAudioPlayer castFrom<T extends _ObjCWrapper>(T other) {
    return AVAudioPlayer._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [AVAudioPlayer] that wraps the given raw object pointer.
  static AVAudioPlayer castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return AVAudioPlayer._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [AVAudioPlayer].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_AVAudioPlayer1);
  }

  AVAudioPlayer initWithContentsOfURL_error_(
      NSURL? url, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    final _ret = _lib._objc_msgSend_734(
        _id,
        _lib._sel_initWithContentsOfURL_error_1,
        url?._id ?? ffi.nullptr,
        outError);
    return AVAudioPlayer._(_ret, _lib, retain: true, release: true);
  }

  AVAudioPlayer initWithData_error_(
      NSData? data, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    final _ret = _lib._objc_msgSend_1026(_id, _lib._sel_initWithData_error_1,
        data?._id ?? ffi.nullptr, outError);
    return AVAudioPlayer._(_ret, _lib, retain: true, release: true);
  }

  AVAudioPlayer initWithContentsOfURL_fileTypeHint_error_(NSURL? url,
      NSString? utiString, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    final _ret = _lib._objc_msgSend_1027(
        _id,
        _lib._sel_initWithContentsOfURL_fileTypeHint_error_1,
        url?._id ?? ffi.nullptr,
        utiString?._id ?? ffi.nullptr,
        outError);
    return AVAudioPlayer._(_ret, _lib, retain: true, release: true);
  }

  AVAudioPlayer initWithData_fileTypeHint_error_(NSData? data,
      NSString? utiString, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {
    final _ret = _lib._objc_msgSend_1028(
        _id,
        _lib._sel_initWithData_fileTypeHint_error_1,
        data?._id ?? ffi.nullptr,
        utiString?._id ?? ffi.nullptr,
        outError);
    return AVAudioPlayer._(_ret, _lib, retain: true, release: true);
  }

  bool prepareToPlay() {
    return _lib._objc_msgSend_12(_id, _lib._sel_prepareToPlay1);
  }

  bool play() {
    return _lib._objc_msgSend_12(_id, _lib._sel_play1);
  }

  bool playAtTime_(double time) {
    return _lib._objc_msgSend_1029(_id, _lib._sel_playAtTime_1, time);
  }

  void pause() {
    return _lib._objc_msgSend_1(_id, _lib._sel_pause1);
  }

  void stop() {
    return _lib._objc_msgSend_1(_id, _lib._sel_stop1);
  }

  bool get playing {
    return _lib._objc_msgSend_12(_id, _lib._sel_isPlaying1);
  }

  int get numberOfChannels {
    return _lib._objc_msgSend_10(_id, _lib._sel_numberOfChannels1);
  }

  double get duration {
    return _lib._objc_msgSend_149(_id, _lib._sel_duration1);
  }

  NSString? get currentDevice {
    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_currentDevice1);
    return _ret.address == 0
        ? null
        : NSString._(_ret, _lib, retain: true, release: true);
  }

  set currentDevice(NSString? value) {
    _lib._objc_msgSend_477(
        _id, _lib._sel_setCurrentDevice_1, value?._id ?? ffi.nullptr);
  }

  NSObject? get delegate {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_delegate1);
    return _ret.address == 0
        ? null
        : NSObject._(_ret, _lib, retain: true, release: true);
  }

  set delegate(NSObject? value) {
    _lib._objc_msgSend_368(
        _id, _lib._sel_setDelegate_1, value?._id ?? ffi.nullptr);
  }

  NSURL? get url {
    final _ret = _lib._objc_msgSend_40(_id, _lib._sel_url1);
    return _ret.address == 0
        ? null
        : NSURL._(_ret, _lib, retain: true, release: true);
  }

  NSData? get data {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_data1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  double get pan {
    return _lib._objc_msgSend_215(_id, _lib._sel_pan1);
  }

  set pan(double value) {
    _lib._objc_msgSend_765(_id, _lib._sel_setPan_1, value);
  }

  double get volume {
    return _lib._objc_msgSend_215(_id, _lib._sel_volume1);
  }

  set volume(double value) {
    _lib._objc_msgSend_765(_id, _lib._sel_setVolume_1, value);
  }

  void setVolume_fadeDuration_(double volume, double duration) {
    return _lib._objc_msgSend_1030(
        _id, _lib._sel_setVolume_fadeDuration_1, volume, duration);
  }

  bool get enableRate {
    return _lib._objc_msgSend_12(_id, _lib._sel_enableRate1);
  }

  set enableRate(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setEnableRate_1, value);
  }

  double get rate {
    return _lib._objc_msgSend_215(_id, _lib._sel_rate1);
  }

  set rate(double value) {
    _lib._objc_msgSend_765(_id, _lib._sel_setRate_1, value);
  }

  double get currentTime {
    return _lib._objc_msgSend_149(_id, _lib._sel_currentTime1);
  }

  set currentTime(double value) {
    _lib._objc_msgSend_474(_id, _lib._sel_setCurrentTime_1, value);
  }

  double get deviceCurrentTime {
    return _lib._objc_msgSend_149(_id, _lib._sel_deviceCurrentTime1);
  }

  int get numberOfLoops {
    return _lib._objc_msgSend_78(_id, _lib._sel_numberOfLoops1);
  }

  set numberOfLoops(int value) {
    _lib._objc_msgSend_558(_id, _lib._sel_setNumberOfLoops_1, value);
  }

  NSDictionary? get settings {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_settings1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  AVAudioFormat? get format {
    final _ret = _lib._objc_msgSend_1046(_id, _lib._sel_format1);
    return _ret.address == 0
        ? null
        : AVAudioFormat._(_ret, _lib, retain: true, release: true);
  }

  bool get meteringEnabled {
    return _lib._objc_msgSend_12(_id, _lib._sel_isMeteringEnabled1);
  }

  set meteringEnabled(bool value) {
    _lib._objc_msgSend_460(_id, _lib._sel_setMeteringEnabled_1, value);
  }

  void updateMeters() {
    return _lib._objc_msgSend_1(_id, _lib._sel_updateMeters1);
  }

  double peakPowerForChannel_(int channelNumber) {
    return _lib._objc_msgSend_1047(
        _id, _lib._sel_peakPowerForChannel_1, channelNumber);
  }

  double averagePowerForChannel_(int channelNumber) {
    return _lib._objc_msgSend_1047(
        _id, _lib._sel_averagePowerForChannel_1, channelNumber);
  }

  NSArray? get channelAssignments {
    final _ret = _lib._objc_msgSend_80(_id, _lib._sel_channelAssignments1);
    return _ret.address == 0
        ? null
        : NSArray._(_ret, _lib, retain: true, release: true);
  }

  set channelAssignments(NSArray? value) {
    _lib._objc_msgSend_696(
        _id, _lib._sel_setChannelAssignments_1, value?._id ?? ffi.nullptr);
  }

  static AVAudioPlayer new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_AVAudioPlayer1, _lib._sel_new1);
    return AVAudioPlayer._(_ret, _lib, retain: false, release: true);
  }

  static AVAudioPlayer alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_AVAudioPlayer1, _lib._sel_alloc1);
    return AVAudioPlayer._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_AVAudioPlayer1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_AVAudioPlayer1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_AVAudioPlayer1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_AVAudioPlayer1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_AVAudioPlayer1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_AVAudioPlayer1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_AVAudioPlayer1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_AVAudioPlayer1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioPlayer1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

class AVAudioFormat extends NSObject {
  AVAudioFormat._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [AVAudioFormat] that points to the same underlying object as [other].
  static AVAudioFormat castFrom<T extends _ObjCWrapper>(T other) {
    return AVAudioFormat._(other._id, other._lib, retain: true, release: true);
  }

  /// Returns a [AVAudioFormat] that wraps the given raw object pointer.
  static AVAudioFormat castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return AVAudioFormat._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [AVAudioFormat].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(
        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_AVAudioFormat1);
  }

  AVAudioFormat initWithStreamDescription_(
      ffi.Pointer<AudioStreamBasicDescription> asbd) {
    final _ret = _lib._objc_msgSend_1031(
        _id, _lib._sel_initWithStreamDescription_1, asbd);
    return AVAudioFormat._(_ret, _lib, retain: true, release: true);
  }

  AVAudioFormat initWithStreamDescription_channelLayout_(
      ffi.Pointer<AudioStreamBasicDescription> asbd,
      AVAudioChannelLayout? layout) {
    final _ret = _lib._objc_msgSend_1036(
        _id,
        _lib._sel_initWithStreamDescription_channelLayout_1,
        asbd,
        layout?._id ?? ffi.nullptr);
    return AVAudioFormat._(_ret, _lib, retain: true, release: true);
  }

  AVAudioFormat initStandardFormatWithSampleRate_channels_(
      double sampleRate, int channels) {
    final _ret = _lib._objc_msgSend_1037(
        _id,
        _lib._sel_initStandardFormatWithSampleRate_channels_1,
        sampleRate,
        channels);
    return AVAudioFormat._(_ret, _lib, retain: true, release: true);
  }

  AVAudioFormat initStandardFormatWithSampleRate_channelLayout_(
      double sampleRate, AVAudioChannelLayout? layout) {
    final _ret = _lib._objc_msgSend_1038(
        _id,
        _lib._sel_initStandardFormatWithSampleRate_channelLayout_1,
        sampleRate,
        layout?._id ?? ffi.nullptr);
    return AVAudioFormat._(_ret, _lib, retain: true, release: true);
  }

  AVAudioFormat initWithCommonFormat_sampleRate_channels_interleaved_(
      int format, double sampleRate, int channels, bool interleaved) {
    final _ret = _lib._objc_msgSend_1039(
        _id,
        _lib._sel_initWithCommonFormat_sampleRate_channels_interleaved_1,
        format,
        sampleRate,
        channels,
        interleaved);
    return AVAudioFormat._(_ret, _lib, retain: true, release: true);
  }

  AVAudioFormat initWithCommonFormat_sampleRate_interleaved_channelLayout_(
      int format,
      double sampleRate,
      bool interleaved,
      AVAudioChannelLayout? layout) {
    final _ret = _lib._objc_msgSend_1040(
        _id,
        _lib._sel_initWithCommonFormat_sampleRate_interleaved_channelLayout_1,
        format,
        sampleRate,
        interleaved,
        layout?._id ?? ffi.nullptr);
    return AVAudioFormat._(_ret, _lib, retain: true, release: true);
  }

  AVAudioFormat initWithSettings_(NSDictionary? settings) {
    final _ret = _lib._objc_msgSend_143(
        _id, _lib._sel_initWithSettings_1, settings?._id ?? ffi.nullptr);
    return AVAudioFormat._(_ret, _lib, retain: true, release: true);
  }

  AVAudioFormat initWithCMAudioFormatDescription_(
      CMAudioFormatDescriptionRef formatDescription) {
    final _ret = _lib._objc_msgSend_1041(
        _id, _lib._sel_initWithCMAudioFormatDescription_1, formatDescription);
    return AVAudioFormat._(_ret, _lib, retain: true, release: true);
  }

  bool isEqual_(NSObject object) {
    return _lib._objc_msgSend_0(_id, _lib._sel_isEqual_1, object._id);
  }

  bool get standard {
    return _lib._objc_msgSend_12(_id, _lib._sel_isStandard1);
  }

  int get commonFormat {
    return _lib._objc_msgSend_1042(_id, _lib._sel_commonFormat1);
  }

  int get channelCount {
    return _lib._objc_msgSend_1035(_id, _lib._sel_channelCount1);
  }

  double get sampleRate {
    return _lib._objc_msgSend_149(_id, _lib._sel_sampleRate1);
  }

  bool get interleaved {
    return _lib._objc_msgSend_12(_id, _lib._sel_isInterleaved1);
  }

  ffi.Pointer<AudioStreamBasicDescription> get streamDescription {
    return _lib._objc_msgSend_1043(_id, _lib._sel_streamDescription1);
  }

  AVAudioChannelLayout? get channelLayout {
    final _ret = _lib._objc_msgSend_1044(_id, _lib._sel_channelLayout1);
    return _ret.address == 0
        ? null
        : AVAudioChannelLayout._(_ret, _lib, retain: true, release: true);
  }

  NSData? get magicCookie {
    final _ret = _lib._objc_msgSend_39(_id, _lib._sel_magicCookie1);
    return _ret.address == 0
        ? null
        : NSData._(_ret, _lib, retain: true, release: true);
  }

  set magicCookie(NSData? value) {
    _lib._objc_msgSend_892(
        _id, _lib._sel_setMagicCookie_1, value?._id ?? ffi.nullptr);
  }

  NSDictionary? get settings {
    final _ret = _lib._objc_msgSend_164(_id, _lib._sel_settings1);
    return _ret.address == 0
        ? null
        : NSDictionary._(_ret, _lib, retain: true, release: true);
  }

  CMAudioFormatDescriptionRef get formatDescription {
    return _lib._objc_msgSend_1045(_id, _lib._sel_formatDescription1);
  }

  static AVAudioFormat new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_AVAudioFormat1, _lib._sel_new1);
    return AVAudioFormat._(_ret, _lib, retain: false, release: true);
  }

  static AVAudioFormat alloc(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_AVAudioFormat1, _lib._sel_alloc1);
    return AVAudioFormat._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_AVAudioFormat1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_AVAudioFormat1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_AVAudioFormat1, _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_AVAudioFormat1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_AVAudioFormat1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_AVAudioFormat1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_AVAudioFormat1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(
        _lib._class_AVAudioFormat1, _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioFormat1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

final class AudioStreamBasicDescription extends ffi.Struct {
  @Float64()
  external double mSampleRate;

  @AudioFormatID()
  external int mFormatID;

  @AudioFormatFlags()
  external int mFormatFlags;

  @UInt32()
  external int mBytesPerPacket;

  @UInt32()
  external int mFramesPerPacket;

  @UInt32()
  external int mBytesPerFrame;

  @UInt32()
  external int mChannelsPerFrame;

  @UInt32()
  external int mBitsPerChannel;

  @UInt32()
  external int mReserved;
}

typedef Float64 = ffi.Double;
typedef AudioFormatID = UInt32;
typedef AudioFormatFlags = UInt32;

class AVAudioChannelLayout extends NSObject {
  AVAudioChannelLayout._(ffi.Pointer<ObjCObject> id, AVFAudio lib,
      {bool retain = false, bool release = false})
      : super._(id, lib, retain: retain, release: release);

  /// Returns a [AVAudioChannelLayout] that points to the same underlying object as [other].
  static AVAudioChannelLayout castFrom<T extends _ObjCWrapper>(T other) {
    return AVAudioChannelLayout._(other._id, other._lib,
        retain: true, release: true);
  }

  /// Returns a [AVAudioChannelLayout] that wraps the given raw object pointer.
  static AVAudioChannelLayout castFromPointer(
      AVFAudio lib, ffi.Pointer<ObjCObject> other,
      {bool retain = false, bool release = false}) {
    return AVAudioChannelLayout._(other, lib, retain: retain, release: release);
  }

  /// Returns whether [obj] is an instance of [AVAudioChannelLayout].
  static bool isInstance(_ObjCWrapper obj) {
    return obj._lib._objc_msgSend_0(obj._id, obj._lib._sel_isKindOfClass_1,
        obj._lib._class_AVAudioChannelLayout1);
  }

  @override
  AVAudioChannelLayout init() {
    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
    return AVAudioChannelLayout._(_ret, _lib, retain: true, release: true);
  }

  AVAudioChannelLayout initWithLayoutTag_(int layoutTag) {
    final _ret =
        _lib._objc_msgSend_1032(_id, _lib._sel_initWithLayoutTag_1, layoutTag);
    return AVAudioChannelLayout._(_ret, _lib, retain: true, release: true);
  }

  AVAudioChannelLayout initWithLayout_(ffi.Pointer<AudioChannelLayout> layout) {
    final _ret =
        _lib._objc_msgSend_1033(_id, _lib._sel_initWithLayout_1, layout);
    return AVAudioChannelLayout._(_ret, _lib, retain: true, release: true);
  }

  bool isEqual_(NSObject object) {
    return _lib._objc_msgSend_0(_id, _lib._sel_isEqual_1, object._id);
  }

  static AVAudioChannelLayout layoutWithLayoutTag_(
      AVFAudio _lib, int layoutTag) {
    final _ret = _lib._objc_msgSend_1032(_lib._class_AVAudioChannelLayout1,
        _lib._sel_layoutWithLayoutTag_1, layoutTag);
    return AVAudioChannelLayout._(_ret, _lib, retain: true, release: true);
  }

  static AVAudioChannelLayout layoutWithLayout_(
      AVFAudio _lib, ffi.Pointer<AudioChannelLayout> layout) {
    final _ret = _lib._objc_msgSend_1033(_lib._class_AVAudioChannelLayout1,
        _lib._sel_layoutWithLayout_1, layout);
    return AVAudioChannelLayout._(_ret, _lib, retain: true, release: true);
  }

  int get layoutTag {
    return _lib._objc_msgSend_191(_id, _lib._sel_layoutTag1);
  }

  ffi.Pointer<AudioChannelLayout> get layout {
    return _lib._objc_msgSend_1034(_id, _lib._sel_layout1);
  }

  int get channelCount {
    return _lib._objc_msgSend_1035(_id, _lib._sel_channelCount1);
  }

  static AVAudioChannelLayout new1(AVFAudio _lib) {
    final _ret =
        _lib._objc_msgSend_2(_lib._class_AVAudioChannelLayout1, _lib._sel_new1);
    return AVAudioChannelLayout._(_ret, _lib, retain: false, release: true);
  }

  static AVAudioChannelLayout alloc(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioChannelLayout1, _lib._sel_alloc1);
    return AVAudioChannelLayout._(_ret, _lib, retain: false, release: true);
  }

  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
      AVFAudio _lib,
      NSObject aTarget,
      ffi.Pointer<ObjCSel> aSelector,
      NSObject anArgument) {
    return _lib._objc_msgSend_14(
        _lib._class_AVAudioChannelLayout1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
        aTarget._id,
        aSelector,
        anArgument._id);
  }

  static void cancelPreviousPerformRequestsWithTarget_(
      AVFAudio _lib, NSObject aTarget) {
    return _lib._objc_msgSend_15(_lib._class_AVAudioChannelLayout1,
        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
  }

  static bool getAccessInstanceVariablesDirectly(AVFAudio _lib) {
    return _lib._objc_msgSend_12(_lib._class_AVAudioChannelLayout1,
        _lib._sel_accessInstanceVariablesDirectly1);
  }

  static bool useStoredAccessor(AVFAudio _lib) {
    return _lib._objc_msgSend_12(
        _lib._class_AVAudioChannelLayout1, _lib._sel_useStoredAccessor1);
  }

  static NSSet keyPathsForValuesAffectingValueForKey_(
      AVFAudio _lib, NSString? key) {
    final _ret = _lib._objc_msgSend_58(
        _lib._class_AVAudioChannelLayout1,
        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
        key?._id ?? ffi.nullptr);
    return NSSet._(_ret, _lib, retain: true, release: true);
  }

  static bool automaticallyNotifiesObserversForKey_(
      AVFAudio _lib, NSString? key) {
    return _lib._objc_msgSend_59(
        _lib._class_AVAudioChannelLayout1,
        _lib._sel_automaticallyNotifiesObserversForKey_1,
        key?._id ?? ffi.nullptr);
  }

  static void setKeys_triggerChangeNotificationsForDependentKey_(
      AVFAudio _lib, NSArray? keys, NSString? dependentKey) {
    return _lib._objc_msgSend_79(
        _lib._class_AVAudioChannelLayout1,
        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
        keys?._id ?? ffi.nullptr,
        dependentKey?._id ?? ffi.nullptr);
  }

  static NSArray classFallbacksForKeyedArchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_80(_lib._class_AVAudioChannelLayout1,
        _lib._sel_classFallbacksForKeyedArchiver1);
    return NSArray._(_ret, _lib, retain: true, release: true);
  }

  static NSObject classForKeyedUnarchiver(AVFAudio _lib) {
    final _ret = _lib._objc_msgSend_2(
        _lib._class_AVAudioChannelLayout1, _lib._sel_classForKeyedUnarchiver1);
    return NSObject._(_ret, _lib, retain: true, release: true);
  }
}

typedef AudioChannelLayoutTag = UInt32;

final class AudioChannelLayout extends ffi.Struct {
  @AudioChannelLayoutTag()
  external int mChannelLayoutTag;

  @ffi.Int32()
  external int mChannelBitmap;

  @UInt32()
  external int mNumberChannelDescriptions;

  @ffi.Array.multi([1])
  external ffi.Array<AudioChannelDescription> mChannelDescriptions;
}

abstract class AudioChannelBitmap {
  static const int kAudioChannelBit_Left = 1;
  static const int kAudioChannelBit_Right = 2;
  static const int kAudioChannelBit_Center = 4;
  static const int kAudioChannelBit_LFEScreen = 8;
  static const int kAudioChannelBit_LeftSurround = 16;
  static const int kAudioChannelBit_RightSurround = 32;
  static const int kAudioChannelBit_LeftCenter = 64;
  static const int kAudioChannelBit_RightCenter = 128;
  static const int kAudioChannelBit_CenterSurround = 256;
  static const int kAudioChannelBit_LeftSurroundDirect = 512;
  static const int kAudioChannelBit_RightSurroundDirect = 1024;
  static const int kAudioChannelBit_TopCenterSurround = 2048;
  static const int kAudioChannelBit_VerticalHeightLeft = 4096;
  static const int kAudioChannelBit_VerticalHeightCenter = 8192;
  static const int kAudioChannelBit_VerticalHeightRight = 16384;
  static const int kAudioChannelBit_TopBackLeft = 32768;
  static const int kAudioChannelBit_TopBackCenter = 65536;
  static const int kAudioChannelBit_TopBackRight = 131072;
  static const int kAudioChannelBit_LeftTopFront = 4096;
  static const int kAudioChannelBit_CenterTopFront = 8192;
  static const int kAudioChannelBit_RightTopFront = 16384;
  static const int kAudioChannelBit_LeftTopMiddle = 2097152;
  static const int kAudioChannelBit_CenterTopMiddle = 2048;
  static const int kAudioChannelBit_RightTopMiddle = 8388608;
  static const int kAudioChannelBit_LeftTopRear = 16777216;
  static const int kAudioChannelBit_CenterTopRear = 33554432;
  static const int kAudioChannelBit_RightTopRear = 67108864;
}

final class AudioChannelDescription extends ffi.Struct {
  @AudioChannelLabel()
  external int mChannelLabel;

  @ffi.Int32()
  external int mChannelFlags;

  @ffi.Array.multi([3])
  external ffi.Array<Float32> mCoordinates;
}

typedef AudioChannelLabel = UInt32;

abstract class AudioChannelFlags {
  static const int kAudioChannelFlags_AllOff = 0;
  static const int kAudioChannelFlags_RectangularCoordinates = 1;
  static const int kAudioChannelFlags_SphericalCoordinates = 2;
  static const int kAudioChannelFlags_Meters = 4;
}

typedef Float32 = ffi.Float;
typedef AVAudioChannelCount = ffi.Uint32;

abstract class AVAudioCommonFormat {
  static const int AVAudioOtherFormat = 0;
  static const int AVAudioPCMFormatFloat32 = 1;
  static const int AVAudioPCMFormatFloat64 = 2;
  static const int AVAudioPCMFormatInt16 = 3;
  static const int AVAudioPCMFormatInt32 = 4;
}

typedef CMAudioFormatDescriptionRef = CMFormatDescriptionRef;
typedef CMFormatDescriptionRef = ffi.Pointer<opaqueCMFormatDescription>;

final class opaqueCMFormatDescription extends ffi.Opaque {}
