diff --git a/.github/ISSUE_TEMPLATE/ffigen.md b/.github/ISSUE_TEMPLATE/ffigen.md
new file mode 100644
index 0000000..d3e7a65
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/ffigen.md
@@ -0,0 +1,5 @@
+---
+name: "package:ffigen"
+about: "Create a bug or file a feature request against package:ffigen."
+labels: "package:ffigen"
+---
diff --git a/.github/ISSUE_TEMPLATE/native_assets_builder.md b/.github/ISSUE_TEMPLATE/native_assets_builder.md
new file mode 100644
index 0000000..5a2b90a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/native_assets_builder.md
@@ -0,0 +1,5 @@
+---
+name: "package:native_assets_builder"
+about: "Create a bug or file a feature request against package:native_assets_builder."
+labels: "package:native_assets_builder"
+---
diff --git a/.github/ISSUE_TEMPLATE/native_assets_cli.md b/.github/ISSUE_TEMPLATE/native_assets_cli.md
new file mode 100644
index 0000000..568e6c1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/native_assets_cli.md
@@ -0,0 +1,5 @@
+---
+name: "package:native_assets_cli"
+about: "Create a bug or file a feature request against package:native_assets_cli."
+labels: "package:native_assets_cli"
+---
diff --git a/.github/ISSUE_TEMPLATE/native_toolchain_c.md b/.github/ISSUE_TEMPLATE/native_toolchain_c.md
new file mode 100644
index 0000000..8a19346
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/native_toolchain_c.md
@@ -0,0 +1,5 @@
+---
+name: "package:native_toolchain_c"
+about: "Create a bug or file a feature request against package:native_toolchain_c."
+labels: "package:native_toolchain_c"
+---
diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml
new file mode 100644
index 0000000..439e796
--- /dev/null
+++ b/.github/dependabot.yaml
@@ -0,0 +1,10 @@
+# Dependabot configuration file.
+version: 2
+
+updates:
+  - package-ecosystem: github-actions
+    directory: /
+    schedule:
+      interval: monthly
+    labels:
+      - autosubmit
diff --git a/.github/labeler.yml b/.github/labeler.yml
new file mode 100644
index 0000000..25aaad6
--- /dev/null
+++ b/.github/labeler.yml
@@ -0,0 +1,16 @@
+# Configuration for .github/workflows/pull_request_label.yml.
+
+'type-infra':
+  - '.github/**'
+
+'package:ffigen':
+  - 'pkgs/ffigen/**'
+
+'package:native_assets_builder':
+  - 'pkgs/native_assets_builder/**'
+
+'package:native_assets_cli':
+  - 'pkgs/native_assets_cli/**'
+
+'package:native_toolchain_c':
+  - 'pkgs/native_toolchain_c/**'
diff --git a/.github/workflows/ffigen.yml b/.github/workflows/ffigen.yml
new file mode 100644
index 0000000..0f44ad7
--- /dev/null
+++ b/.github/workflows/ffigen.yml
@@ -0,0 +1,138 @@
+name: ffigen
+
+on:
+  # Run on PRs and pushes to the default branch.
+  push:
+    branches: [main, stable]
+    paths:
+      - '.github/workflows/ffigen.yml'
+      - 'pkgs/ffigen/**'
+  pull_request:
+    branches: [main, stable]
+    paths:
+      - '.github/workflows/ffigen.yml'
+      - 'pkgs/ffigen/**'
+  schedule:
+    - cron: "0 0 * * 0"
+
+env:
+  PUB_ENVIRONMENT: bot.github
+
+jobs:
+  # Check code formatting and static analysis on a single OS (macos).
+  analyze:
+    runs-on: macos-latest
+    defaults:
+      run:
+        working-directory: pkgs/ffigen/
+    strategy:
+      fail-fast: false
+      matrix:
+        sdk: [3.2.0]
+    steps:
+      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+      - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
+        with:
+          sdk: ${{ matrix.sdk }}
+      - id: install
+        name: Install dependencies
+        run: dart pub get && dart pub get --directory="example/shared_bindings"
+      - name: Check formatting
+        run: dart format --output=none --set-exit-if-changed .
+        if: always() && steps.install.outcome == 'success'
+      - name: Build test dylib and bindings
+        run: dart test/setup.dart
+      - name: Analyze code
+        run: dart analyze --fatal-infos
+        if: always() && steps.install.outcome == 'success'
+
+  test-linux:
+    needs: analyze
+    runs-on: ubuntu-22.04
+    defaults:
+      run:
+        working-directory: pkgs/ffigen/
+    steps:
+      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+      - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
+        with:
+          sdk: 3.2.0
+      - name: Install dependencies
+        run: dart pub get
+      - name: Install libclang-14-dev
+        run: sudo apt-get install libclang-14-dev
+      - name: Build test dylib and bindings
+        run: dart test/setup.dart
+      - name: Run VM tests
+        run: dart test --platform vm --concurrency=1
+
+  test-mac:
+    needs: analyze
+    runs-on: macos-latest
+    defaults:
+      run:
+        working-directory: pkgs/ffigen/
+    steps:
+      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+      - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
+        with:
+          sdk: 3.2.0
+      - name: Install dependencies
+        run: dart pub get
+      - name: Build test dylib and bindings
+        run: dart test/setup.dart
+      - name: Run VM tests
+        run: dart test --platform vm --concurrency=1
+      - name: Collect coverage
+        run: ./tool/coverage.sh
+      - name: Upload coverage
+        uses: coverallsapp/github-action@3dfc5567390f6fa9267c0ee9c251e4c8c3f18949
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          path-to-lcov: pkgs/ffigen/lcov.info
+
+  test-windows:
+    needs: analyze
+    runs-on: windows-latest
+    defaults:
+      run:
+        working-directory: pkgs/ffigen/
+    steps:
+      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+      - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
+        with:
+          sdk: 3.2.0
+      - name: Install dependencies
+        run: dart pub get
+      - name: Build test dylib and bindings
+        run: dart test/setup.dart
+      - name: Run VM tests
+        run: dart test --platform vm --concurrency=1
+
+  # Sanity check the latest `flutter create --template plugin_ffi`.
+  # This will break if we change the Flutter template or the generated code.
+  # But, getting libclang on the LUCI infrastructure has proven to be
+  # non-trivial. See discussion on
+  # https://github.com/flutter/flutter/issues/105513.
+  # If we need to change the generated code, we should temporarily disable this
+  # test, or temporarily disable the requirement for all bots to be green to
+  # merge PRs.
+  # Running this sanity check on one OS should be sufficient. Chosing Windows
+  # because it is the most likely to break.
+  test-windows-flutter:
+    needs: analyze
+    runs-on: windows-latest
+    defaults:
+      run:
+        working-directory: pkgs/ffigen/
+    steps:
+      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+      - uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225
+        with:
+          channel: "master"
+      - name: Install dependencies
+        run: flutter pub get
+      - name: Build test dylib and bindings
+        run: dart test/setup.dart
+      - name: Run VM tests
+        run: flutter pub run test test_flutter/ --platform vm
diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml
new file mode 100644
index 0000000..2da22ce
--- /dev/null
+++ b/.github/workflows/native.yaml
@@ -0,0 +1,139 @@
+# CI for the native_* packages.
+#
+# Combined into a single workflow so that deps are configured and installed once.
+
+name: native
+permissions: read-all
+
+on:
+  pull_request:
+    branches: [main]
+    paths:
+      - ".github/workflows/native.yaml"
+      - "pkgs/native_assets_builder/**"
+      - "pkgs/native_assets_cli/**"
+      - "pkgs/native_toolchain_c/**"
+  push:
+    branches: [main]
+    paths:
+      - ".github/workflows/native.yaml"
+      - "pkgs/native_assets_builder/**"
+      - "pkgs/native_assets_cli/**"
+      - "pkgs/native_toolchain_c/**"
+  schedule:
+    - cron: "0 0 * * 0" # weekly
+
+jobs:
+  build:
+    strategy:
+      matrix:
+        os: [ubuntu, macos, windows]
+        sdk: [stable, dev]
+        package: [native_assets_builder, native_assets_cli, native_toolchain_c]
+        # Breaking changes temporarily break the example run on the Dart SDK until native_assets_builder is rolled into the Dart SDK dev build.
+        breaking-change: [true]
+        exclude:
+          # Only run analyze against dev on one host.
+          - os: macos
+            sdk: dev
+          - os: windows
+            sdk: dev
+
+    runs-on: ${{ matrix.os }}-latest
+
+    defaults:
+      run:
+        working-directory: pkgs/${{ matrix.package }}
+
+    steps:
+      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+
+      - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
+        with:
+          sdk: ${{ matrix.sdk }}
+
+      - uses: nttld/setup-ndk@3354316c3285ea90da09d047280dd79d00d5a37a
+        with:
+          ndk-version: r26b
+        if: ${{ matrix.sdk == 'stable' }}
+
+      - run: dart pub get
+
+      - run: dart pub get -C test/data/dart_app/
+        if: ${{ matrix.package == 'native_assets_builder' }}
+
+      - run: dart pub get -C test/data/native_add/
+        if: ${{ matrix.package == 'native_assets_builder' }}
+
+      - run: dart pub get -C test/data/native_add_add_source/
+        if: ${{ matrix.package == 'native_assets_builder' }}
+
+      - run: dart pub get -C test/data/native_subtract/
+        if: ${{ matrix.package == 'native_assets_builder' }}
+
+      - run: dart pub get -C test/data/package_reading_metadata/
+        if: ${{ matrix.package == 'native_assets_builder' }}
+
+      - run: dart pub get -C test/data/package_with_metadata/
+        if: ${{ matrix.package == 'native_assets_builder' }}
+
+      - run: dart pub get -C example/native_add_app/
+        if: ${{ matrix.package == 'native_assets_cli' }}
+
+      - run: dart pub get -C example/native_add_library/
+        if: ${{ matrix.package == 'native_assets_cli' }}
+
+      - run: dart analyze --fatal-infos
+        # Run on dev to ensure we're not depending on deprecated SDK things.
+
+      - run: dart format --output=none --set-exit-if-changed .
+        if: ${{ matrix.sdk == 'stable' }}
+
+      - name: Install native toolchains
+        run: sudo apt-get update && sudo apt-get install clang-15 gcc-i686-linux-gnu gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf gcc-riscv64-linux-gnu
+        if: ${{ matrix.sdk == 'stable' && matrix.os == 'ubuntu' }}
+
+      - run: dart test
+        if: ${{ matrix.sdk == 'stable' }}
+
+      - run: dart --enable-experiment=native-assets test
+        working-directory: pkgs/${{ matrix.package }}/example/native_add_app/
+        if: ${{ matrix.package == 'native_assets_cli' && matrix.sdk == 'dev' && !matrix.breaking-change }}
+
+      - run: dart --enable-experiment=native-assets run
+        working-directory: pkgs/${{ matrix.package }}/example/native_add_app/
+        if: ${{ matrix.package == 'native_assets_cli' && matrix.sdk == 'dev' && !matrix.breaking-change }}
+
+      - run: dart --enable-experiment=native-assets build bin/native_add_app.dart
+        working-directory: pkgs/${{ matrix.package }}/example/native_add_app/
+        if: ${{ matrix.package == 'native_assets_cli' && matrix.sdk == 'dev' && !matrix.breaking-change }}
+
+      - run: ./native_add_app.exe
+        working-directory: pkgs/${{ matrix.package }}/example/native_add_app/bin/native_add_app/
+        if: ${{ matrix.package == 'native_assets_cli' && matrix.sdk == 'dev' && !matrix.breaking-change }}
+
+      - name: Install coverage
+        run: dart pub global activate coverage
+        if: ${{ matrix.sdk == 'stable' }}
+
+      - name: Collect coverage
+        run: dart pub global run coverage:test_with_coverage
+        if: ${{ matrix.sdk == 'stable' }}
+
+      - name: Upload coverage
+        uses: coverallsapp/github-action@3dfc5567390f6fa9267c0ee9c251e4c8c3f18949
+        with:
+          flag-name: ${{ matrix.package }}-${{ matrix.os }}
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          parallel: true
+        if: ${{ matrix.sdk == 'stable' }}
+
+  coverage-finished:
+    needs: [build]
+    runs-on: ubuntu-latest
+    steps:
+      - name: Upload coverage
+        uses: coverallsapp/github-action@3dfc5567390f6fa9267c0ee9c251e4c8c3f18949
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          parallel-finished: true
diff --git a/.github/workflows/native_toolchain_c.yaml b/.github/workflows/native_toolchain_c.yaml
new file mode 100644
index 0000000..ceb668b
--- /dev/null
+++ b/.github/workflows/native_toolchain_c.yaml
@@ -0,0 +1,60 @@
+# Workflow that runs relevant tests with the clang from the Dart SDK.
+
+name: native_toolchain_c
+permissions: read-all
+
+on:
+  pull_request:
+    branches: [main]
+    paths:
+      - ".github/workflows/native_toolchain_c.yaml"
+      - "pkgs/native_toolchain_c/**"
+  push:
+    branches: [main]
+    paths:
+      - ".github/workflows/native_toolchain_c.yaml"
+      - "pkgs/native_toolchain_c/**"
+  schedule:
+    - cron: "0 0 * * 0" # weekly
+
+jobs:
+  dart-sdk-clang:
+    strategy:
+      matrix:
+        os: [ubuntu]
+        sdk: [stable]
+        package: [native_toolchain_c]
+
+    runs-on: ${{ matrix.os }}-latest
+
+    defaults:
+      run:
+        working-directory: pkgs/${{ matrix.package }}
+
+    steps:
+      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+
+      - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
+        with:
+          sdk: ${{ matrix.sdk }}
+
+      - uses: nttld/setup-ndk@3354316c3285ea90da09d047280dd79d00d5a37a
+        with:
+          ndk-version: r26b
+        if: ${{ matrix.sdk == 'stable' }}
+
+      - run: dart pub get
+
+      - name: Install native toolchains
+        run: sudo apt-get update && sudo apt-get install gcc-i686-linux-gnu gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf gcc-riscv64-linux-gnu
+        if: ${{ matrix.sdk == 'stable' && matrix.os == 'ubuntu' }}
+
+      - run: git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
+      - run: echo "$PWD/depot_tools" >> $GITHUB_PATH
+      - run: mkdir dart-sdk
+      - run: cd dart-sdk && fetch --no-history dart
+      - run: echo "./dart-sdk/sdk/buildtools/linux-x64/clang/bin" >> $GITHUB_PATH
+      - run: clang --version
+
+      - run: dart test
+        if: ${{ matrix.sdk == 'stable' }}
diff --git a/.github/workflows/no-response.yml b/.github/workflows/no-response.yml
new file mode 100644
index 0000000..8e5ed57
--- /dev/null
+++ b/.github/workflows/no-response.yml
@@ -0,0 +1,37 @@
+# A workflow to close issues where the author hasn't responded to a request for
+# more information; see https://github.com/actions/stale.
+
+name: No Response
+
+# Run as a daily cron.
+on:
+  schedule:
+    # Every day at 8am
+    - cron: '0 8 * * *'
+
+# All permissions not specified are set to 'none'.
+permissions:
+  issues: write
+  pull-requests: write
+
+jobs:
+  no-response:
+    runs-on: ubuntu-latest
+    if: ${{ github.repository_owner == 'dart-lang' }}
+    steps:
+      - uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84
+        with:
+          # Don't automatically mark inactive issues+PRs as stale.
+          days-before-stale: -1
+          # Close needs-info issues and PRs after 14 days of inactivity.
+          days-before-close: 14
+          stale-issue-label: "needs-info"
+          close-issue-message: >
+            Without additional information we're not able to resolve this issue.
+            Feel free to add more info or respond to any questions above and we
+            can reopen the case. Thanks for your contribution!
+          stale-pr-label: "needs-info"
+          close-pr-message: >
+            Without additional information we're not able to resolve this PR.
+            Feel free to add more info or respond to any questions above.
+            Thanks for your contribution!
diff --git a/.github/workflows/post_summaries.yaml b/.github/workflows/post_summaries.yaml
new file mode 100644
index 0000000..a475092
--- /dev/null
+++ b/.github/workflows/post_summaries.yaml
@@ -0,0 +1,16 @@
+name: Comment on the pull request
+
+on:
+  # Trigger this workflow after the Health workflow completes. This workflow will have permissions to
+  # do things like create comments on the PR, even if the original workflow couldn't.
+  workflow_run:
+    workflows: 
+      - Publish
+    types:
+      - completed
+
+jobs:
+  upload:
+    uses: dart-lang/ecosystem/.github/workflows/post_summaries.yaml@main
+    permissions:
+      pull-requests: write
diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml
new file mode 100644
index 0000000..4c00b14
--- /dev/null
+++ b/.github/workflows/publish.yaml
@@ -0,0 +1,20 @@
+# A CI configuration to auto-publish pub packages.
+
+name: Publish
+
+on:
+  pull_request:
+    branches: [ main ]
+  push:
+    tags: [ '[A-z]+-v[0-9]+.[0-9]+.[0-9]+' ]
+
+jobs:
+  publish:
+    if: ${{ github.repository_owner == 'dart-lang' }}
+    uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main
+    permissions:
+      id-token: write # Required for authentication using OIDC
+      pull-requests: write # Required for writing the pull request note
+    with:
+      write-comments: false
+      sdk: beta
diff --git a/.github/workflows/pull_request_label.yml b/.github/workflows/pull_request_label.yml
new file mode 100644
index 0000000..9933aad
--- /dev/null
+++ b/.github/workflows/pull_request_label.yml
@@ -0,0 +1,22 @@
+# This workflow applies labels to pull requests based on the paths that are
+# modified in the pull request.
+#
+# Edit `.github/labeler.yml` to configure labels. For more information, see
+# https://github.com/actions/labeler.
+
+name: Pull Request Labeler
+permissions: read-all
+
+on:
+  pull_request_target
+
+jobs:
+  label:
+    permissions:
+      pull-requests: write
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594
+        with:
+          repo-token: "${{ secrets.GITHUB_TOKEN }}"
+          sync-labels: true
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..846e4a1
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,6 @@
+# Below is a list of people and organizations that have contributed
+# to the Dart project. Names should be added to the list like so:
+#
+#   Name/Organization <email address>
+
+Google LLC
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..3c28563
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,51 @@
+# How to Contribute
+
+We'd love to accept your patches and contributions to this project. There are
+just a few small guidelines you need to follow.
+
+## Contributor License Agreement
+
+Contributions to this project must be accompanied by a Contributor License
+Agreement (CLA). You (or your employer) retain the copyright to your
+contribution; this simply gives us permission to use and redistribute your
+contributions as part of the project. Head over to
+<https://cla.developers.google.com/> to see your current agreements on file or
+to sign a new one.
+
+You generally only need to submit a CLA once, so if you've already submitted one
+(even if it was for a different project), you probably don't need to do it
+again.
+
+## Code Reviews
+
+All submissions, including submissions by project members, require review. We
+use GitHub pull requests for this purpose. Consult
+[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
+information on using pull requests.
+
+## Coding style
+
+The Dart source code in this repo follows the:
+
+  * [Dart style guide](https://dart.dev/guides/language/effective-dart/style)
+
+You should familiarize yourself with those guidelines.
+
+## File headers
+
+All files in the Dart project must start with the following header; if you add a
+new file please also add this. The year should be a single number stating the
+year the file was created (don't use a range like "2011-2012"). Additionally, if
+you edit an existing file, you shouldn't update the year.
+
+    // Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+    // for details. All rights reserved. Use of this source code is governed by a
+    // BSD-style license that can be found in the LICENSE file.
+
+## Community Guidelines
+
+This project follows
+[Google's Open Source Community Guidelines](https://opensource.google/conduct/).
+
+We pledge to maintain an open and welcoming environment. For details, see our
+[code of conduct](https://dart.dev/code-of-conduct).
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..4fd5739
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2023, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google LLC nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..cab9898
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+[![Coverage Status](https://coveralls.io/repos/github/dart-lang/native/badge.svg?branch=main)](https://coveralls.io/github/dart-lang/native?branch=main)
+
+## Overview
+
+This repository is home to Dart packages related to FFI and native assets
+building and bundling.
+
+## Packages
+
+| Package | Description | Version |
+| --- | --- | --- |
+| [ffigen](pkgs/ffigen/) | Generator for FFI bindings, using LibClang to parse C, Objective-C, and Swift files. | [![pub package](https://img.shields.io/pub/v/ffigen.svg)](https://pub.dev/packages/ffigen) |
+| [native_assets_builder](pkgs/native_assets_builder/) | This package is the backend that invokes top-level `build.dart` scripts. | [![pub package](https://img.shields.io/pub/v/native_assets_builder.svg)](https://pub.dev/packages/native_assets_builder) |
+| [native_assets_cli](pkgs/native_assets_cli/) | A library that contains the argument and file formats for implementing a native assets CLI. | [![pub package](https://img.shields.io/pub/v/native_assets_cli.svg)](https://pub.dev/packages/native_assets_cli) |
+| [native_toolchain_c](pkgs/native_toolchain_c/) | A library to invoke the native C compiler installed on the host machine. | [![pub package](https://img.shields.io/pub/v/native_toolchain_c.svg)](https://pub.dev/packages/native_toolchain_c) |
+
+## Publishing automation
+
+For information about our publishing automation and release process, see
+https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.
+
+For additional information about contributing, see our
+[contributing](CONTRIBUTING.md) page.
diff --git a/pkgs/ffigen/.gitignore b/pkgs/ffigen/.gitignore
new file mode 100644
index 0000000..d9616e8
--- /dev/null
+++ b/pkgs/ffigen/.gitignore
@@ -0,0 +1,44 @@
+# See https://dart.dev/guides/libraries/private-files
+
+# Files and directories created by pub.
+.dart_tool/
+.packages
+pubspec.lock
+
+# IDE and debugger files.
+.clangd
+.gdb_history
+.history
+.vscode
+compile_commands.json
+
+# Directory created by dartdoc.
+# If you don't generate documentation locally you can remove this line.
+doc/api/
+
+# Avoid committing generated Javascript files:
+*.dart.js
+*.info.json      # Produced by the --dump-info flag.
+*.js             # When generated by dart2js. Don't specify *.js if your
+                 # project includes source files written in JavaScript.
+*.js_
+*.js.deps
+*.js.map
+
+# Generated shared libraries.
+*.so
+*.so.*
+*.dylib
+*.dll
+
+# Directory for quick experiments.
+experiments/
+
+# Files generated by tests for debugging purposes.
+test/debug_generated/*
+!test/debug_generated/readme.md
+lcov.info
+coverage.json
+
+# Files generated by various OSs.
+.DS_Store
diff --git a/pkgs/ffigen/AUTHORS b/pkgs/ffigen/AUTHORS
new file mode 100644
index 0000000..4f334e8
--- /dev/null
+++ b/pkgs/ffigen/AUTHORS
@@ -0,0 +1,8 @@
+# Below is a list of people and organizations that have contributed
+# to the Dart project. Names should be added to the list like so:
+#
+#   Name/Organization <email address>
+
+Google LLC
+
+Prerak Mann <mannprerak2@gmail.com>
diff --git a/pkgs/ffigen/CHANGELOG.md b/pkgs/ffigen/CHANGELOG.md
new file mode 100644
index 0000000..f95edb7
--- /dev/null
+++ b/pkgs/ffigen/CHANGELOG.md
@@ -0,0 +1,435 @@
+## 10.0.0
+
+- Stable release targeting Dart 3.2 using new `dart:ffi` features available
+  in Dart 3.2 and later.
+- Add support for ObjC Blocks that can be invoked from any thread, using
+  NativeCallable.listener.
+- Fix invalid exceptional return value ObjCBlocks that return floats.
+- Fix return_of_invalid_type analysis error for ObjCBlocks.
+- Fix crash in ObjC methods and blocks that return structs by value.
+- Fix ObjC methods returning instancetype having the wrong type in sublasses.
+- When generating typedefs for `Pointer<NativeFunction<Function>>`, also
+  generate a typedef for the `Function`.
+- Use Dart wrapper types in args and returns of ObjCBlocks.
+- Use Dart wrapper types in args and returns of static functions.
+- Renamed `asset` to `assetId` for `ffi-native`.  
+
+## 9.0.1
+
+- Fix doc comment missing on struct/union array fields.
+- Allow extern inline functions to be generated.
+
+## 9.0.0
+
+- Added a JSON schema for FFIgen config files.
+
+## 8.0.2
+
+- Fixed invalid code generated due to zero-length arrays in structs/union.
+
+## 8.0.1
+
+- Fixed invalid code generated due to anonymous structs/unions with unsupported types.
+
+## 8.0.0
+
+- Stable release for Dart 3.0 with support for class modifers, variadic arguments, and `@Native`s.
+
+## 8.0.0-dev.3
+
+- Added support for variadic functions using config `functions -> variadic-arguments`.
+
+## 8.0.0-dev.2
+
+- Use `@Native` syntax instead of deprecated `@FfiNative` syntax.
+
+
+## 8.0.0-dev.1
+
+- Fix invalid struct/enum member references due to multiple anonymous struct/enum in a declaration.
+
+## 8.0.0-dev.0
+
+- Adds `final` class modifier to generated sub types `Struct`, `Union` and
+  `Opaque`. A class modifier is required in Dart 3.0 because the classes
+  `dart:ffi` as marked `base`.
+  When migrating a package that uses FFIgen, _and_ exposes the generated code in
+  the public API of the package, to Dart 3.0, that package does not
+  need a major version bump. Sub typing `Struct`, `Union` and
+  `Opaque` sub types is already disallowed by `dart:ffi` pre 3.0, so adding the
+  `final` keyword is not a breaking change.
+- Bumps SDK lowerbound to 3.0.
+## 7.2.11
+
+- Fix invalid struct/enum member references due to multiple anonymous struct/enum in a declaration.
+
+## 7.2.10
+
+- Generate parameter names in function pointer fields and typedefs.
+
+## 7.2.9
+
+- Detect LLVM installed using Scoop on Windows machines.
+
+## 7.2.8
+
+- Automatically generate `ignore_for_file: type=lint` if not specified in preamble.
+
+## 7.2.7
+
+- Fix some macros not being generated in some cases due to relative header paths.
+
+## 7.2.6
+
+- Fix path normalization behaviour for absolute paths and globs starting with `**`.
+
+## 7.2.5
+
+- Add support nested anonymous union/struct
+
+## 7.2.4
+
+- Add new supported typedef - `uintptr_t` (mapped to `ffi.UintPtr`).
+
+## 7.2.3
+
+- Change compiler option order so that user options can override built-in
+  options.
+
+## 7.2.2
+
+- Added newer versions of LLVM, to default `linuxDylibLocations`.
+
+## 7.2.1
+
+- Fix helper methods sometimes missing from NSString.
+
+## 7.2.0
+
+- Added support for sharing bindings using `symbol-file` config. (See `README.md`
+and examples/shared_bindings).
+
+## 7.1.0
+
+- Handle declarations with definition accessible from a different entry-point.
+
+## 7.0.0
+
+- Fix typedef include/exclude config.
+- Return `ObjCBlock` wrapper instead of raw pointer in more cases.
+
+## 7.0.0-dev
+
+- Relative paths in ffigen config files are now assumed to be relative to the
+  config file, rather than the working directory of the tool invocation.
+
+## 6.1.2
+
+- Fix bug where function bindings were not deduped correctly.
+
+## 6.1.1
+
+- _EXPERIMENTAL_ support for `FfiNative`. The API and output
+  might change at any point.
+
+## 6.1.0
+
+- Added `exclude-all-by-default` config flag, which changes the default behavior
+  of declaration filters to exclude everything, rather than include everything.
+
+## 6.0.2
+
+- Bump `package:ffi` to 2.0.1.
+
+## 6.0.1
+
+- Replace path separators in `include-directives` before matching file names.
+- Add more ways to find `libclang`.
+
+## 6.0.0
+- Removed config `dart-bool`. Booleans are now always generated with `bool`
+and `ffi.Bool` as it's Dart and C Type respectively.
+
+## 5.0.1
+
+- Add a the xcode tools llvm as default path on MacOS.
+
+## 5.0.0
+
+- Stable release targeting Dart 2.17, supporting ABI-specific integer types.
+- _EXPERIMENTAL_ support for ObjectiveC on MacOS hosts. The API and output
+  might change at any point. Feel free to report bugs if encountered.
+
+## 5.0.0-dev.1
+- Fixed invalid default dart types being generated for `size_t` and `wchar_t`.
+
+## 5.0.0-dev.0
+- Added support for generating ABI Specific integers.
+- Breaking: removed config keys - `size-map` and `typedef-map`.
+- Added config keys - `library-imports` and `type-map`.
+
+## 4.1.3
+- Analyzer fixes.
+
+## 4.1.2
+- Added fix for empty include list to exclude all
+
+## 4.1.1
+- Added fix for errors due to name collision between member name
+and type name used internally in structs/unions.
+
+## 4.1.0
+- Add config key `functions -> leaf` for specifying `isLeaf:true` for functions.
+
+## 4.0.0
+- Release for Dart SDK `>=2.14`.
+
+## 4.0.0-dev.2
+- Added config key `functions -> expose-typedefs` to expose the typedef
+to Native and Dart type.
+- Config key `function`->`symbol-address` no longer exposes the typedef
+to Native type. Use `expose-typedefs` to get the native type.
+
+## 4.0.0-dev.1
+- This package now targets package:lints for the generated code. The generated
+code uses C symbol names as is. Use either `// ignore_for_file: lintRule1, lintRule2`
+in the `preamble`, or rename the symbols to make package:lints happy.
+- Name collisions are now resolved by suffixing `<int>` instead of `_<int>`.
+
+## 4.0.0-dev.0
+- Added support for generating typedefs (_referred_ typedefs only).
+<table>
+<tr>
+<td>Example C Code</td>
+<td>Generated Dart typedef</td>
+</tr>
+<tr>
+<td>
+
+```C++
+typedef struct A{
+    ...
+} TA, *PA;
+
+TA func(PA ptr);
+```
+</td>
+<td>
+
+```dart
+class A extends ffi.Struct {...}
+typedef TA = A;
+typedef PA = ffi.Pointer<A>;
+TA func(PA ptr){...}
+```
+</td>
+</tr>
+</table>
+
+- All declarations that are excluded by the user are now only included if being
+used somewhere.
+- Improved struct/union include/exclude. These declarations can now be targetted
+by their actual name, or if they are unnamed then by the name of the first
+typedef that refers to them.
+
+## 3.1.0-dev.1
+- Users can now specify exact path to dynamic library in `llvm-path`.
+
+## 3.1.0-dev.0
+- Added support for generating unions.
+
+## 3.0.0
+- Release for dart sdk `>=2.13` (Support for packed structs and inline arrays).
+
+## 3.0.0-beta.0
+- Added support for inline arrays in `Struct`s.
+- Remove config key `array-workaround`.
+- Remove deprecated key `llvm-lib` from config, Use `llvm-path` instead.
+
+## 2.5.0-beta.1
+- Added support for `Packed` structs. Packed annotations are generated
+automatically but can be overriden using `structs -> pack` config.
+- Updated sdk constraints to `>=2.13.0-211.6.beta`.
+
+## 2.4.2
+- Fix issues due to declarations having duplicate names.
+- Fix name conflict of declaration with ffi library prefix.
+- Fix `char` not being recognized on platforms where it's unsigned by default.
+
+## 2.4.1
+- Added `/usr/lib` to default dynamic library location for linux.
+
+## 2.4.0
+- Added new config key `llvm-path` that accepts a list of `path/to/llvm`.
+- Deprecated config key `llvm-lib`.
+
+## 2.3.0
+- Added config key `compiler-opts-automatic -> macos -> include-c-standard-library`
+(default: true) to automatically find and add C standard library on macOS.
+- Allow passing list of string to config key `compiler-opts`.
+
+## 2.2.5
+- Added new command line flag `--compiler-opts` to the command line tool.
+
+## 2.2.4
+- Fix `sort: true` not working.
+- Fix extra `//` or `///` in comments when using `comments -> style`: `full`.
+
+## 2.2.3
+- Added new subkey `dependency-only` (options - `full (default) | opaque`) under `structs`.
+When set to `opaque`, ffigen will generate empty `Opaque` structs if structs
+were excluded in config (i.e added because they were a dependency) and
+only passed by reference(pointer).
+
+## 2.2.2
+- Fixed generation of empty opaque structs due to forward declarations in header files.
+
+## 2.2.1
+- Fixed generation of duplicate constants suffixed with `_<int>` when using multiple entry points.
+
+## 2.2.0
+- Added subkey `symbol-address` to expose native symbol pointers for `functions` and `globals`.
+
+## 2.1.0
+- Added a new named constructor `NativeLibrary.fromLookup()` to support dynamic linking.
+- Updated dart SDK constraints to latest stable version `2.12.0`.
+
+## 2.0.3
+- Ignore typedef to struct pointer when possible.
+- Recursively create directories for output file.
+
+## 2.0.2
+- Fixed illegal use of `const` in name, crash due to unnamed inline structs and
+structs having `Opaque` members.
+
+## 2.0.1
+- Switch to preview release of `package:quiver`.
+
+## 2.0.0
+- Upgraded all dependencies. `package:ffigen` now runs with sound null safety.
+
+## 2.0.0-dev.6
+- Functions marked `inline` are now skipped.
+
+## 2.0.0-dev.5
+- Use `Opaque` for representing empty `Struct`s.
+
+## 2.0.0-dev.4
+- Add support for parsing and generating globals.
+
+## 2.0.0-dev.3
+- Removed the usage of `--no-sound-null-safety` flag.
+
+## 2.0.0-dev.2
+- Removed setup phase for ffigen. Added new optional config key `llvm-lib`
+to specify path to `llvm/lib` folder.
+
+## 2.0.0-dev.1
+- Added support for passing and returning struct by value in functions.
+
+## 2.0.0-dev.0
+- Added support for Nested structs.
+
+## 2.0.0-nullsafety.1
+- Removed the need for `--no-sound-null-safety` flag.
+
+## 2.0.0-nullsafety.0
+- Migrated to (unsound) null safety.
+
+## 1.2.0
+- Added support for `Dart_Handle` from `dart_api.h`.
+
+## 1.1.0
+- `typedef-map` can now be used to map a typedef name to a native type directly.
+
+## 1.0.6
+- Fixed missing typedefs nested in another typedef's return types.
+
+## 1.0.5
+- Fixed issues with generating macros of type `double.Infinity` and `double.NaN`.
+
+## 1.0.4
+- Updated code to use `dart format` instead of `dartfmt` for sdk version `>= 2.10.0`.
+
+## 1.0.3
+- Fixed errors due to extended ASCII and control characters in macro strings.
+
+## 1.0.2
+- Fix indentation for pub's readme.
+
+## 1.0.1
+- Fixed generation of `NativeFunction` parameters instead of `Pointer<NativeFunction>` in type signatures.
+
+## 1.0.0
+- Bump version to 1.0.0.
+- Handle unimplememnted function pointers causing errors.
+- Log lexical/semantic issues in headers as SEVERE.
+
+## 0.3.0
+- Added support for including/excluding/renaming _un-named enums_ using key `unnamed_enums`.
+
+## 0.2.4+1
+- Minor changes to dylib creation error log.
+
+## 0.2.4
+- Added support for C booleans as Uint8.
+- Added config `dart-bool` (default: true) to use dart bool instead of int in function parameters and return type.
+
+## 0.2.3+3
+- Wrapper dynamic library version now uses ffigen version from its pubspec.yaml file.
+
+## 0.2.3+2
+- Handle code formatting using dartfmt by finding dart-sdk.
+
+## 0.2.3+1
+- Fixed missing typedefs of nested function pointers.
+
+## 0.2.3
+- Fixed parsing structs with bitfields, all members of structs with bit field members will now be removed. See [#84](https://github.com/dart-lang/ffigen/issues/84)
+
+## 0.2.2+1
+- Updated `package:meta` version to `^1.1.8` for compatibility with flutter sdk.
+
+## 0.2.2
+- Fixed multiple generation/skipping of typedef enclosed declarations.
+- Typedef names are now given higher preference over inner names, See [#83](https://github.com/dart-lang/ffigen/pull/83).
+
+## 0.2.1+1
+- Added FAQ to readme.
+
+## 0.2.1
+- Fixed missing/duplicate typedef generation.
+
+## 0.2.0
+- Updated header config. Header `entry-points` and `include-directives` are now specified under `headers` key. Glob syntax is allowed.
+- Updated declaration `include`/`exclude` config. These are now specified as a list.
+- Added Regexp based declaration renaming using `rename` subkey.
+- Added Regexp based member renaming for structs, enums and functions using `member-rename` subkey. `prefix` and `prefix-replacement` subkeys have been removed.
+
+## 0.1.5
+- Added support for parsing macros and anonymous unnamed enums. These are generated as top level constants.
+
+## 0.1.4
+- Comments config now has a style and length sub keys - `style: doxygen(default) | any`, `length: brief | full(default)`, and can be disabled by passing `comments: false`.
+
+## 0.1.3
+- Handled function arguments - dart keyword name collision
+- Fix travis tests: the dynamic library is created using `pub run ffigen:setup` before running the tests.
+
+## 0.1.2
+- Fixed wrapper not found error when running `pub run ffigen`.
+
+## 0.1.1
+- Address pub score: follow dart File conventions, provide documentation, and pass static analysis.
+
+## 0.1.0
+- Support for Functions, Structs and Enums.
+- Glob support for specifying headers.
+- HeaderFilter - Include/Exclude declarations from specific header files using name matching.
+- Filters - Include/Exclude function, structs and enum declarations using Regexp or Name matching.
+- Prefixing - function, structs and enums can have a global prefix. Individual prefix Replacement support using Regexp.
+- Comment extraction: full/brief/none
+- Support for fixed size arrays in struct. `array-workaround` (if enabled) will generate helpers for accessing fixed size arrays in structs.
+- Size for ints can be specified using `size-map` in config.
+- Options to disable using supported typedefs (e.g `uint8_t => Uint8`), sort bindings.
+- Option to add a raw `preamble` which is included as is in the generated file.
diff --git a/pkgs/ffigen/LICENSE b/pkgs/ffigen/LICENSE
new file mode 100644
index 0000000..c7e642d
--- /dev/null
+++ b/pkgs/ffigen/LICENSE
@@ -0,0 +1,30 @@
+Copyright 2020, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google LLC nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by FFIgen is owned by the owner of the input file used
+when generating it.
diff --git a/pkgs/ffigen/README.md b/pkgs/ffigen/README.md
new file mode 100644
index 0000000..b5845c3
--- /dev/null
+++ b/pkgs/ffigen/README.md
@@ -0,0 +1,844 @@
+[![Build Status](https://github.com/dart-lang/native/actions/workflows/ffigen.yml/badge.svg)](https://github.com/dart-lang/native/actions/workflows/ffigen.yml)
+[![Coverage Status](https://coveralls.io/repos/github/dart-lang/native/badge.svg?branch=main)](https://coveralls.io/github/dart-lang/native?branch=main)
+[![pub package](https://img.shields.io/pub/v/ffigen.svg)](https://pub.dev/packages/ffigen)
+[![package publisher](https://img.shields.io/pub/publisher/ffigen.svg)](https://pub.dev/packages/ffigen/publisher)
+
+Binding generator for [FFI](https://dart.dev/guides/libraries/c-interop) bindings.
+
+> Note: ffigen only supports parsing `C` headers, not `C++` headers.
+
+This bindings generator can be used to call C code -- or code in another
+language that compiles to C modules that follow the C calling convention --
+such as Go or Rust. For more details, see:
+https://dart.dev/guides/libraries/c-interop
+
+ffigen also has experimental support for calling ObjC and Swift code;
+for details see:
+https://dart.dev/guides/libraries/objective-c-interop
+
+## Example
+
+For some header file _example.h_:
+```C
+int sum(int a, int b);
+```
+Add configurations to Pubspec File:
+```yaml
+ffigen:
+  output: 'generated_bindings.dart'
+  headers:
+    entry-points:
+      - 'example.h'
+```
+Output (_generated_bindings.dart_).
+```dart
+import 'dart:ffi' as ffi;
+class NativeLibrary {
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  int sum(int a, int b) {
+    return _sum(a, b);
+  }
+
+  late final _sumPtr = _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int, ffi.Int)>>('sum');
+  late final _sum = _sumPtr.asFunction<int Function(int, int)>();
+}
+}
+```
+## Using this package
+- Add `ffigen` under `dev_dependencies` in your `pubspec.yaml` (run `dart pub add -d ffigen`).
+- Add `package:ffi` under `dependencies` in your `pubspec.yaml` (run `dart pub add ffi`).
+- Install LLVM (see [Installing LLVM](#installing-llvm)).
+- Configurations must be provided in `pubspec.yaml` or in a custom YAML file (see [configurations](#configurations)).
+- Run the tool- `dart run ffigen`.
+
+Jump to [FAQ](#faq).
+
+## Installing LLVM
+`package:ffigen` uses LLVM. Install LLVM (9+) in the following way.
+
+#### Linux
+1. Install libclangdev.
+
+   With apt-get: `sudo apt-get install libclang-dev`.
+
+   With dnf: `sudo dnf install clang-devel`.
+
+#### Windows
+1. Install Visual Studio with C++ development support.
+2. Install [LLVM](https://releases.llvm.org/download.html) or `winget install -e --id LLVM.LLVM`.
+
+#### MacOS
+1. Install Xcode.
+2. Install Xcode command line tools - `xcode-select --install`.
+3. Install LLVM - `brew install llvm`.
+
+## Configurations
+Configurations can be provided in 2 ways-
+1. In the project's `pubspec.yaml` file under the key `ffigen`.
+2. Via a custom YAML file, then specify this file while running -
+`dart run ffigen --config config.yaml`
+
+The following configuration options are available-
+<table>
+<thead>
+  <tr>
+    <th>Key</th>
+    <th>Explaination</th>
+    <th>Example</th>
+  </tr>
+  <colgroup>
+      <col>
+      <col style="width: 100px;">
+  </colgroup>
+</thead>
+<tbody>
+  <tr>
+    <td>output<br><i><b>(Required)</b></i></td>
+    <td>Output path of the generated bindings.</td>
+    <td>
+
+```yaml
+output: 'generated_bindings.dart'
+```
+or
+```yaml
+output:
+  bindings: 'generated_bindings.dart'
+  ... 
+```
+  </td>
+  </tr>
+  <tr>
+    <td>llvm-path</td>
+    <td>Path to <i>llvm</i> folder.<br> ffigen will sequentially search
+    for `lib/libclang.so` on linux, `lib/libclang.dylib` on macOs and
+    `bin\libclang.dll` on windows, in the specified paths.<br><br>
+    Complete path to the dynamic library can also be supplied.<br>
+    <i>Required</i> if ffigen is unable to find this at default locations.</td>
+    <td>
+
+```yaml
+llvm-path:
+  - '/usr/local/opt/llvm'
+  - 'C:\Program Files\llvm`
+  - '/usr/lib/llvm-11'
+  # Specify exact path to dylib
+  - '/usr/lib64/libclang.so'
+```
+  </td>
+  </tr>
+  <tr>
+    <td>headers<br><i><b>(Required)</b></i></td>
+    <td>The header entry-points and include-directives. Glob syntax is allowed.<br>
+    If include-directives are not specified ffigen will generate everything directly/transitively under the entry-points.</td>
+    <td>
+
+```yaml
+headers:
+  entry-points:
+    - 'folder/**.h'
+    - 'folder/specific_header.h'
+  include-directives:
+    - '**index.h'
+    - '**/clang-c/**'
+    - '/full/path/to/a/header.h'
+```
+  </td>
+  </tr>
+  <tr>
+    <td>name<br><i>(Prefer)</i></td>
+    <td>Name of generated class.</td>
+    <td>
+
+```yaml
+name: 'SQLite'
+```
+  </td>
+  </tr>
+  <tr>
+    <td>description<br><i>(Prefer)</i></td>
+    <td>Dart Doc for generated class.</td>
+    <td>
+
+```yaml
+description: 'Bindings to SQLite'
+```
+  </td>
+  </tr>
+  <tr>
+    <td>compiler-opts</td>
+    <td>Pass compiler options to clang. You can also pass
+    these via the command line tool.</td>
+    <td>
+
+```yaml
+compiler-opts:
+  - '-I/usr/lib/llvm-9/include/'
+```
+and/or via the command line -
+```bash
+dart run ffigen --compiler-opts "-I/headers
+-L 'path/to/folder name/file'"
+```
+  </td>
+  </tr>
+    <tr>
+    <td>compiler-opts-automatic -> macos -> include-c-standard-library</td>
+    <td>Tries to automatically find and add C standard library path to
+    compiler-opts on macos.<br>
+    <b>Default: true</b>
+    </td>
+    <td>
+
+```yaml
+compiler-opts-automatic:
+  macos:
+    include-c-standard-library: false
+```
+  </td>
+  </tr>
+  <tr>
+    <td>
+      functions<br><br>structs<br><br>unions<br><br>enums<br><br>
+      unnamed-enums<br><br>macros<br><br>globals
+    </td>
+    <td>Filters for declarations.<br><b>Default: all are included.</b><br><br>
+    Options -<br>
+    - Include/Exclude declarations.<br>
+    - Rename declarations.<br>
+    - Rename enum and struct members.<br>
+    - Expose symbol-address for functions and globals.<br>
+    </td>
+    <td>
+
+```yaml
+functions:
+  include: # 'exclude' is also available.
+    # Matches using regexp.
+    - [a-z][a-zA-Z0-9]*
+    # '.' matches any character.
+    - prefix.*
+    # Matches with exact name
+    - someFuncName
+    # Full names have higher priority.
+    - anotherName
+  rename:
+    # Regexp groups based replacement.
+    'clang_(.*)': '$1'
+    'clang_dispose': 'dispose'
+    # Removes '_' from beginning.
+    '_(.*)': '$1'
+  symbol-address:
+    # Used to expose symbol address.
+    include:
+      - myFunc
+structs:
+  rename:
+    # Removes prefix underscores
+    # from all structures.
+    '_(.*)': '$1'
+  member-rename:
+    '.*': # Matches any struct.
+      # Removes prefix underscores
+      # from members.
+      '_(.*)': '$1'
+enums:
+  rename:
+    # Regexp groups based replacement.
+    'CXType_(.*)': '$1'
+  member-rename:
+    '(.*)': # Matches any enum.
+      # Removes '_' from beginning
+      # enum member name.
+      '_(.*)': '$1'
+    # Full names have higher priority.
+    'CXTypeKind':
+      # $1 keeps only the 1st
+      # group i.e only '(.*)'.
+      'CXType(.*)': '$1'
+globals:
+  exclude:
+    - aGlobal
+  rename:
+    # Removes '_' from
+    # beginning of a name.
+    '_(.*)': '$1'
+```
+  </td>
+  </tr>
+  <tr>
+    <td>typedefs</td>
+    <td>Filters for referred typedefs.<br><br>
+    Options -<br>
+    - Include/Exclude (referred typedefs only).<br>
+    - Rename typedefs.<br><br>
+    Note: Typedefs that are not referred to anywhere will not be generated.
+    </td>
+    <td>
+
+```yaml
+typedefs:
+  exclude:
+    # Typedefs starting with `p` are not generated.
+    - 'p.*'
+  rename:
+    # Removes '_' from beginning of a typedef.
+    '_(.*)': '$1'
+```
+  </td>
+  </tr>
+  <tr>
+    <td>functions -> expose-typedefs</td>
+    <td>Generate the typedefs to Native and Dart type of a function<br>
+    <b>Default: Inline types are used and no typedefs to Native/Dart
+    type are generated.</b>
+    </td>
+    <td>
+
+```yaml
+functions:
+  expose-typedefs:
+    include:
+      # Match function name.
+      - 'myFunc'
+       # Do this to expose types for all function.
+      - '.*'
+    exclude:
+      # If you only use exclude, then everything
+      # not excluded is generated.
+      - 'dispose'
+```
+  </td>
+  </tr>
+  <tr>
+    <td>functions -> leaf</td>
+    <td>Set isLeaf:true for functions.<br>
+    <b>Default: all functions are excluded.</b>
+    </td>
+    <td>
+
+```yaml
+functions:
+  leaf:
+    include:
+      # Match function name.
+      - 'myFunc'
+       # Do this to set isLeaf:true for all functions.
+      - '.*'
+    exclude:
+      # If you only use exclude, then everything
+      # not excluded is generated.
+      - 'dispose'
+```
+  </td>
+  </tr>
+  <tr>
+    <td>functions -> variadic-arguments</td>
+    <td>Generate multiple functions with different variadic arguments.<br>
+    <b>Default: var args for any function are ignored.</b>
+    </td>
+    <td>
+
+```yaml
+functions:
+  variadic-arguments:
+    myfunc:
+      // Native C types are supported
+      - [int, unsigned char, long*, float**]
+      // Common C typedefs (stddef.h) are supported too
+      - [uint8_t, intptr_t, size_t, wchar_t*]
+      // Structs/Unions/Typedefs from generated code or a library import can be referred too.
+      - [MyStruct*, my_custom_lib.CustomUnion]
+```
+  </td>
+  </tr>
+  <tr>
+    <td>structs -> pack</td>
+    <td>Override the @Packed(X) annotation for generated structs.<br><br>
+    <i>Options - none, 1, 2, 4, 8, 16</i><br>
+    You can use RegExp to match with the <b>generated</b> names.<br><br>
+    Note: Ffigen can only reliably identify packing specified using
+    __attribute__((__packed__)). However, structs packed using
+    `#pragma pack(...)` or any other way could <i>potentially</i> be incorrect
+    in which case you can override the generated annotations.
+    </td>
+    <td>
+
+```yaml
+structs:
+  pack:
+    # Matches with the generated name.
+    'NoPackStruct': none # No packing
+    '.*': 1 # Pack all structs with value 1
+```
+  </td>
+  </tr>
+  <tr>
+    <td>comments</td>
+    <td>Extract documentation comments for declarations.<br>
+    The style and length of the comments recognized can be specified with the following options- <br>
+    <i>style: doxygen(default) | any </i><br>
+    <i>length: brief | full(default) </i><br>
+    If you want to disable all comments you can also pass<br>
+    comments: false.
+    </td>
+    <td>
+
+```yaml
+comments:
+  style: any
+  length: full
+```
+  </td>
+  </tr>
+  <tr>
+    <td>structs -> dependency-only<br><br>
+        unions -> dependency-only
+    </td>
+    <td>If `opaque`, generates empty `Opaque` structs/unions if they
+were not included in config (but were added since they are a dependency) and
+only passed by reference(pointer).<br>
+    <i>Options - full(default) | opaque</i><br>
+    </td>
+    <td>
+
+```yaml
+structs:
+  dependency-only: opaque
+unions:
+  dependency-only: opaque
+```
+  </td>
+  </tr>
+  <tr>
+    <td>sort</td>
+    <td>Sort the bindings according to name.<br>
+      <b>Default: false</b>, i.e keep the order as in the source files.
+    </td>
+    <td>
+
+```yaml
+sort: true
+```
+  </td>
+  </tr>
+  <tr>
+    <td>use-supported-typedefs</td>
+    <td>Should automatically map typedefs, E.g uint8_t => Uint8, int16_t => Int16, size_t => Size etc.<br>
+    <b>Default: true</b>
+    </td>
+    <td>
+
+```yaml
+use-supported-typedefs: true
+```
+  </td>
+  </tr>
+  <tr>
+    <td>use-dart-handle</td>
+    <td>Should map `Dart_Handle` to `Handle`.<br>
+    <b>Default: true</b>
+    </td>
+    <td>
+
+```yaml
+use-dart-handle: true
+```
+  </td>
+  </tr>
+  <tr>
+    <td>exclude-all-by-default</td>
+    <td>
+      When a declaration filter (eg `functions:` or `structs:`) is empty or
+      unset, it defaults to including everything. If this flag is enabled, the
+      default behavior is to exclude everything instead.<br>
+      <b>Default: false</b>
+    </td>
+    <td>
+
+```yaml
+exclude-all-by-default: true
+```
+  </td>
+  </tr>
+  <tr>
+    <td>preamble</td>
+    <td>Raw header of the file, pasted as-it-is.</td>
+    <td>
+
+```yaml
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names
+```
+</td>
+  </tr>
+  <tr>
+    <td>library-imports</td>
+    <td>Specify library imports for use in type-map.<br><br>
+    Note: ffi (dart:ffi) is already available as a predefined import.
+    </td>
+    <td>
+
+```yaml
+library-imports:
+  custom_lib: 'package:some_pkg/some_file.dart'
+```
+  </td>
+  </tr>
+  <tr>
+    <td>type-map</td>
+    <td>Map types like integers, typedefs, structs,  unions to any other type.<br><br>
+    <b>Sub-fields</b> - <i>typedefs</i>, <i>structs</i>, <i>unions</i>, <i>ints</i><br><br>
+    <b><i>lib</i></b> must be specified in <i>library-imports</i> or be one of a predefined import.
+    </td>
+    <td>
+
+```yaml
+type-map:
+  'native-types': # Targets native types.
+    'char':
+      'lib': 'pkg_ffi' # predefined import.
+      'c-type': 'Char'
+      # For native-types dart-type can be be int, double or float
+      # but same otherwise.
+      'dart-type': 'int'
+    'int':
+      'lib': 'custom_lib'
+      'c-type': 'CustomType4'
+      'dart-type': 'int'
+  'typedefs': # Targets typedefs.
+    'my_type1':
+      'lib': 'custom_lib'
+      'c-type': 'CustomType'
+      'dart-type': 'CustomType'
+  'structs': # Targets structs.
+    'my_type2':
+      'lib': 'custom_lib'
+      'c-type': 'CustomType2'
+      'dart-type': 'CustomType2'
+  'unions': # Targets unions.
+    'my_type3':
+      'lib': 'custom_lib'
+      'c-type': 'CustomType3'
+      'dart-type': 'CustomType3'
+```
+  </td>
+  </tr>
+  <tr>
+    <td>ffi-native</td>
+    <td>
+      <b>WARNING:</b> Native support is EXPERIMENTAL. The API may change
+      in a breaking way without notice.
+      <br><br>
+      Generate `@Native` bindings instead of bindings using `DynamicLibrary` or `lookup`.
+    </td>
+    <td>
+
+```yaml
+ffi-native:
+  assetId: 'myasset' # Optional.
+```
+  </td>
+  </tr>
+  <tr>
+    <td>language</td>
+    <td>
+      <b>WARNING:</b> Other language support is EXPERIMENTAL. The API may change
+      in a breaking way without notice.
+      <br><br>
+      Choose the input langauge. Must be one of 'c', or 'objc'. Defaults to 'c'.
+    </td>
+    <td>
+
+```yaml
+language: 'objc'
+```
+  </td>
+  </tr>
+  <tr>
+    <td>output -> symbol-file</td>
+    <td>Generates a symbol file yaml containing all types defined in the generated output.</td>
+    <td>
+
+```yaml
+output:
+  ...
+  symbol-file:
+    # Although file paths are supported here, prefer Package Uri's here
+    # so that other pacakges can use them.
+    output: 'package:some_pkg/symbols.yaml'
+    import-path: 'package:some_pkg/base.dart'
+```
+</td>
+  </tr>
+  <tr>
+    <td>import -> symbol-files</td>
+    <td>Import symbols from a symbol file. Used for sharing type definitions from other pacakges.</td>
+    <td>
+
+```yaml
+import:
+  symbol-files:
+    # Both package Uri and file paths are supported here.
+    - 'package:some_pkg/symbols.yaml'
+    - 'path/to/some/symbol_file.yaml'
+```
+</td>
+  </tr>
+</tbody>
+</table>
+
+### Objective-C config options
+
+<table>
+<thead>
+  <tr>
+    <th>Key</th>
+    <th>Explaination</th>
+    <th>Example</th>
+  </tr>
+  <colgroup>
+    <col>
+    <col style="width: 100px;">
+  </colgroup>
+</thead>
+<tbody>
+  <tr>
+    <td>
+      objc-interfaces
+    </td>
+    <td>
+      Filters for interface declarations. This option works the same as other
+      declaration filters like `functions` and `structs`.
+    </td>
+    <td>
+
+```yaml
+objc-interfaces:
+  include:
+    # Includes a specific interface.
+    - 'MyInterface'
+    # Includes all interfaces starting with "NS".
+    - 'NS.*'
+  exclude:
+    # Override the above NS.* inclusion, to exclude NSURL.
+    - 'NSURL'
+  rename:
+    # Removes '_' prefix from interface names.
+    '_(.*)': '$1'
+```
+
+  </td>
+  </tr>
+
+  <tr>
+    <td>
+      objc-interfaces -> module
+    </td>
+    <td>
+      Adds a module prefix to the class name when loading the class
+      from the dylib. This is only relevent for ObjC headers that are generated
+      wrappers for a Swift library. See example/swift for more information.
+    </td>
+    <td>
+
+```yaml
+headers:
+  entry-points:
+    # Generated by swiftc to wrap foo_lib.swift.
+    - 'foo_lib-Swift.h'
+objc-interfaces:
+  include:
+    # Eg, foo_lib contains a set of classes prefixed with FL.
+    - 'FL.*'
+  module:
+    # Use 'foo_lib' as the module name for all the FL.* classes.
+    # We don't match .* here because other classes like NSString
+    # shouldn't be given a module prefix.
+    'FL.*': 'foo_lib'
+```
+
+  </td>
+  </tr>
+</tbody>
+</table>
+
+## Trying out examples
+1. `cd examples/<example_u_want_to_run>`, Run `dart pub get`.
+2. Run `dart run ffigen`.
+
+## Running Tests
+
+See [test/README.md](test/README.md)
+
+## FAQ
+### Can ffigen be used for removing underscores or renaming declarations?
+Ffigen supports **regexp based renaming**, the regexp must be a
+full match, for renaming you can use regexp groups (`$1` means group 1).
+
+E.g - For renaming `clang_dispose_string` to `string_dispose`.
+We can can match it using `clang_(.*)_(.*)` and rename with `$2_$1`.
+
+Here's an example of how to remove prefix underscores from any struct and its members.
+```yaml
+structs:
+  ...
+  rename:
+    '_(.*)': '$1' # Removes prefix underscores from all structures.
+  member-rename:
+    '.*': # Matches any struct.
+      '_(.*)': '$1' # Removes prefix underscores from members.
+```
+### How to generate declarations only from particular headers?
+The default behaviour is to include everything directly/transitively under
+each of the `entry-points` specified.
+
+If you only want to have declarations directly particular header you can do so
+using `include-directives`. You can use **glob matching** to match header paths.
+```yaml
+headers:
+  entry-points:
+    - 'path/to/my_header.h'
+  include-directives:
+    - '**my_header.h' # This glob pattern matches the header path.
+```
+### Can ffigen filter declarations by name?
+Ffigen supports including/excluding declarations using full regexp matching.
+
+Here's an example to filter functions using names
+```yaml
+functions:
+  include:
+    - 'clang.*' # Include all functions starting with clang.
+  exclude:
+    - '.*dispose': # Exclude all functions ending with dispose.
+```
+This will include `clang_help`. But will exclude `clang_dispose`.
+
+Note: exclude overrides include.
+### How does ffigen handle C Strings?
+
+Ffigen treats `char*` just as any other pointer,(`Pointer<Int8>`).
+To convert these to/from `String`, you can use [package:ffi](https://pub.dev/packages/ffi). Use `ptr.cast<Utf8>().toDartString()` to convert `char*` to dart `string` and `"str".toNativeUtf8()` to convert `string` to `char*`.
+
+### How are unnamed enums handled?
+
+Unnamed enums are handled separately, under the key `unnamed-enums`, and are generated as top level constants.
+
+Here's an example that shows how to include/exclude/rename unnamed enums
+```yaml
+unnamed-enums:
+  include:
+    - 'CX_.*'
+  exclude:
+    - '.*Flag'
+  rename:
+    'CXType_(.*)': '$1'
+```
+
+### Why are some struct/union declarations generated even after excluded them in config?
+
+This happens when an excluded struct/union is a dependency to some included declaration.
+(A dependency means a struct is being passed/returned by a function or is member of another struct in some way)
+
+Note: If you supply `structs` -> `dependency-only` as `opaque` ffigen will generate
+these struct dependencies as `Opaque` if they were only passed by reference(pointer).
+```yaml
+structs:
+  dependency-only: opaque
+unions:
+  dependency-only: opaque
+```
+
+### How to expose the native pointers?
+
+By default the native pointers are private, but you can use the
+`symbol-address` subkey for functions/globals and make them public by matching with its name. The pointers are then accesible via `nativeLibrary.addresses`.
+
+Example -
+```yaml
+functions:
+  symbol-address:
+    include:
+      - 'myFunc' # Match function name.
+      - '.*' # Do this to expose all function pointers.
+    exclude: # If you only use exclude, then everything not excluded is generated.
+      - 'dispose'
+```
+
+### How to get typedefs to Native and Dart type of a function?
+
+By default these types are inline. But you can use the `expose-typedef` subkey
+for functions to generate them. This will expose the Native and Dart type.
+E.g - for a function named `hello`, the generated typedefs are named
+as `NativeHello` and `DartHello`.
+
+Example -
+```yaml
+functions:
+  expose-typedefs:
+    include:
+      - 'myFunc' # Match function name.
+      - '.*' # Do this to expose types for all function.
+    exclude: # If you only use exclude, then everything not excluded is generated.
+      - 'dispose'
+```
+
+### How are Structs/Unions/Enums that are reffered to via typedefs handled?
+
+Named declarations use their own names even when inside another typedef.
+However, unnamed declarations inside typedefs take the name of the _first_ typedef
+that refers to them.
+
+### Why are some typedefs not generated?
+
+The following typedefs are not generated -
+  - They are not referred to anywhere in the included declarations.
+  - They refer to a struct/union having the same name as itself.
+  - They refer to a boolean, enum, inline array, Handle or any unsupported type.
+
+### How are macros handled?
+
+`ffigen` uses `clang`'s own compiler frontend to parse and traverse the `C` header files. `ffigen` expands the macros using `clang`'s macro expansion and then traverses the expanded code. To do this, `ffigen` generates temporary files in a system tmp directory.
+
+A custom temporary directory can be specified by setting the `TEST_TMPDIR` environment variable.
+
+### What are these logs generated by ffigen and how to fix them?
+
+Ffigen can sometimes generate a lot of logs, especially when it's parsing a lot of code.
+  - `SEVERE` logs are something you *definitely need to address*. They can be
+    caused due to syntax errors, or more generally missing header files
+    (which need to be specified using `compiler-opts` in config)
+  - `WARNING` logs are something *you can ignore*, but should probably look into.
+    These are mostly indications of declarations ffigen couldn't generate due
+    to limitations of dart:ffi, private declarations (which can be resolved
+    by renaming them via ffigen config) or other minor issues in the config
+    file itself.
+  - Everything else can be safely ignored. It's purpose is to simply
+    let you know what ffigen is doing.
+  - The verbosity of the logs can be changed by adding a flag with
+    the log level. E.g - `dart run ffigen --verbose <level>`.
+    Level options are - `[all, fine, info (default), warning, severe]`.
+    The `all` and `fine` will print a ton of logs are meant for debugging
+    purposes only.
+
+### How can type definitions be shared?
+
+Ffigen can share type definitions using symbol files.
+- A package can generate a symbol file using the `output -> symbol-file` config.
+- And another package can then import this, using `import -> symbol-files` config.
+- Doing so will reuse all the types such as Struct/Unions, and will automatically
+ exclude generating other types (E.g functions, enums, macros).
+
+Checkout `examples/shared_bindings` for details.
+
+For manually reusing definitions from another package, the `library-imports`
+and `type-map` config can be used.
diff --git a/pkgs/ffigen/analysis_options.yaml b/pkgs/ffigen/analysis_options.yaml
new file mode 100644
index 0000000..8c036c9
--- /dev/null
+++ b/pkgs/ffigen/analysis_options.yaml
@@ -0,0 +1,25 @@
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+include: package:lints/recommended.yaml
+
+analyzer:
+  exclude:
+    - 'test/**_expected*'
+    # Goldens cannot be generated outside MacOS causing analysis errors.
+    - test/native_objc_test/** 
+  language:
+    strict-casts: true
+    strict-inference: true
+
+linter:
+  rules:
+    # Enabled.
+    directives_ordering: true
+    prefer_final_locals: true
+    prefer_final_in_for_each: true
+    use_super_parameters: true
+    
+    # Disabled.
+    constant_identifier_names: false
diff --git a/pkgs/ffigen/bin/ffigen.dart b/pkgs/ffigen/bin/ffigen.dart
new file mode 100644
index 0000000..6156ed0
--- /dev/null
+++ b/pkgs/ffigen/bin/ffigen.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+
+export 'package:ffigen/src/executables/ffigen.dart';
diff --git a/pkgs/ffigen/example/README.md b/pkgs/ffigen/example/README.md
new file mode 100644
index 0000000..405ceac
--- /dev/null
+++ b/pkgs/ffigen/example/README.md
@@ -0,0 +1,7 @@
+## Examples
+
+- [Simple](https://github.com/dart-lang/native/tree/main/pkgs/ffigen/example/simple)
+- [cJSON](https://github.com/dart-lang/native/tree/main/pkgs/ffigen/example/c_json)
+- [LibClang](https://github.com/dart-lang/native/tree/main/pkgs/ffigen/example/libclang-example)
+- [ObjectiveC](https://github.com/dart-lang/native/tree/main/pkgs/ffigen/example/objective_c)
+- [Swift](https://github.com/dart-lang/native/tree/main/pkgs/ffigen/example/swift)
diff --git a/pkgs/ffigen/example/c_json/.gitignore b/pkgs/ffigen/example/c_json/.gitignore
new file mode 100644
index 0000000..1b05164
--- /dev/null
+++ b/pkgs/ffigen/example/c_json/.gitignore
@@ -0,0 +1,11 @@
+# Files and directories created by pub.
+.dart_tool/
+.packages
+# Remove the following pattern if you wish to check in your lock file.
+pubspec.lock
+
+# Conventional directory for build outputs.
+build/
+
+# Directory created by dartdoc.
+doc/api/
diff --git a/pkgs/ffigen/example/c_json/README.md b/pkgs/ffigen/example/c_json/README.md
new file mode 100644
index 0000000..f222cc2
--- /dev/null
+++ b/pkgs/ffigen/example/c_json/README.md
@@ -0,0 +1,25 @@
+# cJson example
+
+Demonstrates generation of bindings for a C library called
+[cJson](https://github.com/DaveGamble/cJSON) and then using these bindings
+to parse some json.
+
+## Building the cJson dynamic library
+From the root of this repository -
+```
+cd third_party/cjson_library
+cmake .
+make
+```
+
+## Generating bindings
+At the root of this example (`example/c_json`), run -
+```
+dart run ffigen --config config.yaml
+```
+This will generate bindings in a file: [cjson_generated_bindings.dart](./cjson_generated_bindings.dart)
+
+## Running the example
+```
+dart main.dart
+```
diff --git a/pkgs/ffigen/example/c_json/cjson_generated_bindings.dart b/pkgs/ffigen/example/c_json/cjson_generated_bindings.dart
new file mode 100644
index 0000000..9ee0f81
--- /dev/null
+++ b/pkgs/ffigen/example/c_json/cjson_generated_bindings.dart
@@ -0,0 +1,1301 @@
+// Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// ignore_for_file: camel_case_types, non_constant_identifier_names
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Holds bindings to cJSON.
+class CJson {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  CJson(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  CJson.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  ffi.Pointer<ffi.Char> cJSON_Version() {
+    return _cJSON_Version();
+  }
+
+  late final _cJSON_VersionPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
+          'cJSON_Version');
+  late final _cJSON_Version =
+      _cJSON_VersionPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();
+
+  void cJSON_InitHooks(
+    ffi.Pointer<cJSON_Hooks> hooks,
+  ) {
+    return _cJSON_InitHooks(
+      hooks,
+    );
+  }
+
+  late final _cJSON_InitHooksPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<cJSON_Hooks>)>>(
+          'cJSON_InitHooks');
+  late final _cJSON_InitHooks =
+      _cJSON_InitHooksPtr.asFunction<void Function(ffi.Pointer<cJSON_Hooks>)>();
+
+  ffi.Pointer<cJSON> cJSON_Parse(
+    ffi.Pointer<ffi.Char> value,
+  ) {
+    return _cJSON_Parse(
+      value,
+    );
+  }
+
+  late final _cJSON_ParsePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>('cJSON_Parse');
+  late final _cJSON_Parse = _cJSON_ParsePtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_ParseWithOpts(
+    ffi.Pointer<ffi.Char> value,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> return_parse_end,
+    int require_null_terminated,
+  ) {
+    return _cJSON_ParseWithOpts(
+      value,
+      return_parse_end,
+      require_null_terminated,
+    );
+  }
+
+  late final _cJSON_ParseWithOptsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              cJSON_bool)>>('cJSON_ParseWithOpts');
+  late final _cJSON_ParseWithOpts = _cJSON_ParseWithOptsPtr.asFunction<
+      ffi.Pointer<cJSON> Function(
+          ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Pointer<ffi.Char>>, int)>();
+
+  ffi.Pointer<ffi.Char> cJSON_Print(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_Print(
+      item,
+    );
+  }
+
+  late final _cJSON_PrintPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>('cJSON_Print');
+  late final _cJSON_Print = _cJSON_PrintPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<ffi.Char> cJSON_PrintUnformatted(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_PrintUnformatted(
+      item,
+    );
+  }
+
+  late final _cJSON_PrintUnformattedPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_PrintUnformatted');
+  late final _cJSON_PrintUnformatted = _cJSON_PrintUnformattedPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<ffi.Char> cJSON_PrintBuffered(
+    ffi.Pointer<cJSON> item,
+    int prebuffer,
+    int fmt,
+  ) {
+    return _cJSON_PrintBuffered(
+      item,
+      prebuffer,
+      fmt,
+    );
+  }
+
+  late final _cJSON_PrintBufferedPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<cJSON>, ffi.Int, cJSON_bool)>>('cJSON_PrintBuffered');
+  late final _cJSON_PrintBuffered = _cJSON_PrintBufferedPtr.asFunction<
+      ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>, int, int)>();
+
+  int cJSON_PrintPreallocated(
+    ffi.Pointer<cJSON> item,
+    ffi.Pointer<ffi.Char> buffer,
+    int length,
+    int format,
+  ) {
+    return _cJSON_PrintPreallocated(
+      item,
+      buffer,
+      length,
+      format,
+    );
+  }
+
+  late final _cJSON_PrintPreallocatedPtr = _lookup<
+      ffi.NativeFunction<
+          cJSON_bool Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Int, cJSON_bool)>>('cJSON_PrintPreallocated');
+  late final _cJSON_PrintPreallocated = _cJSON_PrintPreallocatedPtr.asFunction<
+      int Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, int, int)>();
+
+  void cJSON_Delete(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_Delete(
+      item,
+    );
+  }
+
+  late final _cJSON_DeletePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_Delete');
+  late final _cJSON_Delete =
+      _cJSON_DeletePtr.asFunction<void Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_GetArraySize(
+    ffi.Pointer<cJSON> array,
+  ) {
+    return _cJSON_GetArraySize(
+      array,
+    );
+  }
+
+  late final _cJSON_GetArraySizePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_GetArraySize');
+  late final _cJSON_GetArraySize =
+      _cJSON_GetArraySizePtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_GetArrayItem(
+    ffi.Pointer<cJSON> array,
+    int index,
+  ) {
+    return _cJSON_GetArrayItem(
+      array,
+      index,
+    );
+  }
+
+  late final _cJSON_GetArrayItemPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Int)>>('cJSON_GetArrayItem');
+  late final _cJSON_GetArrayItem = _cJSON_GetArrayItemPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_GetObjectItem(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_GetObjectItem(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_GetObjectItemPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_GetObjectItem');
+  late final _cJSON_GetObjectItem = _cJSON_GetObjectItemPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_GetObjectItemCaseSensitive(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_GetObjectItemCaseSensitive(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_GetObjectItemCaseSensitivePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_GetObjectItemCaseSensitive');
+  late final _cJSON_GetObjectItemCaseSensitive =
+      _cJSON_GetObjectItemCaseSensitivePtr.asFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  int cJSON_HasObjectItem(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_HasObjectItem(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_HasObjectItemPtr = _lookup<
+      ffi.NativeFunction<
+          cJSON_bool Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_HasObjectItem');
+  late final _cJSON_HasObjectItem = _cJSON_HasObjectItemPtr
+      .asFunction<int Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<ffi.Char> cJSON_GetErrorPtr() {
+    return _cJSON_GetErrorPtr();
+  }
+
+  late final _cJSON_GetErrorPtrPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
+          'cJSON_GetErrorPtr');
+  late final _cJSON_GetErrorPtr =
+      _cJSON_GetErrorPtrPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();
+
+  ffi.Pointer<ffi.Char> cJSON_GetStringValue(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_GetStringValue(
+      item,
+    );
+  }
+
+  late final _cJSON_GetStringValuePtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_GetStringValue');
+  late final _cJSON_GetStringValue = _cJSON_GetStringValuePtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsInvalid(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsInvalid(
+      item,
+    );
+  }
+
+  late final _cJSON_IsInvalidPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsInvalid');
+  late final _cJSON_IsInvalid =
+      _cJSON_IsInvalidPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsFalse(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsFalse(
+      item,
+    );
+  }
+
+  late final _cJSON_IsFalsePtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsFalse');
+  late final _cJSON_IsFalse =
+      _cJSON_IsFalsePtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsTrue(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsTrue(
+      item,
+    );
+  }
+
+  late final _cJSON_IsTruePtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsTrue');
+  late final _cJSON_IsTrue =
+      _cJSON_IsTruePtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsBool(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsBool(
+      item,
+    );
+  }
+
+  late final _cJSON_IsBoolPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsBool');
+  late final _cJSON_IsBool =
+      _cJSON_IsBoolPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsNull(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsNull(
+      item,
+    );
+  }
+
+  late final _cJSON_IsNullPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsNull');
+  late final _cJSON_IsNull =
+      _cJSON_IsNullPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsNumber(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsNumber(
+      item,
+    );
+  }
+
+  late final _cJSON_IsNumberPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsNumber');
+  late final _cJSON_IsNumber =
+      _cJSON_IsNumberPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsString(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsString(
+      item,
+    );
+  }
+
+  late final _cJSON_IsStringPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsString');
+  late final _cJSON_IsString =
+      _cJSON_IsStringPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsArray(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsArray(
+      item,
+    );
+  }
+
+  late final _cJSON_IsArrayPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsArray');
+  late final _cJSON_IsArray =
+      _cJSON_IsArrayPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsObject(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsObject(
+      item,
+    );
+  }
+
+  late final _cJSON_IsObjectPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsObject');
+  late final _cJSON_IsObject =
+      _cJSON_IsObjectPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsRaw(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsRaw(
+      item,
+    );
+  }
+
+  late final _cJSON_IsRawPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsRaw');
+  late final _cJSON_IsRaw =
+      _cJSON_IsRawPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateNull() {
+    return _cJSON_CreateNull();
+  }
+
+  late final _cJSON_CreateNullPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
+          'cJSON_CreateNull');
+  late final _cJSON_CreateNull =
+      _cJSON_CreateNullPtr.asFunction<ffi.Pointer<cJSON> Function()>();
+
+  ffi.Pointer<cJSON> cJSON_CreateTrue() {
+    return _cJSON_CreateTrue();
+  }
+
+  late final _cJSON_CreateTruePtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
+          'cJSON_CreateTrue');
+  late final _cJSON_CreateTrue =
+      _cJSON_CreateTruePtr.asFunction<ffi.Pointer<cJSON> Function()>();
+
+  ffi.Pointer<cJSON> cJSON_CreateFalse() {
+    return _cJSON_CreateFalse();
+  }
+
+  late final _cJSON_CreateFalsePtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
+          'cJSON_CreateFalse');
+  late final _cJSON_CreateFalse =
+      _cJSON_CreateFalsePtr.asFunction<ffi.Pointer<cJSON> Function()>();
+
+  ffi.Pointer<cJSON> cJSON_CreateBool(
+    int boolean,
+  ) {
+    return _cJSON_CreateBool(
+      boolean,
+    );
+  }
+
+  late final _cJSON_CreateBoolPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function(cJSON_bool)>>(
+          'cJSON_CreateBool');
+  late final _cJSON_CreateBool =
+      _cJSON_CreateBoolPtr.asFunction<ffi.Pointer<cJSON> Function(int)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateNumber(
+    double num,
+  ) {
+    return _cJSON_CreateNumber(
+      num,
+    );
+  }
+
+  late final _cJSON_CreateNumberPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function(ffi.Double)>>(
+          'cJSON_CreateNumber');
+  late final _cJSON_CreateNumber =
+      _cJSON_CreateNumberPtr.asFunction<ffi.Pointer<cJSON> Function(double)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateString(
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_CreateString(
+      string,
+    );
+  }
+
+  late final _cJSON_CreateStringPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateString');
+  late final _cJSON_CreateString = _cJSON_CreateStringPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateRaw(
+    ffi.Pointer<ffi.Char> raw,
+  ) {
+    return _cJSON_CreateRaw(
+      raw,
+    );
+  }
+
+  late final _cJSON_CreateRawPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateRaw');
+  late final _cJSON_CreateRaw = _cJSON_CreateRawPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateArray() {
+    return _cJSON_CreateArray();
+  }
+
+  late final _cJSON_CreateArrayPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
+          'cJSON_CreateArray');
+  late final _cJSON_CreateArray =
+      _cJSON_CreateArrayPtr.asFunction<ffi.Pointer<cJSON> Function()>();
+
+  ffi.Pointer<cJSON> cJSON_CreateObject() {
+    return _cJSON_CreateObject();
+  }
+
+  late final _cJSON_CreateObjectPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
+          'cJSON_CreateObject');
+  late final _cJSON_CreateObject =
+      _cJSON_CreateObjectPtr.asFunction<ffi.Pointer<cJSON> Function()>();
+
+  ffi.Pointer<cJSON> cJSON_CreateStringReference(
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_CreateStringReference(
+      string,
+    );
+  }
+
+  late final _cJSON_CreateStringReferencePtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateStringReference');
+  late final _cJSON_CreateStringReference = _cJSON_CreateStringReferencePtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateObjectReference(
+    ffi.Pointer<cJSON> child,
+  ) {
+    return _cJSON_CreateObjectReference(
+      child,
+    );
+  }
+
+  late final _cJSON_CreateObjectReferencePtr = _lookup<
+          ffi.NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_CreateObjectReference');
+  late final _cJSON_CreateObjectReference = _cJSON_CreateObjectReferencePtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateArrayReference(
+    ffi.Pointer<cJSON> child,
+  ) {
+    return _cJSON_CreateArrayReference(
+      child,
+    );
+  }
+
+  late final _cJSON_CreateArrayReferencePtr = _lookup<
+          ffi.NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_CreateArrayReference');
+  late final _cJSON_CreateArrayReference = _cJSON_CreateArrayReferencePtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateIntArray(
+    ffi.Pointer<ffi.Int> numbers,
+    int count,
+  ) {
+    return _cJSON_CreateIntArray(
+      numbers,
+      count,
+    );
+  }
+
+  late final _cJSON_CreateIntArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<ffi.Int>, ffi.Int)>>('cJSON_CreateIntArray');
+  late final _cJSON_CreateIntArray = _cJSON_CreateIntArrayPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Int>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateFloatArray(
+    ffi.Pointer<ffi.Float> numbers,
+    int count,
+  ) {
+    return _cJSON_CreateFloatArray(
+      numbers,
+      count,
+    );
+  }
+
+  late final _cJSON_CreateFloatArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<ffi.Float>, ffi.Int)>>('cJSON_CreateFloatArray');
+  late final _cJSON_CreateFloatArray = _cJSON_CreateFloatArrayPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Float>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateDoubleArray(
+    ffi.Pointer<ffi.Double> numbers,
+    int count,
+  ) {
+    return _cJSON_CreateDoubleArray(
+      numbers,
+      count,
+    );
+  }
+
+  late final _cJSON_CreateDoubleArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<ffi.Double>, ffi.Int)>>('cJSON_CreateDoubleArray');
+  late final _cJSON_CreateDoubleArray = _cJSON_CreateDoubleArrayPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Double>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateStringArray(
+    ffi.Pointer<ffi.Pointer<ffi.Char>> strings,
+    int count,
+  ) {
+    return _cJSON_CreateStringArray(
+      strings,
+      count,
+    );
+  }
+
+  late final _cJSON_CreateStringArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Int)>>('cJSON_CreateStringArray');
+  late final _cJSON_CreateStringArray = _cJSON_CreateStringArrayPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Pointer<ffi.Char>>, int)>();
+
+  void cJSON_AddItemToArray(
+    ffi.Pointer<cJSON> array,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_AddItemToArray(
+      array,
+      item,
+    );
+  }
+
+  late final _cJSON_AddItemToArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>>('cJSON_AddItemToArray');
+  late final _cJSON_AddItemToArray = _cJSON_AddItemToArrayPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_AddItemToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_AddItemToObject(
+      object,
+      string,
+      item,
+    );
+  }
+
+  late final _cJSON_AddItemToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<cJSON>)>>('cJSON_AddItemToObject');
+  late final _cJSON_AddItemToObject = _cJSON_AddItemToObjectPtr.asFunction<
+      void Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_AddItemToObjectCS(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_AddItemToObjectCS(
+      object,
+      string,
+      item,
+    );
+  }
+
+  late final _cJSON_AddItemToObjectCSPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<cJSON>)>>('cJSON_AddItemToObjectCS');
+  late final _cJSON_AddItemToObjectCS = _cJSON_AddItemToObjectCSPtr.asFunction<
+      void Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_AddItemReferenceToArray(
+    ffi.Pointer<cJSON> array,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_AddItemReferenceToArray(
+      array,
+      item,
+    );
+  }
+
+  late final _cJSON_AddItemReferenceToArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<cJSON>)>>('cJSON_AddItemReferenceToArray');
+  late final _cJSON_AddItemReferenceToArray = _cJSON_AddItemReferenceToArrayPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_AddItemReferenceToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_AddItemReferenceToObject(
+      object,
+      string,
+      item,
+    );
+  }
+
+  late final _cJSON_AddItemReferenceToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<cJSON>)>>('cJSON_AddItemReferenceToObject');
+  late final _cJSON_AddItemReferenceToObject =
+      _cJSON_AddItemReferenceToObjectPtr.asFunction<
+          void Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_DetachItemViaPointer(
+    ffi.Pointer<cJSON> parent,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_DetachItemViaPointer(
+      parent,
+      item,
+    );
+  }
+
+  late final _cJSON_DetachItemViaPointerPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<cJSON>)>>('cJSON_DetachItemViaPointer');
+  late final _cJSON_DetachItemViaPointer =
+      _cJSON_DetachItemViaPointerPtr.asFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_DetachItemFromArray(
+    ffi.Pointer<cJSON> array,
+    int which,
+  ) {
+    return _cJSON_DetachItemFromArray(
+      array,
+      which,
+    );
+  }
+
+  late final _cJSON_DetachItemFromArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Int)>>('cJSON_DetachItemFromArray');
+  late final _cJSON_DetachItemFromArray = _cJSON_DetachItemFromArrayPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, int)>();
+
+  void cJSON_DeleteItemFromArray(
+    ffi.Pointer<cJSON> array,
+    int which,
+  ) {
+    return _cJSON_DeleteItemFromArray(
+      array,
+      which,
+    );
+  }
+
+  late final _cJSON_DeleteItemFromArrayPtr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<cJSON>, ffi.Int)>>(
+      'cJSON_DeleteItemFromArray');
+  late final _cJSON_DeleteItemFromArray = _cJSON_DeleteItemFromArrayPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_DetachItemFromObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_DetachItemFromObject(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_DetachItemFromObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_DetachItemFromObject');
+  late final _cJSON_DetachItemFromObject =
+      _cJSON_DetachItemFromObjectPtr.asFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_DetachItemFromObjectCaseSensitive(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_DetachItemFromObjectCaseSensitive(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_DetachItemFromObjectCaseSensitivePtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Pointer<cJSON> Function(
+                  ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>>(
+      'cJSON_DetachItemFromObjectCaseSensitive');
+  late final _cJSON_DetachItemFromObjectCaseSensitive =
+      _cJSON_DetachItemFromObjectCaseSensitivePtr.asFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  void cJSON_DeleteItemFromObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_DeleteItemFromObject(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_DeleteItemFromObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_DeleteItemFromObject');
+  late final _cJSON_DeleteItemFromObject = _cJSON_DeleteItemFromObjectPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  void cJSON_DeleteItemFromObjectCaseSensitive(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_DeleteItemFromObjectCaseSensitive(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_DeleteItemFromObjectCaseSensitivePtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>>(
+      'cJSON_DeleteItemFromObjectCaseSensitive');
+  late final _cJSON_DeleteItemFromObjectCaseSensitive =
+      _cJSON_DeleteItemFromObjectCaseSensitivePtr.asFunction<
+          void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  void cJSON_InsertItemInArray(
+    ffi.Pointer<cJSON> array,
+    int which,
+    ffi.Pointer<cJSON> newitem,
+  ) {
+    return _cJSON_InsertItemInArray(
+      array,
+      which,
+      newitem,
+    );
+  }
+
+  late final _cJSON_InsertItemInArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Int,
+              ffi.Pointer<cJSON>)>>('cJSON_InsertItemInArray');
+  late final _cJSON_InsertItemInArray = _cJSON_InsertItemInArrayPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, int, ffi.Pointer<cJSON>)>();
+
+  int cJSON_ReplaceItemViaPointer(
+    ffi.Pointer<cJSON> parent,
+    ffi.Pointer<cJSON> item,
+    ffi.Pointer<cJSON> replacement,
+  ) {
+    return _cJSON_ReplaceItemViaPointer(
+      parent,
+      item,
+      replacement,
+    );
+  }
+
+  late final _cJSON_ReplaceItemViaPointerPtr = _lookup<
+      ffi.NativeFunction<
+          cJSON_bool Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>,
+              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemViaPointer');
+  late final _cJSON_ReplaceItemViaPointer =
+      _cJSON_ReplaceItemViaPointerPtr.asFunction<
+          int Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_ReplaceItemInArray(
+    ffi.Pointer<cJSON> array,
+    int which,
+    ffi.Pointer<cJSON> newitem,
+  ) {
+    return _cJSON_ReplaceItemInArray(
+      array,
+      which,
+      newitem,
+    );
+  }
+
+  late final _cJSON_ReplaceItemInArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Int,
+              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemInArray');
+  late final _cJSON_ReplaceItemInArray = _cJSON_ReplaceItemInArrayPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, int, ffi.Pointer<cJSON>)>();
+
+  void cJSON_ReplaceItemInObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+    ffi.Pointer<cJSON> newitem,
+  ) {
+    return _cJSON_ReplaceItemInObject(
+      object,
+      string,
+      newitem,
+    );
+  }
+
+  late final _cJSON_ReplaceItemInObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemInObject');
+  late final _cJSON_ReplaceItemInObject =
+      _cJSON_ReplaceItemInObjectPtr.asFunction<
+          void Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_ReplaceItemInObjectCaseSensitive(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+    ffi.Pointer<cJSON> newitem,
+  ) {
+    return _cJSON_ReplaceItemInObjectCaseSensitive(
+      object,
+      string,
+      newitem,
+    );
+  }
+
+  late final _cJSON_ReplaceItemInObjectCaseSensitivePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemInObjectCaseSensitive');
+  late final _cJSON_ReplaceItemInObjectCaseSensitive =
+      _cJSON_ReplaceItemInObjectCaseSensitivePtr.asFunction<
+          void Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_Duplicate(
+    ffi.Pointer<cJSON> item,
+    int recurse,
+  ) {
+    return _cJSON_Duplicate(
+      item,
+      recurse,
+    );
+  }
+
+  late final _cJSON_DuplicatePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, cJSON_bool)>>('cJSON_Duplicate');
+  late final _cJSON_Duplicate = _cJSON_DuplicatePtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, int)>();
+
+  int cJSON_Compare(
+    ffi.Pointer<cJSON> a,
+    ffi.Pointer<cJSON> b,
+    int case_sensitive,
+  ) {
+    return _cJSON_Compare(
+      a,
+      b,
+      case_sensitive,
+    );
+  }
+
+  late final _cJSON_ComparePtr = _lookup<
+      ffi.NativeFunction<
+          cJSON_bool Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>,
+              cJSON_bool)>>('cJSON_Compare');
+  late final _cJSON_Compare = _cJSON_ComparePtr
+      .asFunction<int Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>, int)>();
+
+  void cJSON_Minify(
+    ffi.Pointer<ffi.Char> json,
+  ) {
+    return _cJSON_Minify(
+      json,
+    );
+  }
+
+  late final _cJSON_MinifyPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Char>)>>(
+          'cJSON_Minify');
+  late final _cJSON_Minify =
+      _cJSON_MinifyPtr.asFunction<void Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddNullToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _cJSON_AddNullToObject(
+      object,
+      name,
+    );
+  }
+
+  late final _cJSON_AddNullToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddNullToObject');
+  late final _cJSON_AddNullToObject = _cJSON_AddNullToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddTrueToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _cJSON_AddTrueToObject(
+      object,
+      name,
+    );
+  }
+
+  late final _cJSON_AddTrueToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddTrueToObject');
+  late final _cJSON_AddTrueToObject = _cJSON_AddTrueToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddFalseToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _cJSON_AddFalseToObject(
+      object,
+      name,
+    );
+  }
+
+  late final _cJSON_AddFalseToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddFalseToObject');
+  late final _cJSON_AddFalseToObject = _cJSON_AddFalseToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddBoolToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+    int boolean,
+  ) {
+    return _cJSON_AddBoolToObject(
+      object,
+      name,
+      boolean,
+    );
+  }
+
+  late final _cJSON_AddBoolToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              cJSON_bool)>>('cJSON_AddBoolToObject');
+  late final _cJSON_AddBoolToObject = _cJSON_AddBoolToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_AddNumberToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+    double number,
+  ) {
+    return _cJSON_AddNumberToObject(
+      object,
+      name,
+      number,
+    );
+  }
+
+  late final _cJSON_AddNumberToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Double)>>('cJSON_AddNumberToObject');
+  late final _cJSON_AddNumberToObject = _cJSON_AddNumberToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, double)>();
+
+  ffi.Pointer<cJSON> cJSON_AddStringToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_AddStringToObject(
+      object,
+      name,
+      string,
+    );
+  }
+
+  late final _cJSON_AddStringToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddStringToObject');
+  late final _cJSON_AddStringToObject = _cJSON_AddStringToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddRawToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+    ffi.Pointer<ffi.Char> raw,
+  ) {
+    return _cJSON_AddRawToObject(
+      object,
+      name,
+      raw,
+    );
+  }
+
+  late final _cJSON_AddRawToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddRawToObject');
+  late final _cJSON_AddRawToObject = _cJSON_AddRawToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddObjectToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _cJSON_AddObjectToObject(
+      object,
+      name,
+    );
+  }
+
+  late final _cJSON_AddObjectToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddObjectToObject');
+  late final _cJSON_AddObjectToObject = _cJSON_AddObjectToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddArrayToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _cJSON_AddArrayToObject(
+      object,
+      name,
+    );
+  }
+
+  late final _cJSON_AddArrayToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddArrayToObject');
+  late final _cJSON_AddArrayToObject = _cJSON_AddArrayToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  double cJSON_SetNumberHelper(
+    ffi.Pointer<cJSON> object,
+    double number,
+  ) {
+    return _cJSON_SetNumberHelper(
+      object,
+      number,
+    );
+  }
+
+  late final _cJSON_SetNumberHelperPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Double Function(ffi.Pointer<cJSON>, ffi.Double)>>(
+      'cJSON_SetNumberHelper');
+  late final _cJSON_SetNumberHelper = _cJSON_SetNumberHelperPtr
+      .asFunction<double Function(ffi.Pointer<cJSON>, double)>();
+
+  ffi.Pointer<ffi.Void> cJSON_malloc(
+    int size,
+  ) {
+    return _cJSON_malloc(
+      size,
+    );
+  }
+
+  late final _cJSON_mallocPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Size)>>(
+          'cJSON_malloc');
+  late final _cJSON_malloc =
+      _cJSON_mallocPtr.asFunction<ffi.Pointer<ffi.Void> Function(int)>();
+
+  void cJSON_free(
+    ffi.Pointer<ffi.Void> object,
+  ) {
+    return _cJSON_free(
+      object,
+    );
+  }
+
+  late final _cJSON_freePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
+          'cJSON_free');
+  late final _cJSON_free =
+      _cJSON_freePtr.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
+}
+
+final class cJSON extends ffi.Struct {
+  external ffi.Pointer<cJSON> next;
+
+  external ffi.Pointer<cJSON> prev;
+
+  external ffi.Pointer<cJSON> child;
+
+  @ffi.Int()
+  external int type;
+
+  external ffi.Pointer<ffi.Char> valuestring;
+
+  @ffi.Int()
+  external int valueint;
+
+  @ffi.Double()
+  external double valuedouble;
+
+  external ffi.Pointer<ffi.Char> string;
+}
+
+final class cJSON_Hooks extends ffi.Struct {
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Size sz)>>
+      malloc_fn;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void> ptr)>>
+      free_fn;
+}
+
+typedef cJSON_bool = ffi.Int;
+typedef DartcJSON_bool = int;
+
+const int CJSON_VERSION_MAJOR = 1;
+
+const int CJSON_VERSION_MINOR = 7;
+
+const int CJSON_VERSION_PATCH = 12;
+
+const int cJSON_Invalid = 0;
+
+const int cJSON_False = 1;
+
+const int cJSON_True = 2;
+
+const int cJSON_NULL = 4;
+
+const int cJSON_Number = 8;
+
+const int cJSON_String = 16;
+
+const int cJSON_Array = 32;
+
+const int cJSON_Object = 64;
+
+const int cJSON_Raw = 128;
+
+const int cJSON_IsReference = 256;
+
+const int cJSON_StringIsConst = 512;
+
+const int CJSON_NESTING_LIMIT = 1000;
+
+const double CJSON_DOUBLE_PRECISION = 1e-16;
diff --git a/pkgs/ffigen/example/c_json/config.yaml b/pkgs/ffigen/example/c_json/config.yaml
new file mode 100644
index 0000000..3d61cbd
--- /dev/null
+++ b/pkgs/ffigen/example/c_json/config.yaml
@@ -0,0 +1,33 @@
+# yaml-language-server: $schema=../../ffigen.schema.json
+
+output: 'cjson_generated_bindings.dart'
+name: 'CJson'
+description: 'Holds bindings to cJSON.'
+headers:
+  entry-points:
+    - '../../third_party/cjson_library/cJSON.h'
+  include-directives:
+    - '**cJSON.h'
+comments: false
+preamble: |
+  // Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
+  //
+  // Permission is hereby granted, free of charge, to any person obtaining a copy
+  // of this software and associated documentation files (the "Software"), to deal
+  // in the Software without restriction, including without limitation the rights
+  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  // copies of the Software, and to permit persons to whom the Software is
+  // furnished to do so, subject to the following conditions:
+  //
+  // The above copyright notice and this permission notice shall be included in
+  // all copies or substantial portions of the Software.
+  //
+  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  // THE SOFTWARE.
+
+  // ignore_for_file: camel_case_types, non_constant_identifier_names
\ No newline at end of file
diff --git a/pkgs/ffigen/example/c_json/example.json b/pkgs/ffigen/example/c_json/example.json
new file mode 100644
index 0000000..073b05c
--- /dev/null
+++ b/pkgs/ffigen/example/c_json/example.json
@@ -0,0 +1,14 @@
+{
+    "name": "CoolGuy",
+    "age": 21,
+    "nicknames": [
+        {
+            "name": "Mr. Cool",
+            "length": 8
+        },
+        {
+            "name": "Ice Cold",
+            "length": 8
+        }
+    ]
+}
diff --git a/pkgs/ffigen/example/c_json/main.dart b/pkgs/ffigen/example/c_json/main.dart
new file mode 100644
index 0000000..adbdac6
--- /dev/null
+++ b/pkgs/ffigen/example/c_json/main.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:ffi/ffi.dart';
+import 'package:path/path.dart' as p;
+
+import 'cjson_generated_bindings.dart' as cj;
+
+final cjson = cj.CJson(DynamicLibrary.open(_getPath()));
+
+/// Using the generated C_JSON bindings.
+void main() {
+  // Load json from [example.json] file.
+  final jsonString = File('./example.json').readAsStringSync();
+
+  // Parse this json string using our cJSON library.
+  final cjsonParsedJson = cjson.cJSON_Parse(jsonString.toNativeUtf8().cast());
+  if (cjsonParsedJson == nullptr) {
+    print('Error parsing cjson.');
+    exit(1);
+  }
+  // The json is now stored in some C data structure which we need
+  // to iterate and convert to a dart object (map/list).
+
+  // Converting cjson object to a dart object.
+  final dynamic dartJson = convertCJsonToDartObj(cjsonParsedJson.cast());
+
+  // Delete the cjsonParsedJson object.
+  cjson.cJSON_Delete(cjsonParsedJson);
+
+  // Check if the converted json is correct
+  // by comparing the result with json converted by `dart:convert`.
+  if (dartJson.toString() == json.decode(jsonString).toString()) {
+    print('Parsed Json: $dartJson');
+    print('Json converted successfully');
+  } else {
+    print("Converted json doesn't match\n");
+    print('Actual:\n$dartJson\n');
+    print('Expected:\n${json.decode(jsonString)}');
+  }
+}
+
+String _getPath() {
+  final cjsonExamplePath = Directory.current.absolute.path;
+  var path = p.join(cjsonExamplePath, '../../third_party/cjson_library/');
+  if (Platform.isMacOS) {
+    path = p.join(path, 'libcjson.dylib');
+  } else if (Platform.isWindows) {
+    path = p.join(path, 'Debug', 'cjson.dll');
+  } else {
+    path = p.join(path, 'libcjson.so');
+  }
+  return path;
+}
+
+dynamic convertCJsonToDartObj(Pointer<cj.cJSON> parsedcjson) {
+  dynamic obj;
+  if (cjson.cJSON_IsObject(parsedcjson.cast()) == 1) {
+    obj = <String, dynamic>{};
+
+    Pointer<cj.cJSON>? ptr;
+    ptr = parsedcjson.ref.child;
+    while (ptr != nullptr) {
+      final dynamic o = convertCJsonToDartObj(ptr!);
+      _addToObj(obj, o, ptr.ref.string.cast());
+      ptr = ptr.ref.next;
+    }
+  } else if (cjson.cJSON_IsArray(parsedcjson.cast()) == 1) {
+    obj = <dynamic>[];
+
+    Pointer<cj.cJSON>? ptr;
+    ptr = parsedcjson.ref.child;
+    while (ptr != nullptr) {
+      final dynamic o = convertCJsonToDartObj(ptr!);
+      _addToObj(obj, o);
+      ptr = ptr.ref.next;
+    }
+  } else if (cjson.cJSON_IsString(parsedcjson.cast()) == 1) {
+    obj = parsedcjson.ref.valuestring.cast<Utf8>().toDartString();
+  } else if (cjson.cJSON_IsNumber(parsedcjson.cast()) == 1) {
+    obj = parsedcjson.ref.valueint == parsedcjson.ref.valuedouble
+        ? parsedcjson.ref.valueint
+        : parsedcjson.ref.valuedouble;
+  }
+
+  return obj;
+}
+
+void _addToObj(dynamic obj, dynamic o, [Pointer<Utf8>? name]) {
+  if (obj is Map<String, dynamic>) {
+    obj[name!.toDartString()] = o;
+  } else if (obj is List<dynamic>) {
+    obj.add(o);
+  }
+}
diff --git a/pkgs/ffigen/example/c_json/pubspec.yaml b/pkgs/ffigen/example/c_json/pubspec.yaml
new file mode 100644
index 0000000..4694200
--- /dev/null
+++ b/pkgs/ffigen/example/c_json/pubspec.yaml
@@ -0,0 +1,17 @@
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+name: c_json_example
+
+environment:
+  sdk: '>=3.2.0 <4.0.0'
+
+dependencies:
+  ffi: ^2.0.1
+  path: ^1.8.0
+
+dev_dependencies:
+  ffigen:
+    path: '../../'
+  lints: ^2.0.1
diff --git a/pkgs/ffigen/example/ffinative/.gitignore b/pkgs/ffigen/example/ffinative/.gitignore
new file mode 100644
index 0000000..1b05164
--- /dev/null
+++ b/pkgs/ffigen/example/ffinative/.gitignore
@@ -0,0 +1,11 @@
+# Files and directories created by pub.
+.dart_tool/
+.packages
+# Remove the following pattern if you wish to check in your lock file.
+pubspec.lock
+
+# Conventional directory for build outputs.
+build/
+
+# Directory created by dartdoc.
+doc/api/
diff --git a/pkgs/ffigen/example/ffinative/README.md b/pkgs/ffigen/example/ffinative/README.md
new file mode 100644
index 0000000..7c5b169
--- /dev/null
+++ b/pkgs/ffigen/example/ffinative/README.md
@@ -0,0 +1,10 @@
+# Natives example
+
+A simple example generating `Native` bindings for a very small header file (`headers/example.h`).
+
+## Generating bindings
+At the root of this example (`example/simple`), run -
+```
+dart run ffigen --config config.yaml
+```
+This will generate bindings in a file: [generated_bindings.dart](./generated_bindings.dart).
diff --git a/pkgs/ffigen/example/ffinative/config.yaml b/pkgs/ffigen/example/ffinative/config.yaml
new file mode 100644
index 0000000..1bb3dac
--- /dev/null
+++ b/pkgs/ffigen/example/ffinative/config.yaml
@@ -0,0 +1,12 @@
+# yaml-language-server: $schema=../../ffigen.schema.json
+
+name: NativeLibrary
+ffi-native:
+  assetId: 'package:ffinative_example/generated_bindings.dart' # (optional)
+description: Bindings to `headers/example.h`.
+output: 'lib/generated_bindings.dart'
+headers:
+  entry-points:
+    - 'headers/example.h'
+preamble: |
+  // ignore_for_file: deprecated_member_use
diff --git a/pkgs/ffigen/example/ffinative/headers/example.h b/pkgs/ffigen/example/ffinative/headers/example.h
new file mode 100644
index 0000000..44056dd
--- /dev/null
+++ b/pkgs/ffigen/example/ffinative/headers/example.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/** Adds 2 integers. */
+int sum(int a, int b);
+
+/** Subtracts 2 integers. */
+int subtract(int a, int b);
+
+/** Multiplies 2 integers, returns pointer to an integer,. */
+int *multiply(int a, int b);
+
+/** Divides 2 integers, returns pointer to a float. */
+float *divide(int a, int b);
+
+/** Divides 2 floats, returns a pointer to double. */
+double *dividePrecision(float a, float b);
diff --git a/pkgs/ffigen/example/ffinative/lib/generated_bindings.dart b/pkgs/ffigen/example/ffinative/lib/generated_bindings.dart
new file mode 100644
index 0000000..13c7d2b
--- /dev/null
+++ b/pkgs/ffigen/example/ffinative/lib/generated_bindings.dart
@@ -0,0 +1,51 @@
+// ignore_for_file: deprecated_member_use
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Adds 2 integers.
+@ffi.Native<ffi.Int Function(ffi.Int, ffi.Int)>(
+    symbol: 'sum', assetId: 'package:ffinative_example/generated_bindings.dart')
+external int sum(
+  int a,
+  int b,
+);
+
+/// Subtracts 2 integers.
+@ffi.Native<ffi.Int Function(ffi.Int, ffi.Int)>(
+    symbol: 'subtract',
+    assetId: 'package:ffinative_example/generated_bindings.dart')
+external int subtract(
+  int a,
+  int b,
+);
+
+/// Multiplies 2 integers, returns pointer to an integer,.
+@ffi.Native<ffi.Pointer<ffi.Int> Function(ffi.Int, ffi.Int)>(
+    symbol: 'multiply',
+    assetId: 'package:ffinative_example/generated_bindings.dart')
+external ffi.Pointer<ffi.Int> multiply(
+  int a,
+  int b,
+);
+
+/// Divides 2 integers, returns pointer to a float.
+@ffi.Native<ffi.Pointer<ffi.Float> Function(ffi.Int, ffi.Int)>(
+    symbol: 'divide',
+    assetId: 'package:ffinative_example/generated_bindings.dart')
+external ffi.Pointer<ffi.Float> divide(
+  int a,
+  int b,
+);
+
+/// Divides 2 floats, returns a pointer to double.
+@ffi.Native<ffi.Pointer<ffi.Double> Function(ffi.Float, ffi.Float)>(
+    symbol: 'dividePrecision',
+    assetId: 'package:ffinative_example/generated_bindings.dart')
+external ffi.Pointer<ffi.Double> dividePrecision(
+  double a,
+  double b,
+);
diff --git a/pkgs/ffigen/example/ffinative/pubspec.yaml b/pkgs/ffigen/example/ffinative/pubspec.yaml
new file mode 100644
index 0000000..e971031
--- /dev/null
+++ b/pkgs/ffigen/example/ffinative/pubspec.yaml
@@ -0,0 +1,15 @@
+# Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+name: ffinative_example
+
+environment:
+  sdk: '>=3.2.0 <4.0.0'
+
+dependencies:
+  ffi: ^2.0.1
+dev_dependencies:
+  ffigen:
+    path: '../../'
+  lints: ^2.0.0
diff --git a/pkgs/ffigen/example/libclang-example/.gitignore b/pkgs/ffigen/example/libclang-example/.gitignore
new file mode 100644
index 0000000..1b05164
--- /dev/null
+++ b/pkgs/ffigen/example/libclang-example/.gitignore
@@ -0,0 +1,11 @@
+# Files and directories created by pub.
+.dart_tool/
+.packages
+# Remove the following pattern if you wish to check in your lock file.
+pubspec.lock
+
+# Conventional directory for build outputs.
+build/
+
+# Directory created by dartdoc.
+doc/api/
diff --git a/pkgs/ffigen/example/libclang-example/config.yaml b/pkgs/ffigen/example/libclang-example/config.yaml
new file mode 100644
index 0000000..6b3db35
--- /dev/null
+++ b/pkgs/ffigen/example/libclang-example/config.yaml
@@ -0,0 +1,77 @@
+# yaml-language-server: $schema=../../ffigen.schema.json
+
+output: 'generated_bindings.dart'
+
+# This will sort the bindings alphabetically.
+# sort: true
+
+# This is required if LLVM can't be found in default locations by ffigen.
+# llvm-path:
+#   - '/usr/local/opt/llvm'
+
+# Bash style Glob matching is also supported.
+# TODO(https://github.com/dart-lang/ffigen/issues/11): Globs dont work on
+# windows if they begin with '.' or '..'.
+headers:
+  entry-points:
+    - ../../third_party/libclang/include/clang-c/Index.h
+  include-directives: # use glob syntax to match with header file path.
+    - '**CXString.h'
+    - '**Index.h'
+
+compiler-opts:
+  - '-I../../third_party/libclang/include'
+  - '-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/'
+  - '-Wno-nullability-completeness'
+functions:
+  include:
+    - 'clang_.*' # Can be a regexp, '.' matches any character.
+  symbol-address:
+    include:
+      - 'clang_.*' # Symbol Address for these functions will be exposed via addresses.
+  expose-typedefs:
+    include:
+      - 'clang_.*' # Typedefs for Native and Dart type for these functions will be generated.
+structs:
+  include:
+    - 'CX.*'
+enums:
+  include:
+    - 'CXTypeKind' # Full names are given higher priority than regexp.
+    - 'CXGlobalOptFlags'
+
+library-imports:
+  custom_import: 'custom_import.dart'
+
+# These can be used to map any typedef to a specific native type.
+type-map:
+  typedefs:
+    'time_t':
+      lib: 'ffi'
+      c-type: 'Int64'
+      dart-type: 'int'
+  structs:
+    'CXCursorSetImpl':
+      lib: 'custom_import'
+      c-type: 'CXCursorSetImpl'
+      dart-type: 'CXCursorSetImpl'
+
+# Default is 'NativeLibrary'
+name: 'LibClang'
+
+description: 'Holds bindings to LibClang.'
+
+# Doc Comments for generated binings.
+# Comments can be disabled by using comments: false
+comments:
+  style: doxygen # Options - doxygen(default) / any.
+  length: full # Options - brief / full(default).
+
+# The header of the file, this is pasted as it is.
+preamble: |
+  // Part of the LLVM Project, under the Apache License v2.0 with LLVM
+  // Exceptions.
+  // See https://llvm.org/LICENSE.txt for license information.
+  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+  // ignore_for_file: camel_case_types, non_constant_identifier_names
diff --git a/pkgs/ffigen/example/libclang-example/custom_import.dart b/pkgs/ffigen/example/libclang-example/custom_import.dart
new file mode 100644
index 0000000..dd6196c
--- /dev/null
+++ b/pkgs/ffigen/example/libclang-example/custom_import.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+
+/// Represents a native unsigned pointer-sized integer in C.
+///
+/// [UintPtr] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: Uint64(),
+  Abi.androidIA32: Uint32(),
+  Abi.androidX64: Uint64(),
+  Abi.fuchsiaArm64: Uint64(),
+  Abi.fuchsiaX64: Uint64(),
+  Abi.iosArm: Uint32(),
+  Abi.iosArm64: Uint64(),
+  Abi.iosX64: Uint64(),
+  Abi.linuxArm: Uint32(),
+  Abi.linuxArm64: Uint64(),
+  Abi.linuxIA32: Uint32(),
+  Abi.linuxX64: Uint64(),
+  Abi.macosArm64: Uint64(),
+  Abi.macosX64: Uint64(),
+  Abi.windowsArm64: Uint64(),
+  Abi.windowsIA32: Uint32(),
+  Abi.windowsX64: Uint64(),
+})
+final class UintPtr extends AbiSpecificInteger {
+  const UintPtr();
+}
+
+/// `unsigned long` in C.
+///
+/// [UnsignedLong] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@AbiSpecificIntegerMapping({
+  Abi.androidArm: Uint32(),
+  Abi.androidArm64: Uint64(),
+  Abi.androidIA32: Uint32(),
+  Abi.androidX64: Uint64(),
+  Abi.fuchsiaArm64: Uint64(),
+  Abi.fuchsiaX64: Uint64(),
+  Abi.iosArm: Uint32(),
+  Abi.iosArm64: Uint64(),
+  Abi.iosX64: Uint64(),
+  Abi.linuxArm: Uint32(),
+  Abi.linuxArm64: Uint64(),
+  Abi.linuxIA32: Uint32(),
+  Abi.linuxX64: Uint64(),
+  Abi.macosArm64: Uint64(),
+  Abi.macosX64: Uint64(),
+  Abi.windowsArm64: Uint32(),
+  Abi.windowsIA32: Uint32(),
+  Abi.windowsX64: Uint32(),
+})
+final class UnsignedLong extends AbiSpecificInteger {
+  const UnsignedLong();
+}
+
+final class CXCursorSetImpl extends Opaque {}
diff --git a/pkgs/ffigen/example/libclang-example/generated_bindings.dart b/pkgs/ffigen/example/libclang-example/generated_bindings.dart
new file mode 100644
index 0000000..7cf663e
--- /dev/null
+++ b/pkgs/ffigen/example/libclang-example/generated_bindings.dart
@@ -0,0 +1,11130 @@
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
+// Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// ignore_for_file: camel_case_types, non_constant_identifier_names
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+import 'custom_import.dart' as custom_import;
+
+/// Holds bindings to LibClang.
+class LibClang {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  LibClang(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  LibClang.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  /// Retrieve the character data associated with the given string.
+  ffi.Pointer<ffi.Char> clang_getCString(
+    CXString string,
+  ) {
+    return _clang_getCString(
+      string,
+    );
+  }
+
+  late final _clang_getCStringPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCString>>('clang_getCString');
+  late final _clang_getCString =
+      _clang_getCStringPtr.asFunction<DartClang_getCString>();
+
+  /// Free the given string.
+  void clang_disposeString(
+    CXString string,
+  ) {
+    return _clang_disposeString(
+      string,
+    );
+  }
+
+  late final _clang_disposeStringPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeString>>(
+          'clang_disposeString');
+  late final _clang_disposeString =
+      _clang_disposeStringPtr.asFunction<DartClang_disposeString>();
+
+  /// Free the given string set.
+  void clang_disposeStringSet(
+    ffi.Pointer<CXStringSet> set1,
+  ) {
+    return _clang_disposeStringSet(
+      set1,
+    );
+  }
+
+  late final _clang_disposeStringSetPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeStringSet>>(
+          'clang_disposeStringSet');
+  late final _clang_disposeStringSet =
+      _clang_disposeStringSetPtr.asFunction<DartClang_disposeStringSet>();
+
+  /// Provides a shared context for creating translation units.
+  ///
+  /// It provides two options:
+  ///
+  /// - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local"
+  /// declarations (when loading any new translation units). A "local" declaration
+  /// is one that belongs in the translation unit itself and not in a precompiled
+  /// header that was used by the translation unit. If zero, all declarations
+  /// will be enumerated.
+  ///
+  /// Here is an example:
+  ///
+  /// \code
+  /// // excludeDeclsFromPCH = 1, displayDiagnostics=1
+  /// Idx = clang_createIndex(1, 1);
+  ///
+  /// // IndexTest.pch was produced with the following command:
+  /// // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
+  /// TU = clang_createTranslationUnit(Idx, "IndexTest.pch");
+  ///
+  /// // This will load all the symbols from 'IndexTest.pch'
+  /// clang_visitChildren(clang_getTranslationUnitCursor(TU),
+  /// TranslationUnitVisitor, 0);
+  /// clang_disposeTranslationUnit(TU);
+  ///
+  /// // This will load all the symbols from 'IndexTest.c', excluding symbols
+  /// // from 'IndexTest.pch'.
+  /// char *args[] = { "-Xclang", "-include-pch=IndexTest.pch" };
+  /// TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args,
+  /// 0, 0);
+  /// clang_visitChildren(clang_getTranslationUnitCursor(TU),
+  /// TranslationUnitVisitor, 0);
+  /// clang_disposeTranslationUnit(TU);
+  /// \endcode
+  ///
+  /// This process of creating the 'pch', loading it separately, and using it (via
+  /// -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
+  /// (which gives the indexer the same performance benefit as the compiler).
+  CXIndex clang_createIndex(
+    int excludeDeclarationsFromPCH,
+    int displayDiagnostics,
+  ) {
+    return _clang_createIndex(
+      excludeDeclarationsFromPCH,
+      displayDiagnostics,
+    );
+  }
+
+  late final _clang_createIndexPtr =
+      _lookup<ffi.NativeFunction<NativeClang_createIndex>>('clang_createIndex');
+  late final _clang_createIndex =
+      _clang_createIndexPtr.asFunction<DartClang_createIndex>();
+
+  /// Destroy the given index.
+  ///
+  /// The index must not be destroyed until all of the translation units created
+  /// within that index have been destroyed.
+  void clang_disposeIndex(
+    CXIndex index,
+  ) {
+    return _clang_disposeIndex(
+      index,
+    );
+  }
+
+  late final _clang_disposeIndexPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeIndex>>(
+          'clang_disposeIndex');
+  late final _clang_disposeIndex =
+      _clang_disposeIndexPtr.asFunction<DartClang_disposeIndex>();
+
+  /// Sets general options associated with a CXIndex.
+  ///
+  /// For example:
+  /// \code
+  /// CXIndex idx = ...;
+  /// clang_CXIndex_setGlobalOptions(idx,
+  /// clang_CXIndex_getGlobalOptions(idx) |
+  /// CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
+  /// \endcode
+  ///
+  /// \param options A bitmask of options, a bitwise OR of CXGlobalOpt_XXX flags.
+  void clang_CXIndex_setGlobalOptions(
+    CXIndex arg0,
+    int options,
+  ) {
+    return _clang_CXIndex_setGlobalOptions(
+      arg0,
+      options,
+    );
+  }
+
+  late final _clang_CXIndex_setGlobalOptionsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXIndex_setGlobalOptions>>(
+          'clang_CXIndex_setGlobalOptions');
+  late final _clang_CXIndex_setGlobalOptions =
+      _clang_CXIndex_setGlobalOptionsPtr
+          .asFunction<DartClang_CXIndex_setGlobalOptions>();
+
+  /// Gets the general options associated with a CXIndex.
+  ///
+  /// \returns A bitmask of options, a bitwise OR of CXGlobalOpt_XXX flags that
+  /// are associated with the given CXIndex object.
+  int clang_CXIndex_getGlobalOptions(
+    CXIndex arg0,
+  ) {
+    return _clang_CXIndex_getGlobalOptions(
+      arg0,
+    );
+  }
+
+  late final _clang_CXIndex_getGlobalOptionsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXIndex_getGlobalOptions>>(
+          'clang_CXIndex_getGlobalOptions');
+  late final _clang_CXIndex_getGlobalOptions =
+      _clang_CXIndex_getGlobalOptionsPtr
+          .asFunction<DartClang_CXIndex_getGlobalOptions>();
+
+  /// Sets the invocation emission path option in a CXIndex.
+  ///
+  /// The invocation emission path specifies a path which will contain log
+  /// files for certain libclang invocations. A null value (default) implies that
+  /// libclang invocations are not logged..
+  void clang_CXIndex_setInvocationEmissionPathOption(
+    CXIndex arg0,
+    ffi.Pointer<ffi.Char> Path,
+  ) {
+    return _clang_CXIndex_setInvocationEmissionPathOption(
+      arg0,
+      Path,
+    );
+  }
+
+  late final _clang_CXIndex_setInvocationEmissionPathOptionPtr = _lookup<
+          ffi
+          .NativeFunction<NativeClang_CXIndex_setInvocationEmissionPathOption>>(
+      'clang_CXIndex_setInvocationEmissionPathOption');
+  late final _clang_CXIndex_setInvocationEmissionPathOption =
+      _clang_CXIndex_setInvocationEmissionPathOptionPtr
+          .asFunction<DartClang_CXIndex_setInvocationEmissionPathOption>();
+
+  /// Retrieve the complete file and path name of the given file.
+  CXString clang_getFileName(
+    CXFile SFile,
+  ) {
+    return _clang_getFileName(
+      SFile,
+    );
+  }
+
+  late final _clang_getFileNamePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getFileName>>('clang_getFileName');
+  late final _clang_getFileName =
+      _clang_getFileNamePtr.asFunction<DartClang_getFileName>();
+
+  /// Retrieve the last modification time of the given file.
+  int clang_getFileTime(
+    CXFile SFile,
+  ) {
+    return _clang_getFileTime(
+      SFile,
+    );
+  }
+
+  late final _clang_getFileTimePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getFileTime>>('clang_getFileTime');
+  late final _clang_getFileTime =
+      _clang_getFileTimePtr.asFunction<DartClang_getFileTime>();
+
+  /// Retrieve the unique ID for the given \c file.
+  ///
+  /// \param file the file to get the ID for.
+  /// \param outID stores the returned CXFileUniqueID.
+  /// \returns If there was a failure getting the unique ID, returns non-zero,
+  /// otherwise returns 0.
+  int clang_getFileUniqueID(
+    CXFile file,
+    ffi.Pointer<CXFileUniqueID> outID,
+  ) {
+    return _clang_getFileUniqueID(
+      file,
+      outID,
+    );
+  }
+
+  late final _clang_getFileUniqueIDPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getFileUniqueID>>(
+          'clang_getFileUniqueID');
+  late final _clang_getFileUniqueID =
+      _clang_getFileUniqueIDPtr.asFunction<DartClang_getFileUniqueID>();
+
+  /// Determine whether the given header is guarded against
+  /// multiple inclusions, either with the conventional
+  /// \#ifndef/\#define/\#endif macro guards or with \#pragma once.
+  int clang_isFileMultipleIncludeGuarded(
+    CXTranslationUnit tu,
+    CXFile file,
+  ) {
+    return _clang_isFileMultipleIncludeGuarded(
+      tu,
+      file,
+    );
+  }
+
+  late final _clang_isFileMultipleIncludeGuardedPtr =
+      _lookup<ffi.NativeFunction<NativeClang_isFileMultipleIncludeGuarded>>(
+          'clang_isFileMultipleIncludeGuarded');
+  late final _clang_isFileMultipleIncludeGuarded =
+      _clang_isFileMultipleIncludeGuardedPtr
+          .asFunction<DartClang_isFileMultipleIncludeGuarded>();
+
+  /// Retrieve a file handle within the given translation unit.
+  ///
+  /// \param tu the translation unit
+  ///
+  /// \param file_name the name of the file.
+  ///
+  /// \returns the file handle for the named file in the translation unit \p tu,
+  /// or a NULL file handle if the file was not a part of this translation unit.
+  CXFile clang_getFile(
+    CXTranslationUnit tu,
+    ffi.Pointer<ffi.Char> file_name,
+  ) {
+    return _clang_getFile(
+      tu,
+      file_name,
+    );
+  }
+
+  late final _clang_getFilePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getFile>>('clang_getFile');
+  late final _clang_getFile = _clang_getFilePtr.asFunction<DartClang_getFile>();
+
+  /// Retrieve the buffer associated with the given file.
+  ///
+  /// \param tu the translation unit
+  ///
+  /// \param file the file for which to retrieve the buffer.
+  ///
+  /// \param size [out] if non-NULL, will be set to the size of the buffer.
+  ///
+  /// \returns a pointer to the buffer in memory that holds the contents of
+  /// \p file, or a NULL pointer when the file is not loaded.
+  ffi.Pointer<ffi.Char> clang_getFileContents(
+    CXTranslationUnit tu,
+    CXFile file,
+    ffi.Pointer<ffi.Size> size,
+  ) {
+    return _clang_getFileContents(
+      tu,
+      file,
+      size,
+    );
+  }
+
+  late final _clang_getFileContentsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getFileContents>>(
+          'clang_getFileContents');
+  late final _clang_getFileContents =
+      _clang_getFileContentsPtr.asFunction<DartClang_getFileContents>();
+
+  /// Returns non-zero if the \c file1 and \c file2 point to the same file,
+  /// or they are both NULL.
+  int clang_File_isEqual(
+    CXFile file1,
+    CXFile file2,
+  ) {
+    return _clang_File_isEqual(
+      file1,
+      file2,
+    );
+  }
+
+  late final _clang_File_isEqualPtr =
+      _lookup<ffi.NativeFunction<NativeClang_File_isEqual>>(
+          'clang_File_isEqual');
+  late final _clang_File_isEqual =
+      _clang_File_isEqualPtr.asFunction<DartClang_File_isEqual>();
+
+  /// Returns the real path name of \c file.
+  ///
+  /// An empty string may be returned. Use \c clang_getFileName() in that case.
+  CXString clang_File_tryGetRealPathName(
+    CXFile file,
+  ) {
+    return _clang_File_tryGetRealPathName(
+      file,
+    );
+  }
+
+  late final _clang_File_tryGetRealPathNamePtr =
+      _lookup<ffi.NativeFunction<NativeClang_File_tryGetRealPathName>>(
+          'clang_File_tryGetRealPathName');
+  late final _clang_File_tryGetRealPathName = _clang_File_tryGetRealPathNamePtr
+      .asFunction<DartClang_File_tryGetRealPathName>();
+
+  /// Retrieve a NULL (invalid) source location.
+  CXSourceLocation clang_getNullLocation() {
+    return _clang_getNullLocation();
+  }
+
+  late final _clang_getNullLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getNullLocation>>(
+          'clang_getNullLocation');
+  late final _clang_getNullLocation =
+      _clang_getNullLocationPtr.asFunction<DartClang_getNullLocation>();
+
+  /// Determine whether two source locations, which must refer into
+  /// the same translation unit, refer to exactly the same point in the source
+  /// code.
+  ///
+  /// \returns non-zero if the source locations refer to the same location, zero
+  /// if they refer to different locations.
+  int clang_equalLocations(
+    CXSourceLocation loc1,
+    CXSourceLocation loc2,
+  ) {
+    return _clang_equalLocations(
+      loc1,
+      loc2,
+    );
+  }
+
+  late final _clang_equalLocationsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_equalLocations>>(
+          'clang_equalLocations');
+  late final _clang_equalLocations =
+      _clang_equalLocationsPtr.asFunction<DartClang_equalLocations>();
+
+  /// Retrieves the source location associated with a given file/line/column
+  /// in a particular translation unit.
+  CXSourceLocation clang_getLocation(
+    CXTranslationUnit tu,
+    CXFile file,
+    int line,
+    int column,
+  ) {
+    return _clang_getLocation(
+      tu,
+      file,
+      line,
+      column,
+    );
+  }
+
+  late final _clang_getLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getLocation>>('clang_getLocation');
+  late final _clang_getLocation =
+      _clang_getLocationPtr.asFunction<DartClang_getLocation>();
+
+  /// Retrieves the source location associated with a given character offset
+  /// in a particular translation unit.
+  CXSourceLocation clang_getLocationForOffset(
+    CXTranslationUnit tu,
+    CXFile file,
+    int offset,
+  ) {
+    return _clang_getLocationForOffset(
+      tu,
+      file,
+      offset,
+    );
+  }
+
+  late final _clang_getLocationForOffsetPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getLocationForOffset>>(
+          'clang_getLocationForOffset');
+  late final _clang_getLocationForOffset = _clang_getLocationForOffsetPtr
+      .asFunction<DartClang_getLocationForOffset>();
+
+  /// Returns non-zero if the given source location is in a system header.
+  int clang_Location_isInSystemHeader(
+    CXSourceLocation location,
+  ) {
+    return _clang_Location_isInSystemHeader(
+      location,
+    );
+  }
+
+  late final _clang_Location_isInSystemHeaderPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Location_isInSystemHeader>>(
+          'clang_Location_isInSystemHeader');
+  late final _clang_Location_isInSystemHeader =
+      _clang_Location_isInSystemHeaderPtr
+          .asFunction<DartClang_Location_isInSystemHeader>();
+
+  /// Returns non-zero if the given source location is in the main file of
+  /// the corresponding translation unit.
+  int clang_Location_isFromMainFile(
+    CXSourceLocation location,
+  ) {
+    return _clang_Location_isFromMainFile(
+      location,
+    );
+  }
+
+  late final _clang_Location_isFromMainFilePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Location_isFromMainFile>>(
+          'clang_Location_isFromMainFile');
+  late final _clang_Location_isFromMainFile = _clang_Location_isFromMainFilePtr
+      .asFunction<DartClang_Location_isFromMainFile>();
+
+  /// Retrieve a NULL (invalid) source range.
+  CXSourceRange clang_getNullRange() {
+    return _clang_getNullRange();
+  }
+
+  late final _clang_getNullRangePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getNullRange>>(
+          'clang_getNullRange');
+  late final _clang_getNullRange =
+      _clang_getNullRangePtr.asFunction<DartClang_getNullRange>();
+
+  /// Retrieve a source range given the beginning and ending source
+  /// locations.
+  CXSourceRange clang_getRange(
+    CXSourceLocation begin,
+    CXSourceLocation end,
+  ) {
+    return _clang_getRange(
+      begin,
+      end,
+    );
+  }
+
+  late final _clang_getRangePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getRange>>('clang_getRange');
+  late final _clang_getRange =
+      _clang_getRangePtr.asFunction<DartClang_getRange>();
+
+  /// Determine whether two ranges are equivalent.
+  ///
+  /// \returns non-zero if the ranges are the same, zero if they differ.
+  int clang_equalRanges(
+    CXSourceRange range1,
+    CXSourceRange range2,
+  ) {
+    return _clang_equalRanges(
+      range1,
+      range2,
+    );
+  }
+
+  late final _clang_equalRangesPtr =
+      _lookup<ffi.NativeFunction<NativeClang_equalRanges>>('clang_equalRanges');
+  late final _clang_equalRanges =
+      _clang_equalRangesPtr.asFunction<DartClang_equalRanges>();
+
+  /// Returns non-zero if \p range is null.
+  int clang_Range_isNull(
+    CXSourceRange range,
+  ) {
+    return _clang_Range_isNull(
+      range,
+    );
+  }
+
+  late final _clang_Range_isNullPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Range_isNull>>(
+          'clang_Range_isNull');
+  late final _clang_Range_isNull =
+      _clang_Range_isNullPtr.asFunction<DartClang_Range_isNull>();
+
+  /// Retrieve the file, line, column, and offset represented by
+  /// the given source location.
+  ///
+  /// If the location refers into a macro expansion, retrieves the
+  /// location of the macro expansion.
+  ///
+  /// \param location the location within a source file that will be decomposed
+  /// into its parts.
+  ///
+  /// \param file [out] if non-NULL, will be set to the file to which the given
+  /// source location points.
+  ///
+  /// \param line [out] if non-NULL, will be set to the line to which the given
+  /// source location points.
+  ///
+  /// \param column [out] if non-NULL, will be set to the column to which the given
+  /// source location points.
+  ///
+  /// \param offset [out] if non-NULL, will be set to the offset into the
+  /// buffer to which the given source location points.
+  void clang_getExpansionLocation(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset,
+  ) {
+    return _clang_getExpansionLocation(
+      location,
+      file,
+      line,
+      column,
+      offset,
+    );
+  }
+
+  late final _clang_getExpansionLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getExpansionLocation>>(
+          'clang_getExpansionLocation');
+  late final _clang_getExpansionLocation = _clang_getExpansionLocationPtr
+      .asFunction<DartClang_getExpansionLocation>();
+
+  /// Retrieve the file, line and column represented by the given source
+  /// location, as specified in a # line directive.
+  ///
+  /// Example: given the following source code in a file somefile.c
+  ///
+  /// \code
+  /// #123 "dummy.c" 1
+  ///
+  /// static int func(void)
+  /// {
+  /// return 0;
+  /// }
+  /// \endcode
+  ///
+  /// the location information returned by this function would be
+  ///
+  /// File: dummy.c Line: 124 Column: 12
+  ///
+  /// whereas clang_getExpansionLocation would have returned
+  ///
+  /// File: somefile.c Line: 3 Column: 12
+  ///
+  /// \param location the location within a source file that will be decomposed
+  /// into its parts.
+  ///
+  /// \param filename [out] if non-NULL, will be set to the filename of the
+  /// source location. Note that filenames returned will be for "virtual" files,
+  /// which don't necessarily exist on the machine running clang - e.g. when
+  /// parsing preprocessed output obtained from a different environment. If
+  /// a non-NULL value is passed in, remember to dispose of the returned value
+  /// using \c clang_disposeString() once you've finished with it. For an invalid
+  /// source location, an empty string is returned.
+  ///
+  /// \param line [out] if non-NULL, will be set to the line number of the
+  /// source location. For an invalid source location, zero is returned.
+  ///
+  /// \param column [out] if non-NULL, will be set to the column number of the
+  /// source location. For an invalid source location, zero is returned.
+  void clang_getPresumedLocation(
+    CXSourceLocation location,
+    ffi.Pointer<CXString> filename,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+  ) {
+    return _clang_getPresumedLocation(
+      location,
+      filename,
+      line,
+      column,
+    );
+  }
+
+  late final _clang_getPresumedLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getPresumedLocation>>(
+          'clang_getPresumedLocation');
+  late final _clang_getPresumedLocation =
+      _clang_getPresumedLocationPtr.asFunction<DartClang_getPresumedLocation>();
+
+  /// Legacy API to retrieve the file, line, column, and offset represented
+  /// by the given source location.
+  ///
+  /// This interface has been replaced by the newer interface
+  /// #clang_getExpansionLocation(). See that interface's documentation for
+  /// details.
+  void clang_getInstantiationLocation(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset,
+  ) {
+    return _clang_getInstantiationLocation(
+      location,
+      file,
+      line,
+      column,
+      offset,
+    );
+  }
+
+  late final _clang_getInstantiationLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getInstantiationLocation>>(
+          'clang_getInstantiationLocation');
+  late final _clang_getInstantiationLocation =
+      _clang_getInstantiationLocationPtr
+          .asFunction<DartClang_getInstantiationLocation>();
+
+  /// Retrieve the file, line, column, and offset represented by
+  /// the given source location.
+  ///
+  /// If the location refers into a macro instantiation, return where the
+  /// location was originally spelled in the source file.
+  ///
+  /// \param location the location within a source file that will be decomposed
+  /// into its parts.
+  ///
+  /// \param file [out] if non-NULL, will be set to the file to which the given
+  /// source location points.
+  ///
+  /// \param line [out] if non-NULL, will be set to the line to which the given
+  /// source location points.
+  ///
+  /// \param column [out] if non-NULL, will be set to the column to which the given
+  /// source location points.
+  ///
+  /// \param offset [out] if non-NULL, will be set to the offset into the
+  /// buffer to which the given source location points.
+  void clang_getSpellingLocation(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset,
+  ) {
+    return _clang_getSpellingLocation(
+      location,
+      file,
+      line,
+      column,
+      offset,
+    );
+  }
+
+  late final _clang_getSpellingLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getSpellingLocation>>(
+          'clang_getSpellingLocation');
+  late final _clang_getSpellingLocation =
+      _clang_getSpellingLocationPtr.asFunction<DartClang_getSpellingLocation>();
+
+  /// Retrieve the file, line, column, and offset represented by
+  /// the given source location.
+  ///
+  /// If the location refers into a macro expansion, return where the macro was
+  /// expanded or where the macro argument was written, if the location points at
+  /// a macro argument.
+  ///
+  /// \param location the location within a source file that will be decomposed
+  /// into its parts.
+  ///
+  /// \param file [out] if non-NULL, will be set to the file to which the given
+  /// source location points.
+  ///
+  /// \param line [out] if non-NULL, will be set to the line to which the given
+  /// source location points.
+  ///
+  /// \param column [out] if non-NULL, will be set to the column to which the given
+  /// source location points.
+  ///
+  /// \param offset [out] if non-NULL, will be set to the offset into the
+  /// buffer to which the given source location points.
+  void clang_getFileLocation(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset,
+  ) {
+    return _clang_getFileLocation(
+      location,
+      file,
+      line,
+      column,
+      offset,
+    );
+  }
+
+  late final _clang_getFileLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getFileLocation>>(
+          'clang_getFileLocation');
+  late final _clang_getFileLocation =
+      _clang_getFileLocationPtr.asFunction<DartClang_getFileLocation>();
+
+  /// Retrieve a source location representing the first character within a
+  /// source range.
+  CXSourceLocation clang_getRangeStart(
+    CXSourceRange range,
+  ) {
+    return _clang_getRangeStart(
+      range,
+    );
+  }
+
+  late final _clang_getRangeStartPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getRangeStart>>(
+          'clang_getRangeStart');
+  late final _clang_getRangeStart =
+      _clang_getRangeStartPtr.asFunction<DartClang_getRangeStart>();
+
+  /// Retrieve a source location representing the last character within a
+  /// source range.
+  CXSourceLocation clang_getRangeEnd(
+    CXSourceRange range,
+  ) {
+    return _clang_getRangeEnd(
+      range,
+    );
+  }
+
+  late final _clang_getRangeEndPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getRangeEnd>>('clang_getRangeEnd');
+  late final _clang_getRangeEnd =
+      _clang_getRangeEndPtr.asFunction<DartClang_getRangeEnd>();
+
+  /// Retrieve all ranges that were skipped by the preprocessor.
+  ///
+  /// The preprocessor will skip lines when they are surrounded by an
+  /// if/ifdef/ifndef directive whose condition does not evaluate to true.
+  ffi.Pointer<CXSourceRangeList> clang_getSkippedRanges(
+    CXTranslationUnit tu,
+    CXFile file,
+  ) {
+    return _clang_getSkippedRanges(
+      tu,
+      file,
+    );
+  }
+
+  late final _clang_getSkippedRangesPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getSkippedRanges>>(
+          'clang_getSkippedRanges');
+  late final _clang_getSkippedRanges =
+      _clang_getSkippedRangesPtr.asFunction<DartClang_getSkippedRanges>();
+
+  /// Retrieve all ranges from all files that were skipped by the
+  /// preprocessor.
+  ///
+  /// The preprocessor will skip lines when they are surrounded by an
+  /// if/ifdef/ifndef directive whose condition does not evaluate to true.
+  ffi.Pointer<CXSourceRangeList> clang_getAllSkippedRanges(
+    CXTranslationUnit tu,
+  ) {
+    return _clang_getAllSkippedRanges(
+      tu,
+    );
+  }
+
+  late final _clang_getAllSkippedRangesPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getAllSkippedRanges>>(
+          'clang_getAllSkippedRanges');
+  late final _clang_getAllSkippedRanges =
+      _clang_getAllSkippedRangesPtr.asFunction<DartClang_getAllSkippedRanges>();
+
+  /// Destroy the given \c CXSourceRangeList.
+  void clang_disposeSourceRangeList(
+    ffi.Pointer<CXSourceRangeList> ranges,
+  ) {
+    return _clang_disposeSourceRangeList(
+      ranges,
+    );
+  }
+
+  late final _clang_disposeSourceRangeListPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeSourceRangeList>>(
+          'clang_disposeSourceRangeList');
+  late final _clang_disposeSourceRangeList = _clang_disposeSourceRangeListPtr
+      .asFunction<DartClang_disposeSourceRangeList>();
+
+  /// Determine the number of diagnostics in a CXDiagnosticSet.
+  int clang_getNumDiagnosticsInSet(
+    CXDiagnosticSet Diags,
+  ) {
+    return _clang_getNumDiagnosticsInSet(
+      Diags,
+    );
+  }
+
+  late final _clang_getNumDiagnosticsInSetPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getNumDiagnosticsInSet>>(
+          'clang_getNumDiagnosticsInSet');
+  late final _clang_getNumDiagnosticsInSet = _clang_getNumDiagnosticsInSetPtr
+      .asFunction<DartClang_getNumDiagnosticsInSet>();
+
+  /// Retrieve a diagnostic associated with the given CXDiagnosticSet.
+  ///
+  /// \param Diags the CXDiagnosticSet to query.
+  /// \param Index the zero-based diagnostic number to retrieve.
+  ///
+  /// \returns the requested diagnostic. This diagnostic must be freed
+  /// via a call to \c clang_disposeDiagnostic().
+  CXDiagnostic clang_getDiagnosticInSet(
+    CXDiagnosticSet Diags,
+    int Index,
+  ) {
+    return _clang_getDiagnosticInSet(
+      Diags,
+      Index,
+    );
+  }
+
+  late final _clang_getDiagnosticInSetPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticInSet>>(
+          'clang_getDiagnosticInSet');
+  late final _clang_getDiagnosticInSet =
+      _clang_getDiagnosticInSetPtr.asFunction<DartClang_getDiagnosticInSet>();
+
+  /// Deserialize a set of diagnostics from a Clang diagnostics bitcode
+  /// file.
+  ///
+  /// \param file The name of the file to deserialize.
+  /// \param error A pointer to a enum value recording if there was a problem
+  /// deserializing the diagnostics.
+  /// \param errorString A pointer to a CXString for recording the error string
+  /// if the file was not successfully loaded.
+  ///
+  /// \returns A loaded CXDiagnosticSet if successful, and NULL otherwise.  These
+  /// diagnostics should be released using clang_disposeDiagnosticSet().
+  CXDiagnosticSet clang_loadDiagnostics(
+    ffi.Pointer<ffi.Char> file,
+    ffi.Pointer<ffi.Int32> error,
+    ffi.Pointer<CXString> errorString,
+  ) {
+    return _clang_loadDiagnostics(
+      file,
+      error,
+      errorString,
+    );
+  }
+
+  late final _clang_loadDiagnosticsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_loadDiagnostics>>(
+          'clang_loadDiagnostics');
+  late final _clang_loadDiagnostics =
+      _clang_loadDiagnosticsPtr.asFunction<DartClang_loadDiagnostics>();
+
+  /// Release a CXDiagnosticSet and all of its contained diagnostics.
+  void clang_disposeDiagnosticSet(
+    CXDiagnosticSet Diags,
+  ) {
+    return _clang_disposeDiagnosticSet(
+      Diags,
+    );
+  }
+
+  late final _clang_disposeDiagnosticSetPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeDiagnosticSet>>(
+          'clang_disposeDiagnosticSet');
+  late final _clang_disposeDiagnosticSet = _clang_disposeDiagnosticSetPtr
+      .asFunction<DartClang_disposeDiagnosticSet>();
+
+  /// Retrieve the child diagnostics of a CXDiagnostic.
+  ///
+  /// This CXDiagnosticSet does not need to be released by
+  /// clang_disposeDiagnosticSet.
+  CXDiagnosticSet clang_getChildDiagnostics(
+    CXDiagnostic D,
+  ) {
+    return _clang_getChildDiagnostics(
+      D,
+    );
+  }
+
+  late final _clang_getChildDiagnosticsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getChildDiagnostics>>(
+          'clang_getChildDiagnostics');
+  late final _clang_getChildDiagnostics =
+      _clang_getChildDiagnosticsPtr.asFunction<DartClang_getChildDiagnostics>();
+
+  /// Determine the number of diagnostics produced for the given
+  /// translation unit.
+  int clang_getNumDiagnostics(
+    CXTranslationUnit Unit,
+  ) {
+    return _clang_getNumDiagnostics(
+      Unit,
+    );
+  }
+
+  late final _clang_getNumDiagnosticsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getNumDiagnostics>>(
+          'clang_getNumDiagnostics');
+  late final _clang_getNumDiagnostics =
+      _clang_getNumDiagnosticsPtr.asFunction<DartClang_getNumDiagnostics>();
+
+  /// Retrieve a diagnostic associated with the given translation unit.
+  ///
+  /// \param Unit the translation unit to query.
+  /// \param Index the zero-based diagnostic number to retrieve.
+  ///
+  /// \returns the requested diagnostic. This diagnostic must be freed
+  /// via a call to \c clang_disposeDiagnostic().
+  CXDiagnostic clang_getDiagnostic(
+    CXTranslationUnit Unit,
+    int Index,
+  ) {
+    return _clang_getDiagnostic(
+      Unit,
+      Index,
+    );
+  }
+
+  late final _clang_getDiagnosticPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnostic>>(
+          'clang_getDiagnostic');
+  late final _clang_getDiagnostic =
+      _clang_getDiagnosticPtr.asFunction<DartClang_getDiagnostic>();
+
+  /// Retrieve the complete set of diagnostics associated with a
+  /// translation unit.
+  ///
+  /// \param Unit the translation unit to query.
+  CXDiagnosticSet clang_getDiagnosticSetFromTU(
+    CXTranslationUnit Unit,
+  ) {
+    return _clang_getDiagnosticSetFromTU(
+      Unit,
+    );
+  }
+
+  late final _clang_getDiagnosticSetFromTUPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticSetFromTU>>(
+          'clang_getDiagnosticSetFromTU');
+  late final _clang_getDiagnosticSetFromTU = _clang_getDiagnosticSetFromTUPtr
+      .asFunction<DartClang_getDiagnosticSetFromTU>();
+
+  /// Destroy a diagnostic.
+  void clang_disposeDiagnostic(
+    CXDiagnostic Diagnostic,
+  ) {
+    return _clang_disposeDiagnostic(
+      Diagnostic,
+    );
+  }
+
+  late final _clang_disposeDiagnosticPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeDiagnostic>>(
+          'clang_disposeDiagnostic');
+  late final _clang_disposeDiagnostic =
+      _clang_disposeDiagnosticPtr.asFunction<DartClang_disposeDiagnostic>();
+
+  /// Format the given diagnostic in a manner that is suitable for display.
+  ///
+  /// This routine will format the given diagnostic to a string, rendering
+  /// the diagnostic according to the various options given. The
+  /// \c clang_defaultDiagnosticDisplayOptions() function returns the set of
+  /// options that most closely mimics the behavior of the clang compiler.
+  ///
+  /// \param Diagnostic The diagnostic to print.
+  ///
+  /// \param Options A set of options that control the diagnostic display,
+  /// created by combining \c CXDiagnosticDisplayOptions values.
+  ///
+  /// \returns A new string containing for formatted diagnostic.
+  CXString clang_formatDiagnostic(
+    CXDiagnostic Diagnostic,
+    int Options,
+  ) {
+    return _clang_formatDiagnostic(
+      Diagnostic,
+      Options,
+    );
+  }
+
+  late final _clang_formatDiagnosticPtr =
+      _lookup<ffi.NativeFunction<NativeClang_formatDiagnostic>>(
+          'clang_formatDiagnostic');
+  late final _clang_formatDiagnostic =
+      _clang_formatDiagnosticPtr.asFunction<DartClang_formatDiagnostic>();
+
+  /// Retrieve the set of display options most similar to the
+  /// default behavior of the clang compiler.
+  ///
+  /// \returns A set of display options suitable for use with \c
+  /// clang_formatDiagnostic().
+  int clang_defaultDiagnosticDisplayOptions() {
+    return _clang_defaultDiagnosticDisplayOptions();
+  }
+
+  late final _clang_defaultDiagnosticDisplayOptionsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_defaultDiagnosticDisplayOptions>>(
+          'clang_defaultDiagnosticDisplayOptions');
+  late final _clang_defaultDiagnosticDisplayOptions =
+      _clang_defaultDiagnosticDisplayOptionsPtr
+          .asFunction<DartClang_defaultDiagnosticDisplayOptions>();
+
+  /// Determine the severity of the given diagnostic.
+  int clang_getDiagnosticSeverity(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticSeverity(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticSeverityPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticSeverity>>(
+          'clang_getDiagnosticSeverity');
+  late final _clang_getDiagnosticSeverity = _clang_getDiagnosticSeverityPtr
+      .asFunction<DartClang_getDiagnosticSeverity>();
+
+  /// Retrieve the source location of the given diagnostic.
+  ///
+  /// This location is where Clang would print the caret ('^') when
+  /// displaying the diagnostic on the command line.
+  CXSourceLocation clang_getDiagnosticLocation(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticLocation(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticLocation>>(
+          'clang_getDiagnosticLocation');
+  late final _clang_getDiagnosticLocation = _clang_getDiagnosticLocationPtr
+      .asFunction<DartClang_getDiagnosticLocation>();
+
+  /// Retrieve the text of the given diagnostic.
+  CXString clang_getDiagnosticSpelling(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticSpelling(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticSpellingPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticSpelling>>(
+          'clang_getDiagnosticSpelling');
+  late final _clang_getDiagnosticSpelling = _clang_getDiagnosticSpellingPtr
+      .asFunction<DartClang_getDiagnosticSpelling>();
+
+  /// Retrieve the name of the command-line option that enabled this
+  /// diagnostic.
+  ///
+  /// \param Diag The diagnostic to be queried.
+  ///
+  /// \param Disable If non-NULL, will be set to the option that disables this
+  /// diagnostic (if any).
+  ///
+  /// \returns A string that contains the command-line option used to enable this
+  /// warning, such as "-Wconversion" or "-pedantic".
+  CXString clang_getDiagnosticOption(
+    CXDiagnostic Diag,
+    ffi.Pointer<CXString> Disable,
+  ) {
+    return _clang_getDiagnosticOption(
+      Diag,
+      Disable,
+    );
+  }
+
+  late final _clang_getDiagnosticOptionPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticOption>>(
+          'clang_getDiagnosticOption');
+  late final _clang_getDiagnosticOption =
+      _clang_getDiagnosticOptionPtr.asFunction<DartClang_getDiagnosticOption>();
+
+  /// Retrieve the category number for this diagnostic.
+  ///
+  /// Diagnostics can be categorized into groups along with other, related
+  /// diagnostics (e.g., diagnostics under the same warning flag). This routine
+  /// retrieves the category number for the given diagnostic.
+  ///
+  /// \returns The number of the category that contains this diagnostic, or zero
+  /// if this diagnostic is uncategorized.
+  int clang_getDiagnosticCategory(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticCategory(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticCategoryPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticCategory>>(
+          'clang_getDiagnosticCategory');
+  late final _clang_getDiagnosticCategory = _clang_getDiagnosticCategoryPtr
+      .asFunction<DartClang_getDiagnosticCategory>();
+
+  /// Retrieve the name of a particular diagnostic category.  This
+  /// is now deprecated.  Use clang_getDiagnosticCategoryText()
+  /// instead.
+  ///
+  /// \param Category A diagnostic category number, as returned by
+  /// \c clang_getDiagnosticCategory().
+  ///
+  /// \returns The name of the given diagnostic category.
+  CXString clang_getDiagnosticCategoryName(
+    int Category,
+  ) {
+    return _clang_getDiagnosticCategoryName(
+      Category,
+    );
+  }
+
+  late final _clang_getDiagnosticCategoryNamePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticCategoryName>>(
+          'clang_getDiagnosticCategoryName');
+  late final _clang_getDiagnosticCategoryName =
+      _clang_getDiagnosticCategoryNamePtr
+          .asFunction<DartClang_getDiagnosticCategoryName>();
+
+  /// Retrieve the diagnostic category text for a given diagnostic.
+  ///
+  /// \returns The text of the given diagnostic category.
+  CXString clang_getDiagnosticCategoryText(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticCategoryText(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticCategoryTextPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticCategoryText>>(
+          'clang_getDiagnosticCategoryText');
+  late final _clang_getDiagnosticCategoryText =
+      _clang_getDiagnosticCategoryTextPtr
+          .asFunction<DartClang_getDiagnosticCategoryText>();
+
+  /// Determine the number of source ranges associated with the given
+  /// diagnostic.
+  int clang_getDiagnosticNumRanges(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticNumRanges(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticNumRangesPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticNumRanges>>(
+          'clang_getDiagnosticNumRanges');
+  late final _clang_getDiagnosticNumRanges = _clang_getDiagnosticNumRangesPtr
+      .asFunction<DartClang_getDiagnosticNumRanges>();
+
+  /// Retrieve a source range associated with the diagnostic.
+  ///
+  /// A diagnostic's source ranges highlight important elements in the source
+  /// code. On the command line, Clang displays source ranges by
+  /// underlining them with '~' characters.
+  ///
+  /// \param Diagnostic the diagnostic whose range is being extracted.
+  ///
+  /// \param Range the zero-based index specifying which range to
+  ///
+  /// \returns the requested source range.
+  CXSourceRange clang_getDiagnosticRange(
+    CXDiagnostic Diagnostic,
+    int Range,
+  ) {
+    return _clang_getDiagnosticRange(
+      Diagnostic,
+      Range,
+    );
+  }
+
+  late final _clang_getDiagnosticRangePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticRange>>(
+          'clang_getDiagnosticRange');
+  late final _clang_getDiagnosticRange =
+      _clang_getDiagnosticRangePtr.asFunction<DartClang_getDiagnosticRange>();
+
+  /// Determine the number of fix-it hints associated with the
+  /// given diagnostic.
+  int clang_getDiagnosticNumFixIts(
+    CXDiagnostic Diagnostic,
+  ) {
+    return _clang_getDiagnosticNumFixIts(
+      Diagnostic,
+    );
+  }
+
+  late final _clang_getDiagnosticNumFixItsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticNumFixIts>>(
+          'clang_getDiagnosticNumFixIts');
+  late final _clang_getDiagnosticNumFixIts = _clang_getDiagnosticNumFixItsPtr
+      .asFunction<DartClang_getDiagnosticNumFixIts>();
+
+  /// Retrieve the replacement information for a given fix-it.
+  ///
+  /// Fix-its are described in terms of a source range whose contents
+  /// should be replaced by a string. This approach generalizes over
+  /// three kinds of operations: removal of source code (the range covers
+  /// the code to be removed and the replacement string is empty),
+  /// replacement of source code (the range covers the code to be
+  /// replaced and the replacement string provides the new code), and
+  /// insertion (both the start and end of the range point at the
+  /// insertion location, and the replacement string provides the text to
+  /// insert).
+  ///
+  /// \param Diagnostic The diagnostic whose fix-its are being queried.
+  ///
+  /// \param FixIt The zero-based index of the fix-it.
+  ///
+  /// \param ReplacementRange The source range whose contents will be
+  /// replaced with the returned replacement string. Note that source
+  /// ranges are half-open ranges [a, b), so the source code should be
+  /// replaced from a and up to (but not including) b.
+  ///
+  /// \returns A string containing text that should be replace the source
+  /// code indicated by the \c ReplacementRange.
+  CXString clang_getDiagnosticFixIt(
+    CXDiagnostic Diagnostic,
+    int FixIt,
+    ffi.Pointer<CXSourceRange> ReplacementRange,
+  ) {
+    return _clang_getDiagnosticFixIt(
+      Diagnostic,
+      FixIt,
+      ReplacementRange,
+    );
+  }
+
+  late final _clang_getDiagnosticFixItPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDiagnosticFixIt>>(
+          'clang_getDiagnosticFixIt');
+  late final _clang_getDiagnosticFixIt =
+      _clang_getDiagnosticFixItPtr.asFunction<DartClang_getDiagnosticFixIt>();
+
+  /// Get the original translation unit source file name.
+  CXString clang_getTranslationUnitSpelling(
+    CXTranslationUnit CTUnit,
+  ) {
+    return _clang_getTranslationUnitSpelling(
+      CTUnit,
+    );
+  }
+
+  late final _clang_getTranslationUnitSpellingPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTranslationUnitSpelling>>(
+          'clang_getTranslationUnitSpelling');
+  late final _clang_getTranslationUnitSpelling =
+      _clang_getTranslationUnitSpellingPtr
+          .asFunction<DartClang_getTranslationUnitSpelling>();
+
+  /// Return the CXTranslationUnit for a given source file and the provided
+  /// command line arguments one would pass to the compiler.
+  ///
+  /// Note: The 'source_filename' argument is optional.  If the caller provides a
+  /// NULL pointer, the name of the source file is expected to reside in the
+  /// specified command line arguments.
+  ///
+  /// Note: When encountered in 'clang_command_line_args', the following options
+  /// are ignored:
+  ///
+  /// '-c'
+  /// '-emit-ast'
+  /// '-fsyntax-only'
+  /// '-o \<output file>'  (both '-o' and '\<output file>' are ignored)
+  ///
+  /// \param CIdx The index object with which the translation unit will be
+  /// associated.
+  ///
+  /// \param source_filename The name of the source file to load, or NULL if the
+  /// source file is included in \p clang_command_line_args.
+  ///
+  /// \param num_clang_command_line_args The number of command-line arguments in
+  /// \p clang_command_line_args.
+  ///
+  /// \param clang_command_line_args The command-line arguments that would be
+  /// passed to the \c clang executable if it were being invoked out-of-process.
+  /// These command-line options will be parsed and will affect how the translation
+  /// unit is parsed. Note that the following options are ignored: '-c',
+  /// '-emit-ast', '-fsyntax-only' (which is the default), and '-o \<output file>'.
+  ///
+  /// \param num_unsaved_files the number of unsaved file entries in \p
+  /// unsaved_files.
+  ///
+  /// \param unsaved_files the files that have not yet been saved to disk
+  /// but may be required for code completion, including the contents of
+  /// those files.  The contents and name of these files (as specified by
+  /// CXUnsavedFile) are copied when necessary, so the client only needs to
+  /// guarantee their validity until the call to this function returns.
+  CXTranslationUnit clang_createTranslationUnitFromSourceFile(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    int num_clang_command_line_args,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> clang_command_line_args,
+    int num_unsaved_files,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+  ) {
+    return _clang_createTranslationUnitFromSourceFile(
+      CIdx,
+      source_filename,
+      num_clang_command_line_args,
+      clang_command_line_args,
+      num_unsaved_files,
+      unsaved_files,
+    );
+  }
+
+  late final _clang_createTranslationUnitFromSourceFilePtr = _lookup<
+          ffi.NativeFunction<NativeClang_createTranslationUnitFromSourceFile>>(
+      'clang_createTranslationUnitFromSourceFile');
+  late final _clang_createTranslationUnitFromSourceFile =
+      _clang_createTranslationUnitFromSourceFilePtr
+          .asFunction<DartClang_createTranslationUnitFromSourceFile>();
+
+  /// Same as \c clang_createTranslationUnit2, but returns
+  /// the \c CXTranslationUnit instead of an error code.  In case of an error this
+  /// routine returns a \c NULL \c CXTranslationUnit, without further detailed
+  /// error codes.
+  CXTranslationUnit clang_createTranslationUnit(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> ast_filename,
+  ) {
+    return _clang_createTranslationUnit(
+      CIdx,
+      ast_filename,
+    );
+  }
+
+  late final _clang_createTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<NativeClang_createTranslationUnit>>(
+          'clang_createTranslationUnit');
+  late final _clang_createTranslationUnit = _clang_createTranslationUnitPtr
+      .asFunction<DartClang_createTranslationUnit>();
+
+  /// Create a translation unit from an AST file (\c -emit-ast).
+  ///
+  /// \param[out] out_TU A non-NULL pointer to store the created
+  /// \c CXTranslationUnit.
+  ///
+  /// \returns Zero on success, otherwise returns an error code.
+  int clang_createTranslationUnit2(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> ast_filename,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+  ) {
+    return _clang_createTranslationUnit2(
+      CIdx,
+      ast_filename,
+      out_TU,
+    );
+  }
+
+  late final _clang_createTranslationUnit2Ptr =
+      _lookup<ffi.NativeFunction<NativeClang_createTranslationUnit2>>(
+          'clang_createTranslationUnit2');
+  late final _clang_createTranslationUnit2 = _clang_createTranslationUnit2Ptr
+      .asFunction<DartClang_createTranslationUnit2>();
+
+  /// Returns the set of flags that is suitable for parsing a translation
+  /// unit that is being edited.
+  ///
+  /// The set of flags returned provide options for \c clang_parseTranslationUnit()
+  /// to indicate that the translation unit is likely to be reparsed many times,
+  /// either explicitly (via \c clang_reparseTranslationUnit()) or implicitly
+  /// (e.g., by code completion (\c clang_codeCompletionAt())). The returned flag
+  /// set contains an unspecified set of optimizations (e.g., the precompiled
+  /// preamble) geared toward improving the performance of these routines. The
+  /// set of optimizations enabled may change from one version to the next.
+  int clang_defaultEditingTranslationUnitOptions() {
+    return _clang_defaultEditingTranslationUnitOptions();
+  }
+
+  late final _clang_defaultEditingTranslationUnitOptionsPtr = _lookup<
+          ffi.NativeFunction<NativeClang_defaultEditingTranslationUnitOptions>>(
+      'clang_defaultEditingTranslationUnitOptions');
+  late final _clang_defaultEditingTranslationUnitOptions =
+      _clang_defaultEditingTranslationUnitOptionsPtr
+          .asFunction<DartClang_defaultEditingTranslationUnitOptions>();
+
+  /// Same as \c clang_parseTranslationUnit2, but returns
+  /// the \c CXTranslationUnit instead of an error code.  In case of an error this
+  /// routine returns a \c NULL \c CXTranslationUnit, without further detailed
+  /// error codes.
+  CXTranslationUnit clang_parseTranslationUnit(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options,
+  ) {
+    return _clang_parseTranslationUnit(
+      CIdx,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      unsaved_files,
+      num_unsaved_files,
+      options,
+    );
+  }
+
+  late final _clang_parseTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<NativeClang_parseTranslationUnit>>(
+          'clang_parseTranslationUnit');
+  late final _clang_parseTranslationUnit = _clang_parseTranslationUnitPtr
+      .asFunction<DartClang_parseTranslationUnit>();
+
+  /// Parse the given source file and the translation unit corresponding
+  /// to that file.
+  ///
+  /// This routine is the main entry point for the Clang C API, providing the
+  /// ability to parse a source file into a translation unit that can then be
+  /// queried by other functions in the API. This routine accepts a set of
+  /// command-line arguments so that the compilation can be configured in the same
+  /// way that the compiler is configured on the command line.
+  ///
+  /// \param CIdx The index object with which the translation unit will be
+  /// associated.
+  ///
+  /// \param source_filename The name of the source file to load, or NULL if the
+  /// source file is included in \c command_line_args.
+  ///
+  /// \param command_line_args The command-line arguments that would be
+  /// passed to the \c clang executable if it were being invoked out-of-process.
+  /// These command-line options will be parsed and will affect how the translation
+  /// unit is parsed. Note that the following options are ignored: '-c',
+  /// '-emit-ast', '-fsyntax-only' (which is the default), and '-o \<output file>'.
+  ///
+  /// \param num_command_line_args The number of command-line arguments in
+  /// \c command_line_args.
+  ///
+  /// \param unsaved_files the files that have not yet been saved to disk
+  /// but may be required for parsing, including the contents of
+  /// those files.  The contents and name of these files (as specified by
+  /// CXUnsavedFile) are copied when necessary, so the client only needs to
+  /// guarantee their validity until the call to this function returns.
+  ///
+  /// \param num_unsaved_files the number of unsaved file entries in \p
+  /// unsaved_files.
+  ///
+  /// \param options A bitmask of options that affects how the translation unit
+  /// is managed but not its compilation. This should be a bitwise OR of the
+  /// CXTranslationUnit_XXX flags.
+  ///
+  /// \param[out] out_TU A non-NULL pointer to store the created
+  /// \c CXTranslationUnit, describing the parsed code and containing any
+  /// diagnostics produced by the compiler.
+  ///
+  /// \returns Zero on success, otherwise returns an error code.
+  int clang_parseTranslationUnit2(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+  ) {
+    return _clang_parseTranslationUnit2(
+      CIdx,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      unsaved_files,
+      num_unsaved_files,
+      options,
+      out_TU,
+    );
+  }
+
+  late final _clang_parseTranslationUnit2Ptr =
+      _lookup<ffi.NativeFunction<NativeClang_parseTranslationUnit2>>(
+          'clang_parseTranslationUnit2');
+  late final _clang_parseTranslationUnit2 = _clang_parseTranslationUnit2Ptr
+      .asFunction<DartClang_parseTranslationUnit2>();
+
+  /// Same as clang_parseTranslationUnit2 but requires a full command line
+  /// for \c command_line_args including argv[0]. This is useful if the standard
+  /// library paths are relative to the binary.
+  int clang_parseTranslationUnit2FullArgv(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+  ) {
+    return _clang_parseTranslationUnit2FullArgv(
+      CIdx,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      unsaved_files,
+      num_unsaved_files,
+      options,
+      out_TU,
+    );
+  }
+
+  late final _clang_parseTranslationUnit2FullArgvPtr =
+      _lookup<ffi.NativeFunction<NativeClang_parseTranslationUnit2FullArgv>>(
+          'clang_parseTranslationUnit2FullArgv');
+  late final _clang_parseTranslationUnit2FullArgv =
+      _clang_parseTranslationUnit2FullArgvPtr
+          .asFunction<DartClang_parseTranslationUnit2FullArgv>();
+
+  /// Returns the set of flags that is suitable for saving a translation
+  /// unit.
+  ///
+  /// The set of flags returned provide options for
+  /// \c clang_saveTranslationUnit() by default. The returned flag
+  /// set contains an unspecified set of options that save translation units with
+  /// the most commonly-requested data.
+  int clang_defaultSaveOptions(
+    CXTranslationUnit TU,
+  ) {
+    return _clang_defaultSaveOptions(
+      TU,
+    );
+  }
+
+  late final _clang_defaultSaveOptionsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_defaultSaveOptions>>(
+          'clang_defaultSaveOptions');
+  late final _clang_defaultSaveOptions =
+      _clang_defaultSaveOptionsPtr.asFunction<DartClang_defaultSaveOptions>();
+
+  /// Saves a translation unit into a serialized representation of
+  /// that translation unit on disk.
+  ///
+  /// Any translation unit that was parsed without error can be saved
+  /// into a file. The translation unit can then be deserialized into a
+  /// new \c CXTranslationUnit with \c clang_createTranslationUnit() or,
+  /// if it is an incomplete translation unit that corresponds to a
+  /// header, used as a precompiled header when parsing other translation
+  /// units.
+  ///
+  /// \param TU The translation unit to save.
+  ///
+  /// \param FileName The file to which the translation unit will be saved.
+  ///
+  /// \param options A bitmask of options that affects how the translation unit
+  /// is saved. This should be a bitwise OR of the
+  /// CXSaveTranslationUnit_XXX flags.
+  ///
+  /// \returns A value that will match one of the enumerators of the CXSaveError
+  /// enumeration. Zero (CXSaveError_None) indicates that the translation unit was
+  /// saved successfully, while a non-zero value indicates that a problem occurred.
+  int clang_saveTranslationUnit(
+    CXTranslationUnit TU,
+    ffi.Pointer<ffi.Char> FileName,
+    int options,
+  ) {
+    return _clang_saveTranslationUnit(
+      TU,
+      FileName,
+      options,
+    );
+  }
+
+  late final _clang_saveTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<NativeClang_saveTranslationUnit>>(
+          'clang_saveTranslationUnit');
+  late final _clang_saveTranslationUnit =
+      _clang_saveTranslationUnitPtr.asFunction<DartClang_saveTranslationUnit>();
+
+  /// Suspend a translation unit in order to free memory associated with it.
+  ///
+  /// A suspended translation unit uses significantly less memory but on the other
+  /// side does not support any other calls than \c clang_reparseTranslationUnit
+  /// to resume it or \c clang_disposeTranslationUnit to dispose it completely.
+  int clang_suspendTranslationUnit(
+    CXTranslationUnit arg0,
+  ) {
+    return _clang_suspendTranslationUnit(
+      arg0,
+    );
+  }
+
+  late final _clang_suspendTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<NativeClang_suspendTranslationUnit>>(
+          'clang_suspendTranslationUnit');
+  late final _clang_suspendTranslationUnit = _clang_suspendTranslationUnitPtr
+      .asFunction<DartClang_suspendTranslationUnit>();
+
+  /// Destroy the specified CXTranslationUnit object.
+  void clang_disposeTranslationUnit(
+    CXTranslationUnit arg0,
+  ) {
+    return _clang_disposeTranslationUnit(
+      arg0,
+    );
+  }
+
+  late final _clang_disposeTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeTranslationUnit>>(
+          'clang_disposeTranslationUnit');
+  late final _clang_disposeTranslationUnit = _clang_disposeTranslationUnitPtr
+      .asFunction<DartClang_disposeTranslationUnit>();
+
+  /// Returns the set of flags that is suitable for reparsing a translation
+  /// unit.
+  ///
+  /// The set of flags returned provide options for
+  /// \c clang_reparseTranslationUnit() by default. The returned flag
+  /// set contains an unspecified set of optimizations geared toward common uses
+  /// of reparsing. The set of optimizations enabled may change from one version
+  /// to the next.
+  int clang_defaultReparseOptions(
+    CXTranslationUnit TU,
+  ) {
+    return _clang_defaultReparseOptions(
+      TU,
+    );
+  }
+
+  late final _clang_defaultReparseOptionsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_defaultReparseOptions>>(
+          'clang_defaultReparseOptions');
+  late final _clang_defaultReparseOptions = _clang_defaultReparseOptionsPtr
+      .asFunction<DartClang_defaultReparseOptions>();
+
+  /// Reparse the source files that produced this translation unit.
+  ///
+  /// This routine can be used to re-parse the source files that originally
+  /// created the given translation unit, for example because those source files
+  /// have changed (either on disk or as passed via \p unsaved_files). The
+  /// source code will be reparsed with the same command-line options as it
+  /// was originally parsed.
+  ///
+  /// Reparsing a translation unit invalidates all cursors and source locations
+  /// that refer into that translation unit. This makes reparsing a translation
+  /// unit semantically equivalent to destroying the translation unit and then
+  /// creating a new translation unit with the same command-line arguments.
+  /// However, it may be more efficient to reparse a translation
+  /// unit using this routine.
+  ///
+  /// \param TU The translation unit whose contents will be re-parsed. The
+  /// translation unit must originally have been built with
+  /// \c clang_createTranslationUnitFromSourceFile().
+  ///
+  /// \param num_unsaved_files The number of unsaved file entries in \p
+  /// unsaved_files.
+  ///
+  /// \param unsaved_files The files that have not yet been saved to disk
+  /// but may be required for parsing, including the contents of
+  /// those files.  The contents and name of these files (as specified by
+  /// CXUnsavedFile) are copied when necessary, so the client only needs to
+  /// guarantee their validity until the call to this function returns.
+  ///
+  /// \param options A bitset of options composed of the flags in CXReparse_Flags.
+  /// The function \c clang_defaultReparseOptions() produces a default set of
+  /// options recommended for most uses, based on the translation unit.
+  ///
+  /// \returns 0 if the sources could be reparsed.  A non-zero error code will be
+  /// returned if reparsing was impossible, such that the translation unit is
+  /// invalid. In such cases, the only valid call for \c TU is
+  /// \c clang_disposeTranslationUnit(TU).  The error codes returned by this
+  /// routine are described by the \c CXErrorCode enum.
+  int clang_reparseTranslationUnit(
+    CXTranslationUnit TU,
+    int num_unsaved_files,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int options,
+  ) {
+    return _clang_reparseTranslationUnit(
+      TU,
+      num_unsaved_files,
+      unsaved_files,
+      options,
+    );
+  }
+
+  late final _clang_reparseTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<NativeClang_reparseTranslationUnit>>(
+          'clang_reparseTranslationUnit');
+  late final _clang_reparseTranslationUnit = _clang_reparseTranslationUnitPtr
+      .asFunction<DartClang_reparseTranslationUnit>();
+
+  /// Returns the human-readable null-terminated C string that represents
+  /// the name of the memory category.  This string should never be freed.
+  ffi.Pointer<ffi.Char> clang_getTUResourceUsageName(
+    int kind,
+  ) {
+    return _clang_getTUResourceUsageName(
+      kind,
+    );
+  }
+
+  late final _clang_getTUResourceUsageNamePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTUResourceUsageName>>(
+          'clang_getTUResourceUsageName');
+  late final _clang_getTUResourceUsageName = _clang_getTUResourceUsageNamePtr
+      .asFunction<DartClang_getTUResourceUsageName>();
+
+  /// Return the memory usage of a translation unit.  This object
+  /// should be released with clang_disposeCXTUResourceUsage().
+  CXTUResourceUsage clang_getCXTUResourceUsage(
+    CXTranslationUnit TU,
+  ) {
+    return _clang_getCXTUResourceUsage(
+      TU,
+    );
+  }
+
+  late final _clang_getCXTUResourceUsagePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCXTUResourceUsage>>(
+          'clang_getCXTUResourceUsage');
+  late final _clang_getCXTUResourceUsage = _clang_getCXTUResourceUsagePtr
+      .asFunction<DartClang_getCXTUResourceUsage>();
+
+  void clang_disposeCXTUResourceUsage(
+    CXTUResourceUsage usage,
+  ) {
+    return _clang_disposeCXTUResourceUsage(
+      usage,
+    );
+  }
+
+  late final _clang_disposeCXTUResourceUsagePtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeCXTUResourceUsage>>(
+          'clang_disposeCXTUResourceUsage');
+  late final _clang_disposeCXTUResourceUsage =
+      _clang_disposeCXTUResourceUsagePtr
+          .asFunction<DartClang_disposeCXTUResourceUsage>();
+
+  /// Get target information for this translation unit.
+  ///
+  /// The CXTargetInfo object cannot outlive the CXTranslationUnit object.
+  CXTargetInfo clang_getTranslationUnitTargetInfo(
+    CXTranslationUnit CTUnit,
+  ) {
+    return _clang_getTranslationUnitTargetInfo(
+      CTUnit,
+    );
+  }
+
+  late final _clang_getTranslationUnitTargetInfoPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTranslationUnitTargetInfo>>(
+          'clang_getTranslationUnitTargetInfo');
+  late final _clang_getTranslationUnitTargetInfo =
+      _clang_getTranslationUnitTargetInfoPtr
+          .asFunction<DartClang_getTranslationUnitTargetInfo>();
+
+  /// Destroy the CXTargetInfo object.
+  void clang_TargetInfo_dispose(
+    CXTargetInfo Info,
+  ) {
+    return _clang_TargetInfo_dispose(
+      Info,
+    );
+  }
+
+  late final _clang_TargetInfo_disposePtr =
+      _lookup<ffi.NativeFunction<NativeClang_TargetInfo_dispose>>(
+          'clang_TargetInfo_dispose');
+  late final _clang_TargetInfo_dispose =
+      _clang_TargetInfo_disposePtr.asFunction<DartClang_TargetInfo_dispose>();
+
+  /// Get the normalized target triple as a string.
+  ///
+  /// Returns the empty string in case of any error.
+  CXString clang_TargetInfo_getTriple(
+    CXTargetInfo Info,
+  ) {
+    return _clang_TargetInfo_getTriple(
+      Info,
+    );
+  }
+
+  late final _clang_TargetInfo_getTriplePtr =
+      _lookup<ffi.NativeFunction<NativeClang_TargetInfo_getTriple>>(
+          'clang_TargetInfo_getTriple');
+  late final _clang_TargetInfo_getTriple = _clang_TargetInfo_getTriplePtr
+      .asFunction<DartClang_TargetInfo_getTriple>();
+
+  /// Get the pointer width of the target in bits.
+  ///
+  /// Returns -1 in case of error.
+  int clang_TargetInfo_getPointerWidth(
+    CXTargetInfo Info,
+  ) {
+    return _clang_TargetInfo_getPointerWidth(
+      Info,
+    );
+  }
+
+  late final _clang_TargetInfo_getPointerWidthPtr =
+      _lookup<ffi.NativeFunction<NativeClang_TargetInfo_getPointerWidth>>(
+          'clang_TargetInfo_getPointerWidth');
+  late final _clang_TargetInfo_getPointerWidth =
+      _clang_TargetInfo_getPointerWidthPtr
+          .asFunction<DartClang_TargetInfo_getPointerWidth>();
+
+  /// Retrieve the NULL cursor, which represents no entity.
+  CXCursor clang_getNullCursor() {
+    return _clang_getNullCursor();
+  }
+
+  late final _clang_getNullCursorPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getNullCursor>>(
+          'clang_getNullCursor');
+  late final _clang_getNullCursor =
+      _clang_getNullCursorPtr.asFunction<DartClang_getNullCursor>();
+
+  /// Retrieve the cursor that represents the given translation unit.
+  ///
+  /// The translation unit cursor can be used to start traversing the
+  /// various declarations within the given translation unit.
+  CXCursor clang_getTranslationUnitCursor(
+    CXTranslationUnit arg0,
+  ) {
+    return _clang_getTranslationUnitCursor(
+      arg0,
+    );
+  }
+
+  late final _clang_getTranslationUnitCursorPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTranslationUnitCursor>>(
+          'clang_getTranslationUnitCursor');
+  late final _clang_getTranslationUnitCursor =
+      _clang_getTranslationUnitCursorPtr
+          .asFunction<DartClang_getTranslationUnitCursor>();
+
+  /// Determine whether two cursors are equivalent.
+  int clang_equalCursors(
+    CXCursor arg0,
+    CXCursor arg1,
+  ) {
+    return _clang_equalCursors(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_equalCursorsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_equalCursors>>(
+          'clang_equalCursors');
+  late final _clang_equalCursors =
+      _clang_equalCursorsPtr.asFunction<DartClang_equalCursors>();
+
+  /// Returns non-zero if \p cursor is null.
+  int clang_Cursor_isNull(
+    CXCursor cursor,
+  ) {
+    return _clang_Cursor_isNull(
+      cursor,
+    );
+  }
+
+  late final _clang_Cursor_isNullPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isNull>>(
+          'clang_Cursor_isNull');
+  late final _clang_Cursor_isNull =
+      _clang_Cursor_isNullPtr.asFunction<DartClang_Cursor_isNull>();
+
+  /// Compute a hash value for the given cursor.
+  int clang_hashCursor(
+    CXCursor arg0,
+  ) {
+    return _clang_hashCursor(
+      arg0,
+    );
+  }
+
+  late final _clang_hashCursorPtr =
+      _lookup<ffi.NativeFunction<NativeClang_hashCursor>>('clang_hashCursor');
+  late final _clang_hashCursor =
+      _clang_hashCursorPtr.asFunction<DartClang_hashCursor>();
+
+  /// Retrieve the kind of the given cursor.
+  int clang_getCursorKind(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorKind(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorKindPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorKind>>(
+          'clang_getCursorKind');
+  late final _clang_getCursorKind =
+      _clang_getCursorKindPtr.asFunction<DartClang_getCursorKind>();
+
+  /// Determine whether the given cursor kind represents a declaration.
+  int clang_isDeclaration(
+    int arg0,
+  ) {
+    return _clang_isDeclaration(
+      arg0,
+    );
+  }
+
+  late final _clang_isDeclarationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_isDeclaration>>(
+          'clang_isDeclaration');
+  late final _clang_isDeclaration =
+      _clang_isDeclarationPtr.asFunction<DartClang_isDeclaration>();
+
+  /// Determine whether the given declaration is invalid.
+  ///
+  /// A declaration is invalid if it could not be parsed successfully.
+  ///
+  /// \returns non-zero if the cursor represents a declaration and it is
+  /// invalid, otherwise NULL.
+  int clang_isInvalidDeclaration(
+    CXCursor arg0,
+  ) {
+    return _clang_isInvalidDeclaration(
+      arg0,
+    );
+  }
+
+  late final _clang_isInvalidDeclarationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_isInvalidDeclaration>>(
+          'clang_isInvalidDeclaration');
+  late final _clang_isInvalidDeclaration = _clang_isInvalidDeclarationPtr
+      .asFunction<DartClang_isInvalidDeclaration>();
+
+  /// Determine whether the given cursor kind represents a simple
+  /// reference.
+  ///
+  /// Note that other kinds of cursors (such as expressions) can also refer to
+  /// other cursors. Use clang_getCursorReferenced() to determine whether a
+  /// particular cursor refers to another entity.
+  int clang_isReference(
+    int arg0,
+  ) {
+    return _clang_isReference(
+      arg0,
+    );
+  }
+
+  late final _clang_isReferencePtr =
+      _lookup<ffi.NativeFunction<NativeClang_isReference>>('clang_isReference');
+  late final _clang_isReference =
+      _clang_isReferencePtr.asFunction<DartClang_isReference>();
+
+  /// Determine whether the given cursor kind represents an expression.
+  int clang_isExpression(
+    int arg0,
+  ) {
+    return _clang_isExpression(
+      arg0,
+    );
+  }
+
+  late final _clang_isExpressionPtr =
+      _lookup<ffi.NativeFunction<NativeClang_isExpression>>(
+          'clang_isExpression');
+  late final _clang_isExpression =
+      _clang_isExpressionPtr.asFunction<DartClang_isExpression>();
+
+  /// Determine whether the given cursor kind represents a statement.
+  int clang_isStatement(
+    int arg0,
+  ) {
+    return _clang_isStatement(
+      arg0,
+    );
+  }
+
+  late final _clang_isStatementPtr =
+      _lookup<ffi.NativeFunction<NativeClang_isStatement>>('clang_isStatement');
+  late final _clang_isStatement =
+      _clang_isStatementPtr.asFunction<DartClang_isStatement>();
+
+  /// Determine whether the given cursor kind represents an attribute.
+  int clang_isAttribute(
+    int arg0,
+  ) {
+    return _clang_isAttribute(
+      arg0,
+    );
+  }
+
+  late final _clang_isAttributePtr =
+      _lookup<ffi.NativeFunction<NativeClang_isAttribute>>('clang_isAttribute');
+  late final _clang_isAttribute =
+      _clang_isAttributePtr.asFunction<DartClang_isAttribute>();
+
+  /// Determine whether the given cursor has any attributes.
+  int clang_Cursor_hasAttrs(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_hasAttrs(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_hasAttrsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_hasAttrs>>(
+          'clang_Cursor_hasAttrs');
+  late final _clang_Cursor_hasAttrs =
+      _clang_Cursor_hasAttrsPtr.asFunction<DartClang_Cursor_hasAttrs>();
+
+  /// Determine whether the given cursor kind represents an invalid
+  /// cursor.
+  int clang_isInvalid(
+    int arg0,
+  ) {
+    return _clang_isInvalid(
+      arg0,
+    );
+  }
+
+  late final _clang_isInvalidPtr =
+      _lookup<ffi.NativeFunction<NativeClang_isInvalid>>('clang_isInvalid');
+  late final _clang_isInvalid =
+      _clang_isInvalidPtr.asFunction<DartClang_isInvalid>();
+
+  /// Determine whether the given cursor kind represents a translation
+  /// unit.
+  int clang_isTranslationUnit(
+    int arg0,
+  ) {
+    return _clang_isTranslationUnit(
+      arg0,
+    );
+  }
+
+  late final _clang_isTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<NativeClang_isTranslationUnit>>(
+          'clang_isTranslationUnit');
+  late final _clang_isTranslationUnit =
+      _clang_isTranslationUnitPtr.asFunction<DartClang_isTranslationUnit>();
+
+  /// Determine whether the given cursor represents a preprocessing
+  /// element, such as a preprocessor directive or macro instantiation.
+  int clang_isPreprocessing(
+    int arg0,
+  ) {
+    return _clang_isPreprocessing(
+      arg0,
+    );
+  }
+
+  late final _clang_isPreprocessingPtr =
+      _lookup<ffi.NativeFunction<NativeClang_isPreprocessing>>(
+          'clang_isPreprocessing');
+  late final _clang_isPreprocessing =
+      _clang_isPreprocessingPtr.asFunction<DartClang_isPreprocessing>();
+
+  /// Determine whether the given cursor represents a currently
+  /// unexposed piece of the AST (e.g., CXCursor_UnexposedStmt).
+  int clang_isUnexposed(
+    int arg0,
+  ) {
+    return _clang_isUnexposed(
+      arg0,
+    );
+  }
+
+  late final _clang_isUnexposedPtr =
+      _lookup<ffi.NativeFunction<NativeClang_isUnexposed>>('clang_isUnexposed');
+  late final _clang_isUnexposed =
+      _clang_isUnexposedPtr.asFunction<DartClang_isUnexposed>();
+
+  /// Determine the linkage of the entity referred to by a given cursor.
+  int clang_getCursorLinkage(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorLinkage(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorLinkagePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorLinkage>>(
+          'clang_getCursorLinkage');
+  late final _clang_getCursorLinkage =
+      _clang_getCursorLinkagePtr.asFunction<DartClang_getCursorLinkage>();
+
+  /// Describe the visibility of the entity referred to by a cursor.
+  ///
+  /// This returns the default visibility if not explicitly specified by
+  /// a visibility attribute. The default visibility may be changed by
+  /// commandline arguments.
+  ///
+  /// \param cursor The cursor to query.
+  ///
+  /// \returns The visibility of the cursor.
+  int clang_getCursorVisibility(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorVisibility(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorVisibilityPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorVisibility>>(
+          'clang_getCursorVisibility');
+  late final _clang_getCursorVisibility =
+      _clang_getCursorVisibilityPtr.asFunction<DartClang_getCursorVisibility>();
+
+  /// Determine the availability of the entity that this cursor refers to,
+  /// taking the current target platform into account.
+  ///
+  /// \param cursor The cursor to query.
+  ///
+  /// \returns The availability of the cursor.
+  int clang_getCursorAvailability(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorAvailability(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorAvailabilityPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorAvailability>>(
+          'clang_getCursorAvailability');
+  late final _clang_getCursorAvailability = _clang_getCursorAvailabilityPtr
+      .asFunction<DartClang_getCursorAvailability>();
+
+  /// Determine the availability of the entity that this cursor refers to
+  /// on any platforms for which availability information is known.
+  ///
+  /// \param cursor The cursor to query.
+  ///
+  /// \param always_deprecated If non-NULL, will be set to indicate whether the
+  /// entity is deprecated on all platforms.
+  ///
+  /// \param deprecated_message If non-NULL, will be set to the message text
+  /// provided along with the unconditional deprecation of this entity. The client
+  /// is responsible for deallocating this string.
+  ///
+  /// \param always_unavailable If non-NULL, will be set to indicate whether the
+  /// entity is unavailable on all platforms.
+  ///
+  /// \param unavailable_message If non-NULL, will be set to the message text
+  /// provided along with the unconditional unavailability of this entity. The
+  /// client is responsible for deallocating this string.
+  ///
+  /// \param availability If non-NULL, an array of CXPlatformAvailability instances
+  /// that will be populated with platform availability information, up to either
+  /// the number of platforms for which availability information is available (as
+  /// returned by this function) or \c availability_size, whichever is smaller.
+  ///
+  /// \param availability_size The number of elements available in the
+  /// \c availability array.
+  ///
+  /// \returns The number of platforms (N) for which availability information is
+  /// available (which is unrelated to \c availability_size).
+  ///
+  /// Note that the client is responsible for calling
+  /// \c clang_disposeCXPlatformAvailability to free each of the
+  /// platform-availability structures returned. There are
+  /// \c min(N, availability_size) such structures.
+  int clang_getCursorPlatformAvailability(
+    CXCursor cursor,
+    ffi.Pointer<ffi.Int> always_deprecated,
+    ffi.Pointer<CXString> deprecated_message,
+    ffi.Pointer<ffi.Int> always_unavailable,
+    ffi.Pointer<CXString> unavailable_message,
+    ffi.Pointer<CXPlatformAvailability> availability,
+    int availability_size,
+  ) {
+    return _clang_getCursorPlatformAvailability(
+      cursor,
+      always_deprecated,
+      deprecated_message,
+      always_unavailable,
+      unavailable_message,
+      availability,
+      availability_size,
+    );
+  }
+
+  late final _clang_getCursorPlatformAvailabilityPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorPlatformAvailability>>(
+          'clang_getCursorPlatformAvailability');
+  late final _clang_getCursorPlatformAvailability =
+      _clang_getCursorPlatformAvailabilityPtr
+          .asFunction<DartClang_getCursorPlatformAvailability>();
+
+  /// Free the memory associated with a \c CXPlatformAvailability structure.
+  void clang_disposeCXPlatformAvailability(
+    ffi.Pointer<CXPlatformAvailability> availability,
+  ) {
+    return _clang_disposeCXPlatformAvailability(
+      availability,
+    );
+  }
+
+  late final _clang_disposeCXPlatformAvailabilityPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeCXPlatformAvailability>>(
+          'clang_disposeCXPlatformAvailability');
+  late final _clang_disposeCXPlatformAvailability =
+      _clang_disposeCXPlatformAvailabilityPtr
+          .asFunction<DartClang_disposeCXPlatformAvailability>();
+
+  /// Determine the "language" of the entity referred to by a given cursor.
+  int clang_getCursorLanguage(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorLanguage(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorLanguagePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorLanguage>>(
+          'clang_getCursorLanguage');
+  late final _clang_getCursorLanguage =
+      _clang_getCursorLanguagePtr.asFunction<DartClang_getCursorLanguage>();
+
+  /// Determine the "thread-local storage (TLS) kind" of the declaration
+  /// referred to by a cursor.
+  int clang_getCursorTLSKind(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorTLSKind(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorTLSKindPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorTLSKind>>(
+          'clang_getCursorTLSKind');
+  late final _clang_getCursorTLSKind =
+      _clang_getCursorTLSKindPtr.asFunction<DartClang_getCursorTLSKind>();
+
+  /// Returns the translation unit that a cursor originated from.
+  CXTranslationUnit clang_Cursor_getTranslationUnit(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getTranslationUnit(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getTranslationUnit>>(
+          'clang_Cursor_getTranslationUnit');
+  late final _clang_Cursor_getTranslationUnit =
+      _clang_Cursor_getTranslationUnitPtr
+          .asFunction<DartClang_Cursor_getTranslationUnit>();
+
+  /// Creates an empty CXCursorSet.
+  CXCursorSet clang_createCXCursorSet() {
+    return _clang_createCXCursorSet();
+  }
+
+  late final _clang_createCXCursorSetPtr =
+      _lookup<ffi.NativeFunction<NativeClang_createCXCursorSet>>(
+          'clang_createCXCursorSet');
+  late final _clang_createCXCursorSet =
+      _clang_createCXCursorSetPtr.asFunction<DartClang_createCXCursorSet>();
+
+  /// Disposes a CXCursorSet and releases its associated memory.
+  void clang_disposeCXCursorSet(
+    CXCursorSet cset,
+  ) {
+    return _clang_disposeCXCursorSet(
+      cset,
+    );
+  }
+
+  late final _clang_disposeCXCursorSetPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeCXCursorSet>>(
+          'clang_disposeCXCursorSet');
+  late final _clang_disposeCXCursorSet =
+      _clang_disposeCXCursorSetPtr.asFunction<DartClang_disposeCXCursorSet>();
+
+  /// Queries a CXCursorSet to see if it contains a specific CXCursor.
+  ///
+  /// \returns non-zero if the set contains the specified cursor.
+  int clang_CXCursorSet_contains(
+    CXCursorSet cset,
+    CXCursor cursor,
+  ) {
+    return _clang_CXCursorSet_contains(
+      cset,
+      cursor,
+    );
+  }
+
+  late final _clang_CXCursorSet_containsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXCursorSet_contains>>(
+          'clang_CXCursorSet_contains');
+  late final _clang_CXCursorSet_contains = _clang_CXCursorSet_containsPtr
+      .asFunction<DartClang_CXCursorSet_contains>();
+
+  /// Inserts a CXCursor into a CXCursorSet.
+  ///
+  /// \returns zero if the CXCursor was already in the set, and non-zero otherwise.
+  int clang_CXCursorSet_insert(
+    CXCursorSet cset,
+    CXCursor cursor,
+  ) {
+    return _clang_CXCursorSet_insert(
+      cset,
+      cursor,
+    );
+  }
+
+  late final _clang_CXCursorSet_insertPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXCursorSet_insert>>(
+          'clang_CXCursorSet_insert');
+  late final _clang_CXCursorSet_insert =
+      _clang_CXCursorSet_insertPtr.asFunction<DartClang_CXCursorSet_insert>();
+
+  /// Determine the semantic parent of the given cursor.
+  ///
+  /// The semantic parent of a cursor is the cursor that semantically contains
+  /// the given \p cursor. For many declarations, the lexical and semantic parents
+  /// are equivalent (the lexical parent is returned by
+  /// \c clang_getCursorLexicalParent()). They diverge when declarations or
+  /// definitions are provided out-of-line. For example:
+  ///
+  /// \code
+  /// class C {
+  /// void f();
+  /// };
+  ///
+  /// void C::f() { }
+  /// \endcode
+  ///
+  /// In the out-of-line definition of \c C::f, the semantic parent is
+  /// the class \c C, of which this function is a member. The lexical parent is
+  /// the place where the declaration actually occurs in the source code; in this
+  /// case, the definition occurs in the translation unit. In general, the
+  /// lexical parent for a given entity can change without affecting the semantics
+  /// of the program, and the lexical parent of different declarations of the
+  /// same entity may be different. Changing the semantic parent of a declaration,
+  /// on the other hand, can have a major impact on semantics, and redeclarations
+  /// of a particular entity should all have the same semantic context.
+  ///
+  /// In the example above, both declarations of \c C::f have \c C as their
+  /// semantic context, while the lexical context of the first \c C::f is \c C
+  /// and the lexical context of the second \c C::f is the translation unit.
+  ///
+  /// For global declarations, the semantic parent is the translation unit.
+  CXCursor clang_getCursorSemanticParent(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorSemanticParent(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorSemanticParentPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorSemanticParent>>(
+          'clang_getCursorSemanticParent');
+  late final _clang_getCursorSemanticParent = _clang_getCursorSemanticParentPtr
+      .asFunction<DartClang_getCursorSemanticParent>();
+
+  /// Determine the lexical parent of the given cursor.
+  ///
+  /// The lexical parent of a cursor is the cursor in which the given \p cursor
+  /// was actually written. For many declarations, the lexical and semantic parents
+  /// are equivalent (the semantic parent is returned by
+  /// \c clang_getCursorSemanticParent()). They diverge when declarations or
+  /// definitions are provided out-of-line. For example:
+  ///
+  /// \code
+  /// class C {
+  /// void f();
+  /// };
+  ///
+  /// void C::f() { }
+  /// \endcode
+  ///
+  /// In the out-of-line definition of \c C::f, the semantic parent is
+  /// the class \c C, of which this function is a member. The lexical parent is
+  /// the place where the declaration actually occurs in the source code; in this
+  /// case, the definition occurs in the translation unit. In general, the
+  /// lexical parent for a given entity can change without affecting the semantics
+  /// of the program, and the lexical parent of different declarations of the
+  /// same entity may be different. Changing the semantic parent of a declaration,
+  /// on the other hand, can have a major impact on semantics, and redeclarations
+  /// of a particular entity should all have the same semantic context.
+  ///
+  /// In the example above, both declarations of \c C::f have \c C as their
+  /// semantic context, while the lexical context of the first \c C::f is \c C
+  /// and the lexical context of the second \c C::f is the translation unit.
+  ///
+  /// For declarations written in the global scope, the lexical parent is
+  /// the translation unit.
+  CXCursor clang_getCursorLexicalParent(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorLexicalParent(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorLexicalParentPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorLexicalParent>>(
+          'clang_getCursorLexicalParent');
+  late final _clang_getCursorLexicalParent = _clang_getCursorLexicalParentPtr
+      .asFunction<DartClang_getCursorLexicalParent>();
+
+  /// Determine the set of methods that are overridden by the given
+  /// method.
+  ///
+  /// In both Objective-C and C++, a method (aka virtual member function,
+  /// in C++) can override a virtual method in a base class. For
+  /// Objective-C, a method is said to override any method in the class's
+  /// base class, its protocols, or its categories' protocols, that has the same
+  /// selector and is of the same kind (class or instance).
+  /// If no such method exists, the search continues to the class's superclass,
+  /// its protocols, and its categories, and so on. A method from an Objective-C
+  /// implementation is considered to override the same methods as its
+  /// corresponding method in the interface.
+  ///
+  /// For C++, a virtual member function overrides any virtual member
+  /// function with the same signature that occurs in its base
+  /// classes. With multiple inheritance, a virtual member function can
+  /// override several virtual member functions coming from different
+  /// base classes.
+  ///
+  /// In all cases, this function determines the immediate overridden
+  /// method, rather than all of the overridden methods. For example, if
+  /// a method is originally declared in a class A, then overridden in B
+  /// (which in inherits from A) and also in C (which inherited from B),
+  /// then the only overridden method returned from this function when
+  /// invoked on C's method will be B's method. The client may then
+  /// invoke this function again, given the previously-found overridden
+  /// methods, to map out the complete method-override set.
+  ///
+  /// \param cursor A cursor representing an Objective-C or C++
+  /// method. This routine will compute the set of methods that this
+  /// method overrides.
+  ///
+  /// \param overridden A pointer whose pointee will be replaced with a
+  /// pointer to an array of cursors, representing the set of overridden
+  /// methods. If there are no overridden methods, the pointee will be
+  /// set to NULL. The pointee must be freed via a call to
+  /// \c clang_disposeOverriddenCursors().
+  ///
+  /// \param num_overridden A pointer to the number of overridden
+  /// functions, will be set to the number of overridden functions in the
+  /// array pointed to by \p overridden.
+  void clang_getOverriddenCursors(
+    CXCursor cursor,
+    ffi.Pointer<ffi.Pointer<CXCursor>> overridden,
+    ffi.Pointer<ffi.UnsignedInt> num_overridden,
+  ) {
+    return _clang_getOverriddenCursors(
+      cursor,
+      overridden,
+      num_overridden,
+    );
+  }
+
+  late final _clang_getOverriddenCursorsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getOverriddenCursors>>(
+          'clang_getOverriddenCursors');
+  late final _clang_getOverriddenCursors = _clang_getOverriddenCursorsPtr
+      .asFunction<DartClang_getOverriddenCursors>();
+
+  /// Free the set of overridden cursors returned by \c
+  /// clang_getOverriddenCursors().
+  void clang_disposeOverriddenCursors(
+    ffi.Pointer<CXCursor> overridden,
+  ) {
+    return _clang_disposeOverriddenCursors(
+      overridden,
+    );
+  }
+
+  late final _clang_disposeOverriddenCursorsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeOverriddenCursors>>(
+          'clang_disposeOverriddenCursors');
+  late final _clang_disposeOverriddenCursors =
+      _clang_disposeOverriddenCursorsPtr
+          .asFunction<DartClang_disposeOverriddenCursors>();
+
+  /// Retrieve the file that is included by the given inclusion directive
+  /// cursor.
+  CXFile clang_getIncludedFile(
+    CXCursor cursor,
+  ) {
+    return _clang_getIncludedFile(
+      cursor,
+    );
+  }
+
+  late final _clang_getIncludedFilePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getIncludedFile>>(
+          'clang_getIncludedFile');
+  late final _clang_getIncludedFile =
+      _clang_getIncludedFilePtr.asFunction<DartClang_getIncludedFile>();
+
+  /// Map a source location to the cursor that describes the entity at that
+  /// location in the source code.
+  ///
+  /// clang_getCursor() maps an arbitrary source location within a translation
+  /// unit down to the most specific cursor that describes the entity at that
+  /// location. For example, given an expression \c x + y, invoking
+  /// clang_getCursor() with a source location pointing to "x" will return the
+  /// cursor for "x"; similarly for "y". If the cursor points anywhere between
+  /// "x" or "y" (e.g., on the + or the whitespace around it), clang_getCursor()
+  /// will return a cursor referring to the "+" expression.
+  ///
+  /// \returns a cursor representing the entity at the given source location, or
+  /// a NULL cursor if no such entity can be found.
+  CXCursor clang_getCursor(
+    CXTranslationUnit arg0,
+    CXSourceLocation arg1,
+  ) {
+    return _clang_getCursor(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_getCursorPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursor>>('clang_getCursor');
+  late final _clang_getCursor =
+      _clang_getCursorPtr.asFunction<DartClang_getCursor>();
+
+  /// Retrieve the physical location of the source constructor referenced
+  /// by the given cursor.
+  ///
+  /// The location of a declaration is typically the location of the name of that
+  /// declaration, where the name of that declaration would occur if it is
+  /// unnamed, or some keyword that introduces that particular declaration.
+  /// The location of a reference is where that reference occurs within the
+  /// source code.
+  CXSourceLocation clang_getCursorLocation(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorLocation(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorLocation>>(
+          'clang_getCursorLocation');
+  late final _clang_getCursorLocation =
+      _clang_getCursorLocationPtr.asFunction<DartClang_getCursorLocation>();
+
+  /// Retrieve the physical extent of the source construct referenced by
+  /// the given cursor.
+  ///
+  /// The extent of a cursor starts with the file/line/column pointing at the
+  /// first character within the source construct that the cursor refers to and
+  /// ends with the last character within that source construct. For a
+  /// declaration, the extent covers the declaration itself. For a reference,
+  /// the extent covers the location of the reference (e.g., where the referenced
+  /// entity was actually used).
+  CXSourceRange clang_getCursorExtent(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorExtent(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorExtentPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorExtent>>(
+          'clang_getCursorExtent');
+  late final _clang_getCursorExtent =
+      _clang_getCursorExtentPtr.asFunction<DartClang_getCursorExtent>();
+
+  /// Retrieve the type of a CXCursor (if any).
+  CXType clang_getCursorType(
+    CXCursor C,
+  ) {
+    return _clang_getCursorType(
+      C,
+    );
+  }
+
+  late final _clang_getCursorTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorType>>(
+          'clang_getCursorType');
+  late final _clang_getCursorType =
+      _clang_getCursorTypePtr.asFunction<DartClang_getCursorType>();
+
+  /// Pretty-print the underlying type using the rules of the
+  /// language of the translation unit from which it came.
+  ///
+  /// If the type is invalid, an empty string is returned.
+  CXString clang_getTypeSpelling(
+    CXType CT,
+  ) {
+    return _clang_getTypeSpelling(
+      CT,
+    );
+  }
+
+  late final _clang_getTypeSpellingPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTypeSpelling>>(
+          'clang_getTypeSpelling');
+  late final _clang_getTypeSpelling =
+      _clang_getTypeSpellingPtr.asFunction<DartClang_getTypeSpelling>();
+
+  /// Retrieve the underlying type of a typedef declaration.
+  ///
+  /// If the cursor does not reference a typedef declaration, an invalid type is
+  /// returned.
+  CXType clang_getTypedefDeclUnderlyingType(
+    CXCursor C,
+  ) {
+    return _clang_getTypedefDeclUnderlyingType(
+      C,
+    );
+  }
+
+  late final _clang_getTypedefDeclUnderlyingTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTypedefDeclUnderlyingType>>(
+          'clang_getTypedefDeclUnderlyingType');
+  late final _clang_getTypedefDeclUnderlyingType =
+      _clang_getTypedefDeclUnderlyingTypePtr
+          .asFunction<DartClang_getTypedefDeclUnderlyingType>();
+
+  /// Retrieve the integer type of an enum declaration.
+  ///
+  /// If the cursor does not reference an enum declaration, an invalid type is
+  /// returned.
+  CXType clang_getEnumDeclIntegerType(
+    CXCursor C,
+  ) {
+    return _clang_getEnumDeclIntegerType(
+      C,
+    );
+  }
+
+  late final _clang_getEnumDeclIntegerTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getEnumDeclIntegerType>>(
+          'clang_getEnumDeclIntegerType');
+  late final _clang_getEnumDeclIntegerType = _clang_getEnumDeclIntegerTypePtr
+      .asFunction<DartClang_getEnumDeclIntegerType>();
+
+  /// Retrieve the integer value of an enum constant declaration as a signed
+  /// long long.
+  ///
+  /// If the cursor does not reference an enum constant declaration, LLONG_MIN is returned.
+  /// Since this is also potentially a valid constant value, the kind of the cursor
+  /// must be verified before calling this function.
+  int clang_getEnumConstantDeclValue(
+    CXCursor C,
+  ) {
+    return _clang_getEnumConstantDeclValue(
+      C,
+    );
+  }
+
+  late final _clang_getEnumConstantDeclValuePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getEnumConstantDeclValue>>(
+          'clang_getEnumConstantDeclValue');
+  late final _clang_getEnumConstantDeclValue =
+      _clang_getEnumConstantDeclValuePtr
+          .asFunction<DartClang_getEnumConstantDeclValue>();
+
+  /// Retrieve the integer value of an enum constant declaration as an unsigned
+  /// long long.
+  ///
+  /// If the cursor does not reference an enum constant declaration, ULLONG_MAX is returned.
+  /// Since this is also potentially a valid constant value, the kind of the cursor
+  /// must be verified before calling this function.
+  int clang_getEnumConstantDeclUnsignedValue(
+    CXCursor C,
+  ) {
+    return _clang_getEnumConstantDeclUnsignedValue(
+      C,
+    );
+  }
+
+  late final _clang_getEnumConstantDeclUnsignedValuePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getEnumConstantDeclUnsignedValue>>(
+          'clang_getEnumConstantDeclUnsignedValue');
+  late final _clang_getEnumConstantDeclUnsignedValue =
+      _clang_getEnumConstantDeclUnsignedValuePtr
+          .asFunction<DartClang_getEnumConstantDeclUnsignedValue>();
+
+  /// Retrieve the bit width of a bit field declaration as an integer.
+  ///
+  /// If a cursor that is not a bit field declaration is passed in, -1 is returned.
+  int clang_getFieldDeclBitWidth(
+    CXCursor C,
+  ) {
+    return _clang_getFieldDeclBitWidth(
+      C,
+    );
+  }
+
+  late final _clang_getFieldDeclBitWidthPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getFieldDeclBitWidth>>(
+          'clang_getFieldDeclBitWidth');
+  late final _clang_getFieldDeclBitWidth = _clang_getFieldDeclBitWidthPtr
+      .asFunction<DartClang_getFieldDeclBitWidth>();
+
+  /// Retrieve the number of non-variadic arguments associated with a given
+  /// cursor.
+  ///
+  /// The number of arguments can be determined for calls as well as for
+  /// declarations of functions or methods. For other cursors -1 is returned.
+  int clang_Cursor_getNumArguments(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getNumArguments(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getNumArgumentsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getNumArguments>>(
+          'clang_Cursor_getNumArguments');
+  late final _clang_Cursor_getNumArguments = _clang_Cursor_getNumArgumentsPtr
+      .asFunction<DartClang_Cursor_getNumArguments>();
+
+  /// Retrieve the argument cursor of a function or method.
+  ///
+  /// The argument cursor can be determined for calls as well as for declarations
+  /// of functions or methods. For other cursors and for invalid indices, an
+  /// invalid cursor is returned.
+  CXCursor clang_Cursor_getArgument(
+    CXCursor C,
+    int i,
+  ) {
+    return _clang_Cursor_getArgument(
+      C,
+      i,
+    );
+  }
+
+  late final _clang_Cursor_getArgumentPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getArgument>>(
+          'clang_Cursor_getArgument');
+  late final _clang_Cursor_getArgument =
+      _clang_Cursor_getArgumentPtr.asFunction<DartClang_Cursor_getArgument>();
+
+  /// Returns the number of template args of a function decl representing a
+  /// template specialization.
+  ///
+  /// If the argument cursor cannot be converted into a template function
+  /// declaration, -1 is returned.
+  ///
+  /// For example, for the following declaration and specialization:
+  /// template <typename T, int kInt, bool kBool>
+  /// void foo() { ... }
+  ///
+  /// template <>
+  /// void foo<float, -7, true>();
+  ///
+  /// The value 3 would be returned from this call.
+  int clang_Cursor_getNumTemplateArguments(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getNumTemplateArguments(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getNumTemplateArgumentsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getNumTemplateArguments>>(
+          'clang_Cursor_getNumTemplateArguments');
+  late final _clang_Cursor_getNumTemplateArguments =
+      _clang_Cursor_getNumTemplateArgumentsPtr
+          .asFunction<DartClang_Cursor_getNumTemplateArguments>();
+
+  /// Retrieve the kind of the I'th template argument of the CXCursor C.
+  ///
+  /// If the argument CXCursor does not represent a FunctionDecl, an invalid
+  /// template argument kind is returned.
+  ///
+  /// For example, for the following declaration and specialization:
+  /// template <typename T, int kInt, bool kBool>
+  /// void foo() { ... }
+  ///
+  /// template <>
+  /// void foo<float, -7, true>();
+  ///
+  /// For I = 0, 1, and 2, Type, Integral, and Integral will be returned,
+  /// respectively.
+  int clang_Cursor_getTemplateArgumentKind(
+    CXCursor C,
+    int I,
+  ) {
+    return _clang_Cursor_getTemplateArgumentKind(
+      C,
+      I,
+    );
+  }
+
+  late final _clang_Cursor_getTemplateArgumentKindPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getTemplateArgumentKind>>(
+          'clang_Cursor_getTemplateArgumentKind');
+  late final _clang_Cursor_getTemplateArgumentKind =
+      _clang_Cursor_getTemplateArgumentKindPtr
+          .asFunction<DartClang_Cursor_getTemplateArgumentKind>();
+
+  /// Retrieve a CXType representing the type of a TemplateArgument of a
+  /// function decl representing a template specialization.
+  ///
+  /// If the argument CXCursor does not represent a FunctionDecl whose I'th
+  /// template argument has a kind of CXTemplateArgKind_Integral, an invalid type
+  /// is returned.
+  ///
+  /// For example, for the following declaration and specialization:
+  /// template <typename T, int kInt, bool kBool>
+  /// void foo() { ... }
+  ///
+  /// template <>
+  /// void foo<float, -7, true>();
+  ///
+  /// If called with I = 0, "float", will be returned.
+  /// Invalid types will be returned for I == 1 or 2.
+  CXType clang_Cursor_getTemplateArgumentType(
+    CXCursor C,
+    int I,
+  ) {
+    return _clang_Cursor_getTemplateArgumentType(
+      C,
+      I,
+    );
+  }
+
+  late final _clang_Cursor_getTemplateArgumentTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getTemplateArgumentType>>(
+          'clang_Cursor_getTemplateArgumentType');
+  late final _clang_Cursor_getTemplateArgumentType =
+      _clang_Cursor_getTemplateArgumentTypePtr
+          .asFunction<DartClang_Cursor_getTemplateArgumentType>();
+
+  /// Retrieve the value of an Integral TemplateArgument (of a function
+  /// decl representing a template specialization) as a signed long long.
+  ///
+  /// It is undefined to call this function on a CXCursor that does not represent a
+  /// FunctionDecl or whose I'th template argument is not an integral value.
+  ///
+  /// For example, for the following declaration and specialization:
+  /// template <typename T, int kInt, bool kBool>
+  /// void foo() { ... }
+  ///
+  /// template <>
+  /// void foo<float, -7, true>();
+  ///
+  /// If called with I = 1 or 2, -7 or true will be returned, respectively.
+  /// For I == 0, this function's behavior is undefined.
+  int clang_Cursor_getTemplateArgumentValue(
+    CXCursor C,
+    int I,
+  ) {
+    return _clang_Cursor_getTemplateArgumentValue(
+      C,
+      I,
+    );
+  }
+
+  late final _clang_Cursor_getTemplateArgumentValuePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getTemplateArgumentValue>>(
+          'clang_Cursor_getTemplateArgumentValue');
+  late final _clang_Cursor_getTemplateArgumentValue =
+      _clang_Cursor_getTemplateArgumentValuePtr
+          .asFunction<DartClang_Cursor_getTemplateArgumentValue>();
+
+  /// Retrieve the value of an Integral TemplateArgument (of a function
+  /// decl representing a template specialization) as an unsigned long long.
+  ///
+  /// It is undefined to call this function on a CXCursor that does not represent a
+  /// FunctionDecl or whose I'th template argument is not an integral value.
+  ///
+  /// For example, for the following declaration and specialization:
+  /// template <typename T, int kInt, bool kBool>
+  /// void foo() { ... }
+  ///
+  /// template <>
+  /// void foo<float, 2147483649, true>();
+  ///
+  /// If called with I = 1 or 2, 2147483649 or true will be returned, respectively.
+  /// For I == 0, this function's behavior is undefined.
+  int clang_Cursor_getTemplateArgumentUnsignedValue(
+    CXCursor C,
+    int I,
+  ) {
+    return _clang_Cursor_getTemplateArgumentUnsignedValue(
+      C,
+      I,
+    );
+  }
+
+  late final _clang_Cursor_getTemplateArgumentUnsignedValuePtr = _lookup<
+          ffi
+          .NativeFunction<NativeClang_Cursor_getTemplateArgumentUnsignedValue>>(
+      'clang_Cursor_getTemplateArgumentUnsignedValue');
+  late final _clang_Cursor_getTemplateArgumentUnsignedValue =
+      _clang_Cursor_getTemplateArgumentUnsignedValuePtr
+          .asFunction<DartClang_Cursor_getTemplateArgumentUnsignedValue>();
+
+  /// Determine whether two CXTypes represent the same type.
+  ///
+  /// \returns non-zero if the CXTypes represent the same type and
+  /// zero otherwise.
+  int clang_equalTypes(
+    CXType A,
+    CXType B,
+  ) {
+    return _clang_equalTypes(
+      A,
+      B,
+    );
+  }
+
+  late final _clang_equalTypesPtr =
+      _lookup<ffi.NativeFunction<NativeClang_equalTypes>>('clang_equalTypes');
+  late final _clang_equalTypes =
+      _clang_equalTypesPtr.asFunction<DartClang_equalTypes>();
+
+  /// Return the canonical type for a CXType.
+  ///
+  /// Clang's type system explicitly models typedefs and all the ways
+  /// a specific type can be represented.  The canonical type is the underlying
+  /// type with all the "sugar" removed.  For example, if 'T' is a typedef
+  /// for 'int', the canonical type for 'T' would be 'int'.
+  CXType clang_getCanonicalType(
+    CXType T,
+  ) {
+    return _clang_getCanonicalType(
+      T,
+    );
+  }
+
+  late final _clang_getCanonicalTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCanonicalType>>(
+          'clang_getCanonicalType');
+  late final _clang_getCanonicalType =
+      _clang_getCanonicalTypePtr.asFunction<DartClang_getCanonicalType>();
+
+  /// Determine whether a CXType has the "const" qualifier set,
+  /// without looking through typedefs that may have added "const" at a
+  /// different level.
+  int clang_isConstQualifiedType(
+    CXType T,
+  ) {
+    return _clang_isConstQualifiedType(
+      T,
+    );
+  }
+
+  late final _clang_isConstQualifiedTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_isConstQualifiedType>>(
+          'clang_isConstQualifiedType');
+  late final _clang_isConstQualifiedType = _clang_isConstQualifiedTypePtr
+      .asFunction<DartClang_isConstQualifiedType>();
+
+  /// Determine whether a  CXCursor that is a macro, is
+  /// function like.
+  int clang_Cursor_isMacroFunctionLike(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isMacroFunctionLike(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isMacroFunctionLikePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isMacroFunctionLike>>(
+          'clang_Cursor_isMacroFunctionLike');
+  late final _clang_Cursor_isMacroFunctionLike =
+      _clang_Cursor_isMacroFunctionLikePtr
+          .asFunction<DartClang_Cursor_isMacroFunctionLike>();
+
+  /// Determine whether a  CXCursor that is a macro, is a
+  /// builtin one.
+  int clang_Cursor_isMacroBuiltin(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isMacroBuiltin(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isMacroBuiltinPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isMacroBuiltin>>(
+          'clang_Cursor_isMacroBuiltin');
+  late final _clang_Cursor_isMacroBuiltin = _clang_Cursor_isMacroBuiltinPtr
+      .asFunction<DartClang_Cursor_isMacroBuiltin>();
+
+  /// Determine whether a  CXCursor that is a function declaration, is an
+  /// inline declaration.
+  int clang_Cursor_isFunctionInlined(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isFunctionInlined(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isFunctionInlinedPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isFunctionInlined>>(
+          'clang_Cursor_isFunctionInlined');
+  late final _clang_Cursor_isFunctionInlined =
+      _clang_Cursor_isFunctionInlinedPtr
+          .asFunction<DartClang_Cursor_isFunctionInlined>();
+
+  /// Determine whether a CXType has the "volatile" qualifier set,
+  /// without looking through typedefs that may have added "volatile" at
+  /// a different level.
+  int clang_isVolatileQualifiedType(
+    CXType T,
+  ) {
+    return _clang_isVolatileQualifiedType(
+      T,
+    );
+  }
+
+  late final _clang_isVolatileQualifiedTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_isVolatileQualifiedType>>(
+          'clang_isVolatileQualifiedType');
+  late final _clang_isVolatileQualifiedType = _clang_isVolatileQualifiedTypePtr
+      .asFunction<DartClang_isVolatileQualifiedType>();
+
+  /// Determine whether a CXType has the "restrict" qualifier set,
+  /// without looking through typedefs that may have added "restrict" at a
+  /// different level.
+  int clang_isRestrictQualifiedType(
+    CXType T,
+  ) {
+    return _clang_isRestrictQualifiedType(
+      T,
+    );
+  }
+
+  late final _clang_isRestrictQualifiedTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_isRestrictQualifiedType>>(
+          'clang_isRestrictQualifiedType');
+  late final _clang_isRestrictQualifiedType = _clang_isRestrictQualifiedTypePtr
+      .asFunction<DartClang_isRestrictQualifiedType>();
+
+  /// Returns the address space of the given type.
+  int clang_getAddressSpace(
+    CXType T,
+  ) {
+    return _clang_getAddressSpace(
+      T,
+    );
+  }
+
+  late final _clang_getAddressSpacePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getAddressSpace>>(
+          'clang_getAddressSpace');
+  late final _clang_getAddressSpace =
+      _clang_getAddressSpacePtr.asFunction<DartClang_getAddressSpace>();
+
+  /// Returns the typedef name of the given type.
+  CXString clang_getTypedefName(
+    CXType CT,
+  ) {
+    return _clang_getTypedefName(
+      CT,
+    );
+  }
+
+  late final _clang_getTypedefNamePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTypedefName>>(
+          'clang_getTypedefName');
+  late final _clang_getTypedefName =
+      _clang_getTypedefNamePtr.asFunction<DartClang_getTypedefName>();
+
+  /// For pointer types, returns the type of the pointee.
+  CXType clang_getPointeeType(
+    CXType T,
+  ) {
+    return _clang_getPointeeType(
+      T,
+    );
+  }
+
+  late final _clang_getPointeeTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getPointeeType>>(
+          'clang_getPointeeType');
+  late final _clang_getPointeeType =
+      _clang_getPointeeTypePtr.asFunction<DartClang_getPointeeType>();
+
+  /// Return the cursor for the declaration of the given type.
+  CXCursor clang_getTypeDeclaration(
+    CXType T,
+  ) {
+    return _clang_getTypeDeclaration(
+      T,
+    );
+  }
+
+  late final _clang_getTypeDeclarationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTypeDeclaration>>(
+          'clang_getTypeDeclaration');
+  late final _clang_getTypeDeclaration =
+      _clang_getTypeDeclarationPtr.asFunction<DartClang_getTypeDeclaration>();
+
+  /// Returns the Objective-C type encoding for the specified declaration.
+  CXString clang_getDeclObjCTypeEncoding(
+    CXCursor C,
+  ) {
+    return _clang_getDeclObjCTypeEncoding(
+      C,
+    );
+  }
+
+  late final _clang_getDeclObjCTypeEncodingPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDeclObjCTypeEncoding>>(
+          'clang_getDeclObjCTypeEncoding');
+  late final _clang_getDeclObjCTypeEncoding = _clang_getDeclObjCTypeEncodingPtr
+      .asFunction<DartClang_getDeclObjCTypeEncoding>();
+
+  /// Returns the Objective-C type encoding for the specified CXType.
+  CXString clang_Type_getObjCEncoding(
+    CXType type,
+  ) {
+    return _clang_Type_getObjCEncoding(
+      type,
+    );
+  }
+
+  late final _clang_Type_getObjCEncodingPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getObjCEncoding>>(
+          'clang_Type_getObjCEncoding');
+  late final _clang_Type_getObjCEncoding = _clang_Type_getObjCEncodingPtr
+      .asFunction<DartClang_Type_getObjCEncoding>();
+
+  /// Retrieve the spelling of a given CXTypeKind.
+  CXString clang_getTypeKindSpelling(
+    int K,
+  ) {
+    return _clang_getTypeKindSpelling(
+      K,
+    );
+  }
+
+  late final _clang_getTypeKindSpellingPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTypeKindSpelling>>(
+          'clang_getTypeKindSpelling');
+  late final _clang_getTypeKindSpelling =
+      _clang_getTypeKindSpellingPtr.asFunction<DartClang_getTypeKindSpelling>();
+
+  /// Retrieve the calling convention associated with a function type.
+  ///
+  /// If a non-function type is passed in, CXCallingConv_Invalid is returned.
+  int clang_getFunctionTypeCallingConv(
+    CXType T,
+  ) {
+    return _clang_getFunctionTypeCallingConv(
+      T,
+    );
+  }
+
+  late final _clang_getFunctionTypeCallingConvPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getFunctionTypeCallingConv>>(
+          'clang_getFunctionTypeCallingConv');
+  late final _clang_getFunctionTypeCallingConv =
+      _clang_getFunctionTypeCallingConvPtr
+          .asFunction<DartClang_getFunctionTypeCallingConv>();
+
+  /// Retrieve the return type associated with a function type.
+  ///
+  /// If a non-function type is passed in, an invalid type is returned.
+  CXType clang_getResultType(
+    CXType T,
+  ) {
+    return _clang_getResultType(
+      T,
+    );
+  }
+
+  late final _clang_getResultTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getResultType>>(
+          'clang_getResultType');
+  late final _clang_getResultType =
+      _clang_getResultTypePtr.asFunction<DartClang_getResultType>();
+
+  /// Retrieve the exception specification type associated with a function type.
+  /// This is a value of type CXCursor_ExceptionSpecificationKind.
+  ///
+  /// If a non-function type is passed in, an error code of -1 is returned.
+  int clang_getExceptionSpecificationType(
+    CXType T,
+  ) {
+    return _clang_getExceptionSpecificationType(
+      T,
+    );
+  }
+
+  late final _clang_getExceptionSpecificationTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getExceptionSpecificationType>>(
+          'clang_getExceptionSpecificationType');
+  late final _clang_getExceptionSpecificationType =
+      _clang_getExceptionSpecificationTypePtr
+          .asFunction<DartClang_getExceptionSpecificationType>();
+
+  /// Retrieve the number of non-variadic parameters associated with a
+  /// function type.
+  ///
+  /// If a non-function type is passed in, -1 is returned.
+  int clang_getNumArgTypes(
+    CXType T,
+  ) {
+    return _clang_getNumArgTypes(
+      T,
+    );
+  }
+
+  late final _clang_getNumArgTypesPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getNumArgTypes>>(
+          'clang_getNumArgTypes');
+  late final _clang_getNumArgTypes =
+      _clang_getNumArgTypesPtr.asFunction<DartClang_getNumArgTypes>();
+
+  /// Retrieve the type of a parameter of a function type.
+  ///
+  /// If a non-function type is passed in or the function does not have enough
+  /// parameters, an invalid type is returned.
+  CXType clang_getArgType(
+    CXType T,
+    int i,
+  ) {
+    return _clang_getArgType(
+      T,
+      i,
+    );
+  }
+
+  late final _clang_getArgTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getArgType>>('clang_getArgType');
+  late final _clang_getArgType =
+      _clang_getArgTypePtr.asFunction<DartClang_getArgType>();
+
+  /// Retrieves the base type of the ObjCObjectType.
+  ///
+  /// If the type is not an ObjC object, an invalid type is returned.
+  CXType clang_Type_getObjCObjectBaseType(
+    CXType T,
+  ) {
+    return _clang_Type_getObjCObjectBaseType(
+      T,
+    );
+  }
+
+  late final _clang_Type_getObjCObjectBaseTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getObjCObjectBaseType>>(
+          'clang_Type_getObjCObjectBaseType');
+  late final _clang_Type_getObjCObjectBaseType =
+      _clang_Type_getObjCObjectBaseTypePtr
+          .asFunction<DartClang_Type_getObjCObjectBaseType>();
+
+  /// Retrieve the number of protocol references associated with an ObjC object/id.
+  ///
+  /// If the type is not an ObjC object, 0 is returned.
+  int clang_Type_getNumObjCProtocolRefs(
+    CXType T,
+  ) {
+    return _clang_Type_getNumObjCProtocolRefs(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNumObjCProtocolRefsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getNumObjCProtocolRefs>>(
+          'clang_Type_getNumObjCProtocolRefs');
+  late final _clang_Type_getNumObjCProtocolRefs =
+      _clang_Type_getNumObjCProtocolRefsPtr
+          .asFunction<DartClang_Type_getNumObjCProtocolRefs>();
+
+  /// Retrieve the decl for a protocol reference for an ObjC object/id.
+  ///
+  /// If the type is not an ObjC object or there are not enough protocol
+  /// references, an invalid cursor is returned.
+  CXCursor clang_Type_getObjCProtocolDecl(
+    CXType T,
+    int i,
+  ) {
+    return _clang_Type_getObjCProtocolDecl(
+      T,
+      i,
+    );
+  }
+
+  late final _clang_Type_getObjCProtocolDeclPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getObjCProtocolDecl>>(
+          'clang_Type_getObjCProtocolDecl');
+  late final _clang_Type_getObjCProtocolDecl =
+      _clang_Type_getObjCProtocolDeclPtr
+          .asFunction<DartClang_Type_getObjCProtocolDecl>();
+
+  /// Retreive the number of type arguments associated with an ObjC object.
+  ///
+  /// If the type is not an ObjC object, 0 is returned.
+  int clang_Type_getNumObjCTypeArgs(
+    CXType T,
+  ) {
+    return _clang_Type_getNumObjCTypeArgs(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNumObjCTypeArgsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getNumObjCTypeArgs>>(
+          'clang_Type_getNumObjCTypeArgs');
+  late final _clang_Type_getNumObjCTypeArgs = _clang_Type_getNumObjCTypeArgsPtr
+      .asFunction<DartClang_Type_getNumObjCTypeArgs>();
+
+  /// Retrieve a type argument associated with an ObjC object.
+  ///
+  /// If the type is not an ObjC or the index is not valid,
+  /// an invalid type is returned.
+  CXType clang_Type_getObjCTypeArg(
+    CXType T,
+    int i,
+  ) {
+    return _clang_Type_getObjCTypeArg(
+      T,
+      i,
+    );
+  }
+
+  late final _clang_Type_getObjCTypeArgPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getObjCTypeArg>>(
+          'clang_Type_getObjCTypeArg');
+  late final _clang_Type_getObjCTypeArg =
+      _clang_Type_getObjCTypeArgPtr.asFunction<DartClang_Type_getObjCTypeArg>();
+
+  /// Return 1 if the CXType is a variadic function type, and 0 otherwise.
+  int clang_isFunctionTypeVariadic(
+    CXType T,
+  ) {
+    return _clang_isFunctionTypeVariadic(
+      T,
+    );
+  }
+
+  late final _clang_isFunctionTypeVariadicPtr =
+      _lookup<ffi.NativeFunction<NativeClang_isFunctionTypeVariadic>>(
+          'clang_isFunctionTypeVariadic');
+  late final _clang_isFunctionTypeVariadic = _clang_isFunctionTypeVariadicPtr
+      .asFunction<DartClang_isFunctionTypeVariadic>();
+
+  /// Retrieve the return type associated with a given cursor.
+  ///
+  /// This only returns a valid type if the cursor refers to a function or method.
+  CXType clang_getCursorResultType(
+    CXCursor C,
+  ) {
+    return _clang_getCursorResultType(
+      C,
+    );
+  }
+
+  late final _clang_getCursorResultTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorResultType>>(
+          'clang_getCursorResultType');
+  late final _clang_getCursorResultType =
+      _clang_getCursorResultTypePtr.asFunction<DartClang_getCursorResultType>();
+
+  /// Retrieve the exception specification type associated with a given cursor.
+  /// This is a value of type CXCursor_ExceptionSpecificationKind.
+  ///
+  /// This only returns a valid result if the cursor refers to a function or method.
+  int clang_getCursorExceptionSpecificationType(
+    CXCursor C,
+  ) {
+    return _clang_getCursorExceptionSpecificationType(
+      C,
+    );
+  }
+
+  late final _clang_getCursorExceptionSpecificationTypePtr = _lookup<
+          ffi.NativeFunction<NativeClang_getCursorExceptionSpecificationType>>(
+      'clang_getCursorExceptionSpecificationType');
+  late final _clang_getCursorExceptionSpecificationType =
+      _clang_getCursorExceptionSpecificationTypePtr
+          .asFunction<DartClang_getCursorExceptionSpecificationType>();
+
+  /// Return 1 if the CXType is a POD (plain old data) type, and 0
+  /// otherwise.
+  int clang_isPODType(
+    CXType T,
+  ) {
+    return _clang_isPODType(
+      T,
+    );
+  }
+
+  late final _clang_isPODTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_isPODType>>('clang_isPODType');
+  late final _clang_isPODType =
+      _clang_isPODTypePtr.asFunction<DartClang_isPODType>();
+
+  /// Return the element type of an array, complex, or vector type.
+  ///
+  /// If a type is passed in that is not an array, complex, or vector type,
+  /// an invalid type is returned.
+  CXType clang_getElementType(
+    CXType T,
+  ) {
+    return _clang_getElementType(
+      T,
+    );
+  }
+
+  late final _clang_getElementTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getElementType>>(
+          'clang_getElementType');
+  late final _clang_getElementType =
+      _clang_getElementTypePtr.asFunction<DartClang_getElementType>();
+
+  /// Return the number of elements of an array or vector type.
+  ///
+  /// If a type is passed in that is not an array or vector type,
+  /// -1 is returned.
+  int clang_getNumElements(
+    CXType T,
+  ) {
+    return _clang_getNumElements(
+      T,
+    );
+  }
+
+  late final _clang_getNumElementsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getNumElements>>(
+          'clang_getNumElements');
+  late final _clang_getNumElements =
+      _clang_getNumElementsPtr.asFunction<DartClang_getNumElements>();
+
+  /// Return the element type of an array type.
+  ///
+  /// If a non-array type is passed in, an invalid type is returned.
+  CXType clang_getArrayElementType(
+    CXType T,
+  ) {
+    return _clang_getArrayElementType(
+      T,
+    );
+  }
+
+  late final _clang_getArrayElementTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getArrayElementType>>(
+          'clang_getArrayElementType');
+  late final _clang_getArrayElementType =
+      _clang_getArrayElementTypePtr.asFunction<DartClang_getArrayElementType>();
+
+  /// Return the array size of a constant array.
+  ///
+  /// If a non-array type is passed in, -1 is returned.
+  int clang_getArraySize(
+    CXType T,
+  ) {
+    return _clang_getArraySize(
+      T,
+    );
+  }
+
+  late final _clang_getArraySizePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getArraySize>>(
+          'clang_getArraySize');
+  late final _clang_getArraySize =
+      _clang_getArraySizePtr.asFunction<DartClang_getArraySize>();
+
+  /// Retrieve the type named by the qualified-id.
+  ///
+  /// If a non-elaborated type is passed in, an invalid type is returned.
+  CXType clang_Type_getNamedType(
+    CXType T,
+  ) {
+    return _clang_Type_getNamedType(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNamedTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getNamedType>>(
+          'clang_Type_getNamedType');
+  late final _clang_Type_getNamedType =
+      _clang_Type_getNamedTypePtr.asFunction<DartClang_Type_getNamedType>();
+
+  /// Determine if a typedef is 'transparent' tag.
+  ///
+  /// A typedef is considered 'transparent' if it shares a name and spelling
+  /// location with its underlying tag type, as is the case with the NS_ENUM macro.
+  ///
+  /// \returns non-zero if transparent and zero otherwise.
+  int clang_Type_isTransparentTagTypedef(
+    CXType T,
+  ) {
+    return _clang_Type_isTransparentTagTypedef(
+      T,
+    );
+  }
+
+  late final _clang_Type_isTransparentTagTypedefPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_isTransparentTagTypedef>>(
+          'clang_Type_isTransparentTagTypedef');
+  late final _clang_Type_isTransparentTagTypedef =
+      _clang_Type_isTransparentTagTypedefPtr
+          .asFunction<DartClang_Type_isTransparentTagTypedef>();
+
+  /// Retrieve the nullability kind of a pointer type.
+  int clang_Type_getNullability(
+    CXType T,
+  ) {
+    return _clang_Type_getNullability(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNullabilityPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getNullability>>(
+          'clang_Type_getNullability');
+  late final _clang_Type_getNullability =
+      _clang_Type_getNullabilityPtr.asFunction<DartClang_Type_getNullability>();
+
+  /// Return the alignment of a type in bytes as per C++[expr.alignof]
+  /// standard.
+  ///
+  /// If the type declaration is invalid, CXTypeLayoutError_Invalid is returned.
+  /// If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete
+  /// is returned.
+  /// If the type declaration is a dependent type, CXTypeLayoutError_Dependent is
+  /// returned.
+  /// If the type declaration is not a constant size type,
+  /// CXTypeLayoutError_NotConstantSize is returned.
+  int clang_Type_getAlignOf(
+    CXType T,
+  ) {
+    return _clang_Type_getAlignOf(
+      T,
+    );
+  }
+
+  late final _clang_Type_getAlignOfPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getAlignOf>>(
+          'clang_Type_getAlignOf');
+  late final _clang_Type_getAlignOf =
+      _clang_Type_getAlignOfPtr.asFunction<DartClang_Type_getAlignOf>();
+
+  /// Return the class type of an member pointer type.
+  ///
+  /// If a non-member-pointer type is passed in, an invalid type is returned.
+  CXType clang_Type_getClassType(
+    CXType T,
+  ) {
+    return _clang_Type_getClassType(
+      T,
+    );
+  }
+
+  late final _clang_Type_getClassTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getClassType>>(
+          'clang_Type_getClassType');
+  late final _clang_Type_getClassType =
+      _clang_Type_getClassTypePtr.asFunction<DartClang_Type_getClassType>();
+
+  /// Return the size of a type in bytes as per C++[expr.sizeof] standard.
+  ///
+  /// If the type declaration is invalid, CXTypeLayoutError_Invalid is returned.
+  /// If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete
+  /// is returned.
+  /// If the type declaration is a dependent type, CXTypeLayoutError_Dependent is
+  /// returned.
+  int clang_Type_getSizeOf(
+    CXType T,
+  ) {
+    return _clang_Type_getSizeOf(
+      T,
+    );
+  }
+
+  late final _clang_Type_getSizeOfPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getSizeOf>>(
+          'clang_Type_getSizeOf');
+  late final _clang_Type_getSizeOf =
+      _clang_Type_getSizeOfPtr.asFunction<DartClang_Type_getSizeOf>();
+
+  /// Return the offset of a field named S in a record of type T in bits
+  /// as it would be returned by __offsetof__ as per C++11[18.2p4]
+  ///
+  /// If the cursor is not a record field declaration, CXTypeLayoutError_Invalid
+  /// is returned.
+  /// If the field's type declaration is an incomplete type,
+  /// CXTypeLayoutError_Incomplete is returned.
+  /// If the field's type declaration is a dependent type,
+  /// CXTypeLayoutError_Dependent is returned.
+  /// If the field's name S is not found,
+  /// CXTypeLayoutError_InvalidFieldName is returned.
+  int clang_Type_getOffsetOf(
+    CXType T,
+    ffi.Pointer<ffi.Char> S,
+  ) {
+    return _clang_Type_getOffsetOf(
+      T,
+      S,
+    );
+  }
+
+  late final _clang_Type_getOffsetOfPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getOffsetOf>>(
+          'clang_Type_getOffsetOf');
+  late final _clang_Type_getOffsetOf =
+      _clang_Type_getOffsetOfPtr.asFunction<DartClang_Type_getOffsetOf>();
+
+  /// Return the type that was modified by this attributed type.
+  ///
+  /// If the type is not an attributed type, an invalid type is returned.
+  CXType clang_Type_getModifiedType(
+    CXType T,
+  ) {
+    return _clang_Type_getModifiedType(
+      T,
+    );
+  }
+
+  late final _clang_Type_getModifiedTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getModifiedType>>(
+          'clang_Type_getModifiedType');
+  late final _clang_Type_getModifiedType = _clang_Type_getModifiedTypePtr
+      .asFunction<DartClang_Type_getModifiedType>();
+
+  /// Return the offset of the field represented by the Cursor.
+  ///
+  /// If the cursor is not a field declaration, -1 is returned.
+  /// If the cursor semantic parent is not a record field declaration,
+  /// CXTypeLayoutError_Invalid is returned.
+  /// If the field's type declaration is an incomplete type,
+  /// CXTypeLayoutError_Incomplete is returned.
+  /// If the field's type declaration is a dependent type,
+  /// CXTypeLayoutError_Dependent is returned.
+  /// If the field's name S is not found,
+  /// CXTypeLayoutError_InvalidFieldName is returned.
+  int clang_Cursor_getOffsetOfField(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getOffsetOfField(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getOffsetOfFieldPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getOffsetOfField>>(
+          'clang_Cursor_getOffsetOfField');
+  late final _clang_Cursor_getOffsetOfField = _clang_Cursor_getOffsetOfFieldPtr
+      .asFunction<DartClang_Cursor_getOffsetOfField>();
+
+  /// Determine whether the given cursor represents an anonymous
+  /// tag or namespace
+  int clang_Cursor_isAnonymous(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isAnonymous(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isAnonymousPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isAnonymous>>(
+          'clang_Cursor_isAnonymous');
+  late final _clang_Cursor_isAnonymous =
+      _clang_Cursor_isAnonymousPtr.asFunction<DartClang_Cursor_isAnonymous>();
+
+  /// Determine whether the given cursor represents an anonymous record
+  /// declaration.
+  int clang_Cursor_isAnonymousRecordDecl(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isAnonymousRecordDecl(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isAnonymousRecordDeclPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isAnonymousRecordDecl>>(
+          'clang_Cursor_isAnonymousRecordDecl');
+  late final _clang_Cursor_isAnonymousRecordDecl =
+      _clang_Cursor_isAnonymousRecordDeclPtr
+          .asFunction<DartClang_Cursor_isAnonymousRecordDecl>();
+
+  /// Determine whether the given cursor represents an inline namespace
+  /// declaration.
+  int clang_Cursor_isInlineNamespace(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isInlineNamespace(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isInlineNamespacePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isInlineNamespace>>(
+          'clang_Cursor_isInlineNamespace');
+  late final _clang_Cursor_isInlineNamespace =
+      _clang_Cursor_isInlineNamespacePtr
+          .asFunction<DartClang_Cursor_isInlineNamespace>();
+
+  /// Returns the number of template arguments for given template
+  /// specialization, or -1 if type \c T is not a template specialization.
+  int clang_Type_getNumTemplateArguments(
+    CXType T,
+  ) {
+    return _clang_Type_getNumTemplateArguments(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNumTemplateArgumentsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getNumTemplateArguments>>(
+          'clang_Type_getNumTemplateArguments');
+  late final _clang_Type_getNumTemplateArguments =
+      _clang_Type_getNumTemplateArgumentsPtr
+          .asFunction<DartClang_Type_getNumTemplateArguments>();
+
+  /// Returns the type template argument of a template class specialization
+  /// at given index.
+  ///
+  /// This function only returns template type arguments and does not handle
+  /// template template arguments or variadic packs.
+  CXType clang_Type_getTemplateArgumentAsType(
+    CXType T,
+    int i,
+  ) {
+    return _clang_Type_getTemplateArgumentAsType(
+      T,
+      i,
+    );
+  }
+
+  late final _clang_Type_getTemplateArgumentAsTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getTemplateArgumentAsType>>(
+          'clang_Type_getTemplateArgumentAsType');
+  late final _clang_Type_getTemplateArgumentAsType =
+      _clang_Type_getTemplateArgumentAsTypePtr
+          .asFunction<DartClang_Type_getTemplateArgumentAsType>();
+
+  /// Retrieve the ref-qualifier kind of a function or method.
+  ///
+  /// The ref-qualifier is returned for C++ functions or methods. For other types
+  /// or non-C++ declarations, CXRefQualifier_None is returned.
+  int clang_Type_getCXXRefQualifier(
+    CXType T,
+  ) {
+    return _clang_Type_getCXXRefQualifier(
+      T,
+    );
+  }
+
+  late final _clang_Type_getCXXRefQualifierPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_getCXXRefQualifier>>(
+          'clang_Type_getCXXRefQualifier');
+  late final _clang_Type_getCXXRefQualifier = _clang_Type_getCXXRefQualifierPtr
+      .asFunction<DartClang_Type_getCXXRefQualifier>();
+
+  /// Returns non-zero if the cursor specifies a Record member that is a
+  /// bitfield.
+  int clang_Cursor_isBitField(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isBitField(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isBitFieldPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isBitField>>(
+          'clang_Cursor_isBitField');
+  late final _clang_Cursor_isBitField =
+      _clang_Cursor_isBitFieldPtr.asFunction<DartClang_Cursor_isBitField>();
+
+  /// Returns 1 if the base class specified by the cursor with kind
+  /// CX_CXXBaseSpecifier is virtual.
+  int clang_isVirtualBase(
+    CXCursor arg0,
+  ) {
+    return _clang_isVirtualBase(
+      arg0,
+    );
+  }
+
+  late final _clang_isVirtualBasePtr =
+      _lookup<ffi.NativeFunction<NativeClang_isVirtualBase>>(
+          'clang_isVirtualBase');
+  late final _clang_isVirtualBase =
+      _clang_isVirtualBasePtr.asFunction<DartClang_isVirtualBase>();
+
+  /// Returns the access control level for the referenced object.
+  ///
+  /// If the cursor refers to a C++ declaration, its access control level within its
+  /// parent scope is returned. Otherwise, if the cursor refers to a base specifier or
+  /// access specifier, the specifier itself is returned.
+  int clang_getCXXAccessSpecifier(
+    CXCursor arg0,
+  ) {
+    return _clang_getCXXAccessSpecifier(
+      arg0,
+    );
+  }
+
+  late final _clang_getCXXAccessSpecifierPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCXXAccessSpecifier>>(
+          'clang_getCXXAccessSpecifier');
+  late final _clang_getCXXAccessSpecifier = _clang_getCXXAccessSpecifierPtr
+      .asFunction<DartClang_getCXXAccessSpecifier>();
+
+  /// Returns the storage class for a function or variable declaration.
+  ///
+  /// If the passed in Cursor is not a function or variable declaration,
+  /// CX_SC_Invalid is returned else the storage class.
+  int clang_Cursor_getStorageClass(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getStorageClass(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getStorageClassPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getStorageClass>>(
+          'clang_Cursor_getStorageClass');
+  late final _clang_Cursor_getStorageClass = _clang_Cursor_getStorageClassPtr
+      .asFunction<DartClang_Cursor_getStorageClass>();
+
+  /// Determine the number of overloaded declarations referenced by a
+  /// \c CXCursor_OverloadedDeclRef cursor.
+  ///
+  /// \param cursor The cursor whose overloaded declarations are being queried.
+  ///
+  /// \returns The number of overloaded declarations referenced by \c cursor. If it
+  /// is not a \c CXCursor_OverloadedDeclRef cursor, returns 0.
+  int clang_getNumOverloadedDecls(
+    CXCursor cursor,
+  ) {
+    return _clang_getNumOverloadedDecls(
+      cursor,
+    );
+  }
+
+  late final _clang_getNumOverloadedDeclsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getNumOverloadedDecls>>(
+          'clang_getNumOverloadedDecls');
+  late final _clang_getNumOverloadedDecls = _clang_getNumOverloadedDeclsPtr
+      .asFunction<DartClang_getNumOverloadedDecls>();
+
+  /// Retrieve a cursor for one of the overloaded declarations referenced
+  /// by a \c CXCursor_OverloadedDeclRef cursor.
+  ///
+  /// \param cursor The cursor whose overloaded declarations are being queried.
+  ///
+  /// \param index The zero-based index into the set of overloaded declarations in
+  /// the cursor.
+  ///
+  /// \returns A cursor representing the declaration referenced by the given
+  /// \c cursor at the specified \c index. If the cursor does not have an
+  /// associated set of overloaded declarations, or if the index is out of bounds,
+  /// returns \c clang_getNullCursor();
+  CXCursor clang_getOverloadedDecl(
+    CXCursor cursor,
+    int index,
+  ) {
+    return _clang_getOverloadedDecl(
+      cursor,
+      index,
+    );
+  }
+
+  late final _clang_getOverloadedDeclPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getOverloadedDecl>>(
+          'clang_getOverloadedDecl');
+  late final _clang_getOverloadedDecl =
+      _clang_getOverloadedDeclPtr.asFunction<DartClang_getOverloadedDecl>();
+
+  /// For cursors representing an iboutletcollection attribute,
+  /// this function returns the collection element type.
+  CXType clang_getIBOutletCollectionType(
+    CXCursor arg0,
+  ) {
+    return _clang_getIBOutletCollectionType(
+      arg0,
+    );
+  }
+
+  late final _clang_getIBOutletCollectionTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getIBOutletCollectionType>>(
+          'clang_getIBOutletCollectionType');
+  late final _clang_getIBOutletCollectionType =
+      _clang_getIBOutletCollectionTypePtr
+          .asFunction<DartClang_getIBOutletCollectionType>();
+
+  /// Visit the children of a particular cursor.
+  ///
+  /// This function visits all the direct children of the given cursor,
+  /// invoking the given \p visitor function with the cursors of each
+  /// visited child. The traversal may be recursive, if the visitor returns
+  /// \c CXChildVisit_Recurse. The traversal may also be ended prematurely, if
+  /// the visitor returns \c CXChildVisit_Break.
+  ///
+  /// \param parent the cursor whose child may be visited. All kinds of
+  /// cursors can be visited, including invalid cursors (which, by
+  /// definition, have no children).
+  ///
+  /// \param visitor the visitor function that will be invoked for each
+  /// child of \p parent.
+  ///
+  /// \param client_data pointer data supplied by the client, which will
+  /// be passed to the visitor each time it is invoked.
+  ///
+  /// \returns a non-zero value if the traversal was terminated
+  /// prematurely by the visitor returning \c CXChildVisit_Break.
+  int clang_visitChildren(
+    CXCursor parent,
+    CXCursorVisitor visitor,
+    CXClientData client_data,
+  ) {
+    return _clang_visitChildren(
+      parent,
+      visitor,
+      client_data,
+    );
+  }
+
+  late final _clang_visitChildrenPtr =
+      _lookup<ffi.NativeFunction<NativeClang_visitChildren>>(
+          'clang_visitChildren');
+  late final _clang_visitChildren =
+      _clang_visitChildrenPtr.asFunction<DartClang_visitChildren>();
+
+  /// Retrieve a Unified Symbol Resolution (USR) for the entity referenced
+  /// by the given cursor.
+  ///
+  /// A Unified Symbol Resolution (USR) is a string that identifies a particular
+  /// entity (function, class, variable, etc.) within a program. USRs can be
+  /// compared across translation units to determine, e.g., when references in
+  /// one translation refer to an entity defined in another translation unit.
+  CXString clang_getCursorUSR(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorUSR(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorUSRPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorUSR>>(
+          'clang_getCursorUSR');
+  late final _clang_getCursorUSR =
+      _clang_getCursorUSRPtr.asFunction<DartClang_getCursorUSR>();
+
+  /// Construct a USR for a specified Objective-C class.
+  CXString clang_constructUSR_ObjCClass(
+    ffi.Pointer<ffi.Char> class_name,
+  ) {
+    return _clang_constructUSR_ObjCClass(
+      class_name,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCClassPtr =
+      _lookup<ffi.NativeFunction<NativeClang_constructUSR_ObjCClass>>(
+          'clang_constructUSR_ObjCClass');
+  late final _clang_constructUSR_ObjCClass = _clang_constructUSR_ObjCClassPtr
+      .asFunction<DartClang_constructUSR_ObjCClass>();
+
+  /// Construct a USR for a specified Objective-C category.
+  CXString clang_constructUSR_ObjCCategory(
+    ffi.Pointer<ffi.Char> class_name,
+    ffi.Pointer<ffi.Char> category_name,
+  ) {
+    return _clang_constructUSR_ObjCCategory(
+      class_name,
+      category_name,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCCategoryPtr =
+      _lookup<ffi.NativeFunction<NativeClang_constructUSR_ObjCCategory>>(
+          'clang_constructUSR_ObjCCategory');
+  late final _clang_constructUSR_ObjCCategory =
+      _clang_constructUSR_ObjCCategoryPtr
+          .asFunction<DartClang_constructUSR_ObjCCategory>();
+
+  /// Construct a USR for a specified Objective-C protocol.
+  CXString clang_constructUSR_ObjCProtocol(
+    ffi.Pointer<ffi.Char> protocol_name,
+  ) {
+    return _clang_constructUSR_ObjCProtocol(
+      protocol_name,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCProtocolPtr =
+      _lookup<ffi.NativeFunction<NativeClang_constructUSR_ObjCProtocol>>(
+          'clang_constructUSR_ObjCProtocol');
+  late final _clang_constructUSR_ObjCProtocol =
+      _clang_constructUSR_ObjCProtocolPtr
+          .asFunction<DartClang_constructUSR_ObjCProtocol>();
+
+  /// Construct a USR for a specified Objective-C instance variable and
+  /// the USR for its containing class.
+  CXString clang_constructUSR_ObjCIvar(
+    ffi.Pointer<ffi.Char> name,
+    CXString classUSR,
+  ) {
+    return _clang_constructUSR_ObjCIvar(
+      name,
+      classUSR,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCIvarPtr =
+      _lookup<ffi.NativeFunction<NativeClang_constructUSR_ObjCIvar>>(
+          'clang_constructUSR_ObjCIvar');
+  late final _clang_constructUSR_ObjCIvar = _clang_constructUSR_ObjCIvarPtr
+      .asFunction<DartClang_constructUSR_ObjCIvar>();
+
+  /// Construct a USR for a specified Objective-C method and
+  /// the USR for its containing class.
+  CXString clang_constructUSR_ObjCMethod(
+    ffi.Pointer<ffi.Char> name,
+    int isInstanceMethod,
+    CXString classUSR,
+  ) {
+    return _clang_constructUSR_ObjCMethod(
+      name,
+      isInstanceMethod,
+      classUSR,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCMethodPtr =
+      _lookup<ffi.NativeFunction<NativeClang_constructUSR_ObjCMethod>>(
+          'clang_constructUSR_ObjCMethod');
+  late final _clang_constructUSR_ObjCMethod = _clang_constructUSR_ObjCMethodPtr
+      .asFunction<DartClang_constructUSR_ObjCMethod>();
+
+  /// Construct a USR for a specified Objective-C property and the USR
+  /// for its containing class.
+  CXString clang_constructUSR_ObjCProperty(
+    ffi.Pointer<ffi.Char> property,
+    CXString classUSR,
+  ) {
+    return _clang_constructUSR_ObjCProperty(
+      property,
+      classUSR,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCPropertyPtr =
+      _lookup<ffi.NativeFunction<NativeClang_constructUSR_ObjCProperty>>(
+          'clang_constructUSR_ObjCProperty');
+  late final _clang_constructUSR_ObjCProperty =
+      _clang_constructUSR_ObjCPropertyPtr
+          .asFunction<DartClang_constructUSR_ObjCProperty>();
+
+  /// Retrieve a name for the entity referenced by this cursor.
+  CXString clang_getCursorSpelling(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorSpelling(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorSpellingPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorSpelling>>(
+          'clang_getCursorSpelling');
+  late final _clang_getCursorSpelling =
+      _clang_getCursorSpellingPtr.asFunction<DartClang_getCursorSpelling>();
+
+  /// Retrieve a range for a piece that forms the cursors spelling name.
+  /// Most of the times there is only one range for the complete spelling but for
+  /// Objective-C methods and Objective-C message expressions, there are multiple
+  /// pieces for each selector identifier.
+  ///
+  /// \param pieceIndex the index of the spelling name piece. If this is greater
+  /// than the actual number of pieces, it will return a NULL (invalid) range.
+  ///
+  /// \param options Reserved.
+  CXSourceRange clang_Cursor_getSpellingNameRange(
+    CXCursor arg0,
+    int pieceIndex,
+    int options,
+  ) {
+    return _clang_Cursor_getSpellingNameRange(
+      arg0,
+      pieceIndex,
+      options,
+    );
+  }
+
+  late final _clang_Cursor_getSpellingNameRangePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getSpellingNameRange>>(
+          'clang_Cursor_getSpellingNameRange');
+  late final _clang_Cursor_getSpellingNameRange =
+      _clang_Cursor_getSpellingNameRangePtr
+          .asFunction<DartClang_Cursor_getSpellingNameRange>();
+
+  /// Get a property value for the given printing policy.
+  int clang_PrintingPolicy_getProperty(
+    CXPrintingPolicy Policy,
+    int Property,
+  ) {
+    return _clang_PrintingPolicy_getProperty(
+      Policy,
+      Property,
+    );
+  }
+
+  late final _clang_PrintingPolicy_getPropertyPtr =
+      _lookup<ffi.NativeFunction<NativeClang_PrintingPolicy_getProperty>>(
+          'clang_PrintingPolicy_getProperty');
+  late final _clang_PrintingPolicy_getProperty =
+      _clang_PrintingPolicy_getPropertyPtr
+          .asFunction<DartClang_PrintingPolicy_getProperty>();
+
+  /// Set a property value for the given printing policy.
+  void clang_PrintingPolicy_setProperty(
+    CXPrintingPolicy Policy,
+    int Property,
+    int Value,
+  ) {
+    return _clang_PrintingPolicy_setProperty(
+      Policy,
+      Property,
+      Value,
+    );
+  }
+
+  late final _clang_PrintingPolicy_setPropertyPtr =
+      _lookup<ffi.NativeFunction<NativeClang_PrintingPolicy_setProperty>>(
+          'clang_PrintingPolicy_setProperty');
+  late final _clang_PrintingPolicy_setProperty =
+      _clang_PrintingPolicy_setPropertyPtr
+          .asFunction<DartClang_PrintingPolicy_setProperty>();
+
+  /// Retrieve the default policy for the cursor.
+  ///
+  /// The policy should be released after use with \c
+  /// clang_PrintingPolicy_dispose.
+  CXPrintingPolicy clang_getCursorPrintingPolicy(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorPrintingPolicy(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorPrintingPolicyPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorPrintingPolicy>>(
+          'clang_getCursorPrintingPolicy');
+  late final _clang_getCursorPrintingPolicy = _clang_getCursorPrintingPolicyPtr
+      .asFunction<DartClang_getCursorPrintingPolicy>();
+
+  /// Release a printing policy.
+  void clang_PrintingPolicy_dispose(
+    CXPrintingPolicy Policy,
+  ) {
+    return _clang_PrintingPolicy_dispose(
+      Policy,
+    );
+  }
+
+  late final _clang_PrintingPolicy_disposePtr =
+      _lookup<ffi.NativeFunction<NativeClang_PrintingPolicy_dispose>>(
+          'clang_PrintingPolicy_dispose');
+  late final _clang_PrintingPolicy_dispose = _clang_PrintingPolicy_disposePtr
+      .asFunction<DartClang_PrintingPolicy_dispose>();
+
+  /// Pretty print declarations.
+  ///
+  /// \param Cursor The cursor representing a declaration.
+  ///
+  /// \param Policy The policy to control the entities being printed. If
+  /// NULL, a default policy is used.
+  ///
+  /// \returns The pretty printed declaration or the empty string for
+  /// other cursors.
+  CXString clang_getCursorPrettyPrinted(
+    CXCursor Cursor,
+    CXPrintingPolicy Policy,
+  ) {
+    return _clang_getCursorPrettyPrinted(
+      Cursor,
+      Policy,
+    );
+  }
+
+  late final _clang_getCursorPrettyPrintedPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorPrettyPrinted>>(
+          'clang_getCursorPrettyPrinted');
+  late final _clang_getCursorPrettyPrinted = _clang_getCursorPrettyPrintedPtr
+      .asFunction<DartClang_getCursorPrettyPrinted>();
+
+  /// Retrieve the display name for the entity referenced by this cursor.
+  ///
+  /// The display name contains extra information that helps identify the cursor,
+  /// such as the parameters of a function or template or the arguments of a
+  /// class template specialization.
+  CXString clang_getCursorDisplayName(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorDisplayName(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorDisplayNamePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorDisplayName>>(
+          'clang_getCursorDisplayName');
+  late final _clang_getCursorDisplayName = _clang_getCursorDisplayNamePtr
+      .asFunction<DartClang_getCursorDisplayName>();
+
+  /// For a cursor that is a reference, retrieve a cursor representing the
+  /// entity that it references.
+  ///
+  /// Reference cursors refer to other entities in the AST. For example, an
+  /// Objective-C superclass reference cursor refers to an Objective-C class.
+  /// This function produces the cursor for the Objective-C class from the
+  /// cursor for the superclass reference. If the input cursor is a declaration or
+  /// definition, it returns that declaration or definition unchanged.
+  /// Otherwise, returns the NULL cursor.
+  CXCursor clang_getCursorReferenced(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorReferenced(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorReferencedPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorReferenced>>(
+          'clang_getCursorReferenced');
+  late final _clang_getCursorReferenced =
+      _clang_getCursorReferencedPtr.asFunction<DartClang_getCursorReferenced>();
+
+  /// For a cursor that is either a reference to or a declaration
+  /// of some entity, retrieve a cursor that describes the definition of
+  /// that entity.
+  ///
+  /// Some entities can be declared multiple times within a translation
+  /// unit, but only one of those declarations can also be a
+  /// definition. For example, given:
+  ///
+  /// \code
+  /// int f(int, int);
+  /// int g(int x, int y) { return f(x, y); }
+  /// int f(int a, int b) { return a + b; }
+  /// int f(int, int);
+  /// \endcode
+  ///
+  /// there are three declarations of the function "f", but only the
+  /// second one is a definition. The clang_getCursorDefinition()
+  /// function will take any cursor pointing to a declaration of "f"
+  /// (the first or fourth lines of the example) or a cursor referenced
+  /// that uses "f" (the call to "f' inside "g") and will return a
+  /// declaration cursor pointing to the definition (the second "f"
+  /// declaration).
+  ///
+  /// If given a cursor for which there is no corresponding definition,
+  /// e.g., because there is no definition of that entity within this
+  /// translation unit, returns a NULL cursor.
+  CXCursor clang_getCursorDefinition(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorDefinition(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorDefinitionPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorDefinition>>(
+          'clang_getCursorDefinition');
+  late final _clang_getCursorDefinition =
+      _clang_getCursorDefinitionPtr.asFunction<DartClang_getCursorDefinition>();
+
+  /// Determine whether the declaration pointed to by this cursor
+  /// is also a definition of that entity.
+  int clang_isCursorDefinition(
+    CXCursor arg0,
+  ) {
+    return _clang_isCursorDefinition(
+      arg0,
+    );
+  }
+
+  late final _clang_isCursorDefinitionPtr =
+      _lookup<ffi.NativeFunction<NativeClang_isCursorDefinition>>(
+          'clang_isCursorDefinition');
+  late final _clang_isCursorDefinition =
+      _clang_isCursorDefinitionPtr.asFunction<DartClang_isCursorDefinition>();
+
+  /// Retrieve the canonical cursor corresponding to the given cursor.
+  ///
+  /// In the C family of languages, many kinds of entities can be declared several
+  /// times within a single translation unit. For example, a structure type can
+  /// be forward-declared (possibly multiple times) and later defined:
+  ///
+  /// \code
+  /// struct X;
+  /// struct X;
+  /// struct X {
+  /// int member;
+  /// };
+  /// \endcode
+  ///
+  /// The declarations and the definition of \c X are represented by three
+  /// different cursors, all of which are declarations of the same underlying
+  /// entity. One of these cursor is considered the "canonical" cursor, which
+  /// is effectively the representative for the underlying entity. One can
+  /// determine if two cursors are declarations of the same underlying entity by
+  /// comparing their canonical cursors.
+  ///
+  /// \returns The canonical cursor for the entity referred to by the given cursor.
+  CXCursor clang_getCanonicalCursor(
+    CXCursor arg0,
+  ) {
+    return _clang_getCanonicalCursor(
+      arg0,
+    );
+  }
+
+  late final _clang_getCanonicalCursorPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCanonicalCursor>>(
+          'clang_getCanonicalCursor');
+  late final _clang_getCanonicalCursor =
+      _clang_getCanonicalCursorPtr.asFunction<DartClang_getCanonicalCursor>();
+
+  /// If the cursor points to a selector identifier in an Objective-C
+  /// method or message expression, this returns the selector index.
+  ///
+  /// After getting a cursor with #clang_getCursor, this can be called to
+  /// determine if the location points to a selector identifier.
+  ///
+  /// \returns The selector index if the cursor is an Objective-C method or message
+  /// expression and the cursor is pointing to a selector identifier, or -1
+  /// otherwise.
+  int clang_Cursor_getObjCSelectorIndex(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getObjCSelectorIndex(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getObjCSelectorIndexPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getObjCSelectorIndex>>(
+          'clang_Cursor_getObjCSelectorIndex');
+  late final _clang_Cursor_getObjCSelectorIndex =
+      _clang_Cursor_getObjCSelectorIndexPtr
+          .asFunction<DartClang_Cursor_getObjCSelectorIndex>();
+
+  /// Given a cursor pointing to a C++ method call or an Objective-C
+  /// message, returns non-zero if the method/message is "dynamic", meaning:
+  ///
+  /// For a C++ method: the call is virtual.
+  /// For an Objective-C message: the receiver is an object instance, not 'super'
+  /// or a specific class.
+  ///
+  /// If the method/message is "static" or the cursor does not point to a
+  /// method/message, it will return zero.
+  int clang_Cursor_isDynamicCall(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isDynamicCall(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isDynamicCallPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isDynamicCall>>(
+          'clang_Cursor_isDynamicCall');
+  late final _clang_Cursor_isDynamicCall = _clang_Cursor_isDynamicCallPtr
+      .asFunction<DartClang_Cursor_isDynamicCall>();
+
+  /// Given a cursor pointing to an Objective-C message or property
+  /// reference, or C++ method call, returns the CXType of the receiver.
+  CXType clang_Cursor_getReceiverType(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getReceiverType(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getReceiverTypePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getReceiverType>>(
+          'clang_Cursor_getReceiverType');
+  late final _clang_Cursor_getReceiverType = _clang_Cursor_getReceiverTypePtr
+      .asFunction<DartClang_Cursor_getReceiverType>();
+
+  /// Given a cursor that represents a property declaration, return the
+  /// associated property attributes. The bits are formed from
+  /// \c CXObjCPropertyAttrKind.
+  ///
+  /// \param reserved Reserved for future use, pass 0.
+  int clang_Cursor_getObjCPropertyAttributes(
+    CXCursor C,
+    int reserved,
+  ) {
+    return _clang_Cursor_getObjCPropertyAttributes(
+      C,
+      reserved,
+    );
+  }
+
+  late final _clang_Cursor_getObjCPropertyAttributesPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getObjCPropertyAttributes>>(
+          'clang_Cursor_getObjCPropertyAttributes');
+  late final _clang_Cursor_getObjCPropertyAttributes =
+      _clang_Cursor_getObjCPropertyAttributesPtr
+          .asFunction<DartClang_Cursor_getObjCPropertyAttributes>();
+
+  /// Given a cursor that represents a property declaration, return the
+  /// name of the method that implements the getter.
+  CXString clang_Cursor_getObjCPropertyGetterName(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getObjCPropertyGetterName(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getObjCPropertyGetterNamePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getObjCPropertyGetterName>>(
+          'clang_Cursor_getObjCPropertyGetterName');
+  late final _clang_Cursor_getObjCPropertyGetterName =
+      _clang_Cursor_getObjCPropertyGetterNamePtr
+          .asFunction<DartClang_Cursor_getObjCPropertyGetterName>();
+
+  /// Given a cursor that represents a property declaration, return the
+  /// name of the method that implements the setter, if any.
+  CXString clang_Cursor_getObjCPropertySetterName(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getObjCPropertySetterName(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getObjCPropertySetterNamePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getObjCPropertySetterName>>(
+          'clang_Cursor_getObjCPropertySetterName');
+  late final _clang_Cursor_getObjCPropertySetterName =
+      _clang_Cursor_getObjCPropertySetterNamePtr
+          .asFunction<DartClang_Cursor_getObjCPropertySetterName>();
+
+  /// Given a cursor that represents an Objective-C method or parameter
+  /// declaration, return the associated Objective-C qualifiers for the return
+  /// type or the parameter respectively. The bits are formed from
+  /// CXObjCDeclQualifierKind.
+  int clang_Cursor_getObjCDeclQualifiers(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getObjCDeclQualifiers(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getObjCDeclQualifiersPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getObjCDeclQualifiers>>(
+          'clang_Cursor_getObjCDeclQualifiers');
+  late final _clang_Cursor_getObjCDeclQualifiers =
+      _clang_Cursor_getObjCDeclQualifiersPtr
+          .asFunction<DartClang_Cursor_getObjCDeclQualifiers>();
+
+  /// Given a cursor that represents an Objective-C method or property
+  /// declaration, return non-zero if the declaration was affected by "\@optional".
+  /// Returns zero if the cursor is not such a declaration or it is "\@required".
+  int clang_Cursor_isObjCOptional(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isObjCOptional(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isObjCOptionalPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isObjCOptional>>(
+          'clang_Cursor_isObjCOptional');
+  late final _clang_Cursor_isObjCOptional = _clang_Cursor_isObjCOptionalPtr
+      .asFunction<DartClang_Cursor_isObjCOptional>();
+
+  /// Returns non-zero if the given cursor is a variadic function or method.
+  int clang_Cursor_isVariadic(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isVariadic(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isVariadicPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isVariadic>>(
+          'clang_Cursor_isVariadic');
+  late final _clang_Cursor_isVariadic =
+      _clang_Cursor_isVariadicPtr.asFunction<DartClang_Cursor_isVariadic>();
+
+  /// Returns non-zero if the given cursor points to a symbol marked with
+  /// external_source_symbol attribute.
+  ///
+  /// \param language If non-NULL, and the attribute is present, will be set to
+  /// the 'language' string from the attribute.
+  ///
+  /// \param definedIn If non-NULL, and the attribute is present, will be set to
+  /// the 'definedIn' string from the attribute.
+  ///
+  /// \param isGenerated If non-NULL, and the attribute is present, will be set to
+  /// non-zero if the 'generated_declaration' is set in the attribute.
+  int clang_Cursor_isExternalSymbol(
+    CXCursor C,
+    ffi.Pointer<CXString> language,
+    ffi.Pointer<CXString> definedIn,
+    ffi.Pointer<ffi.UnsignedInt> isGenerated,
+  ) {
+    return _clang_Cursor_isExternalSymbol(
+      C,
+      language,
+      definedIn,
+      isGenerated,
+    );
+  }
+
+  late final _clang_Cursor_isExternalSymbolPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_isExternalSymbol>>(
+          'clang_Cursor_isExternalSymbol');
+  late final _clang_Cursor_isExternalSymbol = _clang_Cursor_isExternalSymbolPtr
+      .asFunction<DartClang_Cursor_isExternalSymbol>();
+
+  /// Given a cursor that represents a declaration, return the associated
+  /// comment's source range.  The range may include multiple consecutive comments
+  /// with whitespace in between.
+  CXSourceRange clang_Cursor_getCommentRange(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getCommentRange(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getCommentRangePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getCommentRange>>(
+          'clang_Cursor_getCommentRange');
+  late final _clang_Cursor_getCommentRange = _clang_Cursor_getCommentRangePtr
+      .asFunction<DartClang_Cursor_getCommentRange>();
+
+  /// Given a cursor that represents a declaration, return the associated
+  /// comment text, including comment markers.
+  CXString clang_Cursor_getRawCommentText(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getRawCommentText(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getRawCommentTextPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getRawCommentText>>(
+          'clang_Cursor_getRawCommentText');
+  late final _clang_Cursor_getRawCommentText =
+      _clang_Cursor_getRawCommentTextPtr
+          .asFunction<DartClang_Cursor_getRawCommentText>();
+
+  /// Given a cursor that represents a documentable entity (e.g.,
+  /// declaration), return the associated \paragraph; otherwise return the
+  /// first paragraph.
+  CXString clang_Cursor_getBriefCommentText(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getBriefCommentText(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getBriefCommentTextPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getBriefCommentText>>(
+          'clang_Cursor_getBriefCommentText');
+  late final _clang_Cursor_getBriefCommentText =
+      _clang_Cursor_getBriefCommentTextPtr
+          .asFunction<DartClang_Cursor_getBriefCommentText>();
+
+  /// Retrieve the CXString representing the mangled name of the cursor.
+  CXString clang_Cursor_getMangling(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getMangling(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getManglingPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getMangling>>(
+          'clang_Cursor_getMangling');
+  late final _clang_Cursor_getMangling =
+      _clang_Cursor_getManglingPtr.asFunction<DartClang_Cursor_getMangling>();
+
+  /// Retrieve the CXStrings representing the mangled symbols of the C++
+  /// constructor or destructor at the cursor.
+  ffi.Pointer<CXStringSet> clang_Cursor_getCXXManglings(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getCXXManglings(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getCXXManglingsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getCXXManglings>>(
+          'clang_Cursor_getCXXManglings');
+  late final _clang_Cursor_getCXXManglings = _clang_Cursor_getCXXManglingsPtr
+      .asFunction<DartClang_Cursor_getCXXManglings>();
+
+  /// Retrieve the CXStrings representing the mangled symbols of the ObjC
+  /// class interface or implementation at the cursor.
+  ffi.Pointer<CXStringSet> clang_Cursor_getObjCManglings(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getObjCManglings(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getObjCManglingsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getObjCManglings>>(
+          'clang_Cursor_getObjCManglings');
+  late final _clang_Cursor_getObjCManglings = _clang_Cursor_getObjCManglingsPtr
+      .asFunction<DartClang_Cursor_getObjCManglings>();
+
+  /// Given a CXCursor_ModuleImportDecl cursor, return the associated module.
+  CXModule clang_Cursor_getModule(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getModule(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getModulePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_getModule>>(
+          'clang_Cursor_getModule');
+  late final _clang_Cursor_getModule =
+      _clang_Cursor_getModulePtr.asFunction<DartClang_Cursor_getModule>();
+
+  /// Given a CXFile header file, return the module that contains it, if one
+  /// exists.
+  CXModule clang_getModuleForFile(
+    CXTranslationUnit arg0,
+    CXFile arg1,
+  ) {
+    return _clang_getModuleForFile(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_getModuleForFilePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getModuleForFile>>(
+          'clang_getModuleForFile');
+  late final _clang_getModuleForFile =
+      _clang_getModuleForFilePtr.asFunction<DartClang_getModuleForFile>();
+
+  /// \param Module a module object.
+  ///
+  /// \returns the module file where the provided module object came from.
+  CXFile clang_Module_getASTFile(
+    CXModule Module,
+  ) {
+    return _clang_Module_getASTFile(
+      Module,
+    );
+  }
+
+  late final _clang_Module_getASTFilePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Module_getASTFile>>(
+          'clang_Module_getASTFile');
+  late final _clang_Module_getASTFile =
+      _clang_Module_getASTFilePtr.asFunction<DartClang_Module_getASTFile>();
+
+  /// \param Module a module object.
+  ///
+  /// \returns the parent of a sub-module or NULL if the given module is top-level,
+  /// e.g. for 'std.vector' it will return the 'std' module.
+  CXModule clang_Module_getParent(
+    CXModule Module,
+  ) {
+    return _clang_Module_getParent(
+      Module,
+    );
+  }
+
+  late final _clang_Module_getParentPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Module_getParent>>(
+          'clang_Module_getParent');
+  late final _clang_Module_getParent =
+      _clang_Module_getParentPtr.asFunction<DartClang_Module_getParent>();
+
+  /// \param Module a module object.
+  ///
+  /// \returns the name of the module, e.g. for the 'std.vector' sub-module it
+  /// will return "vector".
+  CXString clang_Module_getName(
+    CXModule Module,
+  ) {
+    return _clang_Module_getName(
+      Module,
+    );
+  }
+
+  late final _clang_Module_getNamePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Module_getName>>(
+          'clang_Module_getName');
+  late final _clang_Module_getName =
+      _clang_Module_getNamePtr.asFunction<DartClang_Module_getName>();
+
+  /// \param Module a module object.
+  ///
+  /// \returns the full name of the module, e.g. "std.vector".
+  CXString clang_Module_getFullName(
+    CXModule Module,
+  ) {
+    return _clang_Module_getFullName(
+      Module,
+    );
+  }
+
+  late final _clang_Module_getFullNamePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Module_getFullName>>(
+          'clang_Module_getFullName');
+  late final _clang_Module_getFullName =
+      _clang_Module_getFullNamePtr.asFunction<DartClang_Module_getFullName>();
+
+  /// \param Module a module object.
+  ///
+  /// \returns non-zero if the module is a system one.
+  int clang_Module_isSystem(
+    CXModule Module,
+  ) {
+    return _clang_Module_isSystem(
+      Module,
+    );
+  }
+
+  late final _clang_Module_isSystemPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Module_isSystem>>(
+          'clang_Module_isSystem');
+  late final _clang_Module_isSystem =
+      _clang_Module_isSystemPtr.asFunction<DartClang_Module_isSystem>();
+
+  /// \param Module a module object.
+  ///
+  /// \returns the number of top level headers associated with this module.
+  int clang_Module_getNumTopLevelHeaders(
+    CXTranslationUnit arg0,
+    CXModule Module,
+  ) {
+    return _clang_Module_getNumTopLevelHeaders(
+      arg0,
+      Module,
+    );
+  }
+
+  late final _clang_Module_getNumTopLevelHeadersPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Module_getNumTopLevelHeaders>>(
+          'clang_Module_getNumTopLevelHeaders');
+  late final _clang_Module_getNumTopLevelHeaders =
+      _clang_Module_getNumTopLevelHeadersPtr
+          .asFunction<DartClang_Module_getNumTopLevelHeaders>();
+
+  /// \param Module a module object.
+  ///
+  /// \param Index top level header index (zero-based).
+  ///
+  /// \returns the specified top level header associated with the module.
+  CXFile clang_Module_getTopLevelHeader(
+    CXTranslationUnit arg0,
+    CXModule Module,
+    int Index,
+  ) {
+    return _clang_Module_getTopLevelHeader(
+      arg0,
+      Module,
+      Index,
+    );
+  }
+
+  late final _clang_Module_getTopLevelHeaderPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Module_getTopLevelHeader>>(
+          'clang_Module_getTopLevelHeader');
+  late final _clang_Module_getTopLevelHeader =
+      _clang_Module_getTopLevelHeaderPtr
+          .asFunction<DartClang_Module_getTopLevelHeader>();
+
+  /// Determine if a C++ constructor is a converting constructor.
+  int clang_CXXConstructor_isConvertingConstructor(
+    CXCursor C,
+  ) {
+    return _clang_CXXConstructor_isConvertingConstructor(
+      C,
+    );
+  }
+
+  late final _clang_CXXConstructor_isConvertingConstructorPtr = _lookup<
+          ffi
+          .NativeFunction<NativeClang_CXXConstructor_isConvertingConstructor>>(
+      'clang_CXXConstructor_isConvertingConstructor');
+  late final _clang_CXXConstructor_isConvertingConstructor =
+      _clang_CXXConstructor_isConvertingConstructorPtr
+          .asFunction<DartClang_CXXConstructor_isConvertingConstructor>();
+
+  /// Determine if a C++ constructor is a copy constructor.
+  int clang_CXXConstructor_isCopyConstructor(
+    CXCursor C,
+  ) {
+    return _clang_CXXConstructor_isCopyConstructor(
+      C,
+    );
+  }
+
+  late final _clang_CXXConstructor_isCopyConstructorPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXXConstructor_isCopyConstructor>>(
+          'clang_CXXConstructor_isCopyConstructor');
+  late final _clang_CXXConstructor_isCopyConstructor =
+      _clang_CXXConstructor_isCopyConstructorPtr
+          .asFunction<DartClang_CXXConstructor_isCopyConstructor>();
+
+  /// Determine if a C++ constructor is the default constructor.
+  int clang_CXXConstructor_isDefaultConstructor(
+    CXCursor C,
+  ) {
+    return _clang_CXXConstructor_isDefaultConstructor(
+      C,
+    );
+  }
+
+  late final _clang_CXXConstructor_isDefaultConstructorPtr = _lookup<
+          ffi.NativeFunction<NativeClang_CXXConstructor_isDefaultConstructor>>(
+      'clang_CXXConstructor_isDefaultConstructor');
+  late final _clang_CXXConstructor_isDefaultConstructor =
+      _clang_CXXConstructor_isDefaultConstructorPtr
+          .asFunction<DartClang_CXXConstructor_isDefaultConstructor>();
+
+  /// Determine if a C++ constructor is a move constructor.
+  int clang_CXXConstructor_isMoveConstructor(
+    CXCursor C,
+  ) {
+    return _clang_CXXConstructor_isMoveConstructor(
+      C,
+    );
+  }
+
+  late final _clang_CXXConstructor_isMoveConstructorPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXXConstructor_isMoveConstructor>>(
+          'clang_CXXConstructor_isMoveConstructor');
+  late final _clang_CXXConstructor_isMoveConstructor =
+      _clang_CXXConstructor_isMoveConstructorPtr
+          .asFunction<DartClang_CXXConstructor_isMoveConstructor>();
+
+  /// Determine if a C++ field is declared 'mutable'.
+  int clang_CXXField_isMutable(
+    CXCursor C,
+  ) {
+    return _clang_CXXField_isMutable(
+      C,
+    );
+  }
+
+  late final _clang_CXXField_isMutablePtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXXField_isMutable>>(
+          'clang_CXXField_isMutable');
+  late final _clang_CXXField_isMutable =
+      _clang_CXXField_isMutablePtr.asFunction<DartClang_CXXField_isMutable>();
+
+  /// Determine if a C++ method is declared '= default'.
+  int clang_CXXMethod_isDefaulted(
+    CXCursor C,
+  ) {
+    return _clang_CXXMethod_isDefaulted(
+      C,
+    );
+  }
+
+  late final _clang_CXXMethod_isDefaultedPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXXMethod_isDefaulted>>(
+          'clang_CXXMethod_isDefaulted');
+  late final _clang_CXXMethod_isDefaulted = _clang_CXXMethod_isDefaultedPtr
+      .asFunction<DartClang_CXXMethod_isDefaulted>();
+
+  /// Determine if a C++ member function or member function template is
+  /// pure virtual.
+  int clang_CXXMethod_isPureVirtual(
+    CXCursor C,
+  ) {
+    return _clang_CXXMethod_isPureVirtual(
+      C,
+    );
+  }
+
+  late final _clang_CXXMethod_isPureVirtualPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXXMethod_isPureVirtual>>(
+          'clang_CXXMethod_isPureVirtual');
+  late final _clang_CXXMethod_isPureVirtual = _clang_CXXMethod_isPureVirtualPtr
+      .asFunction<DartClang_CXXMethod_isPureVirtual>();
+
+  /// Determine if a C++ member function or member function template is
+  /// declared 'static'.
+  int clang_CXXMethod_isStatic(
+    CXCursor C,
+  ) {
+    return _clang_CXXMethod_isStatic(
+      C,
+    );
+  }
+
+  late final _clang_CXXMethod_isStaticPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXXMethod_isStatic>>(
+          'clang_CXXMethod_isStatic');
+  late final _clang_CXXMethod_isStatic =
+      _clang_CXXMethod_isStaticPtr.asFunction<DartClang_CXXMethod_isStatic>();
+
+  /// Determine if a C++ member function or member function template is
+  /// explicitly declared 'virtual' or if it overrides a virtual method from
+  /// one of the base classes.
+  int clang_CXXMethod_isVirtual(
+    CXCursor C,
+  ) {
+    return _clang_CXXMethod_isVirtual(
+      C,
+    );
+  }
+
+  late final _clang_CXXMethod_isVirtualPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXXMethod_isVirtual>>(
+          'clang_CXXMethod_isVirtual');
+  late final _clang_CXXMethod_isVirtual =
+      _clang_CXXMethod_isVirtualPtr.asFunction<DartClang_CXXMethod_isVirtual>();
+
+  /// Determine if a C++ record is abstract, i.e. whether a class or struct
+  /// has a pure virtual member function.
+  int clang_CXXRecord_isAbstract(
+    CXCursor C,
+  ) {
+    return _clang_CXXRecord_isAbstract(
+      C,
+    );
+  }
+
+  late final _clang_CXXRecord_isAbstractPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXXRecord_isAbstract>>(
+          'clang_CXXRecord_isAbstract');
+  late final _clang_CXXRecord_isAbstract = _clang_CXXRecord_isAbstractPtr
+      .asFunction<DartClang_CXXRecord_isAbstract>();
+
+  /// Determine if an enum declaration refers to a scoped enum.
+  int clang_EnumDecl_isScoped(
+    CXCursor C,
+  ) {
+    return _clang_EnumDecl_isScoped(
+      C,
+    );
+  }
+
+  late final _clang_EnumDecl_isScopedPtr =
+      _lookup<ffi.NativeFunction<NativeClang_EnumDecl_isScoped>>(
+          'clang_EnumDecl_isScoped');
+  late final _clang_EnumDecl_isScoped =
+      _clang_EnumDecl_isScopedPtr.asFunction<DartClang_EnumDecl_isScoped>();
+
+  /// Determine if a C++ member function or member function template is
+  /// declared 'const'.
+  int clang_CXXMethod_isConst(
+    CXCursor C,
+  ) {
+    return _clang_CXXMethod_isConst(
+      C,
+    );
+  }
+
+  late final _clang_CXXMethod_isConstPtr =
+      _lookup<ffi.NativeFunction<NativeClang_CXXMethod_isConst>>(
+          'clang_CXXMethod_isConst');
+  late final _clang_CXXMethod_isConst =
+      _clang_CXXMethod_isConstPtr.asFunction<DartClang_CXXMethod_isConst>();
+
+  /// Given a cursor that represents a template, determine
+  /// the cursor kind of the specializations would be generated by instantiating
+  /// the template.
+  ///
+  /// This routine can be used to determine what flavor of function template,
+  /// class template, or class template partial specialization is stored in the
+  /// cursor. For example, it can describe whether a class template cursor is
+  /// declared with "struct", "class" or "union".
+  ///
+  /// \param C The cursor to query. This cursor should represent a template
+  /// declaration.
+  ///
+  /// \returns The cursor kind of the specializations that would be generated
+  /// by instantiating the template \p C. If \p C is not a template, returns
+  /// \c CXCursor_NoDeclFound.
+  int clang_getTemplateCursorKind(
+    CXCursor C,
+  ) {
+    return _clang_getTemplateCursorKind(
+      C,
+    );
+  }
+
+  late final _clang_getTemplateCursorKindPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTemplateCursorKind>>(
+          'clang_getTemplateCursorKind');
+  late final _clang_getTemplateCursorKind = _clang_getTemplateCursorKindPtr
+      .asFunction<DartClang_getTemplateCursorKind>();
+
+  /// Given a cursor that may represent a specialization or instantiation
+  /// of a template, retrieve the cursor that represents the template that it
+  /// specializes or from which it was instantiated.
+  ///
+  /// This routine determines the template involved both for explicit
+  /// specializations of templates and for implicit instantiations of the template,
+  /// both of which are referred to as "specializations". For a class template
+  /// specialization (e.g., \c std::vector<bool>), this routine will return
+  /// either the primary template (\c std::vector) or, if the specialization was
+  /// instantiated from a class template partial specialization, the class template
+  /// partial specialization. For a class template partial specialization and a
+  /// function template specialization (including instantiations), this
+  /// this routine will return the specialized template.
+  ///
+  /// For members of a class template (e.g., member functions, member classes, or
+  /// static data members), returns the specialized or instantiated member.
+  /// Although not strictly "templates" in the C++ language, members of class
+  /// templates have the same notions of specializations and instantiations that
+  /// templates do, so this routine treats them similarly.
+  ///
+  /// \param C A cursor that may be a specialization of a template or a member
+  /// of a template.
+  ///
+  /// \returns If the given cursor is a specialization or instantiation of a
+  /// template or a member thereof, the template or member that it specializes or
+  /// from which it was instantiated. Otherwise, returns a NULL cursor.
+  CXCursor clang_getSpecializedCursorTemplate(
+    CXCursor C,
+  ) {
+    return _clang_getSpecializedCursorTemplate(
+      C,
+    );
+  }
+
+  late final _clang_getSpecializedCursorTemplatePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getSpecializedCursorTemplate>>(
+          'clang_getSpecializedCursorTemplate');
+  late final _clang_getSpecializedCursorTemplate =
+      _clang_getSpecializedCursorTemplatePtr
+          .asFunction<DartClang_getSpecializedCursorTemplate>();
+
+  /// Given a cursor that references something else, return the source range
+  /// covering that reference.
+  ///
+  /// \param C A cursor pointing to a member reference, a declaration reference, or
+  /// an operator call.
+  /// \param NameFlags A bitset with three independent flags:
+  /// CXNameRange_WantQualifier, CXNameRange_WantTemplateArgs, and
+  /// CXNameRange_WantSinglePiece.
+  /// \param PieceIndex For contiguous names or when passing the flag
+  /// CXNameRange_WantSinglePiece, only one piece with index 0 is
+  /// available. When the CXNameRange_WantSinglePiece flag is not passed for a
+  /// non-contiguous names, this index can be used to retrieve the individual
+  /// pieces of the name. See also CXNameRange_WantSinglePiece.
+  ///
+  /// \returns The piece of the name pointed to by the given cursor. If there is no
+  /// name, or if the PieceIndex is out-of-range, a null-cursor will be returned.
+  CXSourceRange clang_getCursorReferenceNameRange(
+    CXCursor C,
+    int NameFlags,
+    int PieceIndex,
+  ) {
+    return _clang_getCursorReferenceNameRange(
+      C,
+      NameFlags,
+      PieceIndex,
+    );
+  }
+
+  late final _clang_getCursorReferenceNameRangePtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorReferenceNameRange>>(
+          'clang_getCursorReferenceNameRange');
+  late final _clang_getCursorReferenceNameRange =
+      _clang_getCursorReferenceNameRangePtr
+          .asFunction<DartClang_getCursorReferenceNameRange>();
+
+  /// Get the raw lexical token starting with the given location.
+  ///
+  /// \param TU the translation unit whose text is being tokenized.
+  ///
+  /// \param Location the source location with which the token starts.
+  ///
+  /// \returns The token starting with the given location or NULL if no such token
+  /// exist. The returned pointer must be freed with clang_disposeTokens before the
+  /// translation unit is destroyed.
+  ffi.Pointer<CXToken> clang_getToken(
+    CXTranslationUnit TU,
+    CXSourceLocation Location,
+  ) {
+    return _clang_getToken(
+      TU,
+      Location,
+    );
+  }
+
+  late final _clang_getTokenPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getToken>>('clang_getToken');
+  late final _clang_getToken =
+      _clang_getTokenPtr.asFunction<DartClang_getToken>();
+
+  /// Determine the kind of the given token.
+  int clang_getTokenKind(
+    CXToken arg0,
+  ) {
+    return _clang_getTokenKind(
+      arg0,
+    );
+  }
+
+  late final _clang_getTokenKindPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTokenKind>>(
+          'clang_getTokenKind');
+  late final _clang_getTokenKind =
+      _clang_getTokenKindPtr.asFunction<DartClang_getTokenKind>();
+
+  /// Determine the spelling of the given token.
+  ///
+  /// The spelling of a token is the textual representation of that token, e.g.,
+  /// the text of an identifier or keyword.
+  CXString clang_getTokenSpelling(
+    CXTranslationUnit arg0,
+    CXToken arg1,
+  ) {
+    return _clang_getTokenSpelling(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_getTokenSpellingPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTokenSpelling>>(
+          'clang_getTokenSpelling');
+  late final _clang_getTokenSpelling =
+      _clang_getTokenSpellingPtr.asFunction<DartClang_getTokenSpelling>();
+
+  /// Retrieve the source location of the given token.
+  CXSourceLocation clang_getTokenLocation(
+    CXTranslationUnit arg0,
+    CXToken arg1,
+  ) {
+    return _clang_getTokenLocation(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_getTokenLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTokenLocation>>(
+          'clang_getTokenLocation');
+  late final _clang_getTokenLocation =
+      _clang_getTokenLocationPtr.asFunction<DartClang_getTokenLocation>();
+
+  /// Retrieve a source range that covers the given token.
+  CXSourceRange clang_getTokenExtent(
+    CXTranslationUnit arg0,
+    CXToken arg1,
+  ) {
+    return _clang_getTokenExtent(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_getTokenExtentPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getTokenExtent>>(
+          'clang_getTokenExtent');
+  late final _clang_getTokenExtent =
+      _clang_getTokenExtentPtr.asFunction<DartClang_getTokenExtent>();
+
+  /// Tokenize the source code described by the given range into raw
+  /// lexical tokens.
+  ///
+  /// \param TU the translation unit whose text is being tokenized.
+  ///
+  /// \param Range the source range in which text should be tokenized. All of the
+  /// tokens produced by tokenization will fall within this source range,
+  ///
+  /// \param Tokens this pointer will be set to point to the array of tokens
+  /// that occur within the given source range. The returned pointer must be
+  /// freed with clang_disposeTokens() before the translation unit is destroyed.
+  ///
+  /// \param NumTokens will be set to the number of tokens in the \c *Tokens
+  /// array.
+  void clang_tokenize(
+    CXTranslationUnit TU,
+    CXSourceRange Range,
+    ffi.Pointer<ffi.Pointer<CXToken>> Tokens,
+    ffi.Pointer<ffi.UnsignedInt> NumTokens,
+  ) {
+    return _clang_tokenize(
+      TU,
+      Range,
+      Tokens,
+      NumTokens,
+    );
+  }
+
+  late final _clang_tokenizePtr =
+      _lookup<ffi.NativeFunction<NativeClang_tokenize>>('clang_tokenize');
+  late final _clang_tokenize =
+      _clang_tokenizePtr.asFunction<DartClang_tokenize>();
+
+  /// Annotate the given set of tokens by providing cursors for each token
+  /// that can be mapped to a specific entity within the abstract syntax tree.
+  ///
+  /// This token-annotation routine is equivalent to invoking
+  /// clang_getCursor() for the source locations of each of the
+  /// tokens. The cursors provided are filtered, so that only those
+  /// cursors that have a direct correspondence to the token are
+  /// accepted. For example, given a function call \c f(x),
+  /// clang_getCursor() would provide the following cursors:
+  ///
+  /// * when the cursor is over the 'f', a DeclRefExpr cursor referring to 'f'.
+  /// * when the cursor is over the '(' or the ')', a CallExpr referring to 'f'.
+  /// * when the cursor is over the 'x', a DeclRefExpr cursor referring to 'x'.
+  ///
+  /// Only the first and last of these cursors will occur within the
+  /// annotate, since the tokens "f" and "x' directly refer to a function
+  /// and a variable, respectively, but the parentheses are just a small
+  /// part of the full syntax of the function call expression, which is
+  /// not provided as an annotation.
+  ///
+  /// \param TU the translation unit that owns the given tokens.
+  ///
+  /// \param Tokens the set of tokens to annotate.
+  ///
+  /// \param NumTokens the number of tokens in \p Tokens.
+  ///
+  /// \param Cursors an array of \p NumTokens cursors, whose contents will be
+  /// replaced with the cursors corresponding to each token.
+  void clang_annotateTokens(
+    CXTranslationUnit TU,
+    ffi.Pointer<CXToken> Tokens,
+    int NumTokens,
+    ffi.Pointer<CXCursor> Cursors,
+  ) {
+    return _clang_annotateTokens(
+      TU,
+      Tokens,
+      NumTokens,
+      Cursors,
+    );
+  }
+
+  late final _clang_annotateTokensPtr =
+      _lookup<ffi.NativeFunction<NativeClang_annotateTokens>>(
+          'clang_annotateTokens');
+  late final _clang_annotateTokens =
+      _clang_annotateTokensPtr.asFunction<DartClang_annotateTokens>();
+
+  /// Free the given set of tokens.
+  void clang_disposeTokens(
+    CXTranslationUnit TU,
+    ffi.Pointer<CXToken> Tokens,
+    int NumTokens,
+  ) {
+    return _clang_disposeTokens(
+      TU,
+      Tokens,
+      NumTokens,
+    );
+  }
+
+  late final _clang_disposeTokensPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeTokens>>(
+          'clang_disposeTokens');
+  late final _clang_disposeTokens =
+      _clang_disposeTokensPtr.asFunction<DartClang_disposeTokens>();
+
+  /// \defgroup CINDEX_DEBUG Debugging facilities
+  ///
+  /// These routines are used for testing and debugging, only, and should not
+  /// be relied upon.
+  ///
+  /// @{
+  CXString clang_getCursorKindSpelling(
+    int Kind,
+  ) {
+    return _clang_getCursorKindSpelling(
+      Kind,
+    );
+  }
+
+  late final _clang_getCursorKindSpellingPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorKindSpelling>>(
+          'clang_getCursorKindSpelling');
+  late final _clang_getCursorKindSpelling = _clang_getCursorKindSpellingPtr
+      .asFunction<DartClang_getCursorKindSpelling>();
+
+  void clang_getDefinitionSpellingAndExtent(
+    CXCursor arg0,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> startBuf,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> endBuf,
+    ffi.Pointer<ffi.UnsignedInt> startLine,
+    ffi.Pointer<ffi.UnsignedInt> startColumn,
+    ffi.Pointer<ffi.UnsignedInt> endLine,
+    ffi.Pointer<ffi.UnsignedInt> endColumn,
+  ) {
+    return _clang_getDefinitionSpellingAndExtent(
+      arg0,
+      startBuf,
+      endBuf,
+      startLine,
+      startColumn,
+      endLine,
+      endColumn,
+    );
+  }
+
+  late final _clang_getDefinitionSpellingAndExtentPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getDefinitionSpellingAndExtent>>(
+          'clang_getDefinitionSpellingAndExtent');
+  late final _clang_getDefinitionSpellingAndExtent =
+      _clang_getDefinitionSpellingAndExtentPtr
+          .asFunction<DartClang_getDefinitionSpellingAndExtent>();
+
+  void clang_enableStackTraces() {
+    return _clang_enableStackTraces();
+  }
+
+  late final _clang_enableStackTracesPtr =
+      _lookup<ffi.NativeFunction<NativeClang_enableStackTraces>>(
+          'clang_enableStackTraces');
+  late final _clang_enableStackTraces =
+      _clang_enableStackTracesPtr.asFunction<DartClang_enableStackTraces>();
+
+  void clang_executeOnThread(
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        fn,
+    ffi.Pointer<ffi.Void> user_data,
+    int stack_size,
+  ) {
+    return _clang_executeOnThread(
+      fn,
+      user_data,
+      stack_size,
+    );
+  }
+
+  late final _clang_executeOnThreadPtr =
+      _lookup<ffi.NativeFunction<NativeClang_executeOnThread>>(
+          'clang_executeOnThread');
+  late final _clang_executeOnThread =
+      _clang_executeOnThreadPtr.asFunction<DartClang_executeOnThread>();
+
+  /// Determine the kind of a particular chunk within a completion string.
+  ///
+  /// \param completion_string the completion string to query.
+  ///
+  /// \param chunk_number the 0-based index of the chunk in the completion string.
+  ///
+  /// \returns the kind of the chunk at the index \c chunk_number.
+  int clang_getCompletionChunkKind(
+    CXCompletionString completion_string,
+    int chunk_number,
+  ) {
+    return _clang_getCompletionChunkKind(
+      completion_string,
+      chunk_number,
+    );
+  }
+
+  late final _clang_getCompletionChunkKindPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCompletionChunkKind>>(
+          'clang_getCompletionChunkKind');
+  late final _clang_getCompletionChunkKind = _clang_getCompletionChunkKindPtr
+      .asFunction<DartClang_getCompletionChunkKind>();
+
+  /// Retrieve the text associated with a particular chunk within a
+  /// completion string.
+  ///
+  /// \param completion_string the completion string to query.
+  ///
+  /// \param chunk_number the 0-based index of the chunk in the completion string.
+  ///
+  /// \returns the text associated with the chunk at index \c chunk_number.
+  CXString clang_getCompletionChunkText(
+    CXCompletionString completion_string,
+    int chunk_number,
+  ) {
+    return _clang_getCompletionChunkText(
+      completion_string,
+      chunk_number,
+    );
+  }
+
+  late final _clang_getCompletionChunkTextPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCompletionChunkText>>(
+          'clang_getCompletionChunkText');
+  late final _clang_getCompletionChunkText = _clang_getCompletionChunkTextPtr
+      .asFunction<DartClang_getCompletionChunkText>();
+
+  /// Retrieve the completion string associated with a particular chunk
+  /// within a completion string.
+  ///
+  /// \param completion_string the completion string to query.
+  ///
+  /// \param chunk_number the 0-based index of the chunk in the completion string.
+  ///
+  /// \returns the completion string associated with the chunk at index
+  /// \c chunk_number.
+  CXCompletionString clang_getCompletionChunkCompletionString(
+    CXCompletionString completion_string,
+    int chunk_number,
+  ) {
+    return _clang_getCompletionChunkCompletionString(
+      completion_string,
+      chunk_number,
+    );
+  }
+
+  late final _clang_getCompletionChunkCompletionStringPtr = _lookup<
+          ffi.NativeFunction<NativeClang_getCompletionChunkCompletionString>>(
+      'clang_getCompletionChunkCompletionString');
+  late final _clang_getCompletionChunkCompletionString =
+      _clang_getCompletionChunkCompletionStringPtr
+          .asFunction<DartClang_getCompletionChunkCompletionString>();
+
+  /// Retrieve the number of chunks in the given code-completion string.
+  int clang_getNumCompletionChunks(
+    CXCompletionString completion_string,
+  ) {
+    return _clang_getNumCompletionChunks(
+      completion_string,
+    );
+  }
+
+  late final _clang_getNumCompletionChunksPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getNumCompletionChunks>>(
+          'clang_getNumCompletionChunks');
+  late final _clang_getNumCompletionChunks = _clang_getNumCompletionChunksPtr
+      .asFunction<DartClang_getNumCompletionChunks>();
+
+  /// Determine the priority of this code completion.
+  ///
+  /// The priority of a code completion indicates how likely it is that this
+  /// particular completion is the completion that the user will select. The
+  /// priority is selected by various internal heuristics.
+  ///
+  /// \param completion_string The completion string to query.
+  ///
+  /// \returns The priority of this completion string. Smaller values indicate
+  /// higher-priority (more likely) completions.
+  int clang_getCompletionPriority(
+    CXCompletionString completion_string,
+  ) {
+    return _clang_getCompletionPriority(
+      completion_string,
+    );
+  }
+
+  late final _clang_getCompletionPriorityPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCompletionPriority>>(
+          'clang_getCompletionPriority');
+  late final _clang_getCompletionPriority = _clang_getCompletionPriorityPtr
+      .asFunction<DartClang_getCompletionPriority>();
+
+  /// Determine the availability of the entity that this code-completion
+  /// string refers to.
+  ///
+  /// \param completion_string The completion string to query.
+  ///
+  /// \returns The availability of the completion string.
+  int clang_getCompletionAvailability(
+    CXCompletionString completion_string,
+  ) {
+    return _clang_getCompletionAvailability(
+      completion_string,
+    );
+  }
+
+  late final _clang_getCompletionAvailabilityPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCompletionAvailability>>(
+          'clang_getCompletionAvailability');
+  late final _clang_getCompletionAvailability =
+      _clang_getCompletionAvailabilityPtr
+          .asFunction<DartClang_getCompletionAvailability>();
+
+  /// Retrieve the number of annotations associated with the given
+  /// completion string.
+  ///
+  /// \param completion_string the completion string to query.
+  ///
+  /// \returns the number of annotations associated with the given completion
+  /// string.
+  int clang_getCompletionNumAnnotations(
+    CXCompletionString completion_string,
+  ) {
+    return _clang_getCompletionNumAnnotations(
+      completion_string,
+    );
+  }
+
+  late final _clang_getCompletionNumAnnotationsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCompletionNumAnnotations>>(
+          'clang_getCompletionNumAnnotations');
+  late final _clang_getCompletionNumAnnotations =
+      _clang_getCompletionNumAnnotationsPtr
+          .asFunction<DartClang_getCompletionNumAnnotations>();
+
+  /// Retrieve the annotation associated with the given completion string.
+  ///
+  /// \param completion_string the completion string to query.
+  ///
+  /// \param annotation_number the 0-based index of the annotation of the
+  /// completion string.
+  ///
+  /// \returns annotation string associated with the completion at index
+  /// \c annotation_number, or a NULL string if that annotation is not available.
+  CXString clang_getCompletionAnnotation(
+    CXCompletionString completion_string,
+    int annotation_number,
+  ) {
+    return _clang_getCompletionAnnotation(
+      completion_string,
+      annotation_number,
+    );
+  }
+
+  late final _clang_getCompletionAnnotationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCompletionAnnotation>>(
+          'clang_getCompletionAnnotation');
+  late final _clang_getCompletionAnnotation = _clang_getCompletionAnnotationPtr
+      .asFunction<DartClang_getCompletionAnnotation>();
+
+  /// Retrieve the parent context of the given completion string.
+  ///
+  /// The parent context of a completion string is the semantic parent of
+  /// the declaration (if any) that the code completion represents. For example,
+  /// a code completion for an Objective-C method would have the method's class
+  /// or protocol as its context.
+  ///
+  /// \param completion_string The code completion string whose parent is
+  /// being queried.
+  ///
+  /// \param kind DEPRECATED: always set to CXCursor_NotImplemented if non-NULL.
+  ///
+  /// \returns The name of the completion parent, e.g., "NSObject" if
+  /// the completion string represents a method in the NSObject class.
+  CXString clang_getCompletionParent(
+    CXCompletionString completion_string,
+    ffi.Pointer<ffi.Int32> kind,
+  ) {
+    return _clang_getCompletionParent(
+      completion_string,
+      kind,
+    );
+  }
+
+  late final _clang_getCompletionParentPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCompletionParent>>(
+          'clang_getCompletionParent');
+  late final _clang_getCompletionParent =
+      _clang_getCompletionParentPtr.asFunction<DartClang_getCompletionParent>();
+
+  /// Retrieve the brief documentation comment attached to the declaration
+  /// that corresponds to the given completion string.
+  CXString clang_getCompletionBriefComment(
+    CXCompletionString completion_string,
+  ) {
+    return _clang_getCompletionBriefComment(
+      completion_string,
+    );
+  }
+
+  late final _clang_getCompletionBriefCommentPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCompletionBriefComment>>(
+          'clang_getCompletionBriefComment');
+  late final _clang_getCompletionBriefComment =
+      _clang_getCompletionBriefCommentPtr
+          .asFunction<DartClang_getCompletionBriefComment>();
+
+  /// Retrieve a completion string for an arbitrary declaration or macro
+  /// definition cursor.
+  ///
+  /// \param cursor The cursor to query.
+  ///
+  /// \returns A non-context-sensitive completion string for declaration and macro
+  /// definition cursors, or NULL for other kinds of cursors.
+  CXCompletionString clang_getCursorCompletionString(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorCompletionString(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorCompletionStringPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCursorCompletionString>>(
+          'clang_getCursorCompletionString');
+  late final _clang_getCursorCompletionString =
+      _clang_getCursorCompletionStringPtr
+          .asFunction<DartClang_getCursorCompletionString>();
+
+  /// Retrieve the number of fix-its for the given completion index.
+  ///
+  /// Calling this makes sense only if CXCodeComplete_IncludeCompletionsWithFixIts
+  /// option was set.
+  ///
+  /// \param results The structure keeping all completion results
+  ///
+  /// \param completion_index The index of the completion
+  ///
+  /// \return The number of fix-its which must be applied before the completion at
+  /// completion_index can be applied
+  int clang_getCompletionNumFixIts(
+    ffi.Pointer<CXCodeCompleteResults> results,
+    int completion_index,
+  ) {
+    return _clang_getCompletionNumFixIts(
+      results,
+      completion_index,
+    );
+  }
+
+  late final _clang_getCompletionNumFixItsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCompletionNumFixIts>>(
+          'clang_getCompletionNumFixIts');
+  late final _clang_getCompletionNumFixIts = _clang_getCompletionNumFixItsPtr
+      .asFunction<DartClang_getCompletionNumFixIts>();
+
+  /// Fix-its that *must* be applied before inserting the text for the
+  /// corresponding completion.
+  ///
+  /// By default, clang_codeCompleteAt() only returns completions with empty
+  /// fix-its. Extra completions with non-empty fix-its should be explicitly
+  /// requested by setting CXCodeComplete_IncludeCompletionsWithFixIts.
+  ///
+  /// For the clients to be able to compute position of the cursor after applying
+  /// fix-its, the following conditions are guaranteed to hold for
+  /// replacement_range of the stored fix-its:
+  /// - Ranges in the fix-its are guaranteed to never contain the completion
+  /// point (or identifier under completion point, if any) inside them, except
+  /// at the start or at the end of the range.
+  /// - If a fix-it range starts or ends with completion point (or starts or
+  /// ends after the identifier under completion point), it will contain at
+  /// least one character. It allows to unambiguously recompute completion
+  /// point after applying the fix-it.
+  ///
+  /// The intuition is that provided fix-its change code around the identifier we
+  /// complete, but are not allowed to touch the identifier itself or the
+  /// completion point. One example of completions with corrections are the ones
+  /// replacing '.' with '->' and vice versa:
+  ///
+  /// std::unique_ptr<std::vector<int>> vec_ptr;
+  /// In 'vec_ptr.^', one of the completions is 'push_back', it requires
+  /// replacing '.' with '->'.
+  /// In 'vec_ptr->^', one of the completions is 'release', it requires
+  /// replacing '->' with '.'.
+  ///
+  /// \param results The structure keeping all completion results
+  ///
+  /// \param completion_index The index of the completion
+  ///
+  /// \param fixit_index The index of the fix-it for the completion at
+  /// completion_index
+  ///
+  /// \param replacement_range The fix-it range that must be replaced before the
+  /// completion at completion_index can be applied
+  ///
+  /// \returns The fix-it string that must replace the code at replacement_range
+  /// before the completion at completion_index can be applied
+  CXString clang_getCompletionFixIt(
+    ffi.Pointer<CXCodeCompleteResults> results,
+    int completion_index,
+    int fixit_index,
+    ffi.Pointer<CXSourceRange> replacement_range,
+  ) {
+    return _clang_getCompletionFixIt(
+      results,
+      completion_index,
+      fixit_index,
+      replacement_range,
+    );
+  }
+
+  late final _clang_getCompletionFixItPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getCompletionFixIt>>(
+          'clang_getCompletionFixIt');
+  late final _clang_getCompletionFixIt =
+      _clang_getCompletionFixItPtr.asFunction<DartClang_getCompletionFixIt>();
+
+  /// Returns a default set of code-completion options that can be
+  /// passed to\c clang_codeCompleteAt().
+  int clang_defaultCodeCompleteOptions() {
+    return _clang_defaultCodeCompleteOptions();
+  }
+
+  late final _clang_defaultCodeCompleteOptionsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_defaultCodeCompleteOptions>>(
+          'clang_defaultCodeCompleteOptions');
+  late final _clang_defaultCodeCompleteOptions =
+      _clang_defaultCodeCompleteOptionsPtr
+          .asFunction<DartClang_defaultCodeCompleteOptions>();
+
+  /// Perform code completion at a given location in a translation unit.
+  ///
+  /// This function performs code completion at a particular file, line, and
+  /// column within source code, providing results that suggest potential
+  /// code snippets based on the context of the completion. The basic model
+  /// for code completion is that Clang will parse a complete source file,
+  /// performing syntax checking up to the location where code-completion has
+  /// been requested. At that point, a special code-completion token is passed
+  /// to the parser, which recognizes this token and determines, based on the
+  /// current location in the C/Objective-C/C++ grammar and the state of
+  /// semantic analysis, what completions to provide. These completions are
+  /// returned via a new \c CXCodeCompleteResults structure.
+  ///
+  /// Code completion itself is meant to be triggered by the client when the
+  /// user types punctuation characters or whitespace, at which point the
+  /// code-completion location will coincide with the cursor. For example, if \c p
+  /// is a pointer, code-completion might be triggered after the "-" and then
+  /// after the ">" in \c p->. When the code-completion location is after the ">",
+  /// the completion results will provide, e.g., the members of the struct that
+  /// "p" points to. The client is responsible for placing the cursor at the
+  /// beginning of the token currently being typed, then filtering the results
+  /// based on the contents of the token. For example, when code-completing for
+  /// the expression \c p->get, the client should provide the location just after
+  /// the ">" (e.g., pointing at the "g") to this code-completion hook. Then, the
+  /// client can filter the results based on the current token text ("get"), only
+  /// showing those results that start with "get". The intent of this interface
+  /// is to separate the relatively high-latency acquisition of code-completion
+  /// results from the filtering of results on a per-character basis, which must
+  /// have a lower latency.
+  ///
+  /// \param TU The translation unit in which code-completion should
+  /// occur. The source files for this translation unit need not be
+  /// completely up-to-date (and the contents of those source files may
+  /// be overridden via \p unsaved_files). Cursors referring into the
+  /// translation unit may be invalidated by this invocation.
+  ///
+  /// \param complete_filename The name of the source file where code
+  /// completion should be performed. This filename may be any file
+  /// included in the translation unit.
+  ///
+  /// \param complete_line The line at which code-completion should occur.
+  ///
+  /// \param complete_column The column at which code-completion should occur.
+  /// Note that the column should point just after the syntactic construct that
+  /// initiated code completion, and not in the middle of a lexical token.
+  ///
+  /// \param unsaved_files the Files that have not yet been saved to disk
+  /// but may be required for parsing or code completion, including the
+  /// contents of those files.  The contents and name of these files (as
+  /// specified by CXUnsavedFile) are copied when necessary, so the
+  /// client only needs to guarantee their validity until the call to
+  /// this function returns.
+  ///
+  /// \param num_unsaved_files The number of unsaved file entries in \p
+  /// unsaved_files.
+  ///
+  /// \param options Extra options that control the behavior of code
+  /// completion, expressed as a bitwise OR of the enumerators of the
+  /// CXCodeComplete_Flags enumeration. The
+  /// \c clang_defaultCodeCompleteOptions() function returns a default set
+  /// of code-completion options.
+  ///
+  /// \returns If successful, a new \c CXCodeCompleteResults structure
+  /// containing code-completion results, which should eventually be
+  /// freed with \c clang_disposeCodeCompleteResults(). If code
+  /// completion fails, returns NULL.
+  ffi.Pointer<CXCodeCompleteResults> clang_codeCompleteAt(
+    CXTranslationUnit TU,
+    ffi.Pointer<ffi.Char> complete_filename,
+    int complete_line,
+    int complete_column,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options,
+  ) {
+    return _clang_codeCompleteAt(
+      TU,
+      complete_filename,
+      complete_line,
+      complete_column,
+      unsaved_files,
+      num_unsaved_files,
+      options,
+    );
+  }
+
+  late final _clang_codeCompleteAtPtr =
+      _lookup<ffi.NativeFunction<NativeClang_codeCompleteAt>>(
+          'clang_codeCompleteAt');
+  late final _clang_codeCompleteAt =
+      _clang_codeCompleteAtPtr.asFunction<DartClang_codeCompleteAt>();
+
+  /// Sort the code-completion results in case-insensitive alphabetical
+  /// order.
+  ///
+  /// \param Results The set of results to sort.
+  /// \param NumResults The number of results in \p Results.
+  void clang_sortCodeCompletionResults(
+    ffi.Pointer<CXCompletionResult> Results,
+    int NumResults,
+  ) {
+    return _clang_sortCodeCompletionResults(
+      Results,
+      NumResults,
+    );
+  }
+
+  late final _clang_sortCodeCompletionResultsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_sortCodeCompletionResults>>(
+          'clang_sortCodeCompletionResults');
+  late final _clang_sortCodeCompletionResults =
+      _clang_sortCodeCompletionResultsPtr
+          .asFunction<DartClang_sortCodeCompletionResults>();
+
+  /// Free the given set of code-completion results.
+  void clang_disposeCodeCompleteResults(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+  ) {
+    return _clang_disposeCodeCompleteResults(
+      Results,
+    );
+  }
+
+  late final _clang_disposeCodeCompleteResultsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_disposeCodeCompleteResults>>(
+          'clang_disposeCodeCompleteResults');
+  late final _clang_disposeCodeCompleteResults =
+      _clang_disposeCodeCompleteResultsPtr
+          .asFunction<DartClang_disposeCodeCompleteResults>();
+
+  /// Determine the number of diagnostics produced prior to the
+  /// location where code completion was performed.
+  int clang_codeCompleteGetNumDiagnostics(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+  ) {
+    return _clang_codeCompleteGetNumDiagnostics(
+      Results,
+    );
+  }
+
+  late final _clang_codeCompleteGetNumDiagnosticsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_codeCompleteGetNumDiagnostics>>(
+          'clang_codeCompleteGetNumDiagnostics');
+  late final _clang_codeCompleteGetNumDiagnostics =
+      _clang_codeCompleteGetNumDiagnosticsPtr
+          .asFunction<DartClang_codeCompleteGetNumDiagnostics>();
+
+  /// Retrieve a diagnostic associated with the given code completion.
+  ///
+  /// \param Results the code completion results to query.
+  /// \param Index the zero-based diagnostic number to retrieve.
+  ///
+  /// \returns the requested diagnostic. This diagnostic must be freed
+  /// via a call to \c clang_disposeDiagnostic().
+  CXDiagnostic clang_codeCompleteGetDiagnostic(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+    int Index,
+  ) {
+    return _clang_codeCompleteGetDiagnostic(
+      Results,
+      Index,
+    );
+  }
+
+  late final _clang_codeCompleteGetDiagnosticPtr =
+      _lookup<ffi.NativeFunction<NativeClang_codeCompleteGetDiagnostic>>(
+          'clang_codeCompleteGetDiagnostic');
+  late final _clang_codeCompleteGetDiagnostic =
+      _clang_codeCompleteGetDiagnosticPtr
+          .asFunction<DartClang_codeCompleteGetDiagnostic>();
+
+  /// Determines what completions are appropriate for the context
+  /// the given code completion.
+  ///
+  /// \param Results the code completion results to query
+  ///
+  /// \returns the kinds of completions that are appropriate for use
+  /// along with the given code completion results.
+  int clang_codeCompleteGetContexts(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+  ) {
+    return _clang_codeCompleteGetContexts(
+      Results,
+    );
+  }
+
+  late final _clang_codeCompleteGetContextsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_codeCompleteGetContexts>>(
+          'clang_codeCompleteGetContexts');
+  late final _clang_codeCompleteGetContexts = _clang_codeCompleteGetContextsPtr
+      .asFunction<DartClang_codeCompleteGetContexts>();
+
+  /// Returns the cursor kind for the container for the current code
+  /// completion context. The container is only guaranteed to be set for
+  /// contexts where a container exists (i.e. member accesses or Objective-C
+  /// message sends); if there is not a container, this function will return
+  /// CXCursor_InvalidCode.
+  ///
+  /// \param Results the code completion results to query
+  ///
+  /// \param IsIncomplete on return, this value will be false if Clang has complete
+  /// information about the container. If Clang does not have complete
+  /// information, this value will be true.
+  ///
+  /// \returns the container kind, or CXCursor_InvalidCode if there is not a
+  /// container
+  int clang_codeCompleteGetContainerKind(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+    ffi.Pointer<ffi.UnsignedInt> IsIncomplete,
+  ) {
+    return _clang_codeCompleteGetContainerKind(
+      Results,
+      IsIncomplete,
+    );
+  }
+
+  late final _clang_codeCompleteGetContainerKindPtr =
+      _lookup<ffi.NativeFunction<NativeClang_codeCompleteGetContainerKind>>(
+          'clang_codeCompleteGetContainerKind');
+  late final _clang_codeCompleteGetContainerKind =
+      _clang_codeCompleteGetContainerKindPtr
+          .asFunction<DartClang_codeCompleteGetContainerKind>();
+
+  /// Returns the USR for the container for the current code completion
+  /// context. If there is not a container for the current context, this
+  /// function will return the empty string.
+  ///
+  /// \param Results the code completion results to query
+  ///
+  /// \returns the USR for the container
+  CXString clang_codeCompleteGetContainerUSR(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+  ) {
+    return _clang_codeCompleteGetContainerUSR(
+      Results,
+    );
+  }
+
+  late final _clang_codeCompleteGetContainerUSRPtr =
+      _lookup<ffi.NativeFunction<NativeClang_codeCompleteGetContainerUSR>>(
+          'clang_codeCompleteGetContainerUSR');
+  late final _clang_codeCompleteGetContainerUSR =
+      _clang_codeCompleteGetContainerUSRPtr
+          .asFunction<DartClang_codeCompleteGetContainerUSR>();
+
+  /// Returns the currently-entered selector for an Objective-C message
+  /// send, formatted like "initWithFoo:bar:". Only guaranteed to return a
+  /// non-empty string for CXCompletionContext_ObjCInstanceMessage and
+  /// CXCompletionContext_ObjCClassMessage.
+  ///
+  /// \param Results the code completion results to query
+  ///
+  /// \returns the selector (or partial selector) that has been entered thus far
+  /// for an Objective-C message send.
+  CXString clang_codeCompleteGetObjCSelector(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+  ) {
+    return _clang_codeCompleteGetObjCSelector(
+      Results,
+    );
+  }
+
+  late final _clang_codeCompleteGetObjCSelectorPtr =
+      _lookup<ffi.NativeFunction<NativeClang_codeCompleteGetObjCSelector>>(
+          'clang_codeCompleteGetObjCSelector');
+  late final _clang_codeCompleteGetObjCSelector =
+      _clang_codeCompleteGetObjCSelectorPtr
+          .asFunction<DartClang_codeCompleteGetObjCSelector>();
+
+  /// Return a version string, suitable for showing to a user, but not
+  /// intended to be parsed (the format is not guaranteed to be stable).
+  CXString clang_getClangVersion() {
+    return _clang_getClangVersion();
+  }
+
+  late final _clang_getClangVersionPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getClangVersion>>(
+          'clang_getClangVersion');
+  late final _clang_getClangVersion =
+      _clang_getClangVersionPtr.asFunction<DartClang_getClangVersion>();
+
+  /// Enable/disable crash recovery.
+  ///
+  /// \param isEnabled Flag to indicate if crash recovery is enabled.  A non-zero
+  /// value enables crash recovery, while 0 disables it.
+  void clang_toggleCrashRecovery(
+    int isEnabled,
+  ) {
+    return _clang_toggleCrashRecovery(
+      isEnabled,
+    );
+  }
+
+  late final _clang_toggleCrashRecoveryPtr =
+      _lookup<ffi.NativeFunction<NativeClang_toggleCrashRecovery>>(
+          'clang_toggleCrashRecovery');
+  late final _clang_toggleCrashRecovery =
+      _clang_toggleCrashRecoveryPtr.asFunction<DartClang_toggleCrashRecovery>();
+
+  /// Visit the set of preprocessor inclusions in a translation unit.
+  /// The visitor function is called with the provided data for every included
+  /// file.  This does not include headers included by the PCH file (unless one
+  /// is inspecting the inclusions in the PCH file itself).
+  void clang_getInclusions(
+    CXTranslationUnit tu,
+    CXInclusionVisitor visitor,
+    CXClientData client_data,
+  ) {
+    return _clang_getInclusions(
+      tu,
+      visitor,
+      client_data,
+    );
+  }
+
+  late final _clang_getInclusionsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getInclusions>>(
+          'clang_getInclusions');
+  late final _clang_getInclusions =
+      _clang_getInclusionsPtr.asFunction<DartClang_getInclusions>();
+
+  /// If cursor is a statement declaration tries to evaluate the
+  /// statement and if its variable, tries to evaluate its initializer,
+  /// into its corresponding type.
+  CXEvalResult clang_Cursor_Evaluate(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_Evaluate(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_EvaluatePtr =
+      _lookup<ffi.NativeFunction<NativeClang_Cursor_Evaluate>>(
+          'clang_Cursor_Evaluate');
+  late final _clang_Cursor_Evaluate =
+      _clang_Cursor_EvaluatePtr.asFunction<DartClang_Cursor_Evaluate>();
+
+  /// Returns the kind of the evaluated result.
+  int clang_EvalResult_getKind(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getKind(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getKindPtr =
+      _lookup<ffi.NativeFunction<NativeClang_EvalResult_getKind>>(
+          'clang_EvalResult_getKind');
+  late final _clang_EvalResult_getKind =
+      _clang_EvalResult_getKindPtr.asFunction<DartClang_EvalResult_getKind>();
+
+  /// Returns the evaluation result as integer if the
+  /// kind is Int.
+  int clang_EvalResult_getAsInt(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsInt(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsIntPtr =
+      _lookup<ffi.NativeFunction<NativeClang_EvalResult_getAsInt>>(
+          'clang_EvalResult_getAsInt');
+  late final _clang_EvalResult_getAsInt =
+      _clang_EvalResult_getAsIntPtr.asFunction<DartClang_EvalResult_getAsInt>();
+
+  /// Returns the evaluation result as a long long integer if the
+  /// kind is Int. This prevents overflows that may happen if the result is
+  /// returned with clang_EvalResult_getAsInt.
+  int clang_EvalResult_getAsLongLong(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsLongLong(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsLongLongPtr =
+      _lookup<ffi.NativeFunction<NativeClang_EvalResult_getAsLongLong>>(
+          'clang_EvalResult_getAsLongLong');
+  late final _clang_EvalResult_getAsLongLong =
+      _clang_EvalResult_getAsLongLongPtr
+          .asFunction<DartClang_EvalResult_getAsLongLong>();
+
+  /// Returns a non-zero value if the kind is Int and the evaluation
+  /// result resulted in an unsigned integer.
+  int clang_EvalResult_isUnsignedInt(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_isUnsignedInt(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_isUnsignedIntPtr =
+      _lookup<ffi.NativeFunction<NativeClang_EvalResult_isUnsignedInt>>(
+          'clang_EvalResult_isUnsignedInt');
+  late final _clang_EvalResult_isUnsignedInt =
+      _clang_EvalResult_isUnsignedIntPtr
+          .asFunction<DartClang_EvalResult_isUnsignedInt>();
+
+  /// Returns the evaluation result as an unsigned integer if
+  /// the kind is Int and clang_EvalResult_isUnsignedInt is non-zero.
+  int clang_EvalResult_getAsUnsigned(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsUnsigned(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsUnsignedPtr =
+      _lookup<ffi.NativeFunction<NativeClang_EvalResult_getAsUnsigned>>(
+          'clang_EvalResult_getAsUnsigned');
+  late final _clang_EvalResult_getAsUnsigned =
+      _clang_EvalResult_getAsUnsignedPtr
+          .asFunction<DartClang_EvalResult_getAsUnsigned>();
+
+  /// Returns the evaluation result as double if the
+  /// kind is double.
+  double clang_EvalResult_getAsDouble(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsDouble(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsDoublePtr =
+      _lookup<ffi.NativeFunction<NativeClang_EvalResult_getAsDouble>>(
+          'clang_EvalResult_getAsDouble');
+  late final _clang_EvalResult_getAsDouble = _clang_EvalResult_getAsDoublePtr
+      .asFunction<DartClang_EvalResult_getAsDouble>();
+
+  /// Returns the evaluation result as a constant string if the
+  /// kind is other than Int or float. User must not free this pointer,
+  /// instead call clang_EvalResult_dispose on the CXEvalResult returned
+  /// by clang_Cursor_Evaluate.
+  ffi.Pointer<ffi.Char> clang_EvalResult_getAsStr(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsStr(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsStrPtr =
+      _lookup<ffi.NativeFunction<NativeClang_EvalResult_getAsStr>>(
+          'clang_EvalResult_getAsStr');
+  late final _clang_EvalResult_getAsStr =
+      _clang_EvalResult_getAsStrPtr.asFunction<DartClang_EvalResult_getAsStr>();
+
+  /// Disposes the created Eval memory.
+  void clang_EvalResult_dispose(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_dispose(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_disposePtr =
+      _lookup<ffi.NativeFunction<NativeClang_EvalResult_dispose>>(
+          'clang_EvalResult_dispose');
+  late final _clang_EvalResult_dispose =
+      _clang_EvalResult_disposePtr.asFunction<DartClang_EvalResult_dispose>();
+
+  /// Retrieve a remapping.
+  ///
+  /// \param path the path that contains metadata about remappings.
+  ///
+  /// \returns the requested remapping. This remapping must be freed
+  /// via a call to \c clang_remap_dispose(). Can return NULL if an error occurred.
+  CXRemapping clang_getRemappings(
+    ffi.Pointer<ffi.Char> path,
+  ) {
+    return _clang_getRemappings(
+      path,
+    );
+  }
+
+  late final _clang_getRemappingsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getRemappings>>(
+          'clang_getRemappings');
+  late final _clang_getRemappings =
+      _clang_getRemappingsPtr.asFunction<DartClang_getRemappings>();
+
+  /// Retrieve a remapping.
+  ///
+  /// \param filePaths pointer to an array of file paths containing remapping info.
+  ///
+  /// \param numFiles number of file paths.
+  ///
+  /// \returns the requested remapping. This remapping must be freed
+  /// via a call to \c clang_remap_dispose(). Can return NULL if an error occurred.
+  CXRemapping clang_getRemappingsFromFileList(
+    ffi.Pointer<ffi.Pointer<ffi.Char>> filePaths,
+    int numFiles,
+  ) {
+    return _clang_getRemappingsFromFileList(
+      filePaths,
+      numFiles,
+    );
+  }
+
+  late final _clang_getRemappingsFromFileListPtr =
+      _lookup<ffi.NativeFunction<NativeClang_getRemappingsFromFileList>>(
+          'clang_getRemappingsFromFileList');
+  late final _clang_getRemappingsFromFileList =
+      _clang_getRemappingsFromFileListPtr
+          .asFunction<DartClang_getRemappingsFromFileList>();
+
+  /// Determine the number of remappings.
+  int clang_remap_getNumFiles(
+    CXRemapping arg0,
+  ) {
+    return _clang_remap_getNumFiles(
+      arg0,
+    );
+  }
+
+  late final _clang_remap_getNumFilesPtr =
+      _lookup<ffi.NativeFunction<NativeClang_remap_getNumFiles>>(
+          'clang_remap_getNumFiles');
+  late final _clang_remap_getNumFiles =
+      _clang_remap_getNumFilesPtr.asFunction<DartClang_remap_getNumFiles>();
+
+  /// Get the original and the associated filename from the remapping.
+  ///
+  /// \param original If non-NULL, will be set to the original filename.
+  ///
+  /// \param transformed If non-NULL, will be set to the filename that the original
+  /// is associated with.
+  void clang_remap_getFilenames(
+    CXRemapping arg0,
+    int index,
+    ffi.Pointer<CXString> original,
+    ffi.Pointer<CXString> transformed,
+  ) {
+    return _clang_remap_getFilenames(
+      arg0,
+      index,
+      original,
+      transformed,
+    );
+  }
+
+  late final _clang_remap_getFilenamesPtr =
+      _lookup<ffi.NativeFunction<NativeClang_remap_getFilenames>>(
+          'clang_remap_getFilenames');
+  late final _clang_remap_getFilenames =
+      _clang_remap_getFilenamesPtr.asFunction<DartClang_remap_getFilenames>();
+
+  /// Dispose the remapping.
+  void clang_remap_dispose(
+    CXRemapping arg0,
+  ) {
+    return _clang_remap_dispose(
+      arg0,
+    );
+  }
+
+  late final _clang_remap_disposePtr =
+      _lookup<ffi.NativeFunction<NativeClang_remap_dispose>>(
+          'clang_remap_dispose');
+  late final _clang_remap_dispose =
+      _clang_remap_disposePtr.asFunction<DartClang_remap_dispose>();
+
+  /// Find references of a declaration in a specific file.
+  ///
+  /// \param cursor pointing to a declaration or a reference of one.
+  ///
+  /// \param file to search for references.
+  ///
+  /// \param visitor callback that will receive pairs of CXCursor/CXSourceRange for
+  /// each reference found.
+  /// The CXSourceRange will point inside the file; if the reference is inside
+  /// a macro (and not a macro argument) the CXSourceRange will be invalid.
+  ///
+  /// \returns one of the CXResult enumerators.
+  int clang_findReferencesInFile(
+    CXCursor cursor,
+    CXFile file,
+    CXCursorAndRangeVisitor visitor,
+  ) {
+    return _clang_findReferencesInFile(
+      cursor,
+      file,
+      visitor,
+    );
+  }
+
+  late final _clang_findReferencesInFilePtr =
+      _lookup<ffi.NativeFunction<NativeClang_findReferencesInFile>>(
+          'clang_findReferencesInFile');
+  late final _clang_findReferencesInFile = _clang_findReferencesInFilePtr
+      .asFunction<DartClang_findReferencesInFile>();
+
+  /// Find #import/#include directives in a specific file.
+  ///
+  /// \param TU translation unit containing the file to query.
+  ///
+  /// \param file to search for #import/#include directives.
+  ///
+  /// \param visitor callback that will receive pairs of CXCursor/CXSourceRange for
+  /// each directive found.
+  ///
+  /// \returns one of the CXResult enumerators.
+  int clang_findIncludesInFile(
+    CXTranslationUnit TU,
+    CXFile file,
+    CXCursorAndRangeVisitor visitor,
+  ) {
+    return _clang_findIncludesInFile(
+      TU,
+      file,
+      visitor,
+    );
+  }
+
+  late final _clang_findIncludesInFilePtr =
+      _lookup<ffi.NativeFunction<NativeClang_findIncludesInFile>>(
+          'clang_findIncludesInFile');
+  late final _clang_findIncludesInFile =
+      _clang_findIncludesInFilePtr.asFunction<DartClang_findIncludesInFile>();
+
+  int clang_index_isEntityObjCContainerKind(
+    int arg0,
+  ) {
+    return _clang_index_isEntityObjCContainerKind(
+      arg0,
+    );
+  }
+
+  late final _clang_index_isEntityObjCContainerKindPtr =
+      _lookup<ffi.NativeFunction<NativeClang_index_isEntityObjCContainerKind>>(
+          'clang_index_isEntityObjCContainerKind');
+  late final _clang_index_isEntityObjCContainerKind =
+      _clang_index_isEntityObjCContainerKindPtr
+          .asFunction<DartClang_index_isEntityObjCContainerKind>();
+
+  ffi.Pointer<CXIdxObjCContainerDeclInfo> clang_index_getObjCContainerDeclInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getObjCContainerDeclInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getObjCContainerDeclInfoPtr =
+      _lookup<ffi.NativeFunction<NativeClang_index_getObjCContainerDeclInfo>>(
+          'clang_index_getObjCContainerDeclInfo');
+  late final _clang_index_getObjCContainerDeclInfo =
+      _clang_index_getObjCContainerDeclInfoPtr
+          .asFunction<DartClang_index_getObjCContainerDeclInfo>();
+
+  ffi.Pointer<CXIdxObjCInterfaceDeclInfo> clang_index_getObjCInterfaceDeclInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getObjCInterfaceDeclInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getObjCInterfaceDeclInfoPtr =
+      _lookup<ffi.NativeFunction<NativeClang_index_getObjCInterfaceDeclInfo>>(
+          'clang_index_getObjCInterfaceDeclInfo');
+  late final _clang_index_getObjCInterfaceDeclInfo =
+      _clang_index_getObjCInterfaceDeclInfoPtr
+          .asFunction<DartClang_index_getObjCInterfaceDeclInfo>();
+
+  ffi.Pointer<CXIdxObjCCategoryDeclInfo> clang_index_getObjCCategoryDeclInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getObjCCategoryDeclInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getObjCCategoryDeclInfoPtr =
+      _lookup<ffi.NativeFunction<NativeClang_index_getObjCCategoryDeclInfo>>(
+          'clang_index_getObjCCategoryDeclInfo');
+  late final _clang_index_getObjCCategoryDeclInfo =
+      _clang_index_getObjCCategoryDeclInfoPtr
+          .asFunction<DartClang_index_getObjCCategoryDeclInfo>();
+
+  ffi.Pointer<CXIdxObjCProtocolRefListInfo>
+      clang_index_getObjCProtocolRefListInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getObjCProtocolRefListInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getObjCProtocolRefListInfoPtr =
+      _lookup<ffi.NativeFunction<NativeClang_index_getObjCProtocolRefListInfo>>(
+          'clang_index_getObjCProtocolRefListInfo');
+  late final _clang_index_getObjCProtocolRefListInfo =
+      _clang_index_getObjCProtocolRefListInfoPtr
+          .asFunction<DartClang_index_getObjCProtocolRefListInfo>();
+
+  ffi.Pointer<CXIdxObjCPropertyDeclInfo> clang_index_getObjCPropertyDeclInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getObjCPropertyDeclInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getObjCPropertyDeclInfoPtr =
+      _lookup<ffi.NativeFunction<NativeClang_index_getObjCPropertyDeclInfo>>(
+          'clang_index_getObjCPropertyDeclInfo');
+  late final _clang_index_getObjCPropertyDeclInfo =
+      _clang_index_getObjCPropertyDeclInfoPtr
+          .asFunction<DartClang_index_getObjCPropertyDeclInfo>();
+
+  ffi.Pointer<CXIdxIBOutletCollectionAttrInfo>
+      clang_index_getIBOutletCollectionAttrInfo(
+    ffi.Pointer<CXIdxAttrInfo> arg0,
+  ) {
+    return _clang_index_getIBOutletCollectionAttrInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getIBOutletCollectionAttrInfoPtr = _lookup<
+          ffi.NativeFunction<NativeClang_index_getIBOutletCollectionAttrInfo>>(
+      'clang_index_getIBOutletCollectionAttrInfo');
+  late final _clang_index_getIBOutletCollectionAttrInfo =
+      _clang_index_getIBOutletCollectionAttrInfoPtr
+          .asFunction<DartClang_index_getIBOutletCollectionAttrInfo>();
+
+  ffi.Pointer<CXIdxCXXClassDeclInfo> clang_index_getCXXClassDeclInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getCXXClassDeclInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getCXXClassDeclInfoPtr =
+      _lookup<ffi.NativeFunction<NativeClang_index_getCXXClassDeclInfo>>(
+          'clang_index_getCXXClassDeclInfo');
+  late final _clang_index_getCXXClassDeclInfo =
+      _clang_index_getCXXClassDeclInfoPtr
+          .asFunction<DartClang_index_getCXXClassDeclInfo>();
+
+  /// For retrieving a custom CXIdxClientContainer attached to a
+  /// container.
+  CXIdxClientContainer clang_index_getClientContainer(
+    ffi.Pointer<CXIdxContainerInfo> arg0,
+  ) {
+    return _clang_index_getClientContainer(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getClientContainerPtr =
+      _lookup<ffi.NativeFunction<NativeClang_index_getClientContainer>>(
+          'clang_index_getClientContainer');
+  late final _clang_index_getClientContainer =
+      _clang_index_getClientContainerPtr
+          .asFunction<DartClang_index_getClientContainer>();
+
+  /// For setting a custom CXIdxClientContainer attached to a
+  /// container.
+  void clang_index_setClientContainer(
+    ffi.Pointer<CXIdxContainerInfo> arg0,
+    CXIdxClientContainer arg1,
+  ) {
+    return _clang_index_setClientContainer(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_index_setClientContainerPtr =
+      _lookup<ffi.NativeFunction<NativeClang_index_setClientContainer>>(
+          'clang_index_setClientContainer');
+  late final _clang_index_setClientContainer =
+      _clang_index_setClientContainerPtr
+          .asFunction<DartClang_index_setClientContainer>();
+
+  /// For retrieving a custom CXIdxClientEntity attached to an entity.
+  CXIdxClientEntity clang_index_getClientEntity(
+    ffi.Pointer<CXIdxEntityInfo> arg0,
+  ) {
+    return _clang_index_getClientEntity(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getClientEntityPtr =
+      _lookup<ffi.NativeFunction<NativeClang_index_getClientEntity>>(
+          'clang_index_getClientEntity');
+  late final _clang_index_getClientEntity = _clang_index_getClientEntityPtr
+      .asFunction<DartClang_index_getClientEntity>();
+
+  /// For setting a custom CXIdxClientEntity attached to an entity.
+  void clang_index_setClientEntity(
+    ffi.Pointer<CXIdxEntityInfo> arg0,
+    CXIdxClientEntity arg1,
+  ) {
+    return _clang_index_setClientEntity(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_index_setClientEntityPtr =
+      _lookup<ffi.NativeFunction<NativeClang_index_setClientEntity>>(
+          'clang_index_setClientEntity');
+  late final _clang_index_setClientEntity = _clang_index_setClientEntityPtr
+      .asFunction<DartClang_index_setClientEntity>();
+
+  /// An indexing action/session, to be applied to one or multiple
+  /// translation units.
+  ///
+  /// \param CIdx The index object with which the index action will be associated.
+  CXIndexAction clang_IndexAction_create(
+    CXIndex CIdx,
+  ) {
+    return _clang_IndexAction_create(
+      CIdx,
+    );
+  }
+
+  late final _clang_IndexAction_createPtr =
+      _lookup<ffi.NativeFunction<NativeClang_IndexAction_create>>(
+          'clang_IndexAction_create');
+  late final _clang_IndexAction_create =
+      _clang_IndexAction_createPtr.asFunction<DartClang_IndexAction_create>();
+
+  /// Destroy the given index action.
+  ///
+  /// The index action must not be destroyed until all of the translation units
+  /// created within that index action have been destroyed.
+  void clang_IndexAction_dispose(
+    CXIndexAction arg0,
+  ) {
+    return _clang_IndexAction_dispose(
+      arg0,
+    );
+  }
+
+  late final _clang_IndexAction_disposePtr =
+      _lookup<ffi.NativeFunction<NativeClang_IndexAction_dispose>>(
+          'clang_IndexAction_dispose');
+  late final _clang_IndexAction_dispose =
+      _clang_IndexAction_disposePtr.asFunction<DartClang_IndexAction_dispose>();
+
+  /// Index the given source file and the translation unit corresponding
+  /// to that file via callbacks implemented through #IndexerCallbacks.
+  ///
+  /// \param client_data pointer data supplied by the client, which will
+  /// be passed to the invoked callbacks.
+  ///
+  /// \param index_callbacks Pointer to indexing callbacks that the client
+  /// implements.
+  ///
+  /// \param index_callbacks_size Size of #IndexerCallbacks structure that gets
+  /// passed in index_callbacks.
+  ///
+  /// \param index_options A bitmask of options that affects how indexing is
+  /// performed. This should be a bitwise OR of the CXIndexOpt_XXX flags.
+  ///
+  /// \param[out] out_TU pointer to store a \c CXTranslationUnit that can be
+  /// reused after indexing is finished. Set to \c NULL if you do not require it.
+  ///
+  /// \returns 0 on success or if there were errors from which the compiler could
+  /// recover.  If there is a failure from which there is no recovery, returns
+  /// a non-zero \c CXErrorCode.
+  ///
+  /// The rest of the parameters are the same as #clang_parseTranslationUnit.
+  int clang_indexSourceFile(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    int index_callbacks_size,
+    int index_options,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+    int TU_options,
+  ) {
+    return _clang_indexSourceFile(
+      arg0,
+      client_data,
+      index_callbacks,
+      index_callbacks_size,
+      index_options,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      unsaved_files,
+      num_unsaved_files,
+      out_TU,
+      TU_options,
+    );
+  }
+
+  late final _clang_indexSourceFilePtr =
+      _lookup<ffi.NativeFunction<NativeClang_indexSourceFile>>(
+          'clang_indexSourceFile');
+  late final _clang_indexSourceFile =
+      _clang_indexSourceFilePtr.asFunction<DartClang_indexSourceFile>();
+
+  /// Same as clang_indexSourceFile but requires a full command line
+  /// for \c command_line_args including argv[0]. This is useful if the standard
+  /// library paths are relative to the binary.
+  int clang_indexSourceFileFullArgv(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    int index_callbacks_size,
+    int index_options,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+    int TU_options,
+  ) {
+    return _clang_indexSourceFileFullArgv(
+      arg0,
+      client_data,
+      index_callbacks,
+      index_callbacks_size,
+      index_options,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      unsaved_files,
+      num_unsaved_files,
+      out_TU,
+      TU_options,
+    );
+  }
+
+  late final _clang_indexSourceFileFullArgvPtr =
+      _lookup<ffi.NativeFunction<NativeClang_indexSourceFileFullArgv>>(
+          'clang_indexSourceFileFullArgv');
+  late final _clang_indexSourceFileFullArgv = _clang_indexSourceFileFullArgvPtr
+      .asFunction<DartClang_indexSourceFileFullArgv>();
+
+  /// Index the given translation unit via callbacks implemented through
+  /// #IndexerCallbacks.
+  ///
+  /// The order of callback invocations is not guaranteed to be the same as
+  /// when indexing a source file. The high level order will be:
+  ///
+  /// -Preprocessor callbacks invocations
+  /// -Declaration/reference callbacks invocations
+  /// -Diagnostic callback invocations
+  ///
+  /// The parameters are the same as #clang_indexSourceFile.
+  ///
+  /// \returns If there is a failure from which there is no recovery, returns
+  /// non-zero, otherwise returns 0.
+  int clang_indexTranslationUnit(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    int index_callbacks_size,
+    int index_options,
+    CXTranslationUnit arg5,
+  ) {
+    return _clang_indexTranslationUnit(
+      arg0,
+      client_data,
+      index_callbacks,
+      index_callbacks_size,
+      index_options,
+      arg5,
+    );
+  }
+
+  late final _clang_indexTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<NativeClang_indexTranslationUnit>>(
+          'clang_indexTranslationUnit');
+  late final _clang_indexTranslationUnit = _clang_indexTranslationUnitPtr
+      .asFunction<DartClang_indexTranslationUnit>();
+
+  /// Retrieve the CXIdxFile, file, line, column, and offset represented by
+  /// the given CXIdxLoc.
+  ///
+  /// If the location refers into a macro expansion, retrieves the
+  /// location of the macro expansion and if it refers into a macro argument
+  /// retrieves the location of the argument.
+  void clang_indexLoc_getFileLocation(
+    CXIdxLoc loc,
+    ffi.Pointer<CXIdxClientFile> indexFile,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset,
+  ) {
+    return _clang_indexLoc_getFileLocation(
+      loc,
+      indexFile,
+      file,
+      line,
+      column,
+      offset,
+    );
+  }
+
+  late final _clang_indexLoc_getFileLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_indexLoc_getFileLocation>>(
+          'clang_indexLoc_getFileLocation');
+  late final _clang_indexLoc_getFileLocation =
+      _clang_indexLoc_getFileLocationPtr
+          .asFunction<DartClang_indexLoc_getFileLocation>();
+
+  /// Retrieve the CXSourceLocation represented by the given CXIdxLoc.
+  CXSourceLocation clang_indexLoc_getCXSourceLocation(
+    CXIdxLoc loc,
+  ) {
+    return _clang_indexLoc_getCXSourceLocation(
+      loc,
+    );
+  }
+
+  late final _clang_indexLoc_getCXSourceLocationPtr =
+      _lookup<ffi.NativeFunction<NativeClang_indexLoc_getCXSourceLocation>>(
+          'clang_indexLoc_getCXSourceLocation');
+  late final _clang_indexLoc_getCXSourceLocation =
+      _clang_indexLoc_getCXSourceLocationPtr
+          .asFunction<DartClang_indexLoc_getCXSourceLocation>();
+
+  /// Visit the fields of a particular type.
+  ///
+  /// This function visits all the direct fields of the given cursor,
+  /// invoking the given \p visitor function with the cursors of each
+  /// visited field. The traversal may be ended prematurely, if
+  /// the visitor returns \c CXFieldVisit_Break.
+  ///
+  /// \param T the record type whose field may be visited.
+  ///
+  /// \param visitor the visitor function that will be invoked for each
+  /// field of \p T.
+  ///
+  /// \param client_data pointer data supplied by the client, which will
+  /// be passed to the visitor each time it is invoked.
+  ///
+  /// \returns a non-zero value if the traversal was terminated
+  /// prematurely by the visitor returning \c CXFieldVisit_Break.
+  int clang_Type_visitFields(
+    CXType T,
+    CXFieldVisitor visitor,
+    CXClientData client_data,
+  ) {
+    return _clang_Type_visitFields(
+      T,
+      visitor,
+      client_data,
+    );
+  }
+
+  late final _clang_Type_visitFieldsPtr =
+      _lookup<ffi.NativeFunction<NativeClang_Type_visitFields>>(
+          'clang_Type_visitFields');
+  late final _clang_Type_visitFields =
+      _clang_Type_visitFieldsPtr.asFunction<DartClang_Type_visitFields>();
+
+  late final addresses = _SymbolAddresses(this);
+}
+
+class _SymbolAddresses {
+  final LibClang _library;
+  _SymbolAddresses(this._library);
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCString>>
+      get clang_getCString => _library._clang_getCStringPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeString>>
+      get clang_disposeString => _library._clang_disposeStringPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeStringSet>>
+      get clang_disposeStringSet => _library._clang_disposeStringSetPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_createIndex>>
+      get clang_createIndex => _library._clang_createIndexPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeIndex>>
+      get clang_disposeIndex => _library._clang_disposeIndexPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXIndex_setGlobalOptions>>
+      get clang_CXIndex_setGlobalOptions =>
+          _library._clang_CXIndex_setGlobalOptionsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXIndex_getGlobalOptions>>
+      get clang_CXIndex_getGlobalOptions =>
+          _library._clang_CXIndex_getGlobalOptionsPtr;
+  ffi.Pointer<
+          ffi
+          .NativeFunction<NativeClang_CXIndex_setInvocationEmissionPathOption>>
+      get clang_CXIndex_setInvocationEmissionPathOption =>
+          _library._clang_CXIndex_setInvocationEmissionPathOptionPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getFileName>>
+      get clang_getFileName => _library._clang_getFileNamePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getFileTime>>
+      get clang_getFileTime => _library._clang_getFileTimePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getFileUniqueID>>
+      get clang_getFileUniqueID => _library._clang_getFileUniqueIDPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isFileMultipleIncludeGuarded>>
+      get clang_isFileMultipleIncludeGuarded =>
+          _library._clang_isFileMultipleIncludeGuardedPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getFile>> get clang_getFile =>
+      _library._clang_getFilePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getFileContents>>
+      get clang_getFileContents => _library._clang_getFileContentsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_File_isEqual>>
+      get clang_File_isEqual => _library._clang_File_isEqualPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_File_tryGetRealPathName>>
+      get clang_File_tryGetRealPathName =>
+          _library._clang_File_tryGetRealPathNamePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getNullLocation>>
+      get clang_getNullLocation => _library._clang_getNullLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_equalLocations>>
+      get clang_equalLocations => _library._clang_equalLocationsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getLocation>>
+      get clang_getLocation => _library._clang_getLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getLocationForOffset>>
+      get clang_getLocationForOffset => _library._clang_getLocationForOffsetPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Location_isInSystemHeader>>
+      get clang_Location_isInSystemHeader =>
+          _library._clang_Location_isInSystemHeaderPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Location_isFromMainFile>>
+      get clang_Location_isFromMainFile =>
+          _library._clang_Location_isFromMainFilePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getNullRange>>
+      get clang_getNullRange => _library._clang_getNullRangePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getRange>> get clang_getRange =>
+      _library._clang_getRangePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_equalRanges>>
+      get clang_equalRanges => _library._clang_equalRangesPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Range_isNull>>
+      get clang_Range_isNull => _library._clang_Range_isNullPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getExpansionLocation>>
+      get clang_getExpansionLocation => _library._clang_getExpansionLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getPresumedLocation>>
+      get clang_getPresumedLocation => _library._clang_getPresumedLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getInstantiationLocation>>
+      get clang_getInstantiationLocation =>
+          _library._clang_getInstantiationLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getSpellingLocation>>
+      get clang_getSpellingLocation => _library._clang_getSpellingLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getFileLocation>>
+      get clang_getFileLocation => _library._clang_getFileLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getRangeStart>>
+      get clang_getRangeStart => _library._clang_getRangeStartPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getRangeEnd>>
+      get clang_getRangeEnd => _library._clang_getRangeEndPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getSkippedRanges>>
+      get clang_getSkippedRanges => _library._clang_getSkippedRangesPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getAllSkippedRanges>>
+      get clang_getAllSkippedRanges => _library._clang_getAllSkippedRangesPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeSourceRangeList>>
+      get clang_disposeSourceRangeList =>
+          _library._clang_disposeSourceRangeListPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getNumDiagnosticsInSet>>
+      get clang_getNumDiagnosticsInSet =>
+          _library._clang_getNumDiagnosticsInSetPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticInSet>>
+      get clang_getDiagnosticInSet => _library._clang_getDiagnosticInSetPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_loadDiagnostics>>
+      get clang_loadDiagnostics => _library._clang_loadDiagnosticsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeDiagnosticSet>>
+      get clang_disposeDiagnosticSet => _library._clang_disposeDiagnosticSetPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getChildDiagnostics>>
+      get clang_getChildDiagnostics => _library._clang_getChildDiagnosticsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getNumDiagnostics>>
+      get clang_getNumDiagnostics => _library._clang_getNumDiagnosticsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnostic>>
+      get clang_getDiagnostic => _library._clang_getDiagnosticPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticSetFromTU>>
+      get clang_getDiagnosticSetFromTU =>
+          _library._clang_getDiagnosticSetFromTUPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeDiagnostic>>
+      get clang_disposeDiagnostic => _library._clang_disposeDiagnosticPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_formatDiagnostic>>
+      get clang_formatDiagnostic => _library._clang_formatDiagnosticPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_defaultDiagnosticDisplayOptions>>
+      get clang_defaultDiagnosticDisplayOptions =>
+          _library._clang_defaultDiagnosticDisplayOptionsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticSeverity>>
+      get clang_getDiagnosticSeverity =>
+          _library._clang_getDiagnosticSeverityPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticLocation>>
+      get clang_getDiagnosticLocation =>
+          _library._clang_getDiagnosticLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticSpelling>>
+      get clang_getDiagnosticSpelling =>
+          _library._clang_getDiagnosticSpellingPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticOption>>
+      get clang_getDiagnosticOption => _library._clang_getDiagnosticOptionPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticCategory>>
+      get clang_getDiagnosticCategory =>
+          _library._clang_getDiagnosticCategoryPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticCategoryName>>
+      get clang_getDiagnosticCategoryName =>
+          _library._clang_getDiagnosticCategoryNamePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticCategoryText>>
+      get clang_getDiagnosticCategoryText =>
+          _library._clang_getDiagnosticCategoryTextPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticNumRanges>>
+      get clang_getDiagnosticNumRanges =>
+          _library._clang_getDiagnosticNumRangesPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticRange>>
+      get clang_getDiagnosticRange => _library._clang_getDiagnosticRangePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticNumFixIts>>
+      get clang_getDiagnosticNumFixIts =>
+          _library._clang_getDiagnosticNumFixItsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDiagnosticFixIt>>
+      get clang_getDiagnosticFixIt => _library._clang_getDiagnosticFixItPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTranslationUnitSpelling>>
+      get clang_getTranslationUnitSpelling =>
+          _library._clang_getTranslationUnitSpellingPtr;
+  ffi.Pointer<
+          ffi.NativeFunction<NativeClang_createTranslationUnitFromSourceFile>>
+      get clang_createTranslationUnitFromSourceFile =>
+          _library._clang_createTranslationUnitFromSourceFilePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_createTranslationUnit>>
+      get clang_createTranslationUnit =>
+          _library._clang_createTranslationUnitPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_createTranslationUnit2>>
+      get clang_createTranslationUnit2 =>
+          _library._clang_createTranslationUnit2Ptr;
+  ffi.Pointer<
+          ffi.NativeFunction<NativeClang_defaultEditingTranslationUnitOptions>>
+      get clang_defaultEditingTranslationUnitOptions =>
+          _library._clang_defaultEditingTranslationUnitOptionsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_parseTranslationUnit>>
+      get clang_parseTranslationUnit => _library._clang_parseTranslationUnitPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_parseTranslationUnit2>>
+      get clang_parseTranslationUnit2 =>
+          _library._clang_parseTranslationUnit2Ptr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_parseTranslationUnit2FullArgv>>
+      get clang_parseTranslationUnit2FullArgv =>
+          _library._clang_parseTranslationUnit2FullArgvPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_defaultSaveOptions>>
+      get clang_defaultSaveOptions => _library._clang_defaultSaveOptionsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_saveTranslationUnit>>
+      get clang_saveTranslationUnit => _library._clang_saveTranslationUnitPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_suspendTranslationUnit>>
+      get clang_suspendTranslationUnit =>
+          _library._clang_suspendTranslationUnitPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeTranslationUnit>>
+      get clang_disposeTranslationUnit =>
+          _library._clang_disposeTranslationUnitPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_defaultReparseOptions>>
+      get clang_defaultReparseOptions =>
+          _library._clang_defaultReparseOptionsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_reparseTranslationUnit>>
+      get clang_reparseTranslationUnit =>
+          _library._clang_reparseTranslationUnitPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTUResourceUsageName>>
+      get clang_getTUResourceUsageName =>
+          _library._clang_getTUResourceUsageNamePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCXTUResourceUsage>>
+      get clang_getCXTUResourceUsage => _library._clang_getCXTUResourceUsagePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeCXTUResourceUsage>>
+      get clang_disposeCXTUResourceUsage =>
+          _library._clang_disposeCXTUResourceUsagePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTranslationUnitTargetInfo>>
+      get clang_getTranslationUnitTargetInfo =>
+          _library._clang_getTranslationUnitTargetInfoPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_TargetInfo_dispose>>
+      get clang_TargetInfo_dispose => _library._clang_TargetInfo_disposePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_TargetInfo_getTriple>>
+      get clang_TargetInfo_getTriple => _library._clang_TargetInfo_getTriplePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_TargetInfo_getPointerWidth>>
+      get clang_TargetInfo_getPointerWidth =>
+          _library._clang_TargetInfo_getPointerWidthPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getNullCursor>>
+      get clang_getNullCursor => _library._clang_getNullCursorPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTranslationUnitCursor>>
+      get clang_getTranslationUnitCursor =>
+          _library._clang_getTranslationUnitCursorPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_equalCursors>>
+      get clang_equalCursors => _library._clang_equalCursorsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isNull>>
+      get clang_Cursor_isNull => _library._clang_Cursor_isNullPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_hashCursor>>
+      get clang_hashCursor => _library._clang_hashCursorPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorKind>>
+      get clang_getCursorKind => _library._clang_getCursorKindPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isDeclaration>>
+      get clang_isDeclaration => _library._clang_isDeclarationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isInvalidDeclaration>>
+      get clang_isInvalidDeclaration => _library._clang_isInvalidDeclarationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isReference>>
+      get clang_isReference => _library._clang_isReferencePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isExpression>>
+      get clang_isExpression => _library._clang_isExpressionPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isStatement>>
+      get clang_isStatement => _library._clang_isStatementPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isAttribute>>
+      get clang_isAttribute => _library._clang_isAttributePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_hasAttrs>>
+      get clang_Cursor_hasAttrs => _library._clang_Cursor_hasAttrsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isInvalid>> get clang_isInvalid =>
+      _library._clang_isInvalidPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isTranslationUnit>>
+      get clang_isTranslationUnit => _library._clang_isTranslationUnitPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isPreprocessing>>
+      get clang_isPreprocessing => _library._clang_isPreprocessingPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isUnexposed>>
+      get clang_isUnexposed => _library._clang_isUnexposedPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorLinkage>>
+      get clang_getCursorLinkage => _library._clang_getCursorLinkagePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorVisibility>>
+      get clang_getCursorVisibility => _library._clang_getCursorVisibilityPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorAvailability>>
+      get clang_getCursorAvailability =>
+          _library._clang_getCursorAvailabilityPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorPlatformAvailability>>
+      get clang_getCursorPlatformAvailability =>
+          _library._clang_getCursorPlatformAvailabilityPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeCXPlatformAvailability>>
+      get clang_disposeCXPlatformAvailability =>
+          _library._clang_disposeCXPlatformAvailabilityPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorLanguage>>
+      get clang_getCursorLanguage => _library._clang_getCursorLanguagePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorTLSKind>>
+      get clang_getCursorTLSKind => _library._clang_getCursorTLSKindPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getTranslationUnit>>
+      get clang_Cursor_getTranslationUnit =>
+          _library._clang_Cursor_getTranslationUnitPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_createCXCursorSet>>
+      get clang_createCXCursorSet => _library._clang_createCXCursorSetPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeCXCursorSet>>
+      get clang_disposeCXCursorSet => _library._clang_disposeCXCursorSetPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXCursorSet_contains>>
+      get clang_CXCursorSet_contains => _library._clang_CXCursorSet_containsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXCursorSet_insert>>
+      get clang_CXCursorSet_insert => _library._clang_CXCursorSet_insertPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorSemanticParent>>
+      get clang_getCursorSemanticParent =>
+          _library._clang_getCursorSemanticParentPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorLexicalParent>>
+      get clang_getCursorLexicalParent =>
+          _library._clang_getCursorLexicalParentPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getOverriddenCursors>>
+      get clang_getOverriddenCursors => _library._clang_getOverriddenCursorsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeOverriddenCursors>>
+      get clang_disposeOverriddenCursors =>
+          _library._clang_disposeOverriddenCursorsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getIncludedFile>>
+      get clang_getIncludedFile => _library._clang_getIncludedFilePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursor>> get clang_getCursor =>
+      _library._clang_getCursorPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorLocation>>
+      get clang_getCursorLocation => _library._clang_getCursorLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorExtent>>
+      get clang_getCursorExtent => _library._clang_getCursorExtentPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorType>>
+      get clang_getCursorType => _library._clang_getCursorTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTypeSpelling>>
+      get clang_getTypeSpelling => _library._clang_getTypeSpellingPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTypedefDeclUnderlyingType>>
+      get clang_getTypedefDeclUnderlyingType =>
+          _library._clang_getTypedefDeclUnderlyingTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getEnumDeclIntegerType>>
+      get clang_getEnumDeclIntegerType =>
+          _library._clang_getEnumDeclIntegerTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getEnumConstantDeclValue>>
+      get clang_getEnumConstantDeclValue =>
+          _library._clang_getEnumConstantDeclValuePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getEnumConstantDeclUnsignedValue>>
+      get clang_getEnumConstantDeclUnsignedValue =>
+          _library._clang_getEnumConstantDeclUnsignedValuePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getFieldDeclBitWidth>>
+      get clang_getFieldDeclBitWidth => _library._clang_getFieldDeclBitWidthPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getNumArguments>>
+      get clang_Cursor_getNumArguments =>
+          _library._clang_Cursor_getNumArgumentsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getArgument>>
+      get clang_Cursor_getArgument => _library._clang_Cursor_getArgumentPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getNumTemplateArguments>>
+      get clang_Cursor_getNumTemplateArguments =>
+          _library._clang_Cursor_getNumTemplateArgumentsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getTemplateArgumentKind>>
+      get clang_Cursor_getTemplateArgumentKind =>
+          _library._clang_Cursor_getTemplateArgumentKindPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getTemplateArgumentType>>
+      get clang_Cursor_getTemplateArgumentType =>
+          _library._clang_Cursor_getTemplateArgumentTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getTemplateArgumentValue>>
+      get clang_Cursor_getTemplateArgumentValue =>
+          _library._clang_Cursor_getTemplateArgumentValuePtr;
+  ffi.Pointer<
+          ffi
+          .NativeFunction<NativeClang_Cursor_getTemplateArgumentUnsignedValue>>
+      get clang_Cursor_getTemplateArgumentUnsignedValue =>
+          _library._clang_Cursor_getTemplateArgumentUnsignedValuePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_equalTypes>>
+      get clang_equalTypes => _library._clang_equalTypesPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCanonicalType>>
+      get clang_getCanonicalType => _library._clang_getCanonicalTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isConstQualifiedType>>
+      get clang_isConstQualifiedType => _library._clang_isConstQualifiedTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isMacroFunctionLike>>
+      get clang_Cursor_isMacroFunctionLike =>
+          _library._clang_Cursor_isMacroFunctionLikePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isMacroBuiltin>>
+      get clang_Cursor_isMacroBuiltin =>
+          _library._clang_Cursor_isMacroBuiltinPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isFunctionInlined>>
+      get clang_Cursor_isFunctionInlined =>
+          _library._clang_Cursor_isFunctionInlinedPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isVolatileQualifiedType>>
+      get clang_isVolatileQualifiedType =>
+          _library._clang_isVolatileQualifiedTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isRestrictQualifiedType>>
+      get clang_isRestrictQualifiedType =>
+          _library._clang_isRestrictQualifiedTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getAddressSpace>>
+      get clang_getAddressSpace => _library._clang_getAddressSpacePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTypedefName>>
+      get clang_getTypedefName => _library._clang_getTypedefNamePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getPointeeType>>
+      get clang_getPointeeType => _library._clang_getPointeeTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTypeDeclaration>>
+      get clang_getTypeDeclaration => _library._clang_getTypeDeclarationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDeclObjCTypeEncoding>>
+      get clang_getDeclObjCTypeEncoding =>
+          _library._clang_getDeclObjCTypeEncodingPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getObjCEncoding>>
+      get clang_Type_getObjCEncoding => _library._clang_Type_getObjCEncodingPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTypeKindSpelling>>
+      get clang_getTypeKindSpelling => _library._clang_getTypeKindSpellingPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getFunctionTypeCallingConv>>
+      get clang_getFunctionTypeCallingConv =>
+          _library._clang_getFunctionTypeCallingConvPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getResultType>>
+      get clang_getResultType => _library._clang_getResultTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getExceptionSpecificationType>>
+      get clang_getExceptionSpecificationType =>
+          _library._clang_getExceptionSpecificationTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getNumArgTypes>>
+      get clang_getNumArgTypes => _library._clang_getNumArgTypesPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getArgType>>
+      get clang_getArgType => _library._clang_getArgTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getObjCObjectBaseType>>
+      get clang_Type_getObjCObjectBaseType =>
+          _library._clang_Type_getObjCObjectBaseTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getNumObjCProtocolRefs>>
+      get clang_Type_getNumObjCProtocolRefs =>
+          _library._clang_Type_getNumObjCProtocolRefsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getObjCProtocolDecl>>
+      get clang_Type_getObjCProtocolDecl =>
+          _library._clang_Type_getObjCProtocolDeclPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getNumObjCTypeArgs>>
+      get clang_Type_getNumObjCTypeArgs =>
+          _library._clang_Type_getNumObjCTypeArgsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getObjCTypeArg>>
+      get clang_Type_getObjCTypeArg => _library._clang_Type_getObjCTypeArgPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isFunctionTypeVariadic>>
+      get clang_isFunctionTypeVariadic =>
+          _library._clang_isFunctionTypeVariadicPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorResultType>>
+      get clang_getCursorResultType => _library._clang_getCursorResultTypePtr;
+  ffi.Pointer<
+          ffi.NativeFunction<NativeClang_getCursorExceptionSpecificationType>>
+      get clang_getCursorExceptionSpecificationType =>
+          _library._clang_getCursorExceptionSpecificationTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isPODType>> get clang_isPODType =>
+      _library._clang_isPODTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getElementType>>
+      get clang_getElementType => _library._clang_getElementTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getNumElements>>
+      get clang_getNumElements => _library._clang_getNumElementsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getArrayElementType>>
+      get clang_getArrayElementType => _library._clang_getArrayElementTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getArraySize>>
+      get clang_getArraySize => _library._clang_getArraySizePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getNamedType>>
+      get clang_Type_getNamedType => _library._clang_Type_getNamedTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_isTransparentTagTypedef>>
+      get clang_Type_isTransparentTagTypedef =>
+          _library._clang_Type_isTransparentTagTypedefPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getNullability>>
+      get clang_Type_getNullability => _library._clang_Type_getNullabilityPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getAlignOf>>
+      get clang_Type_getAlignOf => _library._clang_Type_getAlignOfPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getClassType>>
+      get clang_Type_getClassType => _library._clang_Type_getClassTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getSizeOf>>
+      get clang_Type_getSizeOf => _library._clang_Type_getSizeOfPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getOffsetOf>>
+      get clang_Type_getOffsetOf => _library._clang_Type_getOffsetOfPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getModifiedType>>
+      get clang_Type_getModifiedType => _library._clang_Type_getModifiedTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getOffsetOfField>>
+      get clang_Cursor_getOffsetOfField =>
+          _library._clang_Cursor_getOffsetOfFieldPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isAnonymous>>
+      get clang_Cursor_isAnonymous => _library._clang_Cursor_isAnonymousPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isAnonymousRecordDecl>>
+      get clang_Cursor_isAnonymousRecordDecl =>
+          _library._clang_Cursor_isAnonymousRecordDeclPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isInlineNamespace>>
+      get clang_Cursor_isInlineNamespace =>
+          _library._clang_Cursor_isInlineNamespacePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getNumTemplateArguments>>
+      get clang_Type_getNumTemplateArguments =>
+          _library._clang_Type_getNumTemplateArgumentsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getTemplateArgumentAsType>>
+      get clang_Type_getTemplateArgumentAsType =>
+          _library._clang_Type_getTemplateArgumentAsTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_getCXXRefQualifier>>
+      get clang_Type_getCXXRefQualifier =>
+          _library._clang_Type_getCXXRefQualifierPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isBitField>>
+      get clang_Cursor_isBitField => _library._clang_Cursor_isBitFieldPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isVirtualBase>>
+      get clang_isVirtualBase => _library._clang_isVirtualBasePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCXXAccessSpecifier>>
+      get clang_getCXXAccessSpecifier =>
+          _library._clang_getCXXAccessSpecifierPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getStorageClass>>
+      get clang_Cursor_getStorageClass =>
+          _library._clang_Cursor_getStorageClassPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getNumOverloadedDecls>>
+      get clang_getNumOverloadedDecls =>
+          _library._clang_getNumOverloadedDeclsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getOverloadedDecl>>
+      get clang_getOverloadedDecl => _library._clang_getOverloadedDeclPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getIBOutletCollectionType>>
+      get clang_getIBOutletCollectionType =>
+          _library._clang_getIBOutletCollectionTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_visitChildren>>
+      get clang_visitChildren => _library._clang_visitChildrenPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorUSR>>
+      get clang_getCursorUSR => _library._clang_getCursorUSRPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_constructUSR_ObjCClass>>
+      get clang_constructUSR_ObjCClass =>
+          _library._clang_constructUSR_ObjCClassPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_constructUSR_ObjCCategory>>
+      get clang_constructUSR_ObjCCategory =>
+          _library._clang_constructUSR_ObjCCategoryPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_constructUSR_ObjCProtocol>>
+      get clang_constructUSR_ObjCProtocol =>
+          _library._clang_constructUSR_ObjCProtocolPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_constructUSR_ObjCIvar>>
+      get clang_constructUSR_ObjCIvar =>
+          _library._clang_constructUSR_ObjCIvarPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_constructUSR_ObjCMethod>>
+      get clang_constructUSR_ObjCMethod =>
+          _library._clang_constructUSR_ObjCMethodPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_constructUSR_ObjCProperty>>
+      get clang_constructUSR_ObjCProperty =>
+          _library._clang_constructUSR_ObjCPropertyPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorSpelling>>
+      get clang_getCursorSpelling => _library._clang_getCursorSpellingPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getSpellingNameRange>>
+      get clang_Cursor_getSpellingNameRange =>
+          _library._clang_Cursor_getSpellingNameRangePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_PrintingPolicy_getProperty>>
+      get clang_PrintingPolicy_getProperty =>
+          _library._clang_PrintingPolicy_getPropertyPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_PrintingPolicy_setProperty>>
+      get clang_PrintingPolicy_setProperty =>
+          _library._clang_PrintingPolicy_setPropertyPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorPrintingPolicy>>
+      get clang_getCursorPrintingPolicy =>
+          _library._clang_getCursorPrintingPolicyPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_PrintingPolicy_dispose>>
+      get clang_PrintingPolicy_dispose =>
+          _library._clang_PrintingPolicy_disposePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorPrettyPrinted>>
+      get clang_getCursorPrettyPrinted =>
+          _library._clang_getCursorPrettyPrintedPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorDisplayName>>
+      get clang_getCursorDisplayName => _library._clang_getCursorDisplayNamePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorReferenced>>
+      get clang_getCursorReferenced => _library._clang_getCursorReferencedPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorDefinition>>
+      get clang_getCursorDefinition => _library._clang_getCursorDefinitionPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_isCursorDefinition>>
+      get clang_isCursorDefinition => _library._clang_isCursorDefinitionPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCanonicalCursor>>
+      get clang_getCanonicalCursor => _library._clang_getCanonicalCursorPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getObjCSelectorIndex>>
+      get clang_Cursor_getObjCSelectorIndex =>
+          _library._clang_Cursor_getObjCSelectorIndexPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isDynamicCall>>
+      get clang_Cursor_isDynamicCall => _library._clang_Cursor_isDynamicCallPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getReceiverType>>
+      get clang_Cursor_getReceiverType =>
+          _library._clang_Cursor_getReceiverTypePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getObjCPropertyAttributes>>
+      get clang_Cursor_getObjCPropertyAttributes =>
+          _library._clang_Cursor_getObjCPropertyAttributesPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getObjCPropertyGetterName>>
+      get clang_Cursor_getObjCPropertyGetterName =>
+          _library._clang_Cursor_getObjCPropertyGetterNamePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getObjCPropertySetterName>>
+      get clang_Cursor_getObjCPropertySetterName =>
+          _library._clang_Cursor_getObjCPropertySetterNamePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getObjCDeclQualifiers>>
+      get clang_Cursor_getObjCDeclQualifiers =>
+          _library._clang_Cursor_getObjCDeclQualifiersPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isObjCOptional>>
+      get clang_Cursor_isObjCOptional =>
+          _library._clang_Cursor_isObjCOptionalPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isVariadic>>
+      get clang_Cursor_isVariadic => _library._clang_Cursor_isVariadicPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_isExternalSymbol>>
+      get clang_Cursor_isExternalSymbol =>
+          _library._clang_Cursor_isExternalSymbolPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getCommentRange>>
+      get clang_Cursor_getCommentRange =>
+          _library._clang_Cursor_getCommentRangePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getRawCommentText>>
+      get clang_Cursor_getRawCommentText =>
+          _library._clang_Cursor_getRawCommentTextPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getBriefCommentText>>
+      get clang_Cursor_getBriefCommentText =>
+          _library._clang_Cursor_getBriefCommentTextPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getMangling>>
+      get clang_Cursor_getMangling => _library._clang_Cursor_getManglingPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getCXXManglings>>
+      get clang_Cursor_getCXXManglings =>
+          _library._clang_Cursor_getCXXManglingsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getObjCManglings>>
+      get clang_Cursor_getObjCManglings =>
+          _library._clang_Cursor_getObjCManglingsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_getModule>>
+      get clang_Cursor_getModule => _library._clang_Cursor_getModulePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getModuleForFile>>
+      get clang_getModuleForFile => _library._clang_getModuleForFilePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Module_getASTFile>>
+      get clang_Module_getASTFile => _library._clang_Module_getASTFilePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Module_getParent>>
+      get clang_Module_getParent => _library._clang_Module_getParentPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Module_getName>>
+      get clang_Module_getName => _library._clang_Module_getNamePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Module_getFullName>>
+      get clang_Module_getFullName => _library._clang_Module_getFullNamePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Module_isSystem>>
+      get clang_Module_isSystem => _library._clang_Module_isSystemPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Module_getNumTopLevelHeaders>>
+      get clang_Module_getNumTopLevelHeaders =>
+          _library._clang_Module_getNumTopLevelHeadersPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Module_getTopLevelHeader>>
+      get clang_Module_getTopLevelHeader =>
+          _library._clang_Module_getTopLevelHeaderPtr;
+  ffi.Pointer<
+          ffi
+          .NativeFunction<NativeClang_CXXConstructor_isConvertingConstructor>>
+      get clang_CXXConstructor_isConvertingConstructor =>
+          _library._clang_CXXConstructor_isConvertingConstructorPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXXConstructor_isCopyConstructor>>
+      get clang_CXXConstructor_isCopyConstructor =>
+          _library._clang_CXXConstructor_isCopyConstructorPtr;
+  ffi.Pointer<
+          ffi.NativeFunction<NativeClang_CXXConstructor_isDefaultConstructor>>
+      get clang_CXXConstructor_isDefaultConstructor =>
+          _library._clang_CXXConstructor_isDefaultConstructorPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXXConstructor_isMoveConstructor>>
+      get clang_CXXConstructor_isMoveConstructor =>
+          _library._clang_CXXConstructor_isMoveConstructorPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXXField_isMutable>>
+      get clang_CXXField_isMutable => _library._clang_CXXField_isMutablePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXXMethod_isDefaulted>>
+      get clang_CXXMethod_isDefaulted =>
+          _library._clang_CXXMethod_isDefaultedPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXXMethod_isPureVirtual>>
+      get clang_CXXMethod_isPureVirtual =>
+          _library._clang_CXXMethod_isPureVirtualPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXXMethod_isStatic>>
+      get clang_CXXMethod_isStatic => _library._clang_CXXMethod_isStaticPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXXMethod_isVirtual>>
+      get clang_CXXMethod_isVirtual => _library._clang_CXXMethod_isVirtualPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXXRecord_isAbstract>>
+      get clang_CXXRecord_isAbstract => _library._clang_CXXRecord_isAbstractPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_EnumDecl_isScoped>>
+      get clang_EnumDecl_isScoped => _library._clang_EnumDecl_isScopedPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_CXXMethod_isConst>>
+      get clang_CXXMethod_isConst => _library._clang_CXXMethod_isConstPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTemplateCursorKind>>
+      get clang_getTemplateCursorKind =>
+          _library._clang_getTemplateCursorKindPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getSpecializedCursorTemplate>>
+      get clang_getSpecializedCursorTemplate =>
+          _library._clang_getSpecializedCursorTemplatePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorReferenceNameRange>>
+      get clang_getCursorReferenceNameRange =>
+          _library._clang_getCursorReferenceNameRangePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getToken>> get clang_getToken =>
+      _library._clang_getTokenPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTokenKind>>
+      get clang_getTokenKind => _library._clang_getTokenKindPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTokenSpelling>>
+      get clang_getTokenSpelling => _library._clang_getTokenSpellingPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTokenLocation>>
+      get clang_getTokenLocation => _library._clang_getTokenLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getTokenExtent>>
+      get clang_getTokenExtent => _library._clang_getTokenExtentPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_tokenize>> get clang_tokenize =>
+      _library._clang_tokenizePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_annotateTokens>>
+      get clang_annotateTokens => _library._clang_annotateTokensPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeTokens>>
+      get clang_disposeTokens => _library._clang_disposeTokensPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorKindSpelling>>
+      get clang_getCursorKindSpelling =>
+          _library._clang_getCursorKindSpellingPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getDefinitionSpellingAndExtent>>
+      get clang_getDefinitionSpellingAndExtent =>
+          _library._clang_getDefinitionSpellingAndExtentPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_enableStackTraces>>
+      get clang_enableStackTraces => _library._clang_enableStackTracesPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_executeOnThread>>
+      get clang_executeOnThread => _library._clang_executeOnThreadPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCompletionChunkKind>>
+      get clang_getCompletionChunkKind =>
+          _library._clang_getCompletionChunkKindPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCompletionChunkText>>
+      get clang_getCompletionChunkText =>
+          _library._clang_getCompletionChunkTextPtr;
+  ffi.Pointer<
+          ffi.NativeFunction<NativeClang_getCompletionChunkCompletionString>>
+      get clang_getCompletionChunkCompletionString =>
+          _library._clang_getCompletionChunkCompletionStringPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getNumCompletionChunks>>
+      get clang_getNumCompletionChunks =>
+          _library._clang_getNumCompletionChunksPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCompletionPriority>>
+      get clang_getCompletionPriority =>
+          _library._clang_getCompletionPriorityPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCompletionAvailability>>
+      get clang_getCompletionAvailability =>
+          _library._clang_getCompletionAvailabilityPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCompletionNumAnnotations>>
+      get clang_getCompletionNumAnnotations =>
+          _library._clang_getCompletionNumAnnotationsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCompletionAnnotation>>
+      get clang_getCompletionAnnotation =>
+          _library._clang_getCompletionAnnotationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCompletionParent>>
+      get clang_getCompletionParent => _library._clang_getCompletionParentPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCompletionBriefComment>>
+      get clang_getCompletionBriefComment =>
+          _library._clang_getCompletionBriefCommentPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCursorCompletionString>>
+      get clang_getCursorCompletionString =>
+          _library._clang_getCursorCompletionStringPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCompletionNumFixIts>>
+      get clang_getCompletionNumFixIts =>
+          _library._clang_getCompletionNumFixItsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getCompletionFixIt>>
+      get clang_getCompletionFixIt => _library._clang_getCompletionFixItPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_defaultCodeCompleteOptions>>
+      get clang_defaultCodeCompleteOptions =>
+          _library._clang_defaultCodeCompleteOptionsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_codeCompleteAt>>
+      get clang_codeCompleteAt => _library._clang_codeCompleteAtPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_sortCodeCompletionResults>>
+      get clang_sortCodeCompletionResults =>
+          _library._clang_sortCodeCompletionResultsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_disposeCodeCompleteResults>>
+      get clang_disposeCodeCompleteResults =>
+          _library._clang_disposeCodeCompleteResultsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_codeCompleteGetNumDiagnostics>>
+      get clang_codeCompleteGetNumDiagnostics =>
+          _library._clang_codeCompleteGetNumDiagnosticsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_codeCompleteGetDiagnostic>>
+      get clang_codeCompleteGetDiagnostic =>
+          _library._clang_codeCompleteGetDiagnosticPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_codeCompleteGetContexts>>
+      get clang_codeCompleteGetContexts =>
+          _library._clang_codeCompleteGetContextsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_codeCompleteGetContainerKind>>
+      get clang_codeCompleteGetContainerKind =>
+          _library._clang_codeCompleteGetContainerKindPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_codeCompleteGetContainerUSR>>
+      get clang_codeCompleteGetContainerUSR =>
+          _library._clang_codeCompleteGetContainerUSRPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_codeCompleteGetObjCSelector>>
+      get clang_codeCompleteGetObjCSelector =>
+          _library._clang_codeCompleteGetObjCSelectorPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getClangVersion>>
+      get clang_getClangVersion => _library._clang_getClangVersionPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_toggleCrashRecovery>>
+      get clang_toggleCrashRecovery => _library._clang_toggleCrashRecoveryPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getInclusions>>
+      get clang_getInclusions => _library._clang_getInclusionsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Cursor_Evaluate>>
+      get clang_Cursor_Evaluate => _library._clang_Cursor_EvaluatePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_EvalResult_getKind>>
+      get clang_EvalResult_getKind => _library._clang_EvalResult_getKindPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_EvalResult_getAsInt>>
+      get clang_EvalResult_getAsInt => _library._clang_EvalResult_getAsIntPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_EvalResult_getAsLongLong>>
+      get clang_EvalResult_getAsLongLong =>
+          _library._clang_EvalResult_getAsLongLongPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_EvalResult_isUnsignedInt>>
+      get clang_EvalResult_isUnsignedInt =>
+          _library._clang_EvalResult_isUnsignedIntPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_EvalResult_getAsUnsigned>>
+      get clang_EvalResult_getAsUnsigned =>
+          _library._clang_EvalResult_getAsUnsignedPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_EvalResult_getAsDouble>>
+      get clang_EvalResult_getAsDouble =>
+          _library._clang_EvalResult_getAsDoublePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_EvalResult_getAsStr>>
+      get clang_EvalResult_getAsStr => _library._clang_EvalResult_getAsStrPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_EvalResult_dispose>>
+      get clang_EvalResult_dispose => _library._clang_EvalResult_disposePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getRemappings>>
+      get clang_getRemappings => _library._clang_getRemappingsPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_getRemappingsFromFileList>>
+      get clang_getRemappingsFromFileList =>
+          _library._clang_getRemappingsFromFileListPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_remap_getNumFiles>>
+      get clang_remap_getNumFiles => _library._clang_remap_getNumFilesPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_remap_getFilenames>>
+      get clang_remap_getFilenames => _library._clang_remap_getFilenamesPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_remap_dispose>>
+      get clang_remap_dispose => _library._clang_remap_disposePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_findReferencesInFile>>
+      get clang_findReferencesInFile => _library._clang_findReferencesInFilePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_findIncludesInFile>>
+      get clang_findIncludesInFile => _library._clang_findIncludesInFilePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_index_isEntityObjCContainerKind>>
+      get clang_index_isEntityObjCContainerKind =>
+          _library._clang_index_isEntityObjCContainerKindPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_index_getObjCContainerDeclInfo>>
+      get clang_index_getObjCContainerDeclInfo =>
+          _library._clang_index_getObjCContainerDeclInfoPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_index_getObjCInterfaceDeclInfo>>
+      get clang_index_getObjCInterfaceDeclInfo =>
+          _library._clang_index_getObjCInterfaceDeclInfoPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_index_getObjCCategoryDeclInfo>>
+      get clang_index_getObjCCategoryDeclInfo =>
+          _library._clang_index_getObjCCategoryDeclInfoPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_index_getObjCProtocolRefListInfo>>
+      get clang_index_getObjCProtocolRefListInfo =>
+          _library._clang_index_getObjCProtocolRefListInfoPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_index_getObjCPropertyDeclInfo>>
+      get clang_index_getObjCPropertyDeclInfo =>
+          _library._clang_index_getObjCPropertyDeclInfoPtr;
+  ffi.Pointer<
+          ffi.NativeFunction<NativeClang_index_getIBOutletCollectionAttrInfo>>
+      get clang_index_getIBOutletCollectionAttrInfo =>
+          _library._clang_index_getIBOutletCollectionAttrInfoPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_index_getCXXClassDeclInfo>>
+      get clang_index_getCXXClassDeclInfo =>
+          _library._clang_index_getCXXClassDeclInfoPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_index_getClientContainer>>
+      get clang_index_getClientContainer =>
+          _library._clang_index_getClientContainerPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_index_setClientContainer>>
+      get clang_index_setClientContainer =>
+          _library._clang_index_setClientContainerPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_index_getClientEntity>>
+      get clang_index_getClientEntity =>
+          _library._clang_index_getClientEntityPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_index_setClientEntity>>
+      get clang_index_setClientEntity =>
+          _library._clang_index_setClientEntityPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_IndexAction_create>>
+      get clang_IndexAction_create => _library._clang_IndexAction_createPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_IndexAction_dispose>>
+      get clang_IndexAction_dispose => _library._clang_IndexAction_disposePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_indexSourceFile>>
+      get clang_indexSourceFile => _library._clang_indexSourceFilePtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_indexSourceFileFullArgv>>
+      get clang_indexSourceFileFullArgv =>
+          _library._clang_indexSourceFileFullArgvPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_indexTranslationUnit>>
+      get clang_indexTranslationUnit => _library._clang_indexTranslationUnitPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_indexLoc_getFileLocation>>
+      get clang_indexLoc_getFileLocation =>
+          _library._clang_indexLoc_getFileLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_indexLoc_getCXSourceLocation>>
+      get clang_indexLoc_getCXSourceLocation =>
+          _library._clang_indexLoc_getCXSourceLocationPtr;
+  ffi.Pointer<ffi.NativeFunction<NativeClang_Type_visitFields>>
+      get clang_Type_visitFields => _library._clang_Type_visitFieldsPtr;
+}
+
+/// A character string.
+///
+/// The \c CXString type is used to return strings from the interface when
+/// the ownership of that string might differ from one call to the next.
+/// Use \c clang_getCString() to retrieve the string data and, once finished
+/// with the string data, call \c clang_disposeString() to free the string.
+final class CXString extends ffi.Struct {
+  external ffi.Pointer<ffi.Void> data;
+
+  @ffi.UnsignedInt()
+  external int private_flags;
+}
+
+final class CXStringSet extends ffi.Struct {
+  external ffi.Pointer<CXString> Strings;
+
+  @ffi.UnsignedInt()
+  external int Count;
+}
+
+typedef NativeClang_getCString = ffi.Pointer<ffi.Char> Function(
+    CXString string);
+typedef DartClang_getCString = ffi.Pointer<ffi.Char> Function(CXString string);
+typedef NativeClang_disposeString = ffi.Void Function(CXString string);
+typedef DartClang_disposeString = void Function(CXString string);
+typedef NativeClang_disposeStringSet = ffi.Void Function(
+    ffi.Pointer<CXStringSet> set1);
+typedef DartClang_disposeStringSet = void Function(
+    ffi.Pointer<CXStringSet> set1);
+
+final class CXTargetInfoImpl extends ffi.Opaque {}
+
+final class CXTranslationUnitImpl extends ffi.Opaque {}
+
+/// Provides the contents of a file that has not yet been saved to disk.
+///
+/// Each CXUnsavedFile instance provides the name of a file on the
+/// system along with the current contents of that file that have not
+/// yet been saved to disk.
+final class CXUnsavedFile extends ffi.Struct {
+  /// The file whose contents have not yet been saved.
+  ///
+  /// This file must already exist in the file system.
+  external ffi.Pointer<ffi.Char> Filename;
+
+  /// A buffer containing the unsaved contents of this file.
+  external ffi.Pointer<ffi.Char> Contents;
+
+  /// The length of the unsaved contents of this buffer.
+  @ffi.UnsignedLong()
+  external int Length;
+}
+
+/// Describes a version number of the form major.minor.subminor.
+final class CXVersion extends ffi.Struct {
+  /// The major version number, e.g., the '10' in '10.7.3'. A negative
+  /// value indicates that there is no version number at all.
+  @ffi.Int()
+  external int Major;
+
+  /// The minor version number, e.g., the '7' in '10.7.3'. This value
+  /// will be negative if no minor version number was provided, e.g., for
+  /// version '10'.
+  @ffi.Int()
+  external int Minor;
+
+  /// The subminor version number, e.g., the '3' in '10.7.3'. This value
+  /// will be negative if no minor or subminor version number was provided,
+  /// e.g., in version '10' or '10.7'.
+  @ffi.Int()
+  external int Subminor;
+}
+
+/// An "index" that consists of a set of translation units that would
+/// typically be linked together into an executable or library.
+typedef CXIndex = ffi.Pointer<ffi.Void>;
+typedef NativeClang_createIndex = CXIndex Function(
+    ffi.Int excludeDeclarationsFromPCH, ffi.Int displayDiagnostics);
+typedef DartClang_createIndex = CXIndex Function(
+    int excludeDeclarationsFromPCH, int displayDiagnostics);
+typedef NativeClang_disposeIndex = ffi.Void Function(CXIndex index);
+typedef DartClang_disposeIndex = void Function(CXIndex index);
+
+abstract class CXGlobalOptFlags {
+  /// Used to indicate that no special CXIndex options are needed.
+  static const int CXGlobalOpt_None = 0;
+
+  /// Used to indicate that threads that libclang creates for indexing
+  /// purposes should use background priority.
+  ///
+  /// Affects #clang_indexSourceFile, #clang_indexTranslationUnit,
+  /// #clang_parseTranslationUnit, #clang_saveTranslationUnit.
+  static const int CXGlobalOpt_ThreadBackgroundPriorityForIndexing = 1;
+
+  /// Used to indicate that threads that libclang creates for editing
+  /// purposes should use background priority.
+  ///
+  /// Affects #clang_reparseTranslationUnit, #clang_codeCompleteAt,
+  /// #clang_annotateTokens
+  static const int CXGlobalOpt_ThreadBackgroundPriorityForEditing = 2;
+
+  /// Used to indicate that all threads that libclang creates should use
+  /// background priority.
+  static const int CXGlobalOpt_ThreadBackgroundPriorityForAll = 3;
+}
+
+typedef NativeClang_CXIndex_setGlobalOptions = ffi.Void Function(
+    CXIndex arg0, ffi.UnsignedInt options);
+typedef DartClang_CXIndex_setGlobalOptions = void Function(
+    CXIndex arg0, int options);
+typedef NativeClang_CXIndex_getGlobalOptions = ffi.UnsignedInt Function(
+    CXIndex arg0);
+typedef DartClang_CXIndex_getGlobalOptions = int Function(CXIndex arg0);
+typedef NativeClang_CXIndex_setInvocationEmissionPathOption = ffi.Void Function(
+    CXIndex arg0, ffi.Pointer<ffi.Char> Path);
+typedef DartClang_CXIndex_setInvocationEmissionPathOption = void Function(
+    CXIndex arg0, ffi.Pointer<ffi.Char> Path);
+
+/// A particular source file that is part of a translation unit.
+typedef CXFile = ffi.Pointer<ffi.Void>;
+typedef NativeClang_getFileName = CXString Function(CXFile SFile);
+typedef DartClang_getFileName = CXString Function(CXFile SFile);
+typedef NativeClang_getFileTime = ffi.Int64 Function(CXFile SFile);
+typedef DartClang_getFileTime = int Function(CXFile SFile);
+
+/// Uniquely identifies a CXFile, that refers to the same underlying file,
+/// across an indexing session.
+final class CXFileUniqueID extends ffi.Struct {
+  @ffi.Array.multi([3])
+  external ffi.Array<ffi.UnsignedLongLong> data;
+}
+
+typedef NativeClang_getFileUniqueID = ffi.Int Function(
+    CXFile file, ffi.Pointer<CXFileUniqueID> outID);
+typedef DartClang_getFileUniqueID = int Function(
+    CXFile file, ffi.Pointer<CXFileUniqueID> outID);
+
+/// A single translation unit, which resides in an index.
+typedef CXTranslationUnit = ffi.Pointer<CXTranslationUnitImpl>;
+typedef NativeClang_isFileMultipleIncludeGuarded = ffi.UnsignedInt Function(
+    CXTranslationUnit tu, CXFile file);
+typedef DartClang_isFileMultipleIncludeGuarded = int Function(
+    CXTranslationUnit tu, CXFile file);
+typedef NativeClang_getFile = CXFile Function(
+    CXTranslationUnit tu, ffi.Pointer<ffi.Char> file_name);
+typedef DartClang_getFile = CXFile Function(
+    CXTranslationUnit tu, ffi.Pointer<ffi.Char> file_name);
+typedef NativeClang_getFileContents = ffi.Pointer<ffi.Char> Function(
+    CXTranslationUnit tu, CXFile file, ffi.Pointer<ffi.Size> size);
+typedef DartClang_getFileContents = ffi.Pointer<ffi.Char> Function(
+    CXTranslationUnit tu, CXFile file, ffi.Pointer<ffi.Size> size);
+typedef NativeClang_File_isEqual = ffi.Int Function(CXFile file1, CXFile file2);
+typedef DartClang_File_isEqual = int Function(CXFile file1, CXFile file2);
+typedef NativeClang_File_tryGetRealPathName = CXString Function(CXFile file);
+typedef DartClang_File_tryGetRealPathName = CXString Function(CXFile file);
+
+/// Identifies a specific source location within a translation
+/// unit.
+///
+/// Use clang_getExpansionLocation() or clang_getSpellingLocation()
+/// to map a source location to a particular file, line, and column.
+final class CXSourceLocation extends ffi.Struct {
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
+
+  @ffi.UnsignedInt()
+  external int int_data;
+}
+
+/// Identifies a half-open character range in the source code.
+///
+/// Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
+/// starting and end locations from a source range, respectively.
+final class CXSourceRange extends ffi.Struct {
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
+
+  @ffi.UnsignedInt()
+  external int begin_int_data;
+
+  @ffi.UnsignedInt()
+  external int end_int_data;
+}
+
+typedef NativeClang_getNullLocation = CXSourceLocation Function();
+typedef DartClang_getNullLocation = CXSourceLocation Function();
+typedef NativeClang_equalLocations = ffi.UnsignedInt Function(
+    CXSourceLocation loc1, CXSourceLocation loc2);
+typedef DartClang_equalLocations = int Function(
+    CXSourceLocation loc1, CXSourceLocation loc2);
+typedef NativeClang_getLocation = CXSourceLocation Function(
+    CXTranslationUnit tu,
+    CXFile file,
+    ffi.UnsignedInt line,
+    ffi.UnsignedInt column);
+typedef DartClang_getLocation = CXSourceLocation Function(
+    CXTranslationUnit tu, CXFile file, int line, int column);
+typedef NativeClang_getLocationForOffset = CXSourceLocation Function(
+    CXTranslationUnit tu, CXFile file, ffi.UnsignedInt offset);
+typedef DartClang_getLocationForOffset = CXSourceLocation Function(
+    CXTranslationUnit tu, CXFile file, int offset);
+typedef NativeClang_Location_isInSystemHeader = ffi.Int Function(
+    CXSourceLocation location);
+typedef DartClang_Location_isInSystemHeader = int Function(
+    CXSourceLocation location);
+typedef NativeClang_Location_isFromMainFile = ffi.Int Function(
+    CXSourceLocation location);
+typedef DartClang_Location_isFromMainFile = int Function(
+    CXSourceLocation location);
+typedef NativeClang_getNullRange = CXSourceRange Function();
+typedef DartClang_getNullRange = CXSourceRange Function();
+typedef NativeClang_getRange = CXSourceRange Function(
+    CXSourceLocation begin, CXSourceLocation end);
+typedef DartClang_getRange = CXSourceRange Function(
+    CXSourceLocation begin, CXSourceLocation end);
+typedef NativeClang_equalRanges = ffi.UnsignedInt Function(
+    CXSourceRange range1, CXSourceRange range2);
+typedef DartClang_equalRanges = int Function(
+    CXSourceRange range1, CXSourceRange range2);
+typedef NativeClang_Range_isNull = ffi.Int Function(CXSourceRange range);
+typedef DartClang_Range_isNull = int Function(CXSourceRange range);
+typedef NativeClang_getExpansionLocation = ffi.Void Function(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset);
+typedef DartClang_getExpansionLocation = void Function(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset);
+typedef NativeClang_getPresumedLocation = ffi.Void Function(
+    CXSourceLocation location,
+    ffi.Pointer<CXString> filename,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column);
+typedef DartClang_getPresumedLocation = void Function(
+    CXSourceLocation location,
+    ffi.Pointer<CXString> filename,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column);
+typedef NativeClang_getInstantiationLocation = ffi.Void Function(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset);
+typedef DartClang_getInstantiationLocation = void Function(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset);
+typedef NativeClang_getSpellingLocation = ffi.Void Function(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset);
+typedef DartClang_getSpellingLocation = void Function(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset);
+typedef NativeClang_getFileLocation = ffi.Void Function(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset);
+typedef DartClang_getFileLocation = void Function(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset);
+typedef NativeClang_getRangeStart = CXSourceLocation Function(
+    CXSourceRange range);
+typedef DartClang_getRangeStart = CXSourceLocation Function(
+    CXSourceRange range);
+typedef NativeClang_getRangeEnd = CXSourceLocation Function(
+    CXSourceRange range);
+typedef DartClang_getRangeEnd = CXSourceLocation Function(CXSourceRange range);
+
+/// Identifies an array of ranges.
+final class CXSourceRangeList extends ffi.Struct {
+  /// The number of ranges in the \c ranges array.
+  @ffi.UnsignedInt()
+  external int count;
+
+  /// An array of \c CXSourceRanges.
+  external ffi.Pointer<CXSourceRange> ranges;
+}
+
+typedef NativeClang_getSkippedRanges = ffi.Pointer<CXSourceRangeList> Function(
+    CXTranslationUnit tu, CXFile file);
+typedef DartClang_getSkippedRanges = ffi.Pointer<CXSourceRangeList> Function(
+    CXTranslationUnit tu, CXFile file);
+typedef NativeClang_getAllSkippedRanges = ffi.Pointer<CXSourceRangeList>
+    Function(CXTranslationUnit tu);
+typedef DartClang_getAllSkippedRanges = ffi.Pointer<CXSourceRangeList> Function(
+    CXTranslationUnit tu);
+typedef NativeClang_disposeSourceRangeList = ffi.Void Function(
+    ffi.Pointer<CXSourceRangeList> ranges);
+typedef DartClang_disposeSourceRangeList = void Function(
+    ffi.Pointer<CXSourceRangeList> ranges);
+
+/// A group of CXDiagnostics.
+typedef CXDiagnosticSet = ffi.Pointer<ffi.Void>;
+typedef NativeClang_getNumDiagnosticsInSet = ffi.UnsignedInt Function(
+    CXDiagnosticSet Diags);
+typedef DartClang_getNumDiagnosticsInSet = int Function(CXDiagnosticSet Diags);
+
+/// A single diagnostic, containing the diagnostic's severity,
+/// location, text, source ranges, and fix-it hints.
+typedef CXDiagnostic = ffi.Pointer<ffi.Void>;
+typedef NativeClang_getDiagnosticInSet = CXDiagnostic Function(
+    CXDiagnosticSet Diags, ffi.UnsignedInt Index);
+typedef DartClang_getDiagnosticInSet = CXDiagnostic Function(
+    CXDiagnosticSet Diags, int Index);
+
+/// Describes the kind of error that occurred (if any) in a call to
+/// \c clang_loadDiagnostics.
+abstract class CXLoadDiag_Error {
+  /// Indicates that no error occurred.
+  static const int CXLoadDiag_None = 0;
+
+  /// Indicates that an unknown error occurred while attempting to
+  /// deserialize diagnostics.
+  static const int CXLoadDiag_Unknown = 1;
+
+  /// Indicates that the file containing the serialized diagnostics
+  /// could not be opened.
+  static const int CXLoadDiag_CannotLoad = 2;
+
+  /// Indicates that the serialized diagnostics file is invalid or
+  /// corrupt.
+  static const int CXLoadDiag_InvalidFile = 3;
+}
+
+typedef NativeClang_loadDiagnostics = CXDiagnosticSet Function(
+    ffi.Pointer<ffi.Char> file,
+    ffi.Pointer<ffi.Int32> error,
+    ffi.Pointer<CXString> errorString);
+typedef DartClang_loadDiagnostics = CXDiagnosticSet Function(
+    ffi.Pointer<ffi.Char> file,
+    ffi.Pointer<ffi.Int32> error,
+    ffi.Pointer<CXString> errorString);
+typedef NativeClang_disposeDiagnosticSet = ffi.Void Function(
+    CXDiagnosticSet Diags);
+typedef DartClang_disposeDiagnosticSet = void Function(CXDiagnosticSet Diags);
+typedef NativeClang_getChildDiagnostics = CXDiagnosticSet Function(
+    CXDiagnostic D);
+typedef DartClang_getChildDiagnostics = CXDiagnosticSet Function(
+    CXDiagnostic D);
+typedef NativeClang_getNumDiagnostics = ffi.UnsignedInt Function(
+    CXTranslationUnit Unit);
+typedef DartClang_getNumDiagnostics = int Function(CXTranslationUnit Unit);
+typedef NativeClang_getDiagnostic = CXDiagnostic Function(
+    CXTranslationUnit Unit, ffi.UnsignedInt Index);
+typedef DartClang_getDiagnostic = CXDiagnostic Function(
+    CXTranslationUnit Unit, int Index);
+typedef NativeClang_getDiagnosticSetFromTU = CXDiagnosticSet Function(
+    CXTranslationUnit Unit);
+typedef DartClang_getDiagnosticSetFromTU = CXDiagnosticSet Function(
+    CXTranslationUnit Unit);
+typedef NativeClang_disposeDiagnostic = ffi.Void Function(
+    CXDiagnostic Diagnostic);
+typedef DartClang_disposeDiagnostic = void Function(CXDiagnostic Diagnostic);
+typedef NativeClang_formatDiagnostic = CXString Function(
+    CXDiagnostic Diagnostic, ffi.UnsignedInt Options);
+typedef DartClang_formatDiagnostic = CXString Function(
+    CXDiagnostic Diagnostic, int Options);
+typedef NativeClang_defaultDiagnosticDisplayOptions = ffi.UnsignedInt
+    Function();
+typedef DartClang_defaultDiagnosticDisplayOptions = int Function();
+
+/// Describes the severity of a particular diagnostic.
+abstract class CXDiagnosticSeverity {
+  /// A diagnostic that has been suppressed, e.g., by a command-line
+  /// option.
+  static const int CXDiagnostic_Ignored = 0;
+
+  /// This diagnostic is a note that should be attached to the
+  /// previous (non-note) diagnostic.
+  static const int CXDiagnostic_Note = 1;
+
+  /// This diagnostic indicates suspicious code that may not be
+  /// wrong.
+  static const int CXDiagnostic_Warning = 2;
+
+  /// This diagnostic indicates that the code is ill-formed.
+  static const int CXDiagnostic_Error = 3;
+
+  /// This diagnostic indicates that the code is ill-formed such
+  /// that future parser recovery is unlikely to produce useful
+  /// results.
+  static const int CXDiagnostic_Fatal = 4;
+}
+
+typedef NativeClang_getDiagnosticSeverity = ffi.Int32 Function(
+    CXDiagnostic arg0);
+typedef DartClang_getDiagnosticSeverity = int Function(CXDiagnostic arg0);
+typedef NativeClang_getDiagnosticLocation = CXSourceLocation Function(
+    CXDiagnostic arg0);
+typedef DartClang_getDiagnosticLocation = CXSourceLocation Function(
+    CXDiagnostic arg0);
+typedef NativeClang_getDiagnosticSpelling = CXString Function(
+    CXDiagnostic arg0);
+typedef DartClang_getDiagnosticSpelling = CXString Function(CXDiagnostic arg0);
+typedef NativeClang_getDiagnosticOption = CXString Function(
+    CXDiagnostic Diag, ffi.Pointer<CXString> Disable);
+typedef DartClang_getDiagnosticOption = CXString Function(
+    CXDiagnostic Diag, ffi.Pointer<CXString> Disable);
+typedef NativeClang_getDiagnosticCategory = ffi.UnsignedInt Function(
+    CXDiagnostic arg0);
+typedef DartClang_getDiagnosticCategory = int Function(CXDiagnostic arg0);
+typedef NativeClang_getDiagnosticCategoryName = CXString Function(
+    ffi.UnsignedInt Category);
+typedef DartClang_getDiagnosticCategoryName = CXString Function(int Category);
+typedef NativeClang_getDiagnosticCategoryText = CXString Function(
+    CXDiagnostic arg0);
+typedef DartClang_getDiagnosticCategoryText = CXString Function(
+    CXDiagnostic arg0);
+typedef NativeClang_getDiagnosticNumRanges = ffi.UnsignedInt Function(
+    CXDiagnostic arg0);
+typedef DartClang_getDiagnosticNumRanges = int Function(CXDiagnostic arg0);
+typedef NativeClang_getDiagnosticRange = CXSourceRange Function(
+    CXDiagnostic Diagnostic, ffi.UnsignedInt Range);
+typedef DartClang_getDiagnosticRange = CXSourceRange Function(
+    CXDiagnostic Diagnostic, int Range);
+typedef NativeClang_getDiagnosticNumFixIts = ffi.UnsignedInt Function(
+    CXDiagnostic Diagnostic);
+typedef DartClang_getDiagnosticNumFixIts = int Function(
+    CXDiagnostic Diagnostic);
+typedef NativeClang_getDiagnosticFixIt = CXString Function(
+    CXDiagnostic Diagnostic,
+    ffi.UnsignedInt FixIt,
+    ffi.Pointer<CXSourceRange> ReplacementRange);
+typedef DartClang_getDiagnosticFixIt = CXString Function(
+    CXDiagnostic Diagnostic,
+    int FixIt,
+    ffi.Pointer<CXSourceRange> ReplacementRange);
+typedef NativeClang_getTranslationUnitSpelling = CXString Function(
+    CXTranslationUnit CTUnit);
+typedef DartClang_getTranslationUnitSpelling = CXString Function(
+    CXTranslationUnit CTUnit);
+typedef NativeClang_createTranslationUnitFromSourceFile
+    = CXTranslationUnit Function(
+        CXIndex CIdx,
+        ffi.Pointer<ffi.Char> source_filename,
+        ffi.Int num_clang_command_line_args,
+        ffi.Pointer<ffi.Pointer<ffi.Char>> clang_command_line_args,
+        ffi.UnsignedInt num_unsaved_files,
+        ffi.Pointer<CXUnsavedFile> unsaved_files);
+typedef DartClang_createTranslationUnitFromSourceFile
+    = CXTranslationUnit Function(
+        CXIndex CIdx,
+        ffi.Pointer<ffi.Char> source_filename,
+        int num_clang_command_line_args,
+        ffi.Pointer<ffi.Pointer<ffi.Char>> clang_command_line_args,
+        int num_unsaved_files,
+        ffi.Pointer<CXUnsavedFile> unsaved_files);
+typedef NativeClang_createTranslationUnit = CXTranslationUnit Function(
+    CXIndex CIdx, ffi.Pointer<ffi.Char> ast_filename);
+typedef DartClang_createTranslationUnit = CXTranslationUnit Function(
+    CXIndex CIdx, ffi.Pointer<ffi.Char> ast_filename);
+
+/// Error codes returned by libclang routines.
+///
+/// Zero (\c CXError_Success) is the only error code indicating success.  Other
+/// error codes, including not yet assigned non-zero values, indicate errors.
+abstract class CXErrorCode {
+  /// No error.
+  static const int CXError_Success = 0;
+
+  /// A generic error code, no further details are available.
+  ///
+  /// Errors of this kind can get their own specific error codes in future
+  /// libclang versions.
+  static const int CXError_Failure = 1;
+
+  /// libclang crashed while performing the requested operation.
+  static const int CXError_Crashed = 2;
+
+  /// The function detected that the arguments violate the function
+  /// contract.
+  static const int CXError_InvalidArguments = 3;
+
+  /// An AST deserialization error has occurred.
+  static const int CXError_ASTReadError = 4;
+}
+
+typedef NativeClang_createTranslationUnit2 = ffi.Int32 Function(CXIndex CIdx,
+    ffi.Pointer<ffi.Char> ast_filename, ffi.Pointer<CXTranslationUnit> out_TU);
+typedef DartClang_createTranslationUnit2 = int Function(CXIndex CIdx,
+    ffi.Pointer<ffi.Char> ast_filename, ffi.Pointer<CXTranslationUnit> out_TU);
+typedef NativeClang_defaultEditingTranslationUnitOptions = ffi.UnsignedInt
+    Function();
+typedef DartClang_defaultEditingTranslationUnitOptions = int Function();
+typedef NativeClang_parseTranslationUnit = CXTranslationUnit Function(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    ffi.Int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    ffi.UnsignedInt num_unsaved_files,
+    ffi.UnsignedInt options);
+typedef DartClang_parseTranslationUnit = CXTranslationUnit Function(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options);
+typedef NativeClang_parseTranslationUnit2 = ffi.Int32 Function(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    ffi.Int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    ffi.UnsignedInt num_unsaved_files,
+    ffi.UnsignedInt options,
+    ffi.Pointer<CXTranslationUnit> out_TU);
+typedef DartClang_parseTranslationUnit2 = int Function(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options,
+    ffi.Pointer<CXTranslationUnit> out_TU);
+typedef NativeClang_parseTranslationUnit2FullArgv = ffi.Int32 Function(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    ffi.Int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    ffi.UnsignedInt num_unsaved_files,
+    ffi.UnsignedInt options,
+    ffi.Pointer<CXTranslationUnit> out_TU);
+typedef DartClang_parseTranslationUnit2FullArgv = int Function(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options,
+    ffi.Pointer<CXTranslationUnit> out_TU);
+typedef NativeClang_defaultSaveOptions = ffi.UnsignedInt Function(
+    CXTranslationUnit TU);
+typedef DartClang_defaultSaveOptions = int Function(CXTranslationUnit TU);
+typedef NativeClang_saveTranslationUnit = ffi.Int Function(CXTranslationUnit TU,
+    ffi.Pointer<ffi.Char> FileName, ffi.UnsignedInt options);
+typedef DartClang_saveTranslationUnit = int Function(
+    CXTranslationUnit TU, ffi.Pointer<ffi.Char> FileName, int options);
+typedef NativeClang_suspendTranslationUnit = ffi.UnsignedInt Function(
+    CXTranslationUnit arg0);
+typedef DartClang_suspendTranslationUnit = int Function(CXTranslationUnit arg0);
+typedef NativeClang_disposeTranslationUnit = ffi.Void Function(
+    CXTranslationUnit arg0);
+typedef DartClang_disposeTranslationUnit = void Function(
+    CXTranslationUnit arg0);
+typedef NativeClang_defaultReparseOptions = ffi.UnsignedInt Function(
+    CXTranslationUnit TU);
+typedef DartClang_defaultReparseOptions = int Function(CXTranslationUnit TU);
+typedef NativeClang_reparseTranslationUnit = ffi.Int Function(
+    CXTranslationUnit TU,
+    ffi.UnsignedInt num_unsaved_files,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    ffi.UnsignedInt options);
+typedef DartClang_reparseTranslationUnit = int Function(
+    CXTranslationUnit TU,
+    int num_unsaved_files,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int options);
+
+/// Categorizes how memory is being used by a translation unit.
+abstract class CXTUResourceUsageKind {
+  static const int CXTUResourceUsage_AST = 1;
+  static const int CXTUResourceUsage_Identifiers = 2;
+  static const int CXTUResourceUsage_Selectors = 3;
+  static const int CXTUResourceUsage_GlobalCompletionResults = 4;
+  static const int CXTUResourceUsage_SourceManagerContentCache = 5;
+  static const int CXTUResourceUsage_AST_SideTables = 6;
+  static const int CXTUResourceUsage_SourceManager_Membuffer_Malloc = 7;
+  static const int CXTUResourceUsage_SourceManager_Membuffer_MMap = 8;
+  static const int CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9;
+  static const int CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10;
+  static const int CXTUResourceUsage_Preprocessor = 11;
+  static const int CXTUResourceUsage_PreprocessingRecord = 12;
+  static const int CXTUResourceUsage_SourceManager_DataStructures = 13;
+  static const int CXTUResourceUsage_Preprocessor_HeaderSearch = 14;
+  static const int CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = 1;
+  static const int CXTUResourceUsage_MEMORY_IN_BYTES_END = 14;
+  static const int CXTUResourceUsage_First = 1;
+  static const int CXTUResourceUsage_Last = 14;
+}
+
+typedef NativeClang_getTUResourceUsageName = ffi.Pointer<ffi.Char> Function(
+    ffi.Int32 kind);
+typedef DartClang_getTUResourceUsageName = ffi.Pointer<ffi.Char> Function(
+    int kind);
+
+final class CXTUResourceUsageEntry extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  @ffi.UnsignedLong()
+  external int amount;
+}
+
+/// The memory usage of a CXTranslationUnit, broken into categories.
+final class CXTUResourceUsage extends ffi.Struct {
+  external ffi.Pointer<ffi.Void> data;
+
+  @ffi.UnsignedInt()
+  external int numEntries;
+
+  external ffi.Pointer<CXTUResourceUsageEntry> entries;
+}
+
+typedef NativeClang_getCXTUResourceUsage = CXTUResourceUsage Function(
+    CXTranslationUnit TU);
+typedef DartClang_getCXTUResourceUsage = CXTUResourceUsage Function(
+    CXTranslationUnit TU);
+typedef NativeClang_disposeCXTUResourceUsage = ffi.Void Function(
+    CXTUResourceUsage usage);
+typedef DartClang_disposeCXTUResourceUsage = void Function(
+    CXTUResourceUsage usage);
+
+/// An opaque type representing target information for a given translation
+/// unit.
+typedef CXTargetInfo = ffi.Pointer<CXTargetInfoImpl>;
+typedef NativeClang_getTranslationUnitTargetInfo = CXTargetInfo Function(
+    CXTranslationUnit CTUnit);
+typedef DartClang_getTranslationUnitTargetInfo = CXTargetInfo Function(
+    CXTranslationUnit CTUnit);
+typedef NativeClang_TargetInfo_dispose = ffi.Void Function(CXTargetInfo Info);
+typedef DartClang_TargetInfo_dispose = void Function(CXTargetInfo Info);
+typedef NativeClang_TargetInfo_getTriple = CXString Function(CXTargetInfo Info);
+typedef DartClang_TargetInfo_getTriple = CXString Function(CXTargetInfo Info);
+typedef NativeClang_TargetInfo_getPointerWidth = ffi.Int Function(
+    CXTargetInfo Info);
+typedef DartClang_TargetInfo_getPointerWidth = int Function(CXTargetInfo Info);
+
+/// A cursor representing some element in the abstract syntax tree for
+/// a translation unit.
+///
+/// The cursor abstraction unifies the different kinds of entities in a
+/// program--declaration, statements, expressions, references to declarations,
+/// etc.--under a single "cursor" abstraction with a common set of operations.
+/// Common operation for a cursor include: getting the physical location in
+/// a source file where the cursor points, getting the name associated with a
+/// cursor, and retrieving cursors for any child nodes of a particular cursor.
+///
+/// Cursors can be produced in two specific ways.
+/// clang_getTranslationUnitCursor() produces a cursor for a translation unit,
+/// from which one can use clang_visitChildren() to explore the rest of the
+/// translation unit. clang_getCursor() maps from a physical source location
+/// to the entity that resides at that location, allowing one to map from the
+/// source code into the AST.
+final class CXCursor extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  @ffi.Int()
+  external int xdata;
+
+  @ffi.Array.multi([3])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
+}
+
+/// Describes the kind of entity that a cursor refers to.
+abstract class CXCursorKind {
+  /// A declaration whose specific kind is not exposed via this
+  /// interface.
+  ///
+  /// Unexposed declarations have the same operations as any other kind
+  /// of declaration; one can extract their location information,
+  /// spelling, find their definitions, etc. However, the specific kind
+  /// of the declaration is not reported.
+  static const int CXCursor_UnexposedDecl = 1;
+
+  /// A C or C++ struct.
+  static const int CXCursor_StructDecl = 2;
+
+  /// A C or C++ union.
+  static const int CXCursor_UnionDecl = 3;
+
+  /// A C++ class.
+  static const int CXCursor_ClassDecl = 4;
+
+  /// An enumeration.
+  static const int CXCursor_EnumDecl = 5;
+
+  /// A field (in C) or non-static data member (in C++) in a
+  /// struct, union, or C++ class.
+  static const int CXCursor_FieldDecl = 6;
+
+  /// An enumerator constant.
+  static const int CXCursor_EnumConstantDecl = 7;
+
+  /// A function.
+  static const int CXCursor_FunctionDecl = 8;
+
+  /// A variable.
+  static const int CXCursor_VarDecl = 9;
+
+  /// A function or method parameter.
+  static const int CXCursor_ParmDecl = 10;
+
+  /// An Objective-C \@interface.
+  static const int CXCursor_ObjCInterfaceDecl = 11;
+
+  /// An Objective-C \@interface for a category.
+  static const int CXCursor_ObjCCategoryDecl = 12;
+
+  /// An Objective-C \@protocol declaration.
+  static const int CXCursor_ObjCProtocolDecl = 13;
+
+  /// An Objective-C \@property declaration.
+  static const int CXCursor_ObjCPropertyDecl = 14;
+
+  /// An Objective-C instance variable.
+  static const int CXCursor_ObjCIvarDecl = 15;
+
+  /// An Objective-C instance method.
+  static const int CXCursor_ObjCInstanceMethodDecl = 16;
+
+  /// An Objective-C class method.
+  static const int CXCursor_ObjCClassMethodDecl = 17;
+
+  /// An Objective-C \@implementation.
+  static const int CXCursor_ObjCImplementationDecl = 18;
+
+  /// An Objective-C \@implementation for a category.
+  static const int CXCursor_ObjCCategoryImplDecl = 19;
+
+  /// A typedef.
+  static const int CXCursor_TypedefDecl = 20;
+
+  /// A C++ class method.
+  static const int CXCursor_CXXMethod = 21;
+
+  /// A C++ namespace.
+  static const int CXCursor_Namespace = 22;
+
+  /// A linkage specification, e.g. 'extern "C"'.
+  static const int CXCursor_LinkageSpec = 23;
+
+  /// A C++ constructor.
+  static const int CXCursor_Constructor = 24;
+
+  /// A C++ destructor.
+  static const int CXCursor_Destructor = 25;
+
+  /// A C++ conversion function.
+  static const int CXCursor_ConversionFunction = 26;
+
+  /// A C++ template type parameter.
+  static const int CXCursor_TemplateTypeParameter = 27;
+
+  /// A C++ non-type template parameter.
+  static const int CXCursor_NonTypeTemplateParameter = 28;
+
+  /// A C++ template template parameter.
+  static const int CXCursor_TemplateTemplateParameter = 29;
+
+  /// A C++ function template.
+  static const int CXCursor_FunctionTemplate = 30;
+
+  /// A C++ class template.
+  static const int CXCursor_ClassTemplate = 31;
+
+  /// A C++ class template partial specialization.
+  static const int CXCursor_ClassTemplatePartialSpecialization = 32;
+
+  /// A C++ namespace alias declaration.
+  static const int CXCursor_NamespaceAlias = 33;
+
+  /// A C++ using directive.
+  static const int CXCursor_UsingDirective = 34;
+
+  /// A C++ using declaration.
+  static const int CXCursor_UsingDeclaration = 35;
+
+  /// A C++ alias declaration
+  static const int CXCursor_TypeAliasDecl = 36;
+
+  /// An Objective-C \@synthesize definition.
+  static const int CXCursor_ObjCSynthesizeDecl = 37;
+
+  /// An Objective-C \@dynamic definition.
+  static const int CXCursor_ObjCDynamicDecl = 38;
+
+  /// An access specifier.
+  static const int CXCursor_CXXAccessSpecifier = 39;
+  static const int CXCursor_FirstDecl = 1;
+  static const int CXCursor_LastDecl = 39;
+  static const int CXCursor_FirstRef = 40;
+  static const int CXCursor_ObjCSuperClassRef = 40;
+  static const int CXCursor_ObjCProtocolRef = 41;
+  static const int CXCursor_ObjCClassRef = 42;
+
+  /// A reference to a type declaration.
+  ///
+  /// A type reference occurs anywhere where a type is named but not
+  /// declared. For example, given:
+  ///
+  /// \code
+  /// typedef unsigned size_type;
+  /// size_type size;
+  /// \endcode
+  ///
+  /// The typedef is a declaration of size_type (CXCursor_TypedefDecl),
+  /// while the type of the variable "size" is referenced. The cursor
+  /// referenced by the type of size is the typedef for size_type.
+  static const int CXCursor_TypeRef = 43;
+  static const int CXCursor_CXXBaseSpecifier = 44;
+
+  /// A reference to a class template, function template, template
+  /// template parameter, or class template partial specialization.
+  static const int CXCursor_TemplateRef = 45;
+
+  /// A reference to a namespace or namespace alias.
+  static const int CXCursor_NamespaceRef = 46;
+
+  /// A reference to a member of a struct, union, or class that occurs in
+  /// some non-expression context, e.g., a designated initializer.
+  static const int CXCursor_MemberRef = 47;
+
+  /// A reference to a labeled statement.
+  ///
+  /// This cursor kind is used to describe the jump to "start_over" in the
+  /// goto statement in the following example:
+  ///
+  /// \code
+  /// start_over:
+  /// ++counter;
+  ///
+  /// goto start_over;
+  /// \endcode
+  ///
+  /// A label reference cursor refers to a label statement.
+  static const int CXCursor_LabelRef = 48;
+
+  /// A reference to a set of overloaded functions or function templates
+  /// that has not yet been resolved to a specific function or function template.
+  ///
+  /// An overloaded declaration reference cursor occurs in C++ templates where
+  /// a dependent name refers to a function. For example:
+  ///
+  /// \code
+  /// template<typename T> void swap(T&, T&);
+  ///
+  /// struct X { ... };
+  /// void swap(X&, X&);
+  ///
+  /// template<typename T>
+  /// void reverse(T* first, T* last) {
+  /// while (first < last - 1) {
+  /// swap(*first, *--last);
+  /// ++first;
+  /// }
+  /// }
+  ///
+  /// struct Y { };
+  /// void swap(Y&, Y&);
+  /// \endcode
+  ///
+  /// Here, the identifier "swap" is associated with an overloaded declaration
+  /// reference. In the template definition, "swap" refers to either of the two
+  /// "swap" functions declared above, so both results will be available. At
+  /// instantiation time, "swap" may also refer to other functions found via
+  /// argument-dependent lookup (e.g., the "swap" function at the end of the
+  /// example).
+  ///
+  /// The functions \c clang_getNumOverloadedDecls() and
+  /// \c clang_getOverloadedDecl() can be used to retrieve the definitions
+  /// referenced by this cursor.
+  static const int CXCursor_OverloadedDeclRef = 49;
+
+  /// A reference to a variable that occurs in some non-expression
+  /// context, e.g., a C++ lambda capture list.
+  static const int CXCursor_VariableRef = 50;
+  static const int CXCursor_LastRef = 50;
+  static const int CXCursor_FirstInvalid = 70;
+  static const int CXCursor_InvalidFile = 70;
+  static const int CXCursor_NoDeclFound = 71;
+  static const int CXCursor_NotImplemented = 72;
+  static const int CXCursor_InvalidCode = 73;
+  static const int CXCursor_LastInvalid = 73;
+  static const int CXCursor_FirstExpr = 100;
+
+  /// An expression whose specific kind is not exposed via this
+  /// interface.
+  ///
+  /// Unexposed expressions have the same operations as any other kind
+  /// of expression; one can extract their location information,
+  /// spelling, children, etc. However, the specific kind of the
+  /// expression is not reported.
+  static const int CXCursor_UnexposedExpr = 100;
+
+  /// An expression that refers to some value declaration, such
+  /// as a function, variable, or enumerator.
+  static const int CXCursor_DeclRefExpr = 101;
+
+  /// An expression that refers to a member of a struct, union,
+  /// class, Objective-C class, etc.
+  static const int CXCursor_MemberRefExpr = 102;
+
+  /// An expression that calls a function.
+  static const int CXCursor_CallExpr = 103;
+
+  /// An expression that sends a message to an Objective-C
+  /// object or class.
+  static const int CXCursor_ObjCMessageExpr = 104;
+
+  /// An expression that represents a block literal.
+  static const int CXCursor_BlockExpr = 105;
+
+  /// An integer literal.
+  static const int CXCursor_IntegerLiteral = 106;
+
+  /// A floating point number literal.
+  static const int CXCursor_FloatingLiteral = 107;
+
+  /// An imaginary number literal.
+  static const int CXCursor_ImaginaryLiteral = 108;
+
+  /// A string literal.
+  static const int CXCursor_StringLiteral = 109;
+
+  /// A character literal.
+  static const int CXCursor_CharacterLiteral = 110;
+
+  /// A parenthesized expression, e.g. "(1)".
+  ///
+  /// This AST node is only formed if full location information is requested.
+  static const int CXCursor_ParenExpr = 111;
+
+  /// This represents the unary-expression's (except sizeof and
+  /// alignof).
+  static const int CXCursor_UnaryOperator = 112;
+
+  /// [C99 6.5.2.1] Array Subscripting.
+  static const int CXCursor_ArraySubscriptExpr = 113;
+
+  /// A builtin binary operation expression such as "x + y" or
+  /// "x <= y".
+  static const int CXCursor_BinaryOperator = 114;
+
+  /// Compound assignment such as "+=".
+  static const int CXCursor_CompoundAssignOperator = 115;
+
+  /// The ?: ternary operator.
+  static const int CXCursor_ConditionalOperator = 116;
+
+  /// An explicit cast in C (C99 6.5.4) or a C-style cast in C++
+  /// (C++ [expr.cast]), which uses the syntax (Type)expr.
+  ///
+  /// For example: (int)f.
+  static const int CXCursor_CStyleCastExpr = 117;
+
+  /// [C99 6.5.2.5]
+  static const int CXCursor_CompoundLiteralExpr = 118;
+
+  /// Describes an C or C++ initializer list.
+  static const int CXCursor_InitListExpr = 119;
+
+  /// The GNU address of label extension, representing &&label.
+  static const int CXCursor_AddrLabelExpr = 120;
+
+  /// This is the GNU Statement Expression extension: ({int X=4; X;})
+  static const int CXCursor_StmtExpr = 121;
+
+  /// Represents a C11 generic selection.
+  static const int CXCursor_GenericSelectionExpr = 122;
+
+  /// Implements the GNU __null extension, which is a name for a null
+  /// pointer constant that has integral type (e.g., int or long) and is the same
+  /// size and alignment as a pointer.
+  ///
+  /// The __null extension is typically only used by system headers, which define
+  /// NULL as __null in C++ rather than using 0 (which is an integer that may not
+  /// match the size of a pointer).
+  static const int CXCursor_GNUNullExpr = 123;
+
+  /// C++'s static_cast<> expression.
+  static const int CXCursor_CXXStaticCastExpr = 124;
+
+  /// C++'s dynamic_cast<> expression.
+  static const int CXCursor_CXXDynamicCastExpr = 125;
+
+  /// C++'s reinterpret_cast<> expression.
+  static const int CXCursor_CXXReinterpretCastExpr = 126;
+
+  /// C++'s const_cast<> expression.
+  static const int CXCursor_CXXConstCastExpr = 127;
+
+  /// Represents an explicit C++ type conversion that uses "functional"
+  /// notion (C++ [expr.type.conv]).
+  ///
+  /// Example:
+  /// \code
+  /// x = int(0.5);
+  /// \endcode
+  static const int CXCursor_CXXFunctionalCastExpr = 128;
+
+  /// A C++ typeid expression (C++ [expr.typeid]).
+  static const int CXCursor_CXXTypeidExpr = 129;
+
+  /// [C++ 2.13.5] C++ Boolean Literal.
+  static const int CXCursor_CXXBoolLiteralExpr = 130;
+
+  /// [C++0x 2.14.7] C++ Pointer Literal.
+  static const int CXCursor_CXXNullPtrLiteralExpr = 131;
+
+  /// Represents the "this" expression in C++
+  static const int CXCursor_CXXThisExpr = 132;
+
+  /// [C++ 15] C++ Throw Expression.
+  ///
+  /// This handles 'throw' and 'throw' assignment-expression. When
+  /// assignment-expression isn't present, Op will be null.
+  static const int CXCursor_CXXThrowExpr = 133;
+
+  /// A new expression for memory allocation and constructor calls, e.g:
+  /// "new CXXNewExpr(foo)".
+  static const int CXCursor_CXXNewExpr = 134;
+
+  /// A delete expression for memory deallocation and destructor calls,
+  /// e.g. "delete[] pArray".
+  static const int CXCursor_CXXDeleteExpr = 135;
+
+  /// A unary expression. (noexcept, sizeof, or other traits)
+  static const int CXCursor_UnaryExpr = 136;
+
+  /// An Objective-C string literal i.e. @"foo".
+  static const int CXCursor_ObjCStringLiteral = 137;
+
+  /// An Objective-C \@encode expression.
+  static const int CXCursor_ObjCEncodeExpr = 138;
+
+  /// An Objective-C \@selector expression.
+  static const int CXCursor_ObjCSelectorExpr = 139;
+
+  /// An Objective-C \@protocol expression.
+  static const int CXCursor_ObjCProtocolExpr = 140;
+
+  /// An Objective-C "bridged" cast expression, which casts between
+  /// Objective-C pointers and C pointers, transferring ownership in the process.
+  ///
+  /// \code
+  /// NSString *str = (__bridge_transfer NSString *)CFCreateString();
+  /// \endcode
+  static const int CXCursor_ObjCBridgedCastExpr = 141;
+
+  /// Represents a C++0x pack expansion that produces a sequence of
+  /// expressions.
+  ///
+  /// A pack expansion expression contains a pattern (which itself is an
+  /// expression) followed by an ellipsis. For example:
+  ///
+  /// \code
+  /// template<typename F, typename ...Types>
+  /// void forward(F f, Types &&...args) {
+  /// f(static_cast<Types&&>(args)...);
+  /// }
+  /// \endcode
+  static const int CXCursor_PackExpansionExpr = 142;
+
+  /// Represents an expression that computes the length of a parameter
+  /// pack.
+  ///
+  /// \code
+  /// template<typename ...Types>
+  /// struct count {
+  /// static const unsigned value = sizeof...(Types);
+  /// };
+  /// \endcode
+  static const int CXCursor_SizeOfPackExpr = 143;
+  static const int CXCursor_LambdaExpr = 144;
+
+  /// Objective-c Boolean Literal.
+  static const int CXCursor_ObjCBoolLiteralExpr = 145;
+
+  /// Represents the "self" expression in an Objective-C method.
+  static const int CXCursor_ObjCSelfExpr = 146;
+
+  /// OpenMP 4.0 [2.4, Array Section].
+  static const int CXCursor_OMPArraySectionExpr = 147;
+
+  /// Represents an @available(...) check.
+  static const int CXCursor_ObjCAvailabilityCheckExpr = 148;
+
+  /// Fixed point literal
+  static const int CXCursor_FixedPointLiteral = 149;
+  static const int CXCursor_LastExpr = 149;
+  static const int CXCursor_FirstStmt = 200;
+
+  /// A statement whose specific kind is not exposed via this
+  /// interface.
+  ///
+  /// Unexposed statements have the same operations as any other kind of
+  /// statement; one can extract their location information, spelling,
+  /// children, etc. However, the specific kind of the statement is not
+  /// reported.
+  static const int CXCursor_UnexposedStmt = 200;
+
+  /// A labelled statement in a function.
+  ///
+  /// This cursor kind is used to describe the "start_over:" label statement in
+  /// the following example:
+  ///
+  /// \code
+  /// start_over:
+  /// ++counter;
+  /// \endcode
+  static const int CXCursor_LabelStmt = 201;
+
+  /// A group of statements like { stmt stmt }.
+  ///
+  /// This cursor kind is used to describe compound statements, e.g. function
+  /// bodies.
+  static const int CXCursor_CompoundStmt = 202;
+
+  /// A case statement.
+  static const int CXCursor_CaseStmt = 203;
+
+  /// A default statement.
+  static const int CXCursor_DefaultStmt = 204;
+
+  /// An if statement
+  static const int CXCursor_IfStmt = 205;
+
+  /// A switch statement.
+  static const int CXCursor_SwitchStmt = 206;
+
+  /// A while statement.
+  static const int CXCursor_WhileStmt = 207;
+
+  /// A do statement.
+  static const int CXCursor_DoStmt = 208;
+
+  /// A for statement.
+  static const int CXCursor_ForStmt = 209;
+
+  /// A goto statement.
+  static const int CXCursor_GotoStmt = 210;
+
+  /// An indirect goto statement.
+  static const int CXCursor_IndirectGotoStmt = 211;
+
+  /// A continue statement.
+  static const int CXCursor_ContinueStmt = 212;
+
+  /// A break statement.
+  static const int CXCursor_BreakStmt = 213;
+
+  /// A return statement.
+  static const int CXCursor_ReturnStmt = 214;
+
+  /// A GCC inline assembly statement extension.
+  static const int CXCursor_GCCAsmStmt = 215;
+  static const int CXCursor_AsmStmt = 215;
+
+  /// Objective-C's overall \@try-\@catch-\@finally statement.
+  static const int CXCursor_ObjCAtTryStmt = 216;
+
+  /// Objective-C's \@catch statement.
+  static const int CXCursor_ObjCAtCatchStmt = 217;
+
+  /// Objective-C's \@finally statement.
+  static const int CXCursor_ObjCAtFinallyStmt = 218;
+
+  /// Objective-C's \@throw statement.
+  static const int CXCursor_ObjCAtThrowStmt = 219;
+
+  /// Objective-C's \@synchronized statement.
+  static const int CXCursor_ObjCAtSynchronizedStmt = 220;
+
+  /// Objective-C's autorelease pool statement.
+  static const int CXCursor_ObjCAutoreleasePoolStmt = 221;
+
+  /// Objective-C's collection statement.
+  static const int CXCursor_ObjCForCollectionStmt = 222;
+
+  /// C++'s catch statement.
+  static const int CXCursor_CXXCatchStmt = 223;
+
+  /// C++'s try statement.
+  static const int CXCursor_CXXTryStmt = 224;
+
+  /// C++'s for (* : *) statement.
+  static const int CXCursor_CXXForRangeStmt = 225;
+
+  /// Windows Structured Exception Handling's try statement.
+  static const int CXCursor_SEHTryStmt = 226;
+
+  /// Windows Structured Exception Handling's except statement.
+  static const int CXCursor_SEHExceptStmt = 227;
+
+  /// Windows Structured Exception Handling's finally statement.
+  static const int CXCursor_SEHFinallyStmt = 228;
+
+  /// A MS inline assembly statement extension.
+  static const int CXCursor_MSAsmStmt = 229;
+
+  /// The null statement ";": C99 6.8.3p3.
+  ///
+  /// This cursor kind is used to describe the null statement.
+  static const int CXCursor_NullStmt = 230;
+
+  /// Adaptor class for mixing declarations with statements and
+  /// expressions.
+  static const int CXCursor_DeclStmt = 231;
+
+  /// OpenMP parallel directive.
+  static const int CXCursor_OMPParallelDirective = 232;
+
+  /// OpenMP SIMD directive.
+  static const int CXCursor_OMPSimdDirective = 233;
+
+  /// OpenMP for directive.
+  static const int CXCursor_OMPForDirective = 234;
+
+  /// OpenMP sections directive.
+  static const int CXCursor_OMPSectionsDirective = 235;
+
+  /// OpenMP section directive.
+  static const int CXCursor_OMPSectionDirective = 236;
+
+  /// OpenMP single directive.
+  static const int CXCursor_OMPSingleDirective = 237;
+
+  /// OpenMP parallel for directive.
+  static const int CXCursor_OMPParallelForDirective = 238;
+
+  /// OpenMP parallel sections directive.
+  static const int CXCursor_OMPParallelSectionsDirective = 239;
+
+  /// OpenMP task directive.
+  static const int CXCursor_OMPTaskDirective = 240;
+
+  /// OpenMP master directive.
+  static const int CXCursor_OMPMasterDirective = 241;
+
+  /// OpenMP critical directive.
+  static const int CXCursor_OMPCriticalDirective = 242;
+
+  /// OpenMP taskyield directive.
+  static const int CXCursor_OMPTaskyieldDirective = 243;
+
+  /// OpenMP barrier directive.
+  static const int CXCursor_OMPBarrierDirective = 244;
+
+  /// OpenMP taskwait directive.
+  static const int CXCursor_OMPTaskwaitDirective = 245;
+
+  /// OpenMP flush directive.
+  static const int CXCursor_OMPFlushDirective = 246;
+
+  /// Windows Structured Exception Handling's leave statement.
+  static const int CXCursor_SEHLeaveStmt = 247;
+
+  /// OpenMP ordered directive.
+  static const int CXCursor_OMPOrderedDirective = 248;
+
+  /// OpenMP atomic directive.
+  static const int CXCursor_OMPAtomicDirective = 249;
+
+  /// OpenMP for SIMD directive.
+  static const int CXCursor_OMPForSimdDirective = 250;
+
+  /// OpenMP parallel for SIMD directive.
+  static const int CXCursor_OMPParallelForSimdDirective = 251;
+
+  /// OpenMP target directive.
+  static const int CXCursor_OMPTargetDirective = 252;
+
+  /// OpenMP teams directive.
+  static const int CXCursor_OMPTeamsDirective = 253;
+
+  /// OpenMP taskgroup directive.
+  static const int CXCursor_OMPTaskgroupDirective = 254;
+
+  /// OpenMP cancellation point directive.
+  static const int CXCursor_OMPCancellationPointDirective = 255;
+
+  /// OpenMP cancel directive.
+  static const int CXCursor_OMPCancelDirective = 256;
+
+  /// OpenMP target data directive.
+  static const int CXCursor_OMPTargetDataDirective = 257;
+
+  /// OpenMP taskloop directive.
+  static const int CXCursor_OMPTaskLoopDirective = 258;
+
+  /// OpenMP taskloop simd directive.
+  static const int CXCursor_OMPTaskLoopSimdDirective = 259;
+
+  /// OpenMP distribute directive.
+  static const int CXCursor_OMPDistributeDirective = 260;
+
+  /// OpenMP target enter data directive.
+  static const int CXCursor_OMPTargetEnterDataDirective = 261;
+
+  /// OpenMP target exit data directive.
+  static const int CXCursor_OMPTargetExitDataDirective = 262;
+
+  /// OpenMP target parallel directive.
+  static const int CXCursor_OMPTargetParallelDirective = 263;
+
+  /// OpenMP target parallel for directive.
+  static const int CXCursor_OMPTargetParallelForDirective = 264;
+
+  /// OpenMP target update directive.
+  static const int CXCursor_OMPTargetUpdateDirective = 265;
+
+  /// OpenMP distribute parallel for directive.
+  static const int CXCursor_OMPDistributeParallelForDirective = 266;
+
+  /// OpenMP distribute parallel for simd directive.
+  static const int CXCursor_OMPDistributeParallelForSimdDirective = 267;
+
+  /// OpenMP distribute simd directive.
+  static const int CXCursor_OMPDistributeSimdDirective = 268;
+
+  /// OpenMP target parallel for simd directive.
+  static const int CXCursor_OMPTargetParallelForSimdDirective = 269;
+
+  /// OpenMP target simd directive.
+  static const int CXCursor_OMPTargetSimdDirective = 270;
+
+  /// OpenMP teams distribute directive.
+  static const int CXCursor_OMPTeamsDistributeDirective = 271;
+
+  /// OpenMP teams distribute simd directive.
+  static const int CXCursor_OMPTeamsDistributeSimdDirective = 272;
+
+  /// OpenMP teams distribute parallel for simd directive.
+  static const int CXCursor_OMPTeamsDistributeParallelForSimdDirective = 273;
+
+  /// OpenMP teams distribute parallel for directive.
+  static const int CXCursor_OMPTeamsDistributeParallelForDirective = 274;
+
+  /// OpenMP target teams directive.
+  static const int CXCursor_OMPTargetTeamsDirective = 275;
+
+  /// OpenMP target teams distribute directive.
+  static const int CXCursor_OMPTargetTeamsDistributeDirective = 276;
+
+  /// OpenMP target teams distribute parallel for directive.
+  static const int CXCursor_OMPTargetTeamsDistributeParallelForDirective = 277;
+
+  /// OpenMP target teams distribute parallel for simd directive.
+  static const int CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective =
+      278;
+
+  /// OpenMP target teams distribute simd directive.
+  static const int CXCursor_OMPTargetTeamsDistributeSimdDirective = 279;
+
+  /// C++2a std::bit_cast expression.
+  static const int CXCursor_BuiltinBitCastExpr = 280;
+
+  /// OpenMP master taskloop directive.
+  static const int CXCursor_OMPMasterTaskLoopDirective = 281;
+
+  /// OpenMP parallel master taskloop directive.
+  static const int CXCursor_OMPParallelMasterTaskLoopDirective = 282;
+
+  /// OpenMP master taskloop simd directive.
+  static const int CXCursor_OMPMasterTaskLoopSimdDirective = 283;
+
+  /// OpenMP parallel master taskloop simd directive.
+  static const int CXCursor_OMPParallelMasterTaskLoopSimdDirective = 284;
+
+  /// OpenMP parallel master directive.
+  static const int CXCursor_OMPParallelMasterDirective = 285;
+  static const int CXCursor_LastStmt = 285;
+
+  /// Cursor that represents the translation unit itself.
+  ///
+  /// The translation unit cursor exists primarily to act as the root
+  /// cursor for traversing the contents of a translation unit.
+  static const int CXCursor_TranslationUnit = 300;
+  static const int CXCursor_FirstAttr = 400;
+
+  /// An attribute whose specific kind is not exposed via this
+  /// interface.
+  static const int CXCursor_UnexposedAttr = 400;
+  static const int CXCursor_IBActionAttr = 401;
+  static const int CXCursor_IBOutletAttr = 402;
+  static const int CXCursor_IBOutletCollectionAttr = 403;
+  static const int CXCursor_CXXFinalAttr = 404;
+  static const int CXCursor_CXXOverrideAttr = 405;
+  static const int CXCursor_AnnotateAttr = 406;
+  static const int CXCursor_AsmLabelAttr = 407;
+  static const int CXCursor_PackedAttr = 408;
+  static const int CXCursor_PureAttr = 409;
+  static const int CXCursor_ConstAttr = 410;
+  static const int CXCursor_NoDuplicateAttr = 411;
+  static const int CXCursor_CUDAConstantAttr = 412;
+  static const int CXCursor_CUDADeviceAttr = 413;
+  static const int CXCursor_CUDAGlobalAttr = 414;
+  static const int CXCursor_CUDAHostAttr = 415;
+  static const int CXCursor_CUDASharedAttr = 416;
+  static const int CXCursor_VisibilityAttr = 417;
+  static const int CXCursor_DLLExport = 418;
+  static const int CXCursor_DLLImport = 419;
+  static const int CXCursor_NSReturnsRetained = 420;
+  static const int CXCursor_NSReturnsNotRetained = 421;
+  static const int CXCursor_NSReturnsAutoreleased = 422;
+  static const int CXCursor_NSConsumesSelf = 423;
+  static const int CXCursor_NSConsumed = 424;
+  static const int CXCursor_ObjCException = 425;
+  static const int CXCursor_ObjCNSObject = 426;
+  static const int CXCursor_ObjCIndependentClass = 427;
+  static const int CXCursor_ObjCPreciseLifetime = 428;
+  static const int CXCursor_ObjCReturnsInnerPointer = 429;
+  static const int CXCursor_ObjCRequiresSuper = 430;
+  static const int CXCursor_ObjCRootClass = 431;
+  static const int CXCursor_ObjCSubclassingRestricted = 432;
+  static const int CXCursor_ObjCExplicitProtocolImpl = 433;
+  static const int CXCursor_ObjCDesignatedInitializer = 434;
+  static const int CXCursor_ObjCRuntimeVisible = 435;
+  static const int CXCursor_ObjCBoxable = 436;
+  static const int CXCursor_FlagEnum = 437;
+  static const int CXCursor_ConvergentAttr = 438;
+  static const int CXCursor_WarnUnusedAttr = 439;
+  static const int CXCursor_WarnUnusedResultAttr = 440;
+  static const int CXCursor_AlignedAttr = 441;
+  static const int CXCursor_LastAttr = 441;
+  static const int CXCursor_PreprocessingDirective = 500;
+  static const int CXCursor_MacroDefinition = 501;
+  static const int CXCursor_MacroExpansion = 502;
+  static const int CXCursor_MacroInstantiation = 502;
+  static const int CXCursor_InclusionDirective = 503;
+  static const int CXCursor_FirstPreprocessing = 500;
+  static const int CXCursor_LastPreprocessing = 503;
+
+  /// A module import declaration.
+  static const int CXCursor_ModuleImportDecl = 600;
+  static const int CXCursor_TypeAliasTemplateDecl = 601;
+
+  /// A static_assert or _Static_assert node
+  static const int CXCursor_StaticAssert = 602;
+
+  /// a friend declaration.
+  static const int CXCursor_FriendDecl = 603;
+  static const int CXCursor_FirstExtraDecl = 600;
+  static const int CXCursor_LastExtraDecl = 603;
+
+  /// A code completion overload candidate.
+  static const int CXCursor_OverloadCandidate = 700;
+}
+
+typedef NativeClang_getNullCursor = CXCursor Function();
+typedef DartClang_getNullCursor = CXCursor Function();
+typedef NativeClang_getTranslationUnitCursor = CXCursor Function(
+    CXTranslationUnit arg0);
+typedef DartClang_getTranslationUnitCursor = CXCursor Function(
+    CXTranslationUnit arg0);
+typedef NativeClang_equalCursors = ffi.UnsignedInt Function(
+    CXCursor arg0, CXCursor arg1);
+typedef DartClang_equalCursors = int Function(CXCursor arg0, CXCursor arg1);
+typedef NativeClang_Cursor_isNull = ffi.Int Function(CXCursor cursor);
+typedef DartClang_Cursor_isNull = int Function(CXCursor cursor);
+typedef NativeClang_hashCursor = ffi.UnsignedInt Function(CXCursor arg0);
+typedef DartClang_hashCursor = int Function(CXCursor arg0);
+typedef NativeClang_getCursorKind = ffi.Int32 Function(CXCursor arg0);
+typedef DartClang_getCursorKind = int Function(CXCursor arg0);
+typedef NativeClang_isDeclaration = ffi.UnsignedInt Function(ffi.Int32 arg0);
+typedef DartClang_isDeclaration = int Function(int arg0);
+typedef NativeClang_isInvalidDeclaration = ffi.UnsignedInt Function(
+    CXCursor arg0);
+typedef DartClang_isInvalidDeclaration = int Function(CXCursor arg0);
+typedef NativeClang_isReference = ffi.UnsignedInt Function(ffi.Int32 arg0);
+typedef DartClang_isReference = int Function(int arg0);
+typedef NativeClang_isExpression = ffi.UnsignedInt Function(ffi.Int32 arg0);
+typedef DartClang_isExpression = int Function(int arg0);
+typedef NativeClang_isStatement = ffi.UnsignedInt Function(ffi.Int32 arg0);
+typedef DartClang_isStatement = int Function(int arg0);
+typedef NativeClang_isAttribute = ffi.UnsignedInt Function(ffi.Int32 arg0);
+typedef DartClang_isAttribute = int Function(int arg0);
+typedef NativeClang_Cursor_hasAttrs = ffi.UnsignedInt Function(CXCursor C);
+typedef DartClang_Cursor_hasAttrs = int Function(CXCursor C);
+typedef NativeClang_isInvalid = ffi.UnsignedInt Function(ffi.Int32 arg0);
+typedef DartClang_isInvalid = int Function(int arg0);
+typedef NativeClang_isTranslationUnit = ffi.UnsignedInt Function(
+    ffi.Int32 arg0);
+typedef DartClang_isTranslationUnit = int Function(int arg0);
+typedef NativeClang_isPreprocessing = ffi.UnsignedInt Function(ffi.Int32 arg0);
+typedef DartClang_isPreprocessing = int Function(int arg0);
+typedef NativeClang_isUnexposed = ffi.UnsignedInt Function(ffi.Int32 arg0);
+typedef DartClang_isUnexposed = int Function(int arg0);
+
+/// Describe the linkage of the entity referred to by a cursor.
+abstract class CXLinkageKind {
+  /// This value indicates that no linkage information is available
+  /// for a provided CXCursor.
+  static const int CXLinkage_Invalid = 0;
+
+  /// This is the linkage for variables, parameters, and so on that
+  /// have automatic storage.  This covers normal (non-extern) local variables.
+  static const int CXLinkage_NoLinkage = 1;
+
+  /// This is the linkage for static variables and static functions.
+  static const int CXLinkage_Internal = 2;
+
+  /// This is the linkage for entities with external linkage that live
+  /// in C++ anonymous namespaces.
+  static const int CXLinkage_UniqueExternal = 3;
+
+  /// This is the linkage for entities with true, external linkage.
+  static const int CXLinkage_External = 4;
+}
+
+typedef NativeClang_getCursorLinkage = ffi.Int32 Function(CXCursor cursor);
+typedef DartClang_getCursorLinkage = int Function(CXCursor cursor);
+
+abstract class CXVisibilityKind {
+  /// This value indicates that no visibility information is available
+  /// for a provided CXCursor.
+  static const int CXVisibility_Invalid = 0;
+
+  /// Symbol not seen by the linker.
+  static const int CXVisibility_Hidden = 1;
+
+  /// Symbol seen by the linker but resolves to a symbol inside this object.
+  static const int CXVisibility_Protected = 2;
+
+  /// Symbol seen by the linker and acts like a normal symbol.
+  static const int CXVisibility_Default = 3;
+}
+
+typedef NativeClang_getCursorVisibility = ffi.Int32 Function(CXCursor cursor);
+typedef DartClang_getCursorVisibility = int Function(CXCursor cursor);
+
+/// Describes the availability of a particular entity, which indicates
+/// whether the use of this entity will result in a warning or error due to
+/// it being deprecated or unavailable.
+abstract class CXAvailabilityKind {
+  /// The entity is available.
+  static const int CXAvailability_Available = 0;
+
+  /// The entity is available, but has been deprecated (and its use is
+  /// not recommended).
+  static const int CXAvailability_Deprecated = 1;
+
+  /// The entity is not available; any use of it will be an error.
+  static const int CXAvailability_NotAvailable = 2;
+
+  /// The entity is available, but not accessible; any use of it will be
+  /// an error.
+  static const int CXAvailability_NotAccessible = 3;
+}
+
+typedef NativeClang_getCursorAvailability = ffi.Int32 Function(CXCursor cursor);
+typedef DartClang_getCursorAvailability = int Function(CXCursor cursor);
+
+/// Describes the availability of a given entity on a particular platform, e.g.,
+/// a particular class might only be available on Mac OS 10.7 or newer.
+final class CXPlatformAvailability extends ffi.Struct {
+  /// A string that describes the platform for which this structure
+  /// provides availability information.
+  ///
+  /// Possible values are "ios" or "macos".
+  external CXString Platform;
+
+  /// The version number in which this entity was introduced.
+  external CXVersion Introduced;
+
+  /// The version number in which this entity was deprecated (but is
+  /// still available).
+  external CXVersion Deprecated;
+
+  /// The version number in which this entity was obsoleted, and therefore
+  /// is no longer available.
+  external CXVersion Obsoleted;
+
+  /// Whether the entity is unconditionally unavailable on this platform.
+  @ffi.Int()
+  external int Unavailable;
+
+  /// An optional message to provide to a user of this API, e.g., to
+  /// suggest replacement APIs.
+  external CXString Message;
+}
+
+typedef NativeClang_getCursorPlatformAvailability = ffi.Int Function(
+    CXCursor cursor,
+    ffi.Pointer<ffi.Int> always_deprecated,
+    ffi.Pointer<CXString> deprecated_message,
+    ffi.Pointer<ffi.Int> always_unavailable,
+    ffi.Pointer<CXString> unavailable_message,
+    ffi.Pointer<CXPlatformAvailability> availability,
+    ffi.Int availability_size);
+typedef DartClang_getCursorPlatformAvailability = int Function(
+    CXCursor cursor,
+    ffi.Pointer<ffi.Int> always_deprecated,
+    ffi.Pointer<CXString> deprecated_message,
+    ffi.Pointer<ffi.Int> always_unavailable,
+    ffi.Pointer<CXString> unavailable_message,
+    ffi.Pointer<CXPlatformAvailability> availability,
+    int availability_size);
+typedef NativeClang_disposeCXPlatformAvailability = ffi.Void Function(
+    ffi.Pointer<CXPlatformAvailability> availability);
+typedef DartClang_disposeCXPlatformAvailability = void Function(
+    ffi.Pointer<CXPlatformAvailability> availability);
+
+/// Describe the "language" of the entity referred to by a cursor.
+abstract class CXLanguageKind {
+  static const int CXLanguage_Invalid = 0;
+  static const int CXLanguage_C = 1;
+  static const int CXLanguage_ObjC = 2;
+  static const int CXLanguage_CPlusPlus = 3;
+}
+
+typedef NativeClang_getCursorLanguage = ffi.Int32 Function(CXCursor cursor);
+typedef DartClang_getCursorLanguage = int Function(CXCursor cursor);
+
+/// Describe the "thread-local storage (TLS) kind" of the declaration
+/// referred to by a cursor.
+abstract class CXTLSKind {
+  static const int CXTLS_None = 0;
+  static const int CXTLS_Dynamic = 1;
+  static const int CXTLS_Static = 2;
+}
+
+typedef NativeClang_getCursorTLSKind = ffi.Int32 Function(CXCursor cursor);
+typedef DartClang_getCursorTLSKind = int Function(CXCursor cursor);
+typedef NativeClang_Cursor_getTranslationUnit = CXTranslationUnit Function(
+    CXCursor arg0);
+typedef DartClang_Cursor_getTranslationUnit = CXTranslationUnit Function(
+    CXCursor arg0);
+
+/// A fast container representing a set of CXCursors.
+typedef CXCursorSet = ffi.Pointer<custom_import.CXCursorSetImpl>;
+typedef NativeClang_createCXCursorSet = CXCursorSet Function();
+typedef DartClang_createCXCursorSet = CXCursorSet Function();
+typedef NativeClang_disposeCXCursorSet = ffi.Void Function(CXCursorSet cset);
+typedef DartClang_disposeCXCursorSet = void Function(CXCursorSet cset);
+typedef NativeClang_CXCursorSet_contains = ffi.UnsignedInt Function(
+    CXCursorSet cset, CXCursor cursor);
+typedef DartClang_CXCursorSet_contains = int Function(
+    CXCursorSet cset, CXCursor cursor);
+typedef NativeClang_CXCursorSet_insert = ffi.UnsignedInt Function(
+    CXCursorSet cset, CXCursor cursor);
+typedef DartClang_CXCursorSet_insert = int Function(
+    CXCursorSet cset, CXCursor cursor);
+typedef NativeClang_getCursorSemanticParent = CXCursor Function(
+    CXCursor cursor);
+typedef DartClang_getCursorSemanticParent = CXCursor Function(CXCursor cursor);
+typedef NativeClang_getCursorLexicalParent = CXCursor Function(CXCursor cursor);
+typedef DartClang_getCursorLexicalParent = CXCursor Function(CXCursor cursor);
+typedef NativeClang_getOverriddenCursors = ffi.Void Function(
+    CXCursor cursor,
+    ffi.Pointer<ffi.Pointer<CXCursor>> overridden,
+    ffi.Pointer<ffi.UnsignedInt> num_overridden);
+typedef DartClang_getOverriddenCursors = void Function(
+    CXCursor cursor,
+    ffi.Pointer<ffi.Pointer<CXCursor>> overridden,
+    ffi.Pointer<ffi.UnsignedInt> num_overridden);
+typedef NativeClang_disposeOverriddenCursors = ffi.Void Function(
+    ffi.Pointer<CXCursor> overridden);
+typedef DartClang_disposeOverriddenCursors = void Function(
+    ffi.Pointer<CXCursor> overridden);
+typedef NativeClang_getIncludedFile = CXFile Function(CXCursor cursor);
+typedef DartClang_getIncludedFile = CXFile Function(CXCursor cursor);
+typedef NativeClang_getCursor = CXCursor Function(
+    CXTranslationUnit arg0, CXSourceLocation arg1);
+typedef DartClang_getCursor = CXCursor Function(
+    CXTranslationUnit arg0, CXSourceLocation arg1);
+typedef NativeClang_getCursorLocation = CXSourceLocation Function(
+    CXCursor arg0);
+typedef DartClang_getCursorLocation = CXSourceLocation Function(CXCursor arg0);
+typedef NativeClang_getCursorExtent = CXSourceRange Function(CXCursor arg0);
+typedef DartClang_getCursorExtent = CXSourceRange Function(CXCursor arg0);
+
+/// Describes the kind of type
+abstract class CXTypeKind {
+  /// Represents an invalid type (e.g., where no type is available).
+  static const int CXType_Invalid = 0;
+
+  /// A type whose specific kind is not exposed via this
+  /// interface.
+  static const int CXType_Unexposed = 1;
+  static const int CXType_Void = 2;
+  static const int CXType_Bool = 3;
+  static const int CXType_Char_U = 4;
+  static const int CXType_UChar = 5;
+  static const int CXType_Char16 = 6;
+  static const int CXType_Char32 = 7;
+  static const int CXType_UShort = 8;
+  static const int CXType_UInt = 9;
+  static const int CXType_ULong = 10;
+  static const int CXType_ULongLong = 11;
+  static const int CXType_UInt128 = 12;
+  static const int CXType_Char_S = 13;
+  static const int CXType_SChar = 14;
+  static const int CXType_WChar = 15;
+  static const int CXType_Short = 16;
+  static const int CXType_Int = 17;
+  static const int CXType_Long = 18;
+  static const int CXType_LongLong = 19;
+  static const int CXType_Int128 = 20;
+  static const int CXType_Float = 21;
+  static const int CXType_Double = 22;
+  static const int CXType_LongDouble = 23;
+  static const int CXType_NullPtr = 24;
+  static const int CXType_Overload = 25;
+  static const int CXType_Dependent = 26;
+  static const int CXType_ObjCId = 27;
+  static const int CXType_ObjCClass = 28;
+  static const int CXType_ObjCSel = 29;
+  static const int CXType_Float128 = 30;
+  static const int CXType_Half = 31;
+  static const int CXType_Float16 = 32;
+  static const int CXType_ShortAccum = 33;
+  static const int CXType_Accum = 34;
+  static const int CXType_LongAccum = 35;
+  static const int CXType_UShortAccum = 36;
+  static const int CXType_UAccum = 37;
+  static const int CXType_ULongAccum = 38;
+  static const int CXType_FirstBuiltin = 2;
+  static const int CXType_LastBuiltin = 38;
+  static const int CXType_Complex = 100;
+  static const int CXType_Pointer = 101;
+  static const int CXType_BlockPointer = 102;
+  static const int CXType_LValueReference = 103;
+  static const int CXType_RValueReference = 104;
+  static const int CXType_Record = 105;
+  static const int CXType_Enum = 106;
+  static const int CXType_Typedef = 107;
+  static const int CXType_ObjCInterface = 108;
+  static const int CXType_ObjCObjectPointer = 109;
+  static const int CXType_FunctionNoProto = 110;
+  static const int CXType_FunctionProto = 111;
+  static const int CXType_ConstantArray = 112;
+  static const int CXType_Vector = 113;
+  static const int CXType_IncompleteArray = 114;
+  static const int CXType_VariableArray = 115;
+  static const int CXType_DependentSizedArray = 116;
+  static const int CXType_MemberPointer = 117;
+  static const int CXType_Auto = 118;
+
+  /// Represents a type that was referred to using an elaborated type keyword.
+  ///
+  /// E.g., struct S, or via a qualified name, e.g., N::M::type, or both.
+  static const int CXType_Elaborated = 119;
+  static const int CXType_Pipe = 120;
+  static const int CXType_OCLImage1dRO = 121;
+  static const int CXType_OCLImage1dArrayRO = 122;
+  static const int CXType_OCLImage1dBufferRO = 123;
+  static const int CXType_OCLImage2dRO = 124;
+  static const int CXType_OCLImage2dArrayRO = 125;
+  static const int CXType_OCLImage2dDepthRO = 126;
+  static const int CXType_OCLImage2dArrayDepthRO = 127;
+  static const int CXType_OCLImage2dMSAARO = 128;
+  static const int CXType_OCLImage2dArrayMSAARO = 129;
+  static const int CXType_OCLImage2dMSAADepthRO = 130;
+  static const int CXType_OCLImage2dArrayMSAADepthRO = 131;
+  static const int CXType_OCLImage3dRO = 132;
+  static const int CXType_OCLImage1dWO = 133;
+  static const int CXType_OCLImage1dArrayWO = 134;
+  static const int CXType_OCLImage1dBufferWO = 135;
+  static const int CXType_OCLImage2dWO = 136;
+  static const int CXType_OCLImage2dArrayWO = 137;
+  static const int CXType_OCLImage2dDepthWO = 138;
+  static const int CXType_OCLImage2dArrayDepthWO = 139;
+  static const int CXType_OCLImage2dMSAAWO = 140;
+  static const int CXType_OCLImage2dArrayMSAAWO = 141;
+  static const int CXType_OCLImage2dMSAADepthWO = 142;
+  static const int CXType_OCLImage2dArrayMSAADepthWO = 143;
+  static const int CXType_OCLImage3dWO = 144;
+  static const int CXType_OCLImage1dRW = 145;
+  static const int CXType_OCLImage1dArrayRW = 146;
+  static const int CXType_OCLImage1dBufferRW = 147;
+  static const int CXType_OCLImage2dRW = 148;
+  static const int CXType_OCLImage2dArrayRW = 149;
+  static const int CXType_OCLImage2dDepthRW = 150;
+  static const int CXType_OCLImage2dArrayDepthRW = 151;
+  static const int CXType_OCLImage2dMSAARW = 152;
+  static const int CXType_OCLImage2dArrayMSAARW = 153;
+  static const int CXType_OCLImage2dMSAADepthRW = 154;
+  static const int CXType_OCLImage2dArrayMSAADepthRW = 155;
+  static const int CXType_OCLImage3dRW = 156;
+  static const int CXType_OCLSampler = 157;
+  static const int CXType_OCLEvent = 158;
+  static const int CXType_OCLQueue = 159;
+  static const int CXType_OCLReserveID = 160;
+  static const int CXType_ObjCObject = 161;
+  static const int CXType_ObjCTypeParam = 162;
+  static const int CXType_Attributed = 163;
+  static const int CXType_OCLIntelSubgroupAVCMcePayload = 164;
+  static const int CXType_OCLIntelSubgroupAVCImePayload = 165;
+  static const int CXType_OCLIntelSubgroupAVCRefPayload = 166;
+  static const int CXType_OCLIntelSubgroupAVCSicPayload = 167;
+  static const int CXType_OCLIntelSubgroupAVCMceResult = 168;
+  static const int CXType_OCLIntelSubgroupAVCImeResult = 169;
+  static const int CXType_OCLIntelSubgroupAVCRefResult = 170;
+  static const int CXType_OCLIntelSubgroupAVCSicResult = 171;
+  static const int CXType_OCLIntelSubgroupAVCImeResultSingleRefStreamout = 172;
+  static const int CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout = 173;
+  static const int CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174;
+  static const int CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175;
+  static const int CXType_ExtVector = 176;
+}
+
+/// The type of an element in the abstract syntax tree.
+final class CXType extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
+}
+
+typedef NativeClang_getCursorType = CXType Function(CXCursor C);
+typedef DartClang_getCursorType = CXType Function(CXCursor C);
+typedef NativeClang_getTypeSpelling = CXString Function(CXType CT);
+typedef DartClang_getTypeSpelling = CXString Function(CXType CT);
+typedef NativeClang_getTypedefDeclUnderlyingType = CXType Function(CXCursor C);
+typedef DartClang_getTypedefDeclUnderlyingType = CXType Function(CXCursor C);
+typedef NativeClang_getEnumDeclIntegerType = CXType Function(CXCursor C);
+typedef DartClang_getEnumDeclIntegerType = CXType Function(CXCursor C);
+typedef NativeClang_getEnumConstantDeclValue = ffi.LongLong Function(
+    CXCursor C);
+typedef DartClang_getEnumConstantDeclValue = int Function(CXCursor C);
+typedef NativeClang_getEnumConstantDeclUnsignedValue = ffi.UnsignedLongLong
+    Function(CXCursor C);
+typedef DartClang_getEnumConstantDeclUnsignedValue = int Function(CXCursor C);
+typedef NativeClang_getFieldDeclBitWidth = ffi.Int Function(CXCursor C);
+typedef DartClang_getFieldDeclBitWidth = int Function(CXCursor C);
+typedef NativeClang_Cursor_getNumArguments = ffi.Int Function(CXCursor C);
+typedef DartClang_Cursor_getNumArguments = int Function(CXCursor C);
+typedef NativeClang_Cursor_getArgument = CXCursor Function(
+    CXCursor C, ffi.UnsignedInt i);
+typedef DartClang_Cursor_getArgument = CXCursor Function(CXCursor C, int i);
+typedef NativeClang_Cursor_getNumTemplateArguments = ffi.Int Function(
+    CXCursor C);
+typedef DartClang_Cursor_getNumTemplateArguments = int Function(CXCursor C);
+
+/// Describes the kind of a template argument.
+///
+/// See the definition of llvm::clang::TemplateArgument::ArgKind for full
+/// element descriptions.
+abstract class CXTemplateArgumentKind {
+  static const int CXTemplateArgumentKind_Null = 0;
+  static const int CXTemplateArgumentKind_Type = 1;
+  static const int CXTemplateArgumentKind_Declaration = 2;
+  static const int CXTemplateArgumentKind_NullPtr = 3;
+  static const int CXTemplateArgumentKind_Integral = 4;
+  static const int CXTemplateArgumentKind_Template = 5;
+  static const int CXTemplateArgumentKind_TemplateExpansion = 6;
+  static const int CXTemplateArgumentKind_Expression = 7;
+  static const int CXTemplateArgumentKind_Pack = 8;
+  static const int CXTemplateArgumentKind_Invalid = 9;
+}
+
+typedef NativeClang_Cursor_getTemplateArgumentKind = ffi.Int32 Function(
+    CXCursor C, ffi.UnsignedInt I);
+typedef DartClang_Cursor_getTemplateArgumentKind = int Function(
+    CXCursor C, int I);
+typedef NativeClang_Cursor_getTemplateArgumentType = CXType Function(
+    CXCursor C, ffi.UnsignedInt I);
+typedef DartClang_Cursor_getTemplateArgumentType = CXType Function(
+    CXCursor C, int I);
+typedef NativeClang_Cursor_getTemplateArgumentValue = ffi.LongLong Function(
+    CXCursor C, ffi.UnsignedInt I);
+typedef DartClang_Cursor_getTemplateArgumentValue = int Function(
+    CXCursor C, int I);
+typedef NativeClang_Cursor_getTemplateArgumentUnsignedValue
+    = ffi.UnsignedLongLong Function(CXCursor C, ffi.UnsignedInt I);
+typedef DartClang_Cursor_getTemplateArgumentUnsignedValue = int Function(
+    CXCursor C, int I);
+typedef NativeClang_equalTypes = ffi.UnsignedInt Function(CXType A, CXType B);
+typedef DartClang_equalTypes = int Function(CXType A, CXType B);
+typedef NativeClang_getCanonicalType = CXType Function(CXType T);
+typedef DartClang_getCanonicalType = CXType Function(CXType T);
+typedef NativeClang_isConstQualifiedType = ffi.UnsignedInt Function(CXType T);
+typedef DartClang_isConstQualifiedType = int Function(CXType T);
+typedef NativeClang_Cursor_isMacroFunctionLike = ffi.UnsignedInt Function(
+    CXCursor C);
+typedef DartClang_Cursor_isMacroFunctionLike = int Function(CXCursor C);
+typedef NativeClang_Cursor_isMacroBuiltin = ffi.UnsignedInt Function(
+    CXCursor C);
+typedef DartClang_Cursor_isMacroBuiltin = int Function(CXCursor C);
+typedef NativeClang_Cursor_isFunctionInlined = ffi.UnsignedInt Function(
+    CXCursor C);
+typedef DartClang_Cursor_isFunctionInlined = int Function(CXCursor C);
+typedef NativeClang_isVolatileQualifiedType = ffi.UnsignedInt Function(
+    CXType T);
+typedef DartClang_isVolatileQualifiedType = int Function(CXType T);
+typedef NativeClang_isRestrictQualifiedType = ffi.UnsignedInt Function(
+    CXType T);
+typedef DartClang_isRestrictQualifiedType = int Function(CXType T);
+typedef NativeClang_getAddressSpace = ffi.UnsignedInt Function(CXType T);
+typedef DartClang_getAddressSpace = int Function(CXType T);
+typedef NativeClang_getTypedefName = CXString Function(CXType CT);
+typedef DartClang_getTypedefName = CXString Function(CXType CT);
+typedef NativeClang_getPointeeType = CXType Function(CXType T);
+typedef DartClang_getPointeeType = CXType Function(CXType T);
+typedef NativeClang_getTypeDeclaration = CXCursor Function(CXType T);
+typedef DartClang_getTypeDeclaration = CXCursor Function(CXType T);
+typedef NativeClang_getDeclObjCTypeEncoding = CXString Function(CXCursor C);
+typedef DartClang_getDeclObjCTypeEncoding = CXString Function(CXCursor C);
+typedef NativeClang_Type_getObjCEncoding = CXString Function(CXType type);
+typedef DartClang_Type_getObjCEncoding = CXString Function(CXType type);
+typedef NativeClang_getTypeKindSpelling = CXString Function(ffi.Int32 K);
+typedef DartClang_getTypeKindSpelling = CXString Function(int K);
+
+/// Describes the calling convention of a function type
+abstract class CXCallingConv {
+  static const int CXCallingConv_Default = 0;
+  static const int CXCallingConv_C = 1;
+  static const int CXCallingConv_X86StdCall = 2;
+  static const int CXCallingConv_X86FastCall = 3;
+  static const int CXCallingConv_X86ThisCall = 4;
+  static const int CXCallingConv_X86Pascal = 5;
+  static const int CXCallingConv_AAPCS = 6;
+  static const int CXCallingConv_AAPCS_VFP = 7;
+  static const int CXCallingConv_X86RegCall = 8;
+  static const int CXCallingConv_IntelOclBicc = 9;
+  static const int CXCallingConv_Win64 = 10;
+  static const int CXCallingConv_X86_64Win64 = 10;
+  static const int CXCallingConv_X86_64SysV = 11;
+  static const int CXCallingConv_X86VectorCall = 12;
+  static const int CXCallingConv_Swift = 13;
+  static const int CXCallingConv_PreserveMost = 14;
+  static const int CXCallingConv_PreserveAll = 15;
+  static const int CXCallingConv_AArch64VectorCall = 16;
+  static const int CXCallingConv_Invalid = 100;
+  static const int CXCallingConv_Unexposed = 200;
+}
+
+typedef NativeClang_getFunctionTypeCallingConv = ffi.Int32 Function(CXType T);
+typedef DartClang_getFunctionTypeCallingConv = int Function(CXType T);
+typedef NativeClang_getResultType = CXType Function(CXType T);
+typedef DartClang_getResultType = CXType Function(CXType T);
+typedef NativeClang_getExceptionSpecificationType = ffi.Int Function(CXType T);
+typedef DartClang_getExceptionSpecificationType = int Function(CXType T);
+typedef NativeClang_getNumArgTypes = ffi.Int Function(CXType T);
+typedef DartClang_getNumArgTypes = int Function(CXType T);
+typedef NativeClang_getArgType = CXType Function(CXType T, ffi.UnsignedInt i);
+typedef DartClang_getArgType = CXType Function(CXType T, int i);
+typedef NativeClang_Type_getObjCObjectBaseType = CXType Function(CXType T);
+typedef DartClang_Type_getObjCObjectBaseType = CXType Function(CXType T);
+typedef NativeClang_Type_getNumObjCProtocolRefs = ffi.UnsignedInt Function(
+    CXType T);
+typedef DartClang_Type_getNumObjCProtocolRefs = int Function(CXType T);
+typedef NativeClang_Type_getObjCProtocolDecl = CXCursor Function(
+    CXType T, ffi.UnsignedInt i);
+typedef DartClang_Type_getObjCProtocolDecl = CXCursor Function(CXType T, int i);
+typedef NativeClang_Type_getNumObjCTypeArgs = ffi.UnsignedInt Function(
+    CXType T);
+typedef DartClang_Type_getNumObjCTypeArgs = int Function(CXType T);
+typedef NativeClang_Type_getObjCTypeArg = CXType Function(
+    CXType T, ffi.UnsignedInt i);
+typedef DartClang_Type_getObjCTypeArg = CXType Function(CXType T, int i);
+typedef NativeClang_isFunctionTypeVariadic = ffi.UnsignedInt Function(CXType T);
+typedef DartClang_isFunctionTypeVariadic = int Function(CXType T);
+typedef NativeClang_getCursorResultType = CXType Function(CXCursor C);
+typedef DartClang_getCursorResultType = CXType Function(CXCursor C);
+typedef NativeClang_getCursorExceptionSpecificationType = ffi.Int Function(
+    CXCursor C);
+typedef DartClang_getCursorExceptionSpecificationType = int Function(
+    CXCursor C);
+typedef NativeClang_isPODType = ffi.UnsignedInt Function(CXType T);
+typedef DartClang_isPODType = int Function(CXType T);
+typedef NativeClang_getElementType = CXType Function(CXType T);
+typedef DartClang_getElementType = CXType Function(CXType T);
+typedef NativeClang_getNumElements = ffi.LongLong Function(CXType T);
+typedef DartClang_getNumElements = int Function(CXType T);
+typedef NativeClang_getArrayElementType = CXType Function(CXType T);
+typedef DartClang_getArrayElementType = CXType Function(CXType T);
+typedef NativeClang_getArraySize = ffi.LongLong Function(CXType T);
+typedef DartClang_getArraySize = int Function(CXType T);
+typedef NativeClang_Type_getNamedType = CXType Function(CXType T);
+typedef DartClang_Type_getNamedType = CXType Function(CXType T);
+typedef NativeClang_Type_isTransparentTagTypedef = ffi.UnsignedInt Function(
+    CXType T);
+typedef DartClang_Type_isTransparentTagTypedef = int Function(CXType T);
+
+abstract class CXTypeNullabilityKind {
+  /// Values of this type can never be null.
+  static const int CXTypeNullability_NonNull = 0;
+
+  /// Values of this type can be null.
+  static const int CXTypeNullability_Nullable = 1;
+
+  /// Whether values of this type can be null is (explicitly)
+  /// unspecified. This captures a (fairly rare) case where we
+  /// can't conclude anything about the nullability of the type even
+  /// though it has been considered.
+  static const int CXTypeNullability_Unspecified = 2;
+
+  /// Nullability is not applicable to this type.
+  static const int CXTypeNullability_Invalid = 3;
+}
+
+typedef NativeClang_Type_getNullability = ffi.Int32 Function(CXType T);
+typedef DartClang_Type_getNullability = int Function(CXType T);
+typedef NativeClang_Type_getAlignOf = ffi.LongLong Function(CXType T);
+typedef DartClang_Type_getAlignOf = int Function(CXType T);
+typedef NativeClang_Type_getClassType = CXType Function(CXType T);
+typedef DartClang_Type_getClassType = CXType Function(CXType T);
+typedef NativeClang_Type_getSizeOf = ffi.LongLong Function(CXType T);
+typedef DartClang_Type_getSizeOf = int Function(CXType T);
+typedef NativeClang_Type_getOffsetOf = ffi.LongLong Function(
+    CXType T, ffi.Pointer<ffi.Char> S);
+typedef DartClang_Type_getOffsetOf = int Function(
+    CXType T, ffi.Pointer<ffi.Char> S);
+typedef NativeClang_Type_getModifiedType = CXType Function(CXType T);
+typedef DartClang_Type_getModifiedType = CXType Function(CXType T);
+typedef NativeClang_Cursor_getOffsetOfField = ffi.LongLong Function(CXCursor C);
+typedef DartClang_Cursor_getOffsetOfField = int Function(CXCursor C);
+typedef NativeClang_Cursor_isAnonymous = ffi.UnsignedInt Function(CXCursor C);
+typedef DartClang_Cursor_isAnonymous = int Function(CXCursor C);
+typedef NativeClang_Cursor_isAnonymousRecordDecl = ffi.UnsignedInt Function(
+    CXCursor C);
+typedef DartClang_Cursor_isAnonymousRecordDecl = int Function(CXCursor C);
+typedef NativeClang_Cursor_isInlineNamespace = ffi.UnsignedInt Function(
+    CXCursor C);
+typedef DartClang_Cursor_isInlineNamespace = int Function(CXCursor C);
+typedef NativeClang_Type_getNumTemplateArguments = ffi.Int Function(CXType T);
+typedef DartClang_Type_getNumTemplateArguments = int Function(CXType T);
+typedef NativeClang_Type_getTemplateArgumentAsType = CXType Function(
+    CXType T, ffi.UnsignedInt i);
+typedef DartClang_Type_getTemplateArgumentAsType = CXType Function(
+    CXType T, int i);
+
+abstract class CXRefQualifierKind {
+  /// No ref-qualifier was provided.
+  static const int CXRefQualifier_None = 0;
+
+  /// An lvalue ref-qualifier was provided (\c &).
+  static const int CXRefQualifier_LValue = 1;
+
+  /// An rvalue ref-qualifier was provided (\c &&).
+  static const int CXRefQualifier_RValue = 2;
+}
+
+typedef NativeClang_Type_getCXXRefQualifier = ffi.Int32 Function(CXType T);
+typedef DartClang_Type_getCXXRefQualifier = int Function(CXType T);
+typedef NativeClang_Cursor_isBitField = ffi.UnsignedInt Function(CXCursor C);
+typedef DartClang_Cursor_isBitField = int Function(CXCursor C);
+typedef NativeClang_isVirtualBase = ffi.UnsignedInt Function(CXCursor arg0);
+typedef DartClang_isVirtualBase = int Function(CXCursor arg0);
+
+/// Represents the C++ access control level to a base class for a
+/// cursor with kind CX_CXXBaseSpecifier.
+abstract class CX_CXXAccessSpecifier {
+  static const int CX_CXXInvalidAccessSpecifier = 0;
+  static const int CX_CXXPublic = 1;
+  static const int CX_CXXProtected = 2;
+  static const int CX_CXXPrivate = 3;
+}
+
+typedef NativeClang_getCXXAccessSpecifier = ffi.Int32 Function(CXCursor arg0);
+typedef DartClang_getCXXAccessSpecifier = int Function(CXCursor arg0);
+
+/// Represents the storage classes as declared in the source. CX_SC_Invalid
+/// was added for the case that the passed cursor in not a declaration.
+abstract class CX_StorageClass {
+  static const int CX_SC_Invalid = 0;
+  static const int CX_SC_None = 1;
+  static const int CX_SC_Extern = 2;
+  static const int CX_SC_Static = 3;
+  static const int CX_SC_PrivateExtern = 4;
+  static const int CX_SC_OpenCLWorkGroupLocal = 5;
+  static const int CX_SC_Auto = 6;
+  static const int CX_SC_Register = 7;
+}
+
+typedef NativeClang_Cursor_getStorageClass = ffi.Int32 Function(CXCursor arg0);
+typedef DartClang_Cursor_getStorageClass = int Function(CXCursor arg0);
+typedef NativeClang_getNumOverloadedDecls = ffi.UnsignedInt Function(
+    CXCursor cursor);
+typedef DartClang_getNumOverloadedDecls = int Function(CXCursor cursor);
+typedef NativeClang_getOverloadedDecl = CXCursor Function(
+    CXCursor cursor, ffi.UnsignedInt index);
+typedef DartClang_getOverloadedDecl = CXCursor Function(
+    CXCursor cursor, int index);
+typedef NativeClang_getIBOutletCollectionType = CXType Function(CXCursor arg0);
+typedef DartClang_getIBOutletCollectionType = CXType Function(CXCursor arg0);
+
+/// Visitor invoked for each cursor found by a traversal.
+///
+/// This visitor function will be invoked for each cursor found by
+/// clang_visitCursorChildren(). Its first argument is the cursor being
+/// visited, its second argument is the parent visitor for that cursor,
+/// and its third argument is the client data provided to
+/// clang_visitCursorChildren().
+///
+/// The visitor should return one of the \c CXChildVisitResult values
+/// to direct clang_visitCursorChildren().
+typedef CXCursorVisitor
+    = ffi.Pointer<ffi.NativeFunction<CXCursorVisitorFunction>>;
+typedef CXCursorVisitorFunction = ffi.Int32 Function(
+    CXCursor cursor, CXCursor parent, CXClientData client_data);
+typedef DartCXCursorVisitorFunction = int Function(
+    CXCursor cursor, CXCursor parent, CXClientData client_data);
+
+/// Describes how the traversal of the children of a particular
+/// cursor should proceed after visiting a particular child cursor.
+///
+/// A value of this enumeration type should be returned by each
+/// \c CXCursorVisitor to indicate how clang_visitChildren() proceed.
+abstract class CXChildVisitResult {
+  /// Terminates the cursor traversal.
+  static const int CXChildVisit_Break = 0;
+
+  /// Continues the cursor traversal with the next sibling of
+  /// the cursor just visited, without visiting its children.
+  static const int CXChildVisit_Continue = 1;
+
+  /// Recursively traverse the children of this cursor, using
+  /// the same visitor and client data.
+  static const int CXChildVisit_Recurse = 2;
+}
+
+/// Opaque pointer representing client data that will be passed through
+/// to various callbacks and visitors.
+typedef CXClientData = ffi.Pointer<ffi.Void>;
+typedef NativeClang_visitChildren = ffi.UnsignedInt Function(
+    CXCursor parent, CXCursorVisitor visitor, CXClientData client_data);
+typedef DartClang_visitChildren = int Function(
+    CXCursor parent, CXCursorVisitor visitor, CXClientData client_data);
+typedef NativeClang_getCursorUSR = CXString Function(CXCursor arg0);
+typedef DartClang_getCursorUSR = CXString Function(CXCursor arg0);
+typedef NativeClang_constructUSR_ObjCClass = CXString Function(
+    ffi.Pointer<ffi.Char> class_name);
+typedef DartClang_constructUSR_ObjCClass = CXString Function(
+    ffi.Pointer<ffi.Char> class_name);
+typedef NativeClang_constructUSR_ObjCCategory = CXString Function(
+    ffi.Pointer<ffi.Char> class_name, ffi.Pointer<ffi.Char> category_name);
+typedef DartClang_constructUSR_ObjCCategory = CXString Function(
+    ffi.Pointer<ffi.Char> class_name, ffi.Pointer<ffi.Char> category_name);
+typedef NativeClang_constructUSR_ObjCProtocol = CXString Function(
+    ffi.Pointer<ffi.Char> protocol_name);
+typedef DartClang_constructUSR_ObjCProtocol = CXString Function(
+    ffi.Pointer<ffi.Char> protocol_name);
+typedef NativeClang_constructUSR_ObjCIvar = CXString Function(
+    ffi.Pointer<ffi.Char> name, CXString classUSR);
+typedef DartClang_constructUSR_ObjCIvar = CXString Function(
+    ffi.Pointer<ffi.Char> name, CXString classUSR);
+typedef NativeClang_constructUSR_ObjCMethod = CXString Function(
+    ffi.Pointer<ffi.Char> name,
+    ffi.UnsignedInt isInstanceMethod,
+    CXString classUSR);
+typedef DartClang_constructUSR_ObjCMethod = CXString Function(
+    ffi.Pointer<ffi.Char> name, int isInstanceMethod, CXString classUSR);
+typedef NativeClang_constructUSR_ObjCProperty = CXString Function(
+    ffi.Pointer<ffi.Char> property, CXString classUSR);
+typedef DartClang_constructUSR_ObjCProperty = CXString Function(
+    ffi.Pointer<ffi.Char> property, CXString classUSR);
+typedef NativeClang_getCursorSpelling = CXString Function(CXCursor arg0);
+typedef DartClang_getCursorSpelling = CXString Function(CXCursor arg0);
+typedef NativeClang_Cursor_getSpellingNameRange = CXSourceRange Function(
+    CXCursor arg0, ffi.UnsignedInt pieceIndex, ffi.UnsignedInt options);
+typedef DartClang_Cursor_getSpellingNameRange = CXSourceRange Function(
+    CXCursor arg0, int pieceIndex, int options);
+
+/// Opaque pointer representing a policy that controls pretty printing
+/// for \c clang_getCursorPrettyPrinted.
+typedef CXPrintingPolicy = ffi.Pointer<ffi.Void>;
+
+/// Properties for the printing policy.
+///
+/// See \c clang::PrintingPolicy for more information.
+abstract class CXPrintingPolicyProperty {
+  static const int CXPrintingPolicy_Indentation = 0;
+  static const int CXPrintingPolicy_SuppressSpecifiers = 1;
+  static const int CXPrintingPolicy_SuppressTagKeyword = 2;
+  static const int CXPrintingPolicy_IncludeTagDefinition = 3;
+  static const int CXPrintingPolicy_SuppressScope = 4;
+  static const int CXPrintingPolicy_SuppressUnwrittenScope = 5;
+  static const int CXPrintingPolicy_SuppressInitializers = 6;
+  static const int CXPrintingPolicy_ConstantArraySizeAsWritten = 7;
+  static const int CXPrintingPolicy_AnonymousTagLocations = 8;
+  static const int CXPrintingPolicy_SuppressStrongLifetime = 9;
+  static const int CXPrintingPolicy_SuppressLifetimeQualifiers = 10;
+  static const int CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors = 11;
+  static const int CXPrintingPolicy_Bool = 12;
+  static const int CXPrintingPolicy_Restrict = 13;
+  static const int CXPrintingPolicy_Alignof = 14;
+  static const int CXPrintingPolicy_UnderscoreAlignof = 15;
+  static const int CXPrintingPolicy_UseVoidForZeroParams = 16;
+  static const int CXPrintingPolicy_TerseOutput = 17;
+  static const int CXPrintingPolicy_PolishForDeclaration = 18;
+  static const int CXPrintingPolicy_Half = 19;
+  static const int CXPrintingPolicy_MSWChar = 20;
+  static const int CXPrintingPolicy_IncludeNewlines = 21;
+  static const int CXPrintingPolicy_MSVCFormatting = 22;
+  static const int CXPrintingPolicy_ConstantsAsWritten = 23;
+  static const int CXPrintingPolicy_SuppressImplicitBase = 24;
+  static const int CXPrintingPolicy_FullyQualifiedName = 25;
+  static const int CXPrintingPolicy_LastProperty = 25;
+}
+
+typedef NativeClang_PrintingPolicy_getProperty = ffi.UnsignedInt Function(
+    CXPrintingPolicy Policy, ffi.Int32 Property);
+typedef DartClang_PrintingPolicy_getProperty = int Function(
+    CXPrintingPolicy Policy, int Property);
+typedef NativeClang_PrintingPolicy_setProperty = ffi.Void Function(
+    CXPrintingPolicy Policy, ffi.Int32 Property, ffi.UnsignedInt Value);
+typedef DartClang_PrintingPolicy_setProperty = void Function(
+    CXPrintingPolicy Policy, int Property, int Value);
+typedef NativeClang_getCursorPrintingPolicy = CXPrintingPolicy Function(
+    CXCursor arg0);
+typedef DartClang_getCursorPrintingPolicy = CXPrintingPolicy Function(
+    CXCursor arg0);
+typedef NativeClang_PrintingPolicy_dispose = ffi.Void Function(
+    CXPrintingPolicy Policy);
+typedef DartClang_PrintingPolicy_dispose = void Function(
+    CXPrintingPolicy Policy);
+typedef NativeClang_getCursorPrettyPrinted = CXString Function(
+    CXCursor Cursor, CXPrintingPolicy Policy);
+typedef DartClang_getCursorPrettyPrinted = CXString Function(
+    CXCursor Cursor, CXPrintingPolicy Policy);
+typedef NativeClang_getCursorDisplayName = CXString Function(CXCursor arg0);
+typedef DartClang_getCursorDisplayName = CXString Function(CXCursor arg0);
+typedef NativeClang_getCursorReferenced = CXCursor Function(CXCursor arg0);
+typedef DartClang_getCursorReferenced = CXCursor Function(CXCursor arg0);
+typedef NativeClang_getCursorDefinition = CXCursor Function(CXCursor arg0);
+typedef DartClang_getCursorDefinition = CXCursor Function(CXCursor arg0);
+typedef NativeClang_isCursorDefinition = ffi.UnsignedInt Function(
+    CXCursor arg0);
+typedef DartClang_isCursorDefinition = int Function(CXCursor arg0);
+typedef NativeClang_getCanonicalCursor = CXCursor Function(CXCursor arg0);
+typedef DartClang_getCanonicalCursor = CXCursor Function(CXCursor arg0);
+typedef NativeClang_Cursor_getObjCSelectorIndex = ffi.Int Function(
+    CXCursor arg0);
+typedef DartClang_Cursor_getObjCSelectorIndex = int Function(CXCursor arg0);
+typedef NativeClang_Cursor_isDynamicCall = ffi.Int Function(CXCursor C);
+typedef DartClang_Cursor_isDynamicCall = int Function(CXCursor C);
+typedef NativeClang_Cursor_getReceiverType = CXType Function(CXCursor C);
+typedef DartClang_Cursor_getReceiverType = CXType Function(CXCursor C);
+typedef NativeClang_Cursor_getObjCPropertyAttributes = ffi.UnsignedInt Function(
+    CXCursor C, ffi.UnsignedInt reserved);
+typedef DartClang_Cursor_getObjCPropertyAttributes = int Function(
+    CXCursor C, int reserved);
+typedef NativeClang_Cursor_getObjCPropertyGetterName = CXString Function(
+    CXCursor C);
+typedef DartClang_Cursor_getObjCPropertyGetterName = CXString Function(
+    CXCursor C);
+typedef NativeClang_Cursor_getObjCPropertySetterName = CXString Function(
+    CXCursor C);
+typedef DartClang_Cursor_getObjCPropertySetterName = CXString Function(
+    CXCursor C);
+typedef NativeClang_Cursor_getObjCDeclQualifiers = ffi.UnsignedInt Function(
+    CXCursor C);
+typedef DartClang_Cursor_getObjCDeclQualifiers = int Function(CXCursor C);
+typedef NativeClang_Cursor_isObjCOptional = ffi.UnsignedInt Function(
+    CXCursor C);
+typedef DartClang_Cursor_isObjCOptional = int Function(CXCursor C);
+typedef NativeClang_Cursor_isVariadic = ffi.UnsignedInt Function(CXCursor C);
+typedef DartClang_Cursor_isVariadic = int Function(CXCursor C);
+typedef NativeClang_Cursor_isExternalSymbol = ffi.UnsignedInt Function(
+    CXCursor C,
+    ffi.Pointer<CXString> language,
+    ffi.Pointer<CXString> definedIn,
+    ffi.Pointer<ffi.UnsignedInt> isGenerated);
+typedef DartClang_Cursor_isExternalSymbol = int Function(
+    CXCursor C,
+    ffi.Pointer<CXString> language,
+    ffi.Pointer<CXString> definedIn,
+    ffi.Pointer<ffi.UnsignedInt> isGenerated);
+typedef NativeClang_Cursor_getCommentRange = CXSourceRange Function(CXCursor C);
+typedef DartClang_Cursor_getCommentRange = CXSourceRange Function(CXCursor C);
+typedef NativeClang_Cursor_getRawCommentText = CXString Function(CXCursor C);
+typedef DartClang_Cursor_getRawCommentText = CXString Function(CXCursor C);
+typedef NativeClang_Cursor_getBriefCommentText = CXString Function(CXCursor C);
+typedef DartClang_Cursor_getBriefCommentText = CXString Function(CXCursor C);
+typedef NativeClang_Cursor_getMangling = CXString Function(CXCursor arg0);
+typedef DartClang_Cursor_getMangling = CXString Function(CXCursor arg0);
+typedef NativeClang_Cursor_getCXXManglings = ffi.Pointer<CXStringSet> Function(
+    CXCursor arg0);
+typedef DartClang_Cursor_getCXXManglings = ffi.Pointer<CXStringSet> Function(
+    CXCursor arg0);
+typedef NativeClang_Cursor_getObjCManglings = ffi.Pointer<CXStringSet> Function(
+    CXCursor arg0);
+typedef DartClang_Cursor_getObjCManglings = ffi.Pointer<CXStringSet> Function(
+    CXCursor arg0);
+
+/// \defgroup CINDEX_MODULE Module introspection
+///
+/// The functions in this group provide access to information about modules.
+///
+/// @{
+typedef CXModule = ffi.Pointer<ffi.Void>;
+typedef NativeClang_Cursor_getModule = CXModule Function(CXCursor C);
+typedef DartClang_Cursor_getModule = CXModule Function(CXCursor C);
+typedef NativeClang_getModuleForFile = CXModule Function(
+    CXTranslationUnit arg0, CXFile arg1);
+typedef DartClang_getModuleForFile = CXModule Function(
+    CXTranslationUnit arg0, CXFile arg1);
+typedef NativeClang_Module_getASTFile = CXFile Function(CXModule Module);
+typedef DartClang_Module_getASTFile = CXFile Function(CXModule Module);
+typedef NativeClang_Module_getParent = CXModule Function(CXModule Module);
+typedef DartClang_Module_getParent = CXModule Function(CXModule Module);
+typedef NativeClang_Module_getName = CXString Function(CXModule Module);
+typedef DartClang_Module_getName = CXString Function(CXModule Module);
+typedef NativeClang_Module_getFullName = CXString Function(CXModule Module);
+typedef DartClang_Module_getFullName = CXString Function(CXModule Module);
+typedef NativeClang_Module_isSystem = ffi.Int Function(CXModule Module);
+typedef DartClang_Module_isSystem = int Function(CXModule Module);
+typedef NativeClang_Module_getNumTopLevelHeaders = ffi.UnsignedInt Function(
+    CXTranslationUnit arg0, CXModule Module);
+typedef DartClang_Module_getNumTopLevelHeaders = int Function(
+    CXTranslationUnit arg0, CXModule Module);
+typedef NativeClang_Module_getTopLevelHeader = CXFile Function(
+    CXTranslationUnit arg0, CXModule Module, ffi.UnsignedInt Index);
+typedef DartClang_Module_getTopLevelHeader = CXFile Function(
+    CXTranslationUnit arg0, CXModule Module, int Index);
+typedef NativeClang_CXXConstructor_isConvertingConstructor = ffi.UnsignedInt
+    Function(CXCursor C);
+typedef DartClang_CXXConstructor_isConvertingConstructor = int Function(
+    CXCursor C);
+typedef NativeClang_CXXConstructor_isCopyConstructor = ffi.UnsignedInt Function(
+    CXCursor C);
+typedef DartClang_CXXConstructor_isCopyConstructor = int Function(CXCursor C);
+typedef NativeClang_CXXConstructor_isDefaultConstructor = ffi.UnsignedInt
+    Function(CXCursor C);
+typedef DartClang_CXXConstructor_isDefaultConstructor = int Function(
+    CXCursor C);
+typedef NativeClang_CXXConstructor_isMoveConstructor = ffi.UnsignedInt Function(
+    CXCursor C);
+typedef DartClang_CXXConstructor_isMoveConstructor = int Function(CXCursor C);
+typedef NativeClang_CXXField_isMutable = ffi.UnsignedInt Function(CXCursor C);
+typedef DartClang_CXXField_isMutable = int Function(CXCursor C);
+typedef NativeClang_CXXMethod_isDefaulted = ffi.UnsignedInt Function(
+    CXCursor C);
+typedef DartClang_CXXMethod_isDefaulted = int Function(CXCursor C);
+typedef NativeClang_CXXMethod_isPureVirtual = ffi.UnsignedInt Function(
+    CXCursor C);
+typedef DartClang_CXXMethod_isPureVirtual = int Function(CXCursor C);
+typedef NativeClang_CXXMethod_isStatic = ffi.UnsignedInt Function(CXCursor C);
+typedef DartClang_CXXMethod_isStatic = int Function(CXCursor C);
+typedef NativeClang_CXXMethod_isVirtual = ffi.UnsignedInt Function(CXCursor C);
+typedef DartClang_CXXMethod_isVirtual = int Function(CXCursor C);
+typedef NativeClang_CXXRecord_isAbstract = ffi.UnsignedInt Function(CXCursor C);
+typedef DartClang_CXXRecord_isAbstract = int Function(CXCursor C);
+typedef NativeClang_EnumDecl_isScoped = ffi.UnsignedInt Function(CXCursor C);
+typedef DartClang_EnumDecl_isScoped = int Function(CXCursor C);
+typedef NativeClang_CXXMethod_isConst = ffi.UnsignedInt Function(CXCursor C);
+typedef DartClang_CXXMethod_isConst = int Function(CXCursor C);
+typedef NativeClang_getTemplateCursorKind = ffi.Int32 Function(CXCursor C);
+typedef DartClang_getTemplateCursorKind = int Function(CXCursor C);
+typedef NativeClang_getSpecializedCursorTemplate = CXCursor Function(
+    CXCursor C);
+typedef DartClang_getSpecializedCursorTemplate = CXCursor Function(CXCursor C);
+typedef NativeClang_getCursorReferenceNameRange = CXSourceRange Function(
+    CXCursor C, ffi.UnsignedInt NameFlags, ffi.UnsignedInt PieceIndex);
+typedef DartClang_getCursorReferenceNameRange = CXSourceRange Function(
+    CXCursor C, int NameFlags, int PieceIndex);
+
+/// Describes a single preprocessing token.
+final class CXToken extends ffi.Struct {
+  @ffi.Array.multi([4])
+  external ffi.Array<ffi.UnsignedInt> int_data;
+
+  external ffi.Pointer<ffi.Void> ptr_data;
+}
+
+typedef NativeClang_getToken = ffi.Pointer<CXToken> Function(
+    CXTranslationUnit TU, CXSourceLocation Location);
+typedef DartClang_getToken = ffi.Pointer<CXToken> Function(
+    CXTranslationUnit TU, CXSourceLocation Location);
+
+/// Describes a kind of token.
+abstract class CXTokenKind {
+  /// A token that contains some kind of punctuation.
+  static const int CXToken_Punctuation = 0;
+
+  /// A language keyword.
+  static const int CXToken_Keyword = 1;
+
+  /// An identifier (that is not a keyword).
+  static const int CXToken_Identifier = 2;
+
+  /// A numeric, string, or character literal.
+  static const int CXToken_Literal = 3;
+
+  /// A comment.
+  static const int CXToken_Comment = 4;
+}
+
+typedef NativeClang_getTokenKind = ffi.Int32 Function(CXToken arg0);
+typedef DartClang_getTokenKind = int Function(CXToken arg0);
+typedef NativeClang_getTokenSpelling = CXString Function(
+    CXTranslationUnit arg0, CXToken arg1);
+typedef DartClang_getTokenSpelling = CXString Function(
+    CXTranslationUnit arg0, CXToken arg1);
+typedef NativeClang_getTokenLocation = CXSourceLocation Function(
+    CXTranslationUnit arg0, CXToken arg1);
+typedef DartClang_getTokenLocation = CXSourceLocation Function(
+    CXTranslationUnit arg0, CXToken arg1);
+typedef NativeClang_getTokenExtent = CXSourceRange Function(
+    CXTranslationUnit arg0, CXToken arg1);
+typedef DartClang_getTokenExtent = CXSourceRange Function(
+    CXTranslationUnit arg0, CXToken arg1);
+typedef NativeClang_tokenize = ffi.Void Function(
+    CXTranslationUnit TU,
+    CXSourceRange Range,
+    ffi.Pointer<ffi.Pointer<CXToken>> Tokens,
+    ffi.Pointer<ffi.UnsignedInt> NumTokens);
+typedef DartClang_tokenize = void Function(
+    CXTranslationUnit TU,
+    CXSourceRange Range,
+    ffi.Pointer<ffi.Pointer<CXToken>> Tokens,
+    ffi.Pointer<ffi.UnsignedInt> NumTokens);
+typedef NativeClang_annotateTokens = ffi.Void Function(
+    CXTranslationUnit TU,
+    ffi.Pointer<CXToken> Tokens,
+    ffi.UnsignedInt NumTokens,
+    ffi.Pointer<CXCursor> Cursors);
+typedef DartClang_annotateTokens = void Function(CXTranslationUnit TU,
+    ffi.Pointer<CXToken> Tokens, int NumTokens, ffi.Pointer<CXCursor> Cursors);
+typedef NativeClang_disposeTokens = ffi.Void Function(CXTranslationUnit TU,
+    ffi.Pointer<CXToken> Tokens, ffi.UnsignedInt NumTokens);
+typedef DartClang_disposeTokens = void Function(
+    CXTranslationUnit TU, ffi.Pointer<CXToken> Tokens, int NumTokens);
+typedef NativeClang_getCursorKindSpelling = CXString Function(ffi.Int32 Kind);
+typedef DartClang_getCursorKindSpelling = CXString Function(int Kind);
+typedef NativeClang_getDefinitionSpellingAndExtent = ffi.Void Function(
+    CXCursor arg0,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> startBuf,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> endBuf,
+    ffi.Pointer<ffi.UnsignedInt> startLine,
+    ffi.Pointer<ffi.UnsignedInt> startColumn,
+    ffi.Pointer<ffi.UnsignedInt> endLine,
+    ffi.Pointer<ffi.UnsignedInt> endColumn);
+typedef DartClang_getDefinitionSpellingAndExtent = void Function(
+    CXCursor arg0,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> startBuf,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> endBuf,
+    ffi.Pointer<ffi.UnsignedInt> startLine,
+    ffi.Pointer<ffi.UnsignedInt> startColumn,
+    ffi.Pointer<ffi.UnsignedInt> endLine,
+    ffi.Pointer<ffi.UnsignedInt> endColumn);
+typedef NativeClang_enableStackTraces = ffi.Void Function();
+typedef DartClang_enableStackTraces = void Function();
+typedef NativeClang_executeOnThread = ffi.Void Function(
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        fn,
+    ffi.Pointer<ffi.Void> user_data,
+    ffi.UnsignedInt stack_size);
+typedef DartClang_executeOnThread = void Function(
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        fn,
+    ffi.Pointer<ffi.Void> user_data,
+    int stack_size);
+
+/// A single result of code completion.
+final class CXCompletionResult extends ffi.Struct {
+  /// The kind of entity that this completion refers to.
+  ///
+  /// The cursor kind will be a macro, keyword, or a declaration (one of the
+  /// *Decl cursor kinds), describing the entity that the completion is
+  /// referring to.
+  ///
+  /// \todo In the future, we would like to provide a full cursor, to allow
+  /// the client to extract additional information from declaration.
+  @ffi.Int32()
+  external int CursorKind;
+
+  /// The code-completion string that describes how to insert this
+  /// code-completion result into the editing buffer.
+  external CXCompletionString CompletionString;
+}
+
+/// A semantic string that describes a code-completion result.
+///
+/// A semantic string that describes the formatting of a code-completion
+/// result as a single "template" of text that should be inserted into the
+/// source buffer when a particular code-completion result is selected.
+/// Each semantic string is made up of some number of "chunks", each of which
+/// contains some text along with a description of what that text means, e.g.,
+/// the name of the entity being referenced, whether the text chunk is part of
+/// the template, or whether it is a "placeholder" that the user should replace
+/// with actual code,of a specific kind. See \c CXCompletionChunkKind for a
+/// description of the different kinds of chunks.
+typedef CXCompletionString = ffi.Pointer<ffi.Void>;
+
+/// Describes a single piece of text within a code-completion string.
+///
+/// Each "chunk" within a code-completion string (\c CXCompletionString) is
+/// either a piece of text with a specific "kind" that describes how that text
+/// should be interpreted by the client or is another completion string.
+abstract class CXCompletionChunkKind {
+  /// A code-completion string that describes "optional" text that
+  /// could be a part of the template (but is not required).
+  ///
+  /// The Optional chunk is the only kind of chunk that has a code-completion
+  /// string for its representation, which is accessible via
+  /// \c clang_getCompletionChunkCompletionString(). The code-completion string
+  /// describes an additional part of the template that is completely optional.
+  /// For example, optional chunks can be used to describe the placeholders for
+  /// arguments that match up with defaulted function parameters, e.g. given:
+  ///
+  /// \code
+  /// void f(int x, float y = 3.14, double z = 2.71828);
+  /// \endcode
+  ///
+  /// The code-completion string for this function would contain:
+  /// - a TypedText chunk for "f".
+  /// - a LeftParen chunk for "(".
+  /// - a Placeholder chunk for "int x"
+  /// - an Optional chunk containing the remaining defaulted arguments, e.g.,
+  /// - a Comma chunk for ","
+  /// - a Placeholder chunk for "float y"
+  /// - an Optional chunk containing the last defaulted argument:
+  /// - a Comma chunk for ","
+  /// - a Placeholder chunk for "double z"
+  /// - a RightParen chunk for ")"
+  ///
+  /// There are many ways to handle Optional chunks. Two simple approaches are:
+  /// - Completely ignore optional chunks, in which case the template for the
+  /// function "f" would only include the first parameter ("int x").
+  /// - Fully expand all optional chunks, in which case the template for the
+  /// function "f" would have all of the parameters.
+  static const int CXCompletionChunk_Optional = 0;
+
+  /// Text that a user would be expected to type to get this
+  /// code-completion result.
+  ///
+  /// There will be exactly one "typed text" chunk in a semantic string, which
+  /// will typically provide the spelling of a keyword or the name of a
+  /// declaration that could be used at the current code point. Clients are
+  /// expected to filter the code-completion results based on the text in this
+  /// chunk.
+  static const int CXCompletionChunk_TypedText = 1;
+
+  /// Text that should be inserted as part of a code-completion result.
+  ///
+  /// A "text" chunk represents text that is part of the template to be
+  /// inserted into user code should this particular code-completion result
+  /// be selected.
+  static const int CXCompletionChunk_Text = 2;
+
+  /// Placeholder text that should be replaced by the user.
+  ///
+  /// A "placeholder" chunk marks a place where the user should insert text
+  /// into the code-completion template. For example, placeholders might mark
+  /// the function parameters for a function declaration, to indicate that the
+  /// user should provide arguments for each of those parameters. The actual
+  /// text in a placeholder is a suggestion for the text to display before
+  /// the user replaces the placeholder with real code.
+  static const int CXCompletionChunk_Placeholder = 3;
+
+  /// Informative text that should be displayed but never inserted as
+  /// part of the template.
+  ///
+  /// An "informative" chunk contains annotations that can be displayed to
+  /// help the user decide whether a particular code-completion result is the
+  /// right option, but which is not part of the actual template to be inserted
+  /// by code completion.
+  static const int CXCompletionChunk_Informative = 4;
+
+  /// Text that describes the current parameter when code-completion is
+  /// referring to function call, message send, or template specialization.
+  ///
+  /// A "current parameter" chunk occurs when code-completion is providing
+  /// information about a parameter corresponding to the argument at the
+  /// code-completion point. For example, given a function
+  ///
+  /// \code
+  /// int add(int x, int y);
+  /// \endcode
+  ///
+  /// and the source code \c add(, where the code-completion point is after the
+  /// "(", the code-completion string will contain a "current parameter" chunk
+  /// for "int x", indicating that the current argument will initialize that
+  /// parameter. After typing further, to \c add(17, (where the code-completion
+  /// point is after the ","), the code-completion string will contain a
+  /// "current parameter" chunk to "int y".
+  static const int CXCompletionChunk_CurrentParameter = 5;
+
+  /// A left parenthesis ('('), used to initiate a function call or
+  /// signal the beginning of a function parameter list.
+  static const int CXCompletionChunk_LeftParen = 6;
+
+  /// A right parenthesis (')'), used to finish a function call or
+  /// signal the end of a function parameter list.
+  static const int CXCompletionChunk_RightParen = 7;
+
+  /// A left bracket ('[').
+  static const int CXCompletionChunk_LeftBracket = 8;
+
+  /// A right bracket (']').
+  static const int CXCompletionChunk_RightBracket = 9;
+
+  /// A left brace ('{').
+  static const int CXCompletionChunk_LeftBrace = 10;
+
+  /// A right brace ('}').
+  static const int CXCompletionChunk_RightBrace = 11;
+
+  /// A left angle bracket ('<').
+  static const int CXCompletionChunk_LeftAngle = 12;
+
+  /// A right angle bracket ('>').
+  static const int CXCompletionChunk_RightAngle = 13;
+
+  /// A comma separator (',').
+  static const int CXCompletionChunk_Comma = 14;
+
+  /// Text that specifies the result type of a given result.
+  ///
+  /// This special kind of informative chunk is not meant to be inserted into
+  /// the text buffer. Rather, it is meant to illustrate the type that an
+  /// expression using the given completion string would have.
+  static const int CXCompletionChunk_ResultType = 15;
+
+  /// A colon (':').
+  static const int CXCompletionChunk_Colon = 16;
+
+  /// A semicolon (';').
+  static const int CXCompletionChunk_SemiColon = 17;
+
+  /// An '=' sign.
+  static const int CXCompletionChunk_Equal = 18;
+
+  /// Horizontal space (' ').
+  static const int CXCompletionChunk_HorizontalSpace = 19;
+
+  /// Vertical space ('\\n'), after which it is generally a good idea to
+  /// perform indentation.
+  static const int CXCompletionChunk_VerticalSpace = 20;
+}
+
+typedef NativeClang_getCompletionChunkKind = ffi.Int32 Function(
+    CXCompletionString completion_string, ffi.UnsignedInt chunk_number);
+typedef DartClang_getCompletionChunkKind = int Function(
+    CXCompletionString completion_string, int chunk_number);
+typedef NativeClang_getCompletionChunkText = CXString Function(
+    CXCompletionString completion_string, ffi.UnsignedInt chunk_number);
+typedef DartClang_getCompletionChunkText = CXString Function(
+    CXCompletionString completion_string, int chunk_number);
+typedef NativeClang_getCompletionChunkCompletionString
+    = CXCompletionString Function(
+        CXCompletionString completion_string, ffi.UnsignedInt chunk_number);
+typedef DartClang_getCompletionChunkCompletionString = CXCompletionString
+    Function(CXCompletionString completion_string, int chunk_number);
+typedef NativeClang_getNumCompletionChunks = ffi.UnsignedInt Function(
+    CXCompletionString completion_string);
+typedef DartClang_getNumCompletionChunks = int Function(
+    CXCompletionString completion_string);
+typedef NativeClang_getCompletionPriority = ffi.UnsignedInt Function(
+    CXCompletionString completion_string);
+typedef DartClang_getCompletionPriority = int Function(
+    CXCompletionString completion_string);
+typedef NativeClang_getCompletionAvailability = ffi.Int32 Function(
+    CXCompletionString completion_string);
+typedef DartClang_getCompletionAvailability = int Function(
+    CXCompletionString completion_string);
+typedef NativeClang_getCompletionNumAnnotations = ffi.UnsignedInt Function(
+    CXCompletionString completion_string);
+typedef DartClang_getCompletionNumAnnotations = int Function(
+    CXCompletionString completion_string);
+typedef NativeClang_getCompletionAnnotation = CXString Function(
+    CXCompletionString completion_string, ffi.UnsignedInt annotation_number);
+typedef DartClang_getCompletionAnnotation = CXString Function(
+    CXCompletionString completion_string, int annotation_number);
+typedef NativeClang_getCompletionParent = CXString Function(
+    CXCompletionString completion_string, ffi.Pointer<ffi.Int32> kind);
+typedef DartClang_getCompletionParent = CXString Function(
+    CXCompletionString completion_string, ffi.Pointer<ffi.Int32> kind);
+typedef NativeClang_getCompletionBriefComment = CXString Function(
+    CXCompletionString completion_string);
+typedef DartClang_getCompletionBriefComment = CXString Function(
+    CXCompletionString completion_string);
+typedef NativeClang_getCursorCompletionString = CXCompletionString Function(
+    CXCursor cursor);
+typedef DartClang_getCursorCompletionString = CXCompletionString Function(
+    CXCursor cursor);
+
+/// Contains the results of code-completion.
+///
+/// This data structure contains the results of code completion, as
+/// produced by \c clang_codeCompleteAt(). Its contents must be freed by
+/// \c clang_disposeCodeCompleteResults.
+final class CXCodeCompleteResults extends ffi.Struct {
+  /// The code-completion results.
+  external ffi.Pointer<CXCompletionResult> Results;
+
+  /// The number of code-completion results stored in the
+  /// \c Results array.
+  @ffi.UnsignedInt()
+  external int NumResults;
+}
+
+typedef NativeClang_getCompletionNumFixIts = ffi.UnsignedInt Function(
+    ffi.Pointer<CXCodeCompleteResults> results,
+    ffi.UnsignedInt completion_index);
+typedef DartClang_getCompletionNumFixIts = int Function(
+    ffi.Pointer<CXCodeCompleteResults> results, int completion_index);
+typedef NativeClang_getCompletionFixIt = CXString Function(
+    ffi.Pointer<CXCodeCompleteResults> results,
+    ffi.UnsignedInt completion_index,
+    ffi.UnsignedInt fixit_index,
+    ffi.Pointer<CXSourceRange> replacement_range);
+typedef DartClang_getCompletionFixIt = CXString Function(
+    ffi.Pointer<CXCodeCompleteResults> results,
+    int completion_index,
+    int fixit_index,
+    ffi.Pointer<CXSourceRange> replacement_range);
+typedef NativeClang_defaultCodeCompleteOptions = ffi.UnsignedInt Function();
+typedef DartClang_defaultCodeCompleteOptions = int Function();
+typedef NativeClang_codeCompleteAt
+    = ffi.Pointer<CXCodeCompleteResults> Function(
+        CXTranslationUnit TU,
+        ffi.Pointer<ffi.Char> complete_filename,
+        ffi.UnsignedInt complete_line,
+        ffi.UnsignedInt complete_column,
+        ffi.Pointer<CXUnsavedFile> unsaved_files,
+        ffi.UnsignedInt num_unsaved_files,
+        ffi.UnsignedInt options);
+typedef DartClang_codeCompleteAt = ffi.Pointer<CXCodeCompleteResults> Function(
+    CXTranslationUnit TU,
+    ffi.Pointer<ffi.Char> complete_filename,
+    int complete_line,
+    int complete_column,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options);
+typedef NativeClang_sortCodeCompletionResults = ffi.Void Function(
+    ffi.Pointer<CXCompletionResult> Results, ffi.UnsignedInt NumResults);
+typedef DartClang_sortCodeCompletionResults = void Function(
+    ffi.Pointer<CXCompletionResult> Results, int NumResults);
+typedef NativeClang_disposeCodeCompleteResults = ffi.Void Function(
+    ffi.Pointer<CXCodeCompleteResults> Results);
+typedef DartClang_disposeCodeCompleteResults = void Function(
+    ffi.Pointer<CXCodeCompleteResults> Results);
+typedef NativeClang_codeCompleteGetNumDiagnostics = ffi.UnsignedInt Function(
+    ffi.Pointer<CXCodeCompleteResults> Results);
+typedef DartClang_codeCompleteGetNumDiagnostics = int Function(
+    ffi.Pointer<CXCodeCompleteResults> Results);
+typedef NativeClang_codeCompleteGetDiagnostic = CXDiagnostic Function(
+    ffi.Pointer<CXCodeCompleteResults> Results, ffi.UnsignedInt Index);
+typedef DartClang_codeCompleteGetDiagnostic = CXDiagnostic Function(
+    ffi.Pointer<CXCodeCompleteResults> Results, int Index);
+typedef NativeClang_codeCompleteGetContexts = ffi.UnsignedLongLong Function(
+    ffi.Pointer<CXCodeCompleteResults> Results);
+typedef DartClang_codeCompleteGetContexts = int Function(
+    ffi.Pointer<CXCodeCompleteResults> Results);
+typedef NativeClang_codeCompleteGetContainerKind = ffi.Int32 Function(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+    ffi.Pointer<ffi.UnsignedInt> IsIncomplete);
+typedef DartClang_codeCompleteGetContainerKind = int Function(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+    ffi.Pointer<ffi.UnsignedInt> IsIncomplete);
+typedef NativeClang_codeCompleteGetContainerUSR = CXString Function(
+    ffi.Pointer<CXCodeCompleteResults> Results);
+typedef DartClang_codeCompleteGetContainerUSR = CXString Function(
+    ffi.Pointer<CXCodeCompleteResults> Results);
+typedef NativeClang_codeCompleteGetObjCSelector = CXString Function(
+    ffi.Pointer<CXCodeCompleteResults> Results);
+typedef DartClang_codeCompleteGetObjCSelector = CXString Function(
+    ffi.Pointer<CXCodeCompleteResults> Results);
+typedef NativeClang_getClangVersion = CXString Function();
+typedef DartClang_getClangVersion = CXString Function();
+typedef NativeClang_toggleCrashRecovery = ffi.Void Function(
+    ffi.UnsignedInt isEnabled);
+typedef DartClang_toggleCrashRecovery = void Function(int isEnabled);
+
+/// Visitor invoked for each file in a translation unit
+/// (used with clang_getInclusions()).
+///
+/// This visitor function will be invoked by clang_getInclusions() for each
+/// file included (either at the top-level or by \#include directives) within
+/// a translation unit.  The first argument is the file being included, and
+/// the second and third arguments provide the inclusion stack.  The
+/// array is sorted in order of immediate inclusion.  For example,
+/// the first element refers to the location that included 'included_file'.
+typedef CXInclusionVisitor
+    = ffi.Pointer<ffi.NativeFunction<CXInclusionVisitorFunction>>;
+typedef CXInclusionVisitorFunction = ffi.Void Function(
+    CXFile included_file,
+    ffi.Pointer<CXSourceLocation> inclusion_stack,
+    ffi.UnsignedInt include_len,
+    CXClientData client_data);
+typedef DartCXInclusionVisitorFunction = void Function(
+    CXFile included_file,
+    ffi.Pointer<CXSourceLocation> inclusion_stack,
+    int include_len,
+    CXClientData client_data);
+typedef NativeClang_getInclusions = ffi.Void Function(
+    CXTranslationUnit tu, CXInclusionVisitor visitor, CXClientData client_data);
+typedef DartClang_getInclusions = void Function(
+    CXTranslationUnit tu, CXInclusionVisitor visitor, CXClientData client_data);
+
+/// Evaluation result of a cursor
+typedef CXEvalResult = ffi.Pointer<ffi.Void>;
+typedef NativeClang_Cursor_Evaluate = CXEvalResult Function(CXCursor C);
+typedef DartClang_Cursor_Evaluate = CXEvalResult Function(CXCursor C);
+
+abstract class CXEvalResultKind {
+  static const int CXEval_Int = 1;
+  static const int CXEval_Float = 2;
+  static const int CXEval_ObjCStrLiteral = 3;
+  static const int CXEval_StrLiteral = 4;
+  static const int CXEval_CFStr = 5;
+  static const int CXEval_Other = 6;
+  static const int CXEval_UnExposed = 0;
+}
+
+typedef NativeClang_EvalResult_getKind = ffi.Int32 Function(CXEvalResult E);
+typedef DartClang_EvalResult_getKind = int Function(CXEvalResult E);
+typedef NativeClang_EvalResult_getAsInt = ffi.Int Function(CXEvalResult E);
+typedef DartClang_EvalResult_getAsInt = int Function(CXEvalResult E);
+typedef NativeClang_EvalResult_getAsLongLong = ffi.LongLong Function(
+    CXEvalResult E);
+typedef DartClang_EvalResult_getAsLongLong = int Function(CXEvalResult E);
+typedef NativeClang_EvalResult_isUnsignedInt = ffi.UnsignedInt Function(
+    CXEvalResult E);
+typedef DartClang_EvalResult_isUnsignedInt = int Function(CXEvalResult E);
+typedef NativeClang_EvalResult_getAsUnsigned = ffi.UnsignedLongLong Function(
+    CXEvalResult E);
+typedef DartClang_EvalResult_getAsUnsigned = int Function(CXEvalResult E);
+typedef NativeClang_EvalResult_getAsDouble = ffi.Double Function(
+    CXEvalResult E);
+typedef DartClang_EvalResult_getAsDouble = double Function(CXEvalResult E);
+typedef NativeClang_EvalResult_getAsStr = ffi.Pointer<ffi.Char> Function(
+    CXEvalResult E);
+typedef DartClang_EvalResult_getAsStr = ffi.Pointer<ffi.Char> Function(
+    CXEvalResult E);
+typedef NativeClang_EvalResult_dispose = ffi.Void Function(CXEvalResult E);
+typedef DartClang_EvalResult_dispose = void Function(CXEvalResult E);
+
+/// A remapping of original source files and their translated files.
+typedef CXRemapping = ffi.Pointer<ffi.Void>;
+typedef NativeClang_getRemappings = CXRemapping Function(
+    ffi.Pointer<ffi.Char> path);
+typedef DartClang_getRemappings = CXRemapping Function(
+    ffi.Pointer<ffi.Char> path);
+typedef NativeClang_getRemappingsFromFileList = CXRemapping Function(
+    ffi.Pointer<ffi.Pointer<ffi.Char>> filePaths, ffi.UnsignedInt numFiles);
+typedef DartClang_getRemappingsFromFileList = CXRemapping Function(
+    ffi.Pointer<ffi.Pointer<ffi.Char>> filePaths, int numFiles);
+typedef NativeClang_remap_getNumFiles = ffi.UnsignedInt Function(
+    CXRemapping arg0);
+typedef DartClang_remap_getNumFiles = int Function(CXRemapping arg0);
+typedef NativeClang_remap_getFilenames = ffi.Void Function(
+    CXRemapping arg0,
+    ffi.UnsignedInt index,
+    ffi.Pointer<CXString> original,
+    ffi.Pointer<CXString> transformed);
+typedef DartClang_remap_getFilenames = void Function(
+    CXRemapping arg0,
+    int index,
+    ffi.Pointer<CXString> original,
+    ffi.Pointer<CXString> transformed);
+typedef NativeClang_remap_dispose = ffi.Void Function(CXRemapping arg0);
+typedef DartClang_remap_dispose = void Function(CXRemapping arg0);
+
+final class CXCursorAndRangeVisitor extends ffi.Struct {
+  external ffi.Pointer<ffi.Void> context;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int32 Function(
+              ffi.Pointer<ffi.Void>, CXCursor, CXSourceRange)>> visit;
+}
+
+/// \defgroup CINDEX_HIGH Higher level API functions
+///
+/// @{
+abstract class CXVisitorResult {
+  static const int CXVisit_Break = 0;
+  static const int CXVisit_Continue = 1;
+}
+
+abstract class CXResult {
+  /// Function returned successfully.
+  static const int CXResult_Success = 0;
+
+  /// One of the parameters was invalid for the function.
+  static const int CXResult_Invalid = 1;
+
+  /// The function was terminated by a callback (e.g. it returned
+  /// CXVisit_Break)
+  static const int CXResult_VisitBreak = 2;
+}
+
+typedef NativeClang_findReferencesInFile = ffi.Int32 Function(
+    CXCursor cursor, CXFile file, CXCursorAndRangeVisitor visitor);
+typedef DartClang_findReferencesInFile = int Function(
+    CXCursor cursor, CXFile file, CXCursorAndRangeVisitor visitor);
+typedef NativeClang_findIncludesInFile = ffi.Int32 Function(
+    CXTranslationUnit TU, CXFile file, CXCursorAndRangeVisitor visitor);
+typedef DartClang_findIncludesInFile = int Function(
+    CXTranslationUnit TU, CXFile file, CXCursorAndRangeVisitor visitor);
+
+/// Source location passed to index callbacks.
+final class CXIdxLoc extends ffi.Struct {
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
+
+  @ffi.UnsignedInt()
+  external int int_data;
+}
+
+/// Data for ppIncludedFile callback.
+final class CXIdxIncludedFileInfo extends ffi.Struct {
+  /// Location of '#' in the \#include/\#import directive.
+  external CXIdxLoc hashLoc;
+
+  /// Filename as written in the \#include/\#import directive.
+  external ffi.Pointer<ffi.Char> filename;
+
+  /// The actual file that the \#include/\#import directive resolved to.
+  external CXFile file;
+
+  @ffi.Int()
+  external int isImport;
+
+  @ffi.Int()
+  external int isAngled;
+
+  /// Non-zero if the directive was automatically turned into a module
+  /// import.
+  @ffi.Int()
+  external int isModuleImport;
+}
+
+/// Data for IndexerCallbacks#importedASTFile.
+final class CXIdxImportedASTFileInfo extends ffi.Struct {
+  /// Top level AST file containing the imported PCH, module or submodule.
+  external CXFile file;
+
+  /// The imported module or NULL if the AST file is a PCH.
+  external CXModule module;
+
+  /// Location where the file is imported. Applicable only for modules.
+  external CXIdxLoc loc;
+
+  /// Non-zero if an inclusion directive was automatically turned into
+  /// a module import. Applicable only for modules.
+  @ffi.Int()
+  external int isImplicit;
+}
+
+final class CXIdxAttrInfo extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  external CXCursor cursor;
+
+  external CXIdxLoc loc;
+}
+
+abstract class CXIdxAttrKind {
+  static const int CXIdxAttr_Unexposed = 0;
+  static const int CXIdxAttr_IBAction = 1;
+  static const int CXIdxAttr_IBOutlet = 2;
+  static const int CXIdxAttr_IBOutletCollection = 3;
+}
+
+final class CXIdxEntityInfo extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  @ffi.Int32()
+  external int templateKind;
+
+  @ffi.Int32()
+  external int lang;
+
+  external ffi.Pointer<ffi.Char> name;
+
+  external ffi.Pointer<ffi.Char> USR;
+
+  external CXCursor cursor;
+
+  external ffi.Pointer<ffi.Pointer<CXIdxAttrInfo>> attributes;
+
+  @ffi.UnsignedInt()
+  external int numAttributes;
+}
+
+abstract class CXIdxEntityKind {
+  static const int CXIdxEntity_Unexposed = 0;
+  static const int CXIdxEntity_Typedef = 1;
+  static const int CXIdxEntity_Function = 2;
+  static const int CXIdxEntity_Variable = 3;
+  static const int CXIdxEntity_Field = 4;
+  static const int CXIdxEntity_EnumConstant = 5;
+  static const int CXIdxEntity_ObjCClass = 6;
+  static const int CXIdxEntity_ObjCProtocol = 7;
+  static const int CXIdxEntity_ObjCCategory = 8;
+  static const int CXIdxEntity_ObjCInstanceMethod = 9;
+  static const int CXIdxEntity_ObjCClassMethod = 10;
+  static const int CXIdxEntity_ObjCProperty = 11;
+  static const int CXIdxEntity_ObjCIvar = 12;
+  static const int CXIdxEntity_Enum = 13;
+  static const int CXIdxEntity_Struct = 14;
+  static const int CXIdxEntity_Union = 15;
+  static const int CXIdxEntity_CXXClass = 16;
+  static const int CXIdxEntity_CXXNamespace = 17;
+  static const int CXIdxEntity_CXXNamespaceAlias = 18;
+  static const int CXIdxEntity_CXXStaticVariable = 19;
+  static const int CXIdxEntity_CXXStaticMethod = 20;
+  static const int CXIdxEntity_CXXInstanceMethod = 21;
+  static const int CXIdxEntity_CXXConstructor = 22;
+  static const int CXIdxEntity_CXXDestructor = 23;
+  static const int CXIdxEntity_CXXConversionFunction = 24;
+  static const int CXIdxEntity_CXXTypeAlias = 25;
+  static const int CXIdxEntity_CXXInterface = 26;
+}
+
+/// Extra C++ template information for an entity. This can apply to:
+/// CXIdxEntity_Function
+/// CXIdxEntity_CXXClass
+/// CXIdxEntity_CXXStaticMethod
+/// CXIdxEntity_CXXInstanceMethod
+/// CXIdxEntity_CXXConstructor
+/// CXIdxEntity_CXXConversionFunction
+/// CXIdxEntity_CXXTypeAlias
+abstract class CXIdxEntityCXXTemplateKind {
+  static const int CXIdxEntity_NonTemplate = 0;
+  static const int CXIdxEntity_Template = 1;
+  static const int CXIdxEntity_TemplatePartialSpecialization = 2;
+  static const int CXIdxEntity_TemplateSpecialization = 3;
+}
+
+abstract class CXIdxEntityLanguage {
+  static const int CXIdxEntityLang_None = 0;
+  static const int CXIdxEntityLang_C = 1;
+  static const int CXIdxEntityLang_ObjC = 2;
+  static const int CXIdxEntityLang_CXX = 3;
+  static const int CXIdxEntityLang_Swift = 4;
+}
+
+final class CXIdxContainerInfo extends ffi.Struct {
+  external CXCursor cursor;
+}
+
+final class CXIdxIBOutletCollectionAttrInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxAttrInfo> attrInfo;
+
+  external ffi.Pointer<CXIdxEntityInfo> objcClass;
+
+  external CXCursor classCursor;
+
+  external CXIdxLoc classLoc;
+}
+
+final class CXIdxDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxEntityInfo> entityInfo;
+
+  external CXCursor cursor;
+
+  external CXIdxLoc loc;
+
+  external ffi.Pointer<CXIdxContainerInfo> semanticContainer;
+
+  /// Generally same as #semanticContainer but can be different in
+  /// cases like out-of-line C++ member functions.
+  external ffi.Pointer<CXIdxContainerInfo> lexicalContainer;
+
+  @ffi.Int()
+  external int isRedeclaration;
+
+  @ffi.Int()
+  external int isDefinition;
+
+  @ffi.Int()
+  external int isContainer;
+
+  external ffi.Pointer<CXIdxContainerInfo> declAsContainer;
+
+  /// Whether the declaration exists in code or was created implicitly
+  /// by the compiler, e.g. implicit Objective-C methods for properties.
+  @ffi.Int()
+  external int isImplicit;
+
+  external ffi.Pointer<ffi.Pointer<CXIdxAttrInfo>> attributes;
+
+  @ffi.UnsignedInt()
+  external int numAttributes;
+
+  @ffi.UnsignedInt()
+  external int flags;
+}
+
+final class CXIdxObjCContainerDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxDeclInfo> declInfo;
+
+  @ffi.Int32()
+  external int kind;
+}
+
+abstract class CXIdxObjCContainerKind {
+  static const int CXIdxObjCContainer_ForwardRef = 0;
+  static const int CXIdxObjCContainer_Interface = 1;
+  static const int CXIdxObjCContainer_Implementation = 2;
+}
+
+final class CXIdxBaseClassInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxEntityInfo> base;
+
+  external CXCursor cursor;
+
+  external CXIdxLoc loc;
+}
+
+final class CXIdxObjCProtocolRefInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxEntityInfo> protocol;
+
+  external CXCursor cursor;
+
+  external CXIdxLoc loc;
+}
+
+final class CXIdxObjCProtocolRefListInfo extends ffi.Struct {
+  external ffi.Pointer<ffi.Pointer<CXIdxObjCProtocolRefInfo>> protocols;
+
+  @ffi.UnsignedInt()
+  external int numProtocols;
+}
+
+final class CXIdxObjCInterfaceDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxObjCContainerDeclInfo> containerInfo;
+
+  external ffi.Pointer<CXIdxBaseClassInfo> superInfo;
+
+  external ffi.Pointer<CXIdxObjCProtocolRefListInfo> protocols;
+}
+
+final class CXIdxObjCCategoryDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxObjCContainerDeclInfo> containerInfo;
+
+  external ffi.Pointer<CXIdxEntityInfo> objcClass;
+
+  external CXCursor classCursor;
+
+  external CXIdxLoc classLoc;
+
+  external ffi.Pointer<CXIdxObjCProtocolRefListInfo> protocols;
+}
+
+final class CXIdxObjCPropertyDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxDeclInfo> declInfo;
+
+  external ffi.Pointer<CXIdxEntityInfo> getter;
+
+  external ffi.Pointer<CXIdxEntityInfo> setter;
+}
+
+final class CXIdxCXXClassDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxDeclInfo> declInfo;
+
+  external ffi.Pointer<ffi.Pointer<CXIdxBaseClassInfo>> bases;
+
+  @ffi.UnsignedInt()
+  external int numBases;
+}
+
+/// Data for IndexerCallbacks#indexEntityReference.
+final class CXIdxEntityRefInfo extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  /// Reference cursor.
+  external CXCursor cursor;
+
+  external CXIdxLoc loc;
+
+  /// The entity that gets referenced.
+  external ffi.Pointer<CXIdxEntityInfo> referencedEntity;
+
+  /// Immediate "parent" of the reference. For example:
+  ///
+  /// \code
+  /// Foo *var;
+  /// \endcode
+  ///
+  /// The parent of reference of type 'Foo' is the variable 'var'.
+  /// For references inside statement bodies of functions/methods,
+  /// the parentEntity will be the function/method.
+  external ffi.Pointer<CXIdxEntityInfo> parentEntity;
+
+  /// Lexical container context of the reference.
+  external ffi.Pointer<CXIdxContainerInfo> container;
+
+  /// Sets of symbol roles of the reference.
+  @ffi.Int32()
+  external int role;
+}
+
+/// Data for IndexerCallbacks#indexEntityReference.
+///
+/// This may be deprecated in a future version as this duplicates
+/// the \c CXSymbolRole_Implicit bit in \c CXSymbolRole.
+abstract class CXIdxEntityRefKind {
+  /// The entity is referenced directly in user's code.
+  static const int CXIdxEntityRef_Direct = 1;
+
+  /// An implicit reference, e.g. a reference of an Objective-C method
+  /// via the dot syntax.
+  static const int CXIdxEntityRef_Implicit = 2;
+}
+
+/// Roles that are attributed to symbol occurrences.
+///
+/// Internal: this currently mirrors low 9 bits of clang::index::SymbolRole with
+/// higher bits zeroed. These high bits may be exposed in the future.
+abstract class CXSymbolRole {
+  static const int CXSymbolRole_None = 0;
+  static const int CXSymbolRole_Declaration = 1;
+  static const int CXSymbolRole_Definition = 2;
+  static const int CXSymbolRole_Reference = 4;
+  static const int CXSymbolRole_Read = 8;
+  static const int CXSymbolRole_Write = 16;
+  static const int CXSymbolRole_Call = 32;
+  static const int CXSymbolRole_Dynamic = 64;
+  static const int CXSymbolRole_AddressOf = 128;
+  static const int CXSymbolRole_Implicit = 256;
+}
+
+typedef NativeClang_index_isEntityObjCContainerKind = ffi.Int Function(
+    ffi.Int32 arg0);
+typedef DartClang_index_isEntityObjCContainerKind = int Function(int arg0);
+typedef NativeClang_index_getObjCContainerDeclInfo
+    = ffi.Pointer<CXIdxObjCContainerDeclInfo> Function(
+        ffi.Pointer<CXIdxDeclInfo> arg0);
+typedef DartClang_index_getObjCContainerDeclInfo
+    = ffi.Pointer<CXIdxObjCContainerDeclInfo> Function(
+        ffi.Pointer<CXIdxDeclInfo> arg0);
+typedef NativeClang_index_getObjCInterfaceDeclInfo
+    = ffi.Pointer<CXIdxObjCInterfaceDeclInfo> Function(
+        ffi.Pointer<CXIdxDeclInfo> arg0);
+typedef DartClang_index_getObjCInterfaceDeclInfo
+    = ffi.Pointer<CXIdxObjCInterfaceDeclInfo> Function(
+        ffi.Pointer<CXIdxDeclInfo> arg0);
+typedef NativeClang_index_getObjCCategoryDeclInfo
+    = ffi.Pointer<CXIdxObjCCategoryDeclInfo> Function(
+        ffi.Pointer<CXIdxDeclInfo> arg0);
+typedef DartClang_index_getObjCCategoryDeclInfo
+    = ffi.Pointer<CXIdxObjCCategoryDeclInfo> Function(
+        ffi.Pointer<CXIdxDeclInfo> arg0);
+typedef NativeClang_index_getObjCProtocolRefListInfo
+    = ffi.Pointer<CXIdxObjCProtocolRefListInfo> Function(
+        ffi.Pointer<CXIdxDeclInfo> arg0);
+typedef DartClang_index_getObjCProtocolRefListInfo
+    = ffi.Pointer<CXIdxObjCProtocolRefListInfo> Function(
+        ffi.Pointer<CXIdxDeclInfo> arg0);
+typedef NativeClang_index_getObjCPropertyDeclInfo
+    = ffi.Pointer<CXIdxObjCPropertyDeclInfo> Function(
+        ffi.Pointer<CXIdxDeclInfo> arg0);
+typedef DartClang_index_getObjCPropertyDeclInfo
+    = ffi.Pointer<CXIdxObjCPropertyDeclInfo> Function(
+        ffi.Pointer<CXIdxDeclInfo> arg0);
+typedef NativeClang_index_getIBOutletCollectionAttrInfo
+    = ffi.Pointer<CXIdxIBOutletCollectionAttrInfo> Function(
+        ffi.Pointer<CXIdxAttrInfo> arg0);
+typedef DartClang_index_getIBOutletCollectionAttrInfo
+    = ffi.Pointer<CXIdxIBOutletCollectionAttrInfo> Function(
+        ffi.Pointer<CXIdxAttrInfo> arg0);
+typedef NativeClang_index_getCXXClassDeclInfo
+    = ffi.Pointer<CXIdxCXXClassDeclInfo> Function(
+        ffi.Pointer<CXIdxDeclInfo> arg0);
+typedef DartClang_index_getCXXClassDeclInfo = ffi.Pointer<CXIdxCXXClassDeclInfo>
+    Function(ffi.Pointer<CXIdxDeclInfo> arg0);
+
+/// The client's data object that is associated with a semantic container
+/// of entities.
+typedef CXIdxClientContainer = ffi.Pointer<ffi.Void>;
+typedef NativeClang_index_getClientContainer = CXIdxClientContainer Function(
+    ffi.Pointer<CXIdxContainerInfo> arg0);
+typedef DartClang_index_getClientContainer = CXIdxClientContainer Function(
+    ffi.Pointer<CXIdxContainerInfo> arg0);
+typedef NativeClang_index_setClientContainer = ffi.Void Function(
+    ffi.Pointer<CXIdxContainerInfo> arg0, CXIdxClientContainer arg1);
+typedef DartClang_index_setClientContainer = void Function(
+    ffi.Pointer<CXIdxContainerInfo> arg0, CXIdxClientContainer arg1);
+
+/// The client's data object that is associated with a semantic entity.
+typedef CXIdxClientEntity = ffi.Pointer<ffi.Void>;
+typedef NativeClang_index_getClientEntity = CXIdxClientEntity Function(
+    ffi.Pointer<CXIdxEntityInfo> arg0);
+typedef DartClang_index_getClientEntity = CXIdxClientEntity Function(
+    ffi.Pointer<CXIdxEntityInfo> arg0);
+typedef NativeClang_index_setClientEntity = ffi.Void Function(
+    ffi.Pointer<CXIdxEntityInfo> arg0, CXIdxClientEntity arg1);
+typedef DartClang_index_setClientEntity = void Function(
+    ffi.Pointer<CXIdxEntityInfo> arg0, CXIdxClientEntity arg1);
+
+/// An indexing action/session, to be applied to one or multiple
+/// translation units.
+typedef CXIndexAction = ffi.Pointer<ffi.Void>;
+typedef NativeClang_IndexAction_create = CXIndexAction Function(CXIndex CIdx);
+typedef DartClang_IndexAction_create = CXIndexAction Function(CXIndex CIdx);
+typedef NativeClang_IndexAction_dispose = ffi.Void Function(CXIndexAction arg0);
+typedef DartClang_IndexAction_dispose = void Function(CXIndexAction arg0);
+
+/// A group of callbacks used by #clang_indexSourceFile and
+/// #clang_indexTranslationUnit.
+final class IndexerCallbacks extends ffi.Struct {
+  /// Called periodically to check whether indexing should be aborted.
+  /// Should return 0 to continue, and non-zero to abort.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  CXClientData client_data, ffi.Pointer<ffi.Void> reserved)>>
+      abortQuery;
+
+  /// Called at the end of indexing; passes the complete diagnostic set.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Void Function(
+                  CXClientData, CXDiagnosticSet, ffi.Pointer<ffi.Void>)>>
+      diagnostic;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          CXIdxClientFile Function(CXClientData client_data, CXFile mainFile,
+              ffi.Pointer<ffi.Void> reserved)>> enteredMainFile;
+
+  /// Called when a file gets \#included/\#imported.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              CXIdxClientFile Function(
+                  CXClientData, ffi.Pointer<CXIdxIncludedFileInfo>)>>
+      ppIncludedFile;
+
+  /// Called when a AST file (PCH or module) gets imported.
+  ///
+  /// AST files will not get indexed (there will not be callbacks to index all
+  /// the entities in an AST file). The recommended action is that, if the AST
+  /// file is not already indexed, to initiate a new indexing job specific to
+  /// the AST file.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              CXIdxClientASTFile Function(
+                  CXClientData, ffi.Pointer<CXIdxImportedASTFileInfo>)>>
+      importedASTFile;
+
+  /// Called at the beginning of indexing a translation unit.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              CXIdxClientContainer Function(
+                  CXClientData client_data, ffi.Pointer<ffi.Void> reserved)>>
+      startedTranslationUnit;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Void Function(CXClientData, ffi.Pointer<CXIdxDeclInfo>)>>
+      indexDeclaration;
+
+  /// Called to index a reference of an entity.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Void Function(CXClientData, ffi.Pointer<CXIdxEntityRefInfo>)>>
+      indexEntityReference;
+}
+
+/// The client's data object that is associated with a CXFile.
+typedef CXIdxClientFile = ffi.Pointer<ffi.Void>;
+
+/// The client's data object that is associated with an AST file (PCH
+/// or module).
+typedef CXIdxClientASTFile = ffi.Pointer<ffi.Void>;
+typedef NativeClang_indexSourceFile = ffi.Int Function(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    ffi.UnsignedInt index_callbacks_size,
+    ffi.UnsignedInt index_options,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    ffi.Int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    ffi.UnsignedInt num_unsaved_files,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+    ffi.UnsignedInt TU_options);
+typedef DartClang_indexSourceFile = int Function(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    int index_callbacks_size,
+    int index_options,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+    int TU_options);
+typedef NativeClang_indexSourceFileFullArgv = ffi.Int Function(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    ffi.UnsignedInt index_callbacks_size,
+    ffi.UnsignedInt index_options,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    ffi.Int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    ffi.UnsignedInt num_unsaved_files,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+    ffi.UnsignedInt TU_options);
+typedef DartClang_indexSourceFileFullArgv = int Function(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    int index_callbacks_size,
+    int index_options,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+    int TU_options);
+typedef NativeClang_indexTranslationUnit = ffi.Int Function(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    ffi.UnsignedInt index_callbacks_size,
+    ffi.UnsignedInt index_options,
+    CXTranslationUnit arg5);
+typedef DartClang_indexTranslationUnit = int Function(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    int index_callbacks_size,
+    int index_options,
+    CXTranslationUnit arg5);
+typedef NativeClang_indexLoc_getFileLocation = ffi.Void Function(
+    CXIdxLoc loc,
+    ffi.Pointer<CXIdxClientFile> indexFile,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset);
+typedef DartClang_indexLoc_getFileLocation = void Function(
+    CXIdxLoc loc,
+    ffi.Pointer<CXIdxClientFile> indexFile,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset);
+typedef NativeClang_indexLoc_getCXSourceLocation = CXSourceLocation Function(
+    CXIdxLoc loc);
+typedef DartClang_indexLoc_getCXSourceLocation = CXSourceLocation Function(
+    CXIdxLoc loc);
+
+/// Visitor invoked for each field found by a traversal.
+///
+/// This visitor function will be invoked for each field found by
+/// \c clang_Type_visitFields. Its first argument is the cursor being
+/// visited, its second argument is the client data provided to
+/// \c clang_Type_visitFields.
+///
+/// The visitor should return one of the \c CXVisitorResult values
+/// to direct \c clang_Type_visitFields.
+typedef CXFieldVisitor
+    = ffi.Pointer<ffi.NativeFunction<CXFieldVisitorFunction>>;
+typedef CXFieldVisitorFunction = ffi.Int32 Function(
+    CXCursor C, CXClientData client_data);
+typedef DartCXFieldVisitorFunction = int Function(
+    CXCursor C, CXClientData client_data);
+typedef NativeClang_Type_visitFields = ffi.UnsignedInt Function(
+    CXType T, CXFieldVisitor visitor, CXClientData client_data);
+typedef DartClang_Type_visitFields = int Function(
+    CXType T, CXFieldVisitor visitor, CXClientData client_data);
+
+const int CINDEX_VERSION_MAJOR = 0;
+
+const int CINDEX_VERSION_MINOR = 59;
+
+const int CINDEX_VERSION = 59;
+
+const String CINDEX_VERSION_STRING = '0.59';
diff --git a/pkgs/ffigen/example/libclang-example/pubspec.yaml b/pkgs/ffigen/example/libclang-example/pubspec.yaml
new file mode 100644
index 0000000..e27a2b4
--- /dev/null
+++ b/pkgs/ffigen/example/libclang-example/pubspec.yaml
@@ -0,0 +1,15 @@
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+name: libclang_example
+
+environment:
+  sdk: '>=3.2.0 <4.0.0'
+
+dependencies:
+  ffi: ^2.0.1
+dev_dependencies:
+  ffigen:
+    path: '../../'
+  lints: ^2.0.1
diff --git a/pkgs/ffigen/example/libclang-example/readme.md b/pkgs/ffigen/example/libclang-example/readme.md
new file mode 100644
index 0000000..39f2474
--- /dev/null
+++ b/pkgs/ffigen/example/libclang-example/readme.md
@@ -0,0 +1,11 @@
+# Libclang example
+
+Demonstrates generating bindings for [Libclang](https://clang.llvm.org/doxygen/group__CINDEX.html).
+The C header source files for libclang are in [third_party/libclang](/third_party/libclang).
+
+## Generating bindings
+At the root of this example (`example/libclang-example`), run -
+```
+dart run ffigen --config config.yaml
+```
+This will generate bindings in a file: [generated_bindings.dart](./generated_bindings.dart).
diff --git a/pkgs/ffigen/example/objective_c/README.md b/pkgs/ffigen/example/objective_c/README.md
new file mode 100644
index 0000000..846b77a
--- /dev/null
+++ b/pkgs/ffigen/example/objective_c/README.md
@@ -0,0 +1,44 @@
+# Objective C example
+
+This example shows how to use ffigen to generate bindings for an Objective C
+library. It uses the AVFAudio framework to play audio files.
+
+```
+dart play_audio.dart test.mp3
+```
+
+## Config notes
+
+The ffigen config for an Objective C library looks very similar to a C library.
+The most important difference is that you must set `language: objc`. If you want
+to filter which interfaces are included you can use the `objc-interfaces:`
+option. This works similarly to the other filtering options.
+
+It is recommended that you filter out just about everything you're not
+interested in binding (see the ffigen config in [pubspec.yaml](./pubspec.yaml)).
+Virtually all Objective C libraries depend on Apple's internal libraries, which
+are huge. Filtering can reduce the generated bindings from millions of lines to
+tens of thousands. You can use the `exclude-all-by-default` flag, or exclude
+individual sets of declarations like this:
+
+```yaml
+functions:
+  exclude:
+    - '.*'
+# Same for structs/unions/enums etc.
+```
+
+In this example, we're only interested in `AVAudioPlayer`, so we've filtered out
+everything else. But ffigen will automatically pull in anything referenced by
+any of the fields or methods of `AVAudioPlayer`, so we're still able to use
+`NSURL` etc to load our audio file.
+
+## Generating bindings
+
+At the root of this example (`example/objective_c`), run:
+
+```
+dart run ffigen --config config.yaml
+```
+
+This will generate [avf_audio_bindings.dart](./avf_audio_bindings.dart).
diff --git a/pkgs/ffigen/example/objective_c/avf_audio_bindings.dart b/pkgs/ffigen/example/objective_c/avf_audio_bindings.dart
new file mode 100644
index 0000000..8d4936f
--- /dev/null
+++ b/pkgs/ffigen/example/objective_c/avf_audio_bindings.dart
@@ -0,0 +1,67761 @@
+// 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 {}
diff --git a/pkgs/ffigen/example/objective_c/config.yaml b/pkgs/ffigen/example/objective_c/config.yaml
new file mode 100644
index 0000000..3a76517
--- /dev/null
+++ b/pkgs/ffigen/example/objective_c/config.yaml
@@ -0,0 +1,15 @@
+# yaml-language-server: $schema=../../ffigen.schema.json
+
+name: AVFAudio
+description: Bindings for AVFAudio.
+language: objc
+output: 'avf_audio_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - 'AVAudioPlayer'
+headers:
+  entry-points:
+    - '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/AVFAudio.framework/Headers/AVAudioPlayer.h'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field, void_checks, annotate_overrides, no_leading_underscores_for_local_identifiers, library_private_types_in_public_api
diff --git a/pkgs/ffigen/example/objective_c/play_audio.dart b/pkgs/ffigen/example/objective_c/play_audio.dart
new file mode 100644
index 0000000..05708c6
--- /dev/null
+++ b/pkgs/ffigen/example/objective_c/play_audio.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+import 'avf_audio_bindings.dart';
+
+const _dylibPath =
+    '/System/Library/Frameworks/AVFAudio.framework/Versions/Current/AVFAudio';
+
+void main(List<String> args) async {
+  final lib = AVFAudio(DynamicLibrary.open(_dylibPath));
+  for (final file in args) {
+    final fileStr = NSString(lib, file);
+    print('Loading $fileStr');
+    final fileUrl = NSURL.fileURLWithPath_(lib, fileStr);
+    final player =
+        AVAudioPlayer.alloc(lib).initWithContentsOfURL_error_(fileUrl, nullptr);
+    final durationSeconds = player.duration.ceil();
+    print('$durationSeconds sec');
+    final status = player.play();
+    if (status) {
+      print('Playing...');
+      await Future<void>.delayed(Duration(seconds: durationSeconds));
+    } else {
+      print('Failed to play audio.');
+    }
+  }
+}
diff --git a/pkgs/ffigen/example/objective_c/pubspec.yaml b/pkgs/ffigen/example/objective_c/pubspec.yaml
new file mode 100644
index 0000000..a912faa
--- /dev/null
+++ b/pkgs/ffigen/example/objective_c/pubspec.yaml
@@ -0,0 +1,15 @@
+# Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+name: objective_c_example
+
+environment:
+  sdk: '>=3.2.0 <4.0.0'
+
+dependencies:
+  ffi: ^2.0.1
+dev_dependencies:
+  ffigen:
+    path: '../../'
+  lints: ^2.0.0
diff --git a/pkgs/ffigen/example/objective_c/test.mp3 b/pkgs/ffigen/example/objective_c/test.mp3
new file mode 100644
index 0000000..077b618
--- /dev/null
+++ b/pkgs/ffigen/example/objective_c/test.mp3
Binary files differ
diff --git a/pkgs/ffigen/example/shared_bindings/.gitignore b/pkgs/ffigen/example/shared_bindings/.gitignore
new file mode 100644
index 0000000..1b05164
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/.gitignore
@@ -0,0 +1,11 @@
+# Files and directories created by pub.
+.dart_tool/
+.packages
+# Remove the following pattern if you wish to check in your lock file.
+pubspec.lock
+
+# Conventional directory for build outputs.
+build/
+
+# Directory created by dartdoc.
+doc/api/
diff --git a/pkgs/ffigen/example/shared_bindings/README.md b/pkgs/ffigen/example/shared_bindings/README.md
new file mode 100644
index 0000000..6a81fdd
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/README.md
@@ -0,0 +1,10 @@
+# Shared bindings
+
+An example to showcase how bindings can share types
+with other bindings.
+
+## Generating bindings
+At the root of this example (`example/shared_bindings`), run -
+```
+dart run generate.dart
+```
diff --git a/pkgs/ffigen/example/shared_bindings/ffigen_configs/a.yaml b/pkgs/ffigen/example/shared_bindings/ffigen_configs/a.yaml
new file mode 100644
index 0000000..a23faa1
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/ffigen_configs/a.yaml
@@ -0,0 +1,14 @@
+# Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# yaml-language-server: $schema=../../../ffigen.schema.json
+
+name: NativeLibraryA
+description: Bindings to `headers/a.h`.
+output: '../lib/generated/a_gen.dart'
+headers:
+  entry-points:
+    - '../headers/a.h'
+preamble: |
+  // ignore_for_file: non_constant_identifier_names, camel_case_types
diff --git a/pkgs/ffigen/example/shared_bindings/ffigen_configs/a_shared_base.yaml b/pkgs/ffigen/example/shared_bindings/ffigen_configs/a_shared_base.yaml
new file mode 100644
index 0000000..aa4f1b1
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/ffigen_configs/a_shared_base.yaml
@@ -0,0 +1,18 @@
+# Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# yaml-language-server: $schema=../../../ffigen.schema.json
+
+name: NativeLibraryASharedB
+description: Bindings to `headers/a.h` with shared definitions from `headers/base.h`.
+output: '../lib/generated/a_shared_b_gen.dart'
+headers:
+  entry-points:
+    - '../headers/a.h'
+import:
+  symbol-files:
+    # Both package Uri and file paths are supported here.
+    - 'package:shared_bindings/generated/base_symbols.yaml'
+preamble: |
+  // ignore_for_file: non_constant_identifier_names, camel_case_types
diff --git a/pkgs/ffigen/example/shared_bindings/ffigen_configs/base.yaml b/pkgs/ffigen/example/shared_bindings/ffigen_configs/base.yaml
new file mode 100644
index 0000000..da03542
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/ffigen_configs/base.yaml
@@ -0,0 +1,19 @@
+# Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# yaml-language-server: $schema=../../../ffigen.schema.json
+
+name: NativeLibraryBase
+description: Bindings to `headers/base.h`.
+output:
+  bindings: '../lib/generated/base_gen.dart'
+  symbol-file:
+    # Although file paths are supported here, prefer Package Uri's here.
+    output: 'package:shared_bindings/generated/base_symbols.yaml'
+    import-path: 'package:shared_bindings/generated/base_gen.dart'
+headers:
+  entry-points:
+    - '../headers/base.h'
+preamble: |
+  // ignore_for_file: non_constant_identifier_names, camel_case_types
diff --git a/pkgs/ffigen/example/shared_bindings/generate.dart b/pkgs/ffigen/example/shared_bindings/generate.dart
new file mode 100644
index 0000000..8e565cf
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/generate.dart
@@ -0,0 +1,32 @@
+import 'dart:io';
+
+import 'package:cli_util/cli_util.dart';
+import 'package:path/path.dart' as p;
+
+ProcessResult runFfigenForConfig(String sdkPath, String configPath) {
+  return Process.runSync(
+    p.join(sdkPath, 'bin', 'dart'),
+    [
+      'run',
+      'ffigen',
+      '--config=$configPath',
+    ],
+    runInShell: Platform.isWindows,
+  );
+}
+
+void main() {
+  final sdkPath = getSdkPath();
+  final configPaths = [
+    'ffigen_configs/base.yaml',
+    'ffigen_configs/a.yaml',
+    'ffigen_configs/a_shared_base.yaml'
+  ];
+  for (final configPath in configPaths) {
+    final res = runFfigenForConfig(sdkPath, configPath);
+    print(res.stdout.toString());
+    if (res.exitCode != 0) {
+      throw Exception("Some error occurred: ${res.stderr.toString()}");
+    }
+  }
+}
diff --git a/pkgs/ffigen/example/shared_bindings/headers/a.h b/pkgs/ffigen/example/shared_bindings/headers/a.h
new file mode 100644
index 0000000..ef3bbea
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/headers/a.h
@@ -0,0 +1,21 @@
+
+#include "base.h"
+
+struct A_Struct1{
+    int a;
+};
+
+union A_Union1{
+    int a;
+};
+
+enum A_Enum{
+    A_ENUM_1,
+    A_ENUM_2,
+};
+
+#define A_MACRO_1 1;
+
+void a_func1();
+
+void a_func2(struct BaseStruct2 s, union BaseUnion2 u, BaseTypedef2 t);
diff --git a/pkgs/ffigen/example/shared_bindings/headers/base.h b/pkgs/ffigen/example/shared_bindings/headers/base.h
new file mode 100644
index 0000000..345cac6
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/headers/base.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+struct BaseStruct1{
+    int a;
+};
+
+union BaseUnion1{
+    int a;
+};
+
+struct BaseStruct2{
+    int a;
+};
+
+union BaseUnion2{
+    int a;
+};
+
+typedef struct BaseStruct1 BaseTypedef1;
+typedef struct BaseStruct2 BaseTypedef2;
+
+enum BaseEnum{
+    BASE_ENUM_1,
+    BASE_ENUM_2,
+};
+
+#define BASE_MACRO_1 1;
+
+void base_func1(BaseTypedef1 t1, BaseTypedef2 t2);
diff --git a/pkgs/ffigen/example/shared_bindings/lib/generated/a_gen.dart b/pkgs/ffigen/example/shared_bindings/lib/generated/a_gen.dart
new file mode 100644
index 0000000..4661c25
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/lib/generated/a_gen.dart
@@ -0,0 +1,113 @@
+// ignore_for_file: non_constant_identifier_names, camel_case_types
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Bindings to `headers/a.h`.
+class NativeLibraryA {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibraryA(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibraryA.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void base_func1(
+    BaseTypedef1 t1,
+    BaseTypedef2 t2,
+  ) {
+    return _base_func1(
+      t1,
+      t2,
+    );
+  }
+
+  late final _base_func1Ptr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(BaseTypedef1, BaseTypedef2)>>(
+      'base_func1');
+  late final _base_func1 =
+      _base_func1Ptr.asFunction<void Function(BaseTypedef1, BaseTypedef2)>();
+
+  void a_func1() {
+    return _a_func1();
+  }
+
+  late final _a_func1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('a_func1');
+  late final _a_func1 = _a_func1Ptr.asFunction<void Function()>();
+
+  void a_func2(
+    BaseStruct2 s,
+    BaseUnion2 u,
+    BaseTypedef2 t,
+  ) {
+    return _a_func2(
+      s,
+      u,
+      t,
+    );
+  }
+
+  late final _a_func2Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(BaseStruct2, BaseUnion2, BaseTypedef2)>>('a_func2');
+  late final _a_func2 = _a_func2Ptr
+      .asFunction<void Function(BaseStruct2, BaseUnion2, BaseTypedef2)>();
+}
+
+final class BaseStruct1 extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+final class BaseUnion1 extends ffi.Union {
+  @ffi.Int()
+  external int a;
+}
+
+final class BaseStruct2 extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+final class BaseUnion2 extends ffi.Union {
+  @ffi.Int()
+  external int a;
+}
+
+abstract class BaseEnum {
+  static const int BASE_ENUM_1 = 0;
+  static const int BASE_ENUM_2 = 1;
+}
+
+typedef BaseTypedef1 = BaseStruct1;
+typedef BaseTypedef2 = BaseStruct2;
+
+final class A_Struct1 extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+final class A_Union1 extends ffi.Union {
+  @ffi.Int()
+  external int a;
+}
+
+abstract class A_Enum {
+  static const int A_ENUM_1 = 0;
+  static const int A_ENUM_2 = 1;
+}
+
+const int BASE_MACRO_1 = 1;
+
+const int A_MACRO_1 = 1;
diff --git a/pkgs/ffigen/example/shared_bindings/lib/generated/a_shared_b_gen.dart b/pkgs/ffigen/example/shared_bindings/lib/generated/a_shared_b_gen.dart
new file mode 100644
index 0000000..ba61da4
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/lib/generated/a_shared_b_gen.dart
@@ -0,0 +1,71 @@
+// ignore_for_file: non_constant_identifier_names, camel_case_types
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+import 'package:shared_bindings/generated/base_gen.dart' as imp1;
+
+/// Bindings to `headers/a.h` with shared definitions from `headers/base.h`.
+class NativeLibraryASharedB {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibraryASharedB(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibraryASharedB.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void a_func1() {
+    return _a_func1();
+  }
+
+  late final _a_func1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('a_func1');
+  late final _a_func1 = _a_func1Ptr.asFunction<void Function()>();
+
+  void a_func2(
+    imp1.BaseStruct2 s,
+    imp1.BaseUnion2 u,
+    imp1.BaseTypedef2 t,
+  ) {
+    return _a_func2(
+      s,
+      u,
+      t,
+    );
+  }
+
+  late final _a_func2Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(imp1.BaseStruct2, imp1.BaseUnion2,
+              imp1.BaseTypedef2)>>('a_func2');
+  late final _a_func2 = _a_func2Ptr.asFunction<
+      void Function(imp1.BaseStruct2, imp1.BaseUnion2, imp1.BaseTypedef2)>();
+}
+
+final class A_Struct1 extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+final class A_Union1 extends ffi.Union {
+  @ffi.Int()
+  external int a;
+}
+
+abstract class A_Enum {
+  static const int A_ENUM_1 = 0;
+  static const int A_ENUM_2 = 1;
+}
+
+const int BASE_MACRO_1 = 1;
+
+const int A_MACRO_1 = 1;
diff --git a/pkgs/ffigen/example/shared_bindings/lib/generated/base_gen.dart b/pkgs/ffigen/example/shared_bindings/lib/generated/base_gen.dart
new file mode 100644
index 0000000..9d90b53
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/lib/generated/base_gen.dart
@@ -0,0 +1,70 @@
+// ignore_for_file: non_constant_identifier_names, camel_case_types
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Bindings to `headers/base.h`.
+class NativeLibraryBase {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibraryBase(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibraryBase.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void base_func1(
+    BaseTypedef1 t1,
+    BaseTypedef2 t2,
+  ) {
+    return _base_func1(
+      t1,
+      t2,
+    );
+  }
+
+  late final _base_func1Ptr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(BaseTypedef1, BaseTypedef2)>>(
+      'base_func1');
+  late final _base_func1 =
+      _base_func1Ptr.asFunction<void Function(BaseTypedef1, BaseTypedef2)>();
+}
+
+final class BaseStruct1 extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+final class BaseUnion1 extends ffi.Union {
+  @ffi.Int()
+  external int a;
+}
+
+final class BaseStruct2 extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+final class BaseUnion2 extends ffi.Union {
+  @ffi.Int()
+  external int a;
+}
+
+abstract class BaseEnum {
+  static const int BASE_ENUM_1 = 0;
+  static const int BASE_ENUM_2 = 1;
+}
+
+typedef BaseTypedef1 = BaseStruct1;
+typedef BaseTypedef2 = BaseStruct2;
+
+const int BASE_MACRO_1 = 1;
diff --git a/pkgs/ffigen/example/shared_bindings/lib/generated/base_symbols.yaml b/pkgs/ffigen/example/shared_bindings/lib/generated/base_symbols.yaml
new file mode 100644
index 0000000..ad455fa
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/lib/generated/base_symbols.yaml
@@ -0,0 +1,22 @@
+format_version: 1.0.0
+files:
+  package:shared_bindings/generated/base_gen.dart:
+    used-config:
+      ffi-native: false
+    symbols:
+      c:@E@BaseEnum:
+        name: BaseEnum
+      c:@F@base_func1:
+        name: base_func1
+      c:@S@BaseStruct1:
+        name: BaseStruct1
+      c:@S@BaseStruct2:
+        name: BaseStruct2
+      c:@U@BaseUnion1:
+        name: BaseUnion1
+      c:@U@BaseUnion2:
+        name: BaseUnion2
+      c:base.h@T@BaseTypedef1:
+        name: BaseTypedef1
+      c:base.h@T@BaseTypedef2:
+        name: BaseTypedef2
diff --git a/pkgs/ffigen/example/shared_bindings/pubspec.yaml b/pkgs/ffigen/example/shared_bindings/pubspec.yaml
new file mode 100644
index 0000000..1684c99
--- /dev/null
+++ b/pkgs/ffigen/example/shared_bindings/pubspec.yaml
@@ -0,0 +1,18 @@
+# Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+name: shared_bindings
+
+environment:
+  sdk: '>=3.2.0 <4.0.0'
+
+dependencies:
+  cli_util: ^0.4.0
+  ffi: ^2.0.1
+  path: ^1.8.0
+
+dev_dependencies:
+  ffigen:
+    path: '../../'
+  lints: ^2.0.1
diff --git a/pkgs/ffigen/example/simple/.gitignore b/pkgs/ffigen/example/simple/.gitignore
new file mode 100644
index 0000000..1b05164
--- /dev/null
+++ b/pkgs/ffigen/example/simple/.gitignore
@@ -0,0 +1,11 @@
+# Files and directories created by pub.
+.dart_tool/
+.packages
+# Remove the following pattern if you wish to check in your lock file.
+pubspec.lock
+
+# Conventional directory for build outputs.
+build/
+
+# Directory created by dartdoc.
+doc/api/
diff --git a/pkgs/ffigen/example/simple/README.md b/pkgs/ffigen/example/simple/README.md
new file mode 100644
index 0000000..81d9569
--- /dev/null
+++ b/pkgs/ffigen/example/simple/README.md
@@ -0,0 +1,10 @@
+# Simple header example
+
+A very simple example, generates bindings for a very small header file (`headers/example.h`).
+
+## Generating bindings
+At the root of this example (`example/simple`), run -
+```
+dart run ffigen --config config.yaml
+```
+This will generate bindings in a file: [generated_bindings.dart](./generated_bindings.dart).
diff --git a/pkgs/ffigen/example/simple/config.yaml b/pkgs/ffigen/example/simple/config.yaml
new file mode 100644
index 0000000..f12c349
--- /dev/null
+++ b/pkgs/ffigen/example/simple/config.yaml
@@ -0,0 +1,8 @@
+# yaml-language-server: $schema=../../ffigen.schema.json
+
+name: NativeLibrary
+description: Bindings to `headers/example.h`.
+output: 'generated_bindings.dart'
+headers:
+  entry-points:
+    - 'headers/example.h'
\ No newline at end of file
diff --git a/pkgs/ffigen/example/simple/generated_bindings.dart b/pkgs/ffigen/example/simple/generated_bindings.dart
new file mode 100644
index 0000000..71f0414
--- /dev/null
+++ b/pkgs/ffigen/example/simple/generated_bindings.dart
@@ -0,0 +1,107 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Bindings to `headers/example.h`.
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  /// Adds 2 integers.
+  int sum(
+    int a,
+    int b,
+  ) {
+    return _sum(
+      a,
+      b,
+    );
+  }
+
+  late final _sumPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int, ffi.Int)>>('sum');
+  late final _sum = _sumPtr.asFunction<int Function(int, int)>();
+
+  /// Subtracts 2 integers.
+  int subtract(
+    ffi.Pointer<ffi.Int> a,
+    int b,
+  ) {
+    return _subtract(
+      a,
+      b,
+    );
+  }
+
+  late final _subtractPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Int>, ffi.Int)>>(
+      'subtract');
+  late final _subtract =
+      _subtractPtr.asFunction<int Function(ffi.Pointer<ffi.Int>, int)>();
+
+  /// Multiplies 2 integers, returns pointer to an integer,.
+  ffi.Pointer<ffi.Int> multiply(
+    int a,
+    int b,
+  ) {
+    return _multiply(
+      a,
+      b,
+    );
+  }
+
+  late final _multiplyPtr = _lookup<
+          ffi.NativeFunction<ffi.Pointer<ffi.Int> Function(ffi.Int, ffi.Int)>>(
+      'multiply');
+  late final _multiply =
+      _multiplyPtr.asFunction<ffi.Pointer<ffi.Int> Function(int, int)>();
+
+  /// Divides 2 integers, returns pointer to a float.
+  ffi.Pointer<ffi.Float> divide(
+    int a,
+    int b,
+  ) {
+    return _divide(
+      a,
+      b,
+    );
+  }
+
+  late final _dividePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Float> Function(ffi.Int, ffi.Int)>>('divide');
+  late final _divide =
+      _dividePtr.asFunction<ffi.Pointer<ffi.Float> Function(int, int)>();
+
+  /// Divides 2 floats, returns a pointer to double.
+  ffi.Pointer<ffi.Double> dividePrecision(
+    ffi.Pointer<ffi.Float> a,
+    ffi.Pointer<ffi.Float> b,
+  ) {
+    return _dividePrecision(
+      a,
+      b,
+    );
+  }
+
+  late final _dividePrecisionPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Double> Function(ffi.Pointer<ffi.Float>,
+              ffi.Pointer<ffi.Float>)>>('dividePrecision');
+  late final _dividePrecision = _dividePrecisionPtr.asFunction<
+      ffi.Pointer<ffi.Double> Function(
+          ffi.Pointer<ffi.Float>, ffi.Pointer<ffi.Float>)>();
+}
diff --git a/pkgs/ffigen/example/simple/headers/example.h b/pkgs/ffigen/example/simple/headers/example.h
new file mode 100644
index 0000000..40c6b9e
--- /dev/null
+++ b/pkgs/ffigen/example/simple/headers/example.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/** Adds 2 integers. */
+int sum(int a, int b);
+
+/** Subtracts 2 integers. */
+int subtract(int *a, int b);
+
+/** Multiplies 2 integers, returns pointer to an integer,. */
+int *multiply(int a, int b);
+
+/** Divides 2 integers, returns pointer to a float. */
+float *divide(int a, int b);
+
+/** Divides 2 floats, returns a pointer to double. */
+double *dividePrecision(float *a, float *b);
diff --git a/pkgs/ffigen/example/simple/pubspec.yaml b/pkgs/ffigen/example/simple/pubspec.yaml
new file mode 100644
index 0000000..f1912eb
--- /dev/null
+++ b/pkgs/ffigen/example/simple/pubspec.yaml
@@ -0,0 +1,15 @@
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+name: simple_example
+
+environment:
+  sdk: '>=3.2.0 <4.0.0'
+
+dependencies:
+  ffi: ^2.0.1
+dev_dependencies:
+  ffigen:
+    path: '../../'
+  lints: ^2.0.1
diff --git a/pkgs/ffigen/example/swift/README.md b/pkgs/ffigen/example/swift/README.md
new file mode 100644
index 0000000..caa482e
--- /dev/null
+++ b/pkgs/ffigen/example/swift/README.md
@@ -0,0 +1,72 @@
+# Swift example
+
+This example shows how to use ffigen to interact with Swift libraries.
+
+Swift APIs can be made compatible with Objective-C, using the `@objc`
+annotation. Then you can use the `swiftc` tool to build a dylib for the library
+using `-emit-library`, and generate an Objective-C wrapper header using
+`-emit-objc-header-path filename.h`:
+
+```shell
+swiftc -c swift_api.swift                           \
+    -module-name swift_module                       \
+    -emit-objc-header-path third_party/swift_api.h  \
+    -emit-library -o libswiftapi.dylib
+```
+
+This should generate libswiftapi.dylib and swift_api.h.
+For more information about Objective-C / Swift interoperability, see the
+[Apple documentation](https://developer.apple.com/documentation/swift/importing-swift-into-objective-c).
+
+Once you have an Objective-C wrapper header, ffigen can parse it like
+any other header:
+
+```shell
+dart run ffigen --config config.yaml
+```
+
+This will generate [swift_api_bindings.dart](./swift_api_bindings.dart),
+using the config in the ffigen section of the pubspec.yaml.
+
+Finally, you can run the example using this command:
+
+```shell
+dart run example.dart
+```
+
+## Config notes
+
+Ffigen only sees the Objective-C wrapper header, swift_api.h. So you
+need to set the language to objc, and set the entry-point to the header:
+
+```yaml
+language: objc
+headers:
+  entry-points:
+    - 'third_party/swift_api.h'
+```
+
+Swift classes become Objective-C interfaces, so include them like this:
+
+```yaml
+objc-interfaces:
+  include:
+    - 'SwiftClass'
+```
+
+There is one extra option you need to set when wrapping a Swift library.
+When `swiftc` compiles the library, it gives the Objective-C interface
+a module prefix. Internally, our `SwiftClass` is actually registered
+as `swift_module.SwiftClass`. So you need to tell ffigen about this prefix,
+so it loads the correct class from the dylib:
+
+```yaml
+objc-interfaces:
+  include:
+    - 'SwiftClass'
+  module:
+    'SwiftClass': 'swift_module'
+```
+
+The module prefix is whatever you passed to `swiftc` in the
+`-module-name` flag.
diff --git a/pkgs/ffigen/example/swift/config.yaml b/pkgs/ffigen/example/swift/config.yaml
new file mode 100644
index 0000000..7f820ba
--- /dev/null
+++ b/pkgs/ffigen/example/swift/config.yaml
@@ -0,0 +1,21 @@
+# yaml-language-server: $schema=../../ffigen.schema.json
+
+name: SwiftLibrary
+description: Bindings for swift_api.
+language: objc
+output: 'swift_api_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - 'SwiftClass'
+  module:
+    'SwiftClass': 'swift_module'
+headers:
+  entry-points:
+    - 'third_party/swift_api.h'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names
+  // ignore_for_file: unused_element, unused_field, return_of_invalid_type
+  // ignore_for_file: void_checks, annotate_overrides
+  // ignore_for_file: no_leading_underscores_for_local_identifiers
+  // ignore_for_file: library_private_types_in_public_api
diff --git a/pkgs/ffigen/example/swift/example.dart b/pkgs/ffigen/example/swift/example.dart
new file mode 100644
index 0000000..c9dd5ba
--- /dev/null
+++ b/pkgs/ffigen/example/swift/example.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+import 'swift_api_bindings.dart';
+
+void main() {
+  // TODO(https://github.com/dart-lang/ffigen/issues/443): Add a test for this.
+  final lib = SwiftLibrary(DynamicLibrary.open('libswiftapi.dylib'));
+  final object = SwiftClass.new1(lib);
+  print(object.sayHello());
+  print('field = ${object.someField}');
+  object.someField = 456;
+  print('field = ${object.someField}');
+}
diff --git a/pkgs/ffigen/example/swift/pubspec.yaml b/pkgs/ffigen/example/swift/pubspec.yaml
new file mode 100644
index 0000000..de19bf2
--- /dev/null
+++ b/pkgs/ffigen/example/swift/pubspec.yaml
@@ -0,0 +1,15 @@
+# Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+name: swift_example
+
+environment:
+  sdk: ">=3.2.0-42.1.beta <4.0.0"
+
+dependencies:
+  ffi: ^2.0.1
+dev_dependencies:
+  ffigen:
+    path: "../../"
+  lints: ^2.0.0
diff --git a/pkgs/ffigen/example/swift/swift_api.swift b/pkgs/ffigen/example/swift/swift_api.swift
new file mode 100644
index 0000000..a978226
--- /dev/null
+++ b/pkgs/ffigen/example/swift/swift_api.swift
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import Foundation
+
+@objc public class SwiftClass: NSObject {
+  @objc public func sayHello() -> String {
+    return "Hello from Swift!";
+  }
+
+  @objc public var someField = 123;
+}
diff --git a/pkgs/ffigen/example/swift/swift_api_bindings.dart b/pkgs/ffigen/example/swift/swift_api_bindings.dart
new file mode 100644
index 0000000..9d19d79
--- /dev/null
+++ b/pkgs/ffigen/example/swift/swift_api_bindings.dart
@@ -0,0 +1,64755 @@
+// ignore_for_file: camel_case_types, non_constant_identifier_names
+// ignore_for_file: unused_element, unused_field, return_of_invalid_type
+// ignore_for_file: void_checks, annotate_overrides
+// ignore_for_file: no_leading_underscores_for_local_identifiers
+// ignore_for_file: 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 swift_api.
+class SwiftLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  SwiftLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  SwiftLibrary.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_SwiftClass1 = _getClass1("swift_module.SwiftClass");
+  late final _sel_sayHello1 = _registerName1("sayHello");
+  late final _sel_someField1 = _registerName1("someField");
+  late final _sel_setSomeField_1 = _registerName1("setSomeField:");
+}
+
+class _ObjCWrapper implements ffi.Finalizable {
+  final ffi.Pointer<ObjCObject> _id;
+  final SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_1(_lib._class_NSObject1, _lib._sel_load1);
+  }
+
+  static void initialize(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSObject1, _lib._sel_new1);
+    return NSObject._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSObject allocWithZone_(SwiftLibrary _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(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, ffi.Pointer<ObjCSel> aSelector) {
+    return _lib._objc_msgSend_4(_lib._class_NSObject1,
+        _lib._sel_instancesRespondToSelector_1, aSelector);
+  }
+
+  static bool conformsToProtocol_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _lib, NSObject aClass) {
+    return _lib._objc_msgSend_0(
+        _lib._class_NSObject1, _lib._sel_isSubclassOfClass_1, aClass._id);
+  }
+
+  static bool resolveClassMethod_(SwiftLibrary _lib, ffi.Pointer<ObjCSel> sel) {
+    return _lib._objc_msgSend_4(
+        _lib._class_NSObject1, _lib._sel_resolveClassMethod_1, sel);
+  }
+
+  static bool resolveInstanceMethod_(
+      SwiftLibrary _lib, ffi.Pointer<ObjCSel> sel) {
+    return _lib._objc_msgSend_4(
+        _lib._class_NSObject1, _lib._sel_resolveInstanceMethod_1, sel);
+  }
+
+  static int hash(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_10(_lib._class_NSObject1, _lib._sel_hash1);
+  }
+
+  static NSObject superclass(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSObject1, _lib._sel_superclass1);
+    return NSObject._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject class1(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSObject1, _lib._sel_class1);
+    return NSObject._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSString description(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_20(_lib._class_NSObject1, _lib._sel_description1);
+    return NSString._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSString debugDescription(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_20(
+        _lib._class_NSObject1, _lib._sel_debugDescription1);
+    return NSString._(_ret, _lib, retain: true, release: true);
+  }
+
+  static int version(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_78(_lib._class_NSObject1, _lib._sel_version1);
+  }
+
+  static void setVersion_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSObject1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSInvocation1, _lib._sel_new1);
+    return NSInvocation._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSInvocation alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSInvocation1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSInvocation1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSInvocation1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSInvocation1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSInvocation1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMethodSignature1, _lib._sel_new1);
+    return NSMethodSignature._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSMethodSignature alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSMethodSignature1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSMethodSignature1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMethodSignature1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSMethodSignature1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSMethodSignature1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSSet1, _lib._sel_set1);
+    return NSSet._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSSet setWithObject_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSSet1, _lib._sel_new1);
+    return NSSet._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSSet alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSSet1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSSet1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSSet1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSSet1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSSet1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSEnumerator1, _lib._sel_new1);
+    return NSEnumerator._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSEnumerator alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSEnumerator1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSEnumerator1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSEnumerator1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSEnumerator1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSEnumerator1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(
+      SwiftLibrary _lib) {
+    return _lib._objc_msgSend_318(
+        _lib._class_NSString1, _lib._sel_availableStringEncodings1);
+  }
+
+  static NSString localizedNameOfStringEncoding_(
+      SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSString1, _lib._sel_string1);
+    return NSString._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSString stringWithString_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+          SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSString1, _lib._sel_new1);
+    return NSString._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSString alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSString1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSString1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSString1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSString1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSString1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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(SwiftLibrary lib) => NSString(lib, this);
+}
+
+typedef unichar = ffi.UnsignedShort;
+
+class NSCoder extends NSObject {
+  NSCoder._(ffi.Pointer<ObjCObject> id, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSCoder1, _lib._sel_new1);
+    return NSCoder._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSCoder alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSCoder1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSCoder1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSCoder1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSCoder1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSCoder1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(SwiftLibrary 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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSData1, _lib._sel_new1);
+    return NSData._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSData alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSData1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSData1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSData1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSData1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSData1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSURL1, _lib._sel_new1);
+    return NSURL._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURL alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURL1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURL1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURL1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURL1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSURL1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSNumber1, _lib._sel_new1);
+    return NSNumber._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSNumber alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSNumber1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSNumber1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSNumber1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSNumber1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSNumber1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSValue1, _lib._sel_new1);
+    return NSValue._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSValue alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSValue1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSValue1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSValue1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSValue1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSValue1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSArray1, _lib._sel_array1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSArray arrayWithObject_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSArray1, _lib._sel_new1);
+    return NSArray._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSArray alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSArray1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSArray1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSArray1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSArray1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSArray1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSError1, _lib._sel_new1);
+    return NSError._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSError alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSError1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSError1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSError1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSError1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSError1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSIndexSet1, _lib._sel_indexSet1);
+    return NSIndexSet._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSIndexSet indexSetWithIndex_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSIndexSet1, _lib._sel_new1);
+    return NSIndexSet._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSIndexSet alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSIndexSet1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSIndexSet1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSIndexSet1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSIndexSet1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSIndexSet1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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 SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock1.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock2.fromFunctionPointer(
+      SwiftLibrary 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(SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock3.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock4.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock5.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSPredicate1, _lib._sel_new1);
+    return NSPredicate._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSPredicate alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSPredicate1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSPredicate1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSPredicate1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSPredicate1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSPredicate1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock6.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSDictionary1, _lib._sel_new1);
+    return NSDictionary._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSDictionary alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSDictionary1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSDictionary1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSDictionary1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSDictionary1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSDictionary1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock7.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSDate1, _lib._sel_date1);
+    return NSDate._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSDate dateWithTimeIntervalSinceNow_(SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSDate1, _lib._sel_new1);
+    return NSDate._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSDate alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSDate1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSDate1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSDate1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSDate1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSDate1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSCalendarDate1, _lib._sel_date1);
+    return NSCalendarDate._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSCalendarDate dateWithTimeIntervalSinceNow_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSCalendarDate1, _lib._sel_new1);
+    return NSCalendarDate._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSCalendarDate alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSCalendarDate1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSCalendarDate1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSCalendarDate1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSCalendarDate1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSCalendarDate1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_1(
+        _lib._class_NSTimeZone1, _lib._sel_resetSystemTimeZone1);
+  }
+
+  static NSTimeZone? getDefaultTimeZone(SwiftLibrary _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(SwiftLibrary _lib, NSTimeZone? value) {
+    _lib._objc_msgSend_163(_lib._class_NSTimeZone1,
+        _lib._sel_setDefaultTimeZone_1, value?._id ?? ffi.nullptr);
+  }
+
+  static NSTimeZone? getLocalTimeZone(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(
+      SwiftLibrary _lib, NSDictionary? value) {
+    _lib._objc_msgSend_165(_lib._class_NSTimeZone1,
+        _lib._sel_setAbbreviationDictionary_1, value?._id ?? ffi.nullptr);
+  }
+
+  static NSString? getTimeZoneDataVersion(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSTimeZone1, _lib._sel_new1);
+    return NSTimeZone._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSTimeZone alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSTimeZone1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSTimeZone1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSTimeZone1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSTimeZone1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSTimeZone1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? localeIdentifier) {
+    return _lib._objc_msgSend_179(
+        _lib._class_NSLocale1,
+        _lib._sel_windowsLocaleCodeFromLocaleIdentifier_1,
+        localeIdentifier?._id ?? ffi.nullptr);
+  }
+
+  static int characterDirectionForLanguage_(
+      SwiftLibrary _lib, NSString? isoLangCode) {
+    return _lib._objc_msgSend_180(
+        _lib._class_NSLocale1,
+        _lib._sel_characterDirectionForLanguage_1,
+        isoLangCode?._id ?? ffi.nullptr);
+  }
+
+  static int lineDirectionForLanguage_(
+      SwiftLibrary _lib, NSString? isoLangCode) {
+    return _lib._objc_msgSend_180(_lib._class_NSLocale1,
+        _lib._sel_lineDirectionForLanguage_1, isoLangCode?._id ?? ffi.nullptr);
+  }
+
+  static NSLocale new1(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSLocale1, _lib._sel_new1);
+    return NSLocale._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSLocale alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSLocale1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSLocale1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSLocale1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSLocale1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSLocale1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _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(
+      SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSCharacterSet1, _lib._sel_new1);
+    return NSCharacterSet._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSCharacterSet alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSCharacterSet1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSCharacterSet1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSCharacterSet1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSCharacterSet1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSCharacterSet1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _lib, NSObject anURLHandleSubclass) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLHandle1,
+        _lib._sel_registerURLHandleClass_1, anURLHandleSubclass._id);
+  }
+
+  static NSObject URLHandleClassForURL_(SwiftLibrary _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_(SwiftLibrary _lib, NSURL? anURL) {
+    return _lib._objc_msgSend_229(_lib._class_NSURLHandle1,
+        _lib._sel_canInitWithURL_1, anURL?._id ?? ffi.nullptr);
+  }
+
+  static NSURLHandle cachedHandleForURL_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSURLHandle1, _lib._sel_new1);
+    return NSURLHandle._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLHandle alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLHandle1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLHandle1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLHandle1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLHandle1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSURLHandle1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock8.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock9.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock10.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock11.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock12.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSOrthography1, _lib._sel_new1);
+    return NSOrthography._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSOrthography alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSOrthography1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSOrthography1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSOrthography1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSOrthography1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSOrthography1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock13.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock14.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSFileManager1, _lib._sel_new1);
+    return NSFileManager._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSFileManager alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSFileManager1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSFileManager1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSFileManager1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSFileManager1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSFileManager1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock15.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMutableArray1, _lib._sel_array1);
+    return NSMutableArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSMutableArray arrayWithObject_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMutableArray1, _lib._sel_new1);
+    return NSMutableArray._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSMutableArray alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSMutableArray1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSMutableArray1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMutableArray1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSMutableArray1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSMutableArray1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSMutableOrderedSet1, _lib._sel_orderedSet1);
+    return NSMutableOrderedSet._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSMutableOrderedSet orderedSetWithObject_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMutableOrderedSet1, _lib._sel_new1);
+    return NSMutableOrderedSet._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSMutableOrderedSet alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSMutableOrderedSet1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSMutableOrderedSet1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMutableOrderedSet1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSMutableOrderedSet1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSMutableOrderedSet1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSOrderedSet1, _lib._sel_orderedSet1);
+    return NSOrderedSet._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSOrderedSet orderedSetWithObject_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSOrderedSet1, _lib._sel_new1);
+    return NSOrderedSet._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSOrderedSet alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSOrderedSet1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSOrderedSet1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSOrderedSet1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSOrderedSet1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSOrderedSet1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMutableSet1, _lib._sel_set1);
+    return NSMutableSet._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSMutableSet setWithObject_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMutableSet1, _lib._sel_new1);
+    return NSMutableSet._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSMutableSet alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSMutableSet1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMutableSet1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMutableSet1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSMutableSet1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSMutableSet1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSKeyedArchiver1, _lib._sel_new1);
+    return NSKeyedArchiver._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSKeyedArchiver alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSKeyedArchiver1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSKeyedArchiver1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSKeyedArchiver1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSKeyedArchiver1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSKeyedArchiver1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMutableData1, _lib._sel_new1);
+    return NSMutableData._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSMutableData alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSMutableData1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMutableData1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMutableData1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSMutableData1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSMutableData1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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_(SwiftLibrary _lib, ObjCBlock16 block) {
+    return _lib._objc_msgSend_465(
+        _lib._class_NSThread1, _lib._sel_detachNewThreadWithBlock_1, block._id);
+  }
+
+  static void detachNewThreadSelector_toTarget_withObject_(SwiftLibrary _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(SwiftLibrary _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_(SwiftLibrary _lib, NSDate? date) {
+    return _lib._objc_msgSend_472(_lib._class_NSThread1,
+        _lib._sel_sleepUntilDate_1, date?._id ?? ffi.nullptr);
+  }
+
+  static void sleepForTimeInterval_(SwiftLibrary _lib, double ti) {
+    return _lib._objc_msgSend_473(
+        _lib._class_NSThread1, _lib._sel_sleepForTimeInterval_1, ti);
+  }
+
+  static void exit(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSThread1, _lib._sel_new1);
+    return NSThread._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSThread alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSThread1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSThread1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSThread1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSThread1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSThread1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock16.fromFunctionPointer(SwiftLibrary 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(SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMutableDictionary1, _lib._sel_new1);
+    return NSMutableDictionary._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSMutableDictionary alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSMutableDictionary1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSMutableDictionary1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMutableDictionary1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSMutableDictionary1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSMutableDictionary1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSArchiver1, _lib._sel_new1);
+    return NSArchiver._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSArchiver alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSArchiver1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSArchiver1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSArchiver1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSArchiver1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSArchiver1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSPortCoder1, _lib._sel_new1);
+    return NSPortCoder._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSPortCoder alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSPortCoder1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSPortCoder1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSPortCoder1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSPortCoder1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSPortCoder1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSPort1, _lib._sel_new1);
+    return NSPort._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSPort alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSPort1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSPort1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSPort1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSPort1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSPort1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSRunLoop1, _lib._sel_new1);
+    return NSRunLoop._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSRunLoop alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSRunLoop1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSRunLoop1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSRunLoop1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSRunLoop1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSRunLoop1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+          SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSTimer1, _lib._sel_new1);
+    return NSTimer._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSTimer alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSTimer1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSTimer1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSTimer1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSTimer1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSTimer1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock17.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSConnection1, _lib._sel_allConnections1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSConnection defaultConnection(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+          SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSConnection1, _lib._sel_new1);
+    return NSConnection._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSConnection alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSConnection1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSConnection1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSConnection1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSConnection1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSConnection1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSPortNameServer1, _lib._sel_new1);
+    return NSPortNameServer._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSPortNameServer alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSPortNameServer1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSPortNameServer1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSPortNameServer1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSPortNameServer1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSPortNameServer1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSDistantObject1, _lib._sel_alloc1);
+    return NSObject._(_ret, _lib, retain: false, release: true);
+  }
+
+  static bool respondsToSelector_(
+      SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSProxy1, _lib._sel_alloc1);
+    return NSObject._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSObject allocWithZone_(SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_1(_lib._class_NSClassDescription1,
+        _lib._sel_invalidateClassDescriptionCache1);
+  }
+
+  static NSClassDescription classDescriptionForClass_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSClassDescription1, _lib._sel_new1);
+    return NSClassDescription._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSClassDescription alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSClassDescription1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSClassDescription1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSClassDescription1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSClassDescription1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSClassDescription1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSScriptObjectSpecifier1, _lib._sel_new1);
+    return NSScriptObjectSpecifier._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSScriptObjectSpecifier alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSScriptObjectSpecifier1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSScriptObjectSpecifier1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSScriptObjectSpecifier1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSScriptObjectSpecifier1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSScriptObjectSpecifier1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+          SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_526(
+        _lib._class_NSAppleEventDescriptor1, _lib._sel_listDescriptor1);
+    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSAppleEventDescriptor recordDescriptor(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_526(
+        _lib._class_NSAppleEventDescriptor1, _lib._sel_recordDescriptor1);
+    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSAppleEventDescriptor currentProcessDescriptor(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_526(_lib._class_NSAppleEventDescriptor1,
+        _lib._sel_currentProcessDescriptor1);
+    return NSAppleEventDescriptor._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSAppleEventDescriptor descriptorWithProcessIdentifier_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSAppleEventDescriptor1, _lib._sel_new1);
+    return NSAppleEventDescriptor._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSAppleEventDescriptor alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSAppleEventDescriptor1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSAppleEventDescriptor1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSAppleEventDescriptor1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSAppleEventDescriptor1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSAppleEventDescriptor1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_1(_lib._class_NSScriptClassDescription1,
+        _lib._sel_invalidateClassDescriptionCache1);
+  }
+
+  static NSScriptClassDescription new1(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSScriptClassDescription1, _lib._sel_new1);
+    return NSScriptClassDescription._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSScriptClassDescription alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSScriptClassDescription1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSScriptClassDescription1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSScriptClassDescription1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSScriptClassDescription1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSScriptClassDescription1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSScriptCommandDescription1, _lib._sel_new1);
+    return NSScriptCommandDescription._(_ret, _lib,
+        retain: false, release: true);
+  }
+
+  static NSScriptCommandDescription alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSScriptCommandDescription1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSScriptCommandDescription1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSScriptCommandDescription1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSScriptCommandDescription1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSScriptCommandDescription1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSScriptCommand1, _lib._sel_new1);
+    return NSScriptCommand._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSScriptCommand alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSScriptCommand1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSScriptCommand1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSScriptCommand1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSScriptCommand1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSScriptCommand1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSItemProvider1, _lib._sel_new1);
+    return NSItemProvider._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSItemProvider alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSItemProvider1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSItemProvider1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSItemProvider1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSItemProvider1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSItemProvider1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock18.fromFunctionPointer(
+      SwiftLibrary 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(SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_577(
+        _lib._class_NSProgress1, _lib._sel_currentProgress1);
+    return NSProgress._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSProgress progressWithTotalUnitCount_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSProgress1, _lib._sel_new1);
+    return NSProgress._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSProgress alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSProgress1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSProgress1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSProgress1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSProgress1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSProgress1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock19.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock20.fromFunctionPointer(
+      SwiftLibrary 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(SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock21.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock22.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock23.fromFunctionPointer(
+      SwiftLibrary 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(SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock24.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock25.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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(
+      SwiftLibrary _lib) {
+    return _lib._objc_msgSend_318(
+        _lib._class_NSMutableString1, _lib._sel_availableStringEncodings1);
+  }
+
+  static NSString localizedNameOfStringEncoding_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_10(
+        _lib._class_NSMutableString1, _lib._sel_defaultCStringEncoding1);
+  }
+
+  static NSMutableString string(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMutableString1, _lib._sel_string1);
+    return NSMutableString._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSMutableString stringWithString_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+          SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMutableString1, _lib._sel_new1);
+    return NSMutableString._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSMutableString alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSMutableString1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSMutableString1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMutableString1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSMutableString1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSMutableString1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSNotification1, _lib._sel_new1);
+    return NSNotification._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSNotification alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSNotification1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSNotification1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSNotification1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSNotification1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSNotification1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSBundle1, _lib._sel_new1);
+    return NSBundle._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSBundle alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSBundle1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSBundle1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSBundle1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSBundle1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSBundle1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSAttributedString1, _lib._sel_new1);
+    return NSAttributedString._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSAttributedString alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSAttributedString1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSAttributedString1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSAttributedString1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSAttributedString1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSAttributedString1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock26.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock27.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSAttributedStringMarkdownParsingOptions1, _lib._sel_new1);
+    return NSAttributedStringMarkdownParsingOptions._(_ret, _lib,
+        retain: false, release: true);
+  }
+
+  static NSAttributedStringMarkdownParsingOptions alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(
+        _lib._class_NSAttributedStringMarkdownParsingOptions1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1,
+        aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSAttributedStringMarkdownParsingOptions1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSAttributedStringMarkdownParsingOptions1,
+        _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSAttributedStringMarkdownParsingOptions1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSAttributedStringMarkdownParsingOptions1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSMutableAttributedString1, _lib._sel_new1);
+    return NSMutableAttributedString._(_ret, _lib,
+        retain: false, release: true);
+  }
+
+  static NSMutableAttributedString alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSMutableAttributedString1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSMutableAttributedString1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMutableAttributedString1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSMutableAttributedString1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSMutableAttributedString1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_660(
+        _lib._class_NSDateFormatter1, _lib._sel_defaultFormatterBehavior1);
+  }
+
+  static void setDefaultFormatterBehavior(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSDateFormatter1, _lib._sel_new1);
+    return NSDateFormatter._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSDateFormatter alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSDateFormatter1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSDateFormatter1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSDateFormatter1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSDateFormatter1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSDateFormatter1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSFormatter1, _lib._sel_new1);
+    return NSFormatter._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSFormatter alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSFormatter1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSFormatter1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSFormatter1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSFormatter1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSFormatter1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSCalendar1, _lib._sel_new1);
+    return NSCalendar._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSCalendar alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSCalendar1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSCalendar1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSCalendar1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSCalendar1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSCalendar1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSDateComponents1, _lib._sel_new1);
+    return NSDateComponents._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSDateComponents alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSDateComponents1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSDateComponents1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSDateComponents1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSDateComponents1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSDateComponents1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock28.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_700(
+        _lib._class_NSNumberFormatter1, _lib._sel_defaultFormatterBehavior1);
+  }
+
+  static void setDefaultFormatterBehavior_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSNumberFormatter1, _lib._sel_new1);
+    return NSNumberFormatter._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSNumberFormatter alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSNumberFormatter1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSNumberFormatter1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSNumberFormatter1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSNumberFormatter1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSNumberFormatter1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(
+      SwiftLibrary _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_(
+          SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSDecimalNumberHandler1, _lib._sel_new1);
+    return NSDecimalNumberHandler._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSDecimalNumberHandler alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSDecimalNumberHandler1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSDecimalNumberHandler1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSDecimalNumberHandler1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSDecimalNumberHandler1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSDecimalNumberHandler1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSScanner1, _lib._sel_new1);
+    return NSScanner._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSScanner alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSScanner1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSScanner1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSScanner1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSScanner1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSScanner1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSException1, _lib._sel_new1);
+    return NSException._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSException alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSException1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSException1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSException1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSException1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSException1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSFileHandle1, _lib._sel_new1);
+    return NSFileHandle._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSFileHandle alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSFileHandle1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSFileHandle1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSFileHandle1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSFileHandle1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSFileHandle1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock29.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSHTTPCookieStorage1, _lib._sel_new1);
+    return NSHTTPCookieStorage._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSHTTPCookieStorage alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSHTTPCookieStorage1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSHTTPCookieStorage1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSHTTPCookieStorage1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSHTTPCookieStorage1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSHTTPCookieStorage1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSHTTPCookie1, _lib._sel_new1);
+    return NSHTTPCookie._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSHTTPCookie alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSHTTPCookie1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSHTTPCookie1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSHTTPCookie1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSHTTPCookie1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSHTTPCookie1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSURLSessionTask1, _lib._sel_new1);
+    return NSURLSessionTask._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLSessionTask alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLSessionTask1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLSessionTask1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLSessionTask1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLSessionTask1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionTask1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLRequest1, _lib._sel_supportsSecureCoding1);
+  }
+
+  static NSURLRequest requestWithURL_cachePolicy_timeoutInterval_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSURLRequest1, _lib._sel_new1);
+    return NSURLRequest._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLRequest alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLRequest1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLRequest1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLRequest1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLRequest1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSURLRequest1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSInputStream1, _lib._sel_new1);
+    return NSInputStream._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSInputStream alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSInputStream1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSInputStream1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSInputStream1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSInputStream1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSInputStream1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSStream1, _lib._sel_new1);
+    return NSStream._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSStream alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSStream1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSStream1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSStream1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSStream1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSStream1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSOutputStream1, _lib._sel_new1);
+    return NSOutputStream._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSOutputStream alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSOutputStream1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSOutputStream1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSOutputStream1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSOutputStream1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSOutputStream1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSHost1, _lib._sel_currentHost1);
+    return NSHost._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSHost hostWithName_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _lib, bool flag) {
+    return _lib._objc_msgSend_756(
+        _lib._class_NSHost1, _lib._sel_setHostCacheEnabled_1, flag);
+  }
+
+  static bool isHostCacheEnabled(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSHost1, _lib._sel_isHostCacheEnabled1);
+  }
+
+  static void flushHostCache(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_1(_lib._class_NSHost1, _lib._sel_flushHostCache1);
+  }
+
+  static NSHost new1(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSHost1, _lib._sel_new1);
+    return NSHost._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSHost alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSHost1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSHost1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSHost1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSHost1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSHost1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSURLResponse1, _lib._sel_new1);
+    return NSURLResponse._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLResponse alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLResponse1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLResponse1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLResponse1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLResponse1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSURLResponse1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock30.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSIndexPath1, _lib._sel_new1);
+    return NSIndexPath._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSIndexPath alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSIndexPath1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSIndexPath1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSIndexPath1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSIndexPath1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSIndexPath1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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_(SwiftLibrary _lib, NSString? language) {
+    return _lib._objc_msgSend_59(_lib._class_NSInflectionRule1,
+        _lib._sel_canInflectLanguage_1, language?._id ?? ffi.nullptr);
+  }
+
+  static bool getCanInflectPreferredLocalization(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSInflectionRule1,
+        _lib._sel_canInflectPreferredLocalization1);
+  }
+
+  static NSInflectionRule new1(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSInflectionRule1, _lib._sel_new1);
+    return NSInflectionRule._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSInflectionRule alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSInflectionRule1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSInflectionRule1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSInflectionRule1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSInflectionRule1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSInflectionRule1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMorphology1, _lib._sel_new1);
+    return NSMorphology._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSMorphology alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSMorphology1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMorphology1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMorphology1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSMorphology1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSMorphology1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _lib, NSString? language) {
+    return _lib._objc_msgSend_59(_lib._class_NSMorphologyCustomPronoun1,
+        _lib._sel_isSupportedForLanguage_1, language?._id ?? ffi.nullptr);
+  }
+
+  static NSArray requiredKeysForLanguage_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSMorphologyCustomPronoun1, _lib._sel_new1);
+    return NSMorphologyCustomPronoun._(_ret, _lib,
+        retain: false, release: true);
+  }
+
+  static NSMorphologyCustomPronoun alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSMorphologyCustomPronoun1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSMorphologyCustomPronoun1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMorphologyCustomPronoun1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSMorphologyCustomPronoun1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSMorphologyCustomPronoun1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSOperationQueue1, _lib._sel_new1);
+    return NSOperationQueue._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSOperationQueue alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSOperationQueue1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSOperationQueue1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSOperationQueue1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSOperationQueue1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSOperationQueue1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSOperation1, _lib._sel_new1);
+    return NSOperation._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSOperation alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSOperation1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSOperation1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSOperation1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSOperation1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSOperation1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSPointerArray1, _lib._sel_pointerArrayWithStrongObjects1);
+    return NSObject._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject pointerArrayWithWeakObjects(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSPointerArray1, _lib._sel_pointerArrayWithWeakObjects1);
+    return NSObject._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSPointerArray strongObjectsPointerArray(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_811(
+        _lib._class_NSPointerArray1, _lib._sel_strongObjectsPointerArray1);
+    return NSPointerArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSPointerArray weakObjectsPointerArray(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSPointerArray1, _lib._sel_new1);
+    return NSPointerArray._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSPointerArray alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSPointerArray1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSPointerArray1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSPointerArray1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSPointerArray1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSPointerArray1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSPointerFunctions1, _lib._sel_new1);
+    return NSPointerFunctions._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSPointerFunctions alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSPointerFunctions1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSPointerFunctions1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSPointerFunctions1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSPointerFunctions1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSPointerFunctions1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSProcessInfo1, _lib._sel_new1);
+    return NSProcessInfo._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSProcessInfo alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSProcessInfo1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSProcessInfo1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSProcessInfo1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSProcessInfo1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSProcessInfo1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock31.fromFunctionPointer(SwiftLibrary 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(SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+          SwiftLibrary _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_(
+          SwiftLibrary _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_(
+          SwiftLibrary _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_(
+          SwiftLibrary _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_(
+      SwiftLibrary _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_(
+          SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSTextCheckingResult1, _lib._sel_new1);
+    return NSTextCheckingResult._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSTextCheckingResult alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSTextCheckingResult1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSTextCheckingResult1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSTextCheckingResult1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSTextCheckingResult1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSTextCheckingResult1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSRegularExpression1, _lib._sel_new1);
+    return NSRegularExpression._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSRegularExpression alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSRegularExpression1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSRegularExpression1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSRegularExpression1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSRegularExpression1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSRegularExpression1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock32.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSURLCache1, _lib._sel_new1);
+    return NSURLCache._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLCache alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLCache1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLCache1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLCache1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLCache1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSURLCache1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSCachedURLResponse1, _lib._sel_new1);
+    return NSCachedURLResponse._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSCachedURLResponse alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSCachedURLResponse1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSCachedURLResponse1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSCachedURLResponse1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSCachedURLResponse1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSCachedURLResponse1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSURLSessionDataTask1, _lib._sel_new1);
+    return NSURLSessionDataTask._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLSessionDataTask alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLSessionDataTask1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLSessionDataTask1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLSessionDataTask1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLSessionDataTask1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionDataTask1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock33.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(SwiftLibrary _lib, NSURLRequest? request) {
+    return _lib._objc_msgSend_861(_lib._class_NSURLConnection1,
+        _lib._sel_canHandleRequest_1, request?._id ?? ffi.nullptr);
+  }
+
+  static NSData sendSynchronousRequest_returningResponse_error_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSURLConnection1, _lib._sel_new1);
+    return NSURLConnection._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLConnection alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLConnection1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLConnection1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLConnection1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLConnection1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLConnection1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock34.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSURLCredential1, _lib._sel_new1);
+    return NSURLCredential._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLCredential alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLCredential1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLCredential1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLCredential1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLCredential1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLCredential1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSURLProtectionSpace1, _lib._sel_new1);
+    return NSURLProtectionSpace._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLProtectionSpace alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLProtectionSpace1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLProtectionSpace1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLProtectionSpace1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLProtectionSpace1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLProtectionSpace1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSURLCredentialStorage1, _lib._sel_new1);
+    return NSURLCredentialStorage._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLCredentialStorage alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLCredentialStorage1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLCredentialStorage1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLCredentialStorage1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLCredentialStorage1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLCredentialStorage1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock35.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock36.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _lib, NSURLRequest? request) {
+    return _lib._objc_msgSend_861(_lib._class_NSURLProtocol1,
+        _lib._sel_canInitWithRequest_1, request?._id ?? ffi.nullptr);
+  }
+
+  static NSURLRequest canonicalRequestForRequest_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _lib, NSObject protocolClass) {
+    return _lib._objc_msgSend_0(_lib._class_NSURLProtocol1,
+        _lib._sel_registerClass_1, protocolClass._id);
+  }
+
+  static void unregisterClass_(SwiftLibrary _lib, NSObject protocolClass) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLProtocol1,
+        _lib._sel_unregisterClass_1, protocolClass._id);
+  }
+
+  static bool canInitWithTask_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSURLProtocol1, _lib._sel_new1);
+    return NSURLProtocol._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLProtocol alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLProtocol1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLProtocol1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLProtocol1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLProtocol1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSURLProtocol1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMutableURLRequest1, _lib._sel_supportsSecureCoding1);
+  }
+
+  static NSMutableURLRequest requestWithURL_cachePolicy_timeoutInterval_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSMutableURLRequest1, _lib._sel_new1);
+    return NSMutableURLRequest._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSMutableURLRequest alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSMutableURLRequest1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSMutableURLRequest1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSMutableURLRequest1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSMutableURLRequest1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSMutableURLRequest1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSXMLParser1, _lib._sel_new1);
+    return NSXMLParser._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSXMLParser alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSXMLParser1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLParser1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLParser1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSXMLParser1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSXMLParser1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSFileWrapper1, _lib._sel_new1);
+    return NSFileWrapper._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSFileWrapper alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSFileWrapper1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSFileWrapper1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSFileWrapper1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSFileWrapper1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSFileWrapper1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLSession1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLSession1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLSession1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLSession1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSURLSession1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(
+      SwiftLibrary _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(
+      SwiftLibrary _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_(
+          SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSURLSessionConfiguration1, _lib._sel_new1);
+    return NSURLSessionConfiguration._(_ret, _lib,
+        retain: false, release: true);
+  }
+
+  static NSURLSessionConfiguration backgroundSessionConfiguration_(
+      SwiftLibrary _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(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLSessionConfiguration1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLSessionConfiguration1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLSessionConfiguration1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLSessionConfiguration1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionConfiguration1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock37.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSURLSessionUploadTask1, _lib._sel_new1);
+    return NSURLSessionUploadTask._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLSessionUploadTask alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLSessionUploadTask1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLSessionUploadTask1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLSessionUploadTask1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLSessionUploadTask1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionUploadTask1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSURLSessionDownloadTask1, _lib._sel_new1);
+    return NSURLSessionDownloadTask._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLSessionDownloadTask alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLSessionDownloadTask1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLSessionDownloadTask1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLSessionDownloadTask1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLSessionDownloadTask1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionDownloadTask1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock38.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSURLSessionStreamTask1, _lib._sel_new1);
+    return NSURLSessionStreamTask._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSURLSessionStreamTask alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLSessionStreamTask1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLSessionStreamTask1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLSessionStreamTask1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLSessionStreamTask1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionStreamTask1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock39.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSNetService1, _lib._sel_new1);
+    return NSNetService._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSNetService alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSNetService1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSNetService1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSNetService1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSNetService1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSNetService1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSURLSessionWebSocketTask1, _lib._sel_new1);
+    return NSURLSessionWebSocketTask._(_ret, _lib,
+        retain: false, release: true);
+  }
+
+  static NSURLSessionWebSocketTask alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLSessionWebSocketTask1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLSessionWebSocketTask1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSURLSessionWebSocketTask1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLSessionWebSocketTask1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(_lib._class_NSURLSessionWebSocketTask1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_NSURLSessionWebSocketMessage1, _lib._sel_new1);
+    return NSURLSessionWebSocketMessage._(_ret, _lib,
+        retain: false, release: true);
+  }
+
+  static NSURLSessionWebSocketMessage alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSURLSessionWebSocketMessage1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLSessionWebSocketMessage1,
+        _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(_lib._class_NSURLSessionWebSocketMessage1,
+        _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSURLSessionWebSocketMessage1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSURLSessionWebSocketMessage1,
+        _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock40.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock41.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock42.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSProtocolChecker1, _lib._sel_alloc1);
+    return NSObject._(_ret, _lib, retain: false, release: true);
+  }
+
+  static bool respondsToSelector_(
+      SwiftLibrary _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, SwiftLibrary 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(SwiftLibrary 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_(
+          SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSTask1, _lib._sel_new1);
+    return NSTask._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSTask alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSTask1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSTask1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSTask1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSTask1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSTask1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary lib)
+      : super._(id, lib, retain: false, release: true);
+
+  /// Creates a block from a C function pointer.
+  ObjCBlock43.fromFunctionPointer(
+      SwiftLibrary 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(
+      SwiftLibrary 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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSXMLElement1, _lib._sel_document1);
+    return NSObject._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject documentWithRootElement_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSXMLElement1, _lib._sel_new1);
+    return NSXMLElement._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSXMLElement alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSXMLElement1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLElement1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLElement1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSXMLElement1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSXMLElement1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSXMLNode1, _lib._sel_document1);
+    return NSObject._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject documentWithRootElement_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSXMLNode1, _lib._sel_new1);
+    return NSXMLNode._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSXMLNode alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSXMLNode1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLNode1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLNode1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSXMLNode1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSXMLNode1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSXMLDocument1, _lib._sel_document1);
+    return NSObject._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject documentWithRootElement_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSXMLDocument1, _lib._sel_new1);
+    return NSXMLDocument._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSXMLDocument alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSXMLDocument1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLDocument1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLDocument1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSXMLDocument1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSXMLDocument1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSXMLDTD1, _lib._sel_document1);
+    return NSObject._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject documentWithRootElement_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_NSXMLDTD1, _lib._sel_new1);
+    return NSXMLDTD._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSXMLDTD alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSXMLDTD1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLDTD1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLDTD1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSXMLDTD1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSXMLDTD1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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, SwiftLibrary 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(
+      SwiftLibrary 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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSXMLDTDNode1, _lib._sel_document1);
+    return NSObject._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject documentWithRootElement_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(SwiftLibrary _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_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_NSXMLDTDNode1, _lib._sel_new1);
+    return NSXMLDTDNode._(_ret, _lib, retain: false, release: true);
+  }
+
+  static NSXMLDTDNode alloc(SwiftLibrary _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_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_NSXMLDTDNode1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLDTDNode1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_NSXMLDTDNode1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _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_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_NSXMLDTDNode1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _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(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_NSXMLDTDNode1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _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 SwiftClass extends NSObject {
+  SwiftClass._(ffi.Pointer<ObjCObject> id, SwiftLibrary lib,
+      {bool retain = false, bool release = false})
+      : super._(id, lib, retain: retain, release: release);
+
+  /// Returns a [SwiftClass] that points to the same underlying object as [other].
+  static SwiftClass castFrom<T extends _ObjCWrapper>(T other) {
+    return SwiftClass._(other._id, other._lib, retain: true, release: true);
+  }
+
+  /// Returns a [SwiftClass] that wraps the given raw object pointer.
+  static SwiftClass castFromPointer(
+      SwiftLibrary lib, ffi.Pointer<ObjCObject> other,
+      {bool retain = false, bool release = false}) {
+    return SwiftClass._(other, lib, retain: retain, release: release);
+  }
+
+  /// Returns whether [obj] is an instance of [SwiftClass].
+  static bool isInstance(_ObjCWrapper obj) {
+    return obj._lib._objc_msgSend_0(
+        obj._id, obj._lib._sel_isKindOfClass_1, obj._lib._class_SwiftClass1);
+  }
+
+  NSString sayHello() {
+    final _ret = _lib._objc_msgSend_20(_id, _lib._sel_sayHello1);
+    return NSString._(_ret, _lib, retain: true, release: true);
+  }
+
+  int get someField {
+    return _lib._objc_msgSend_78(_id, _lib._sel_someField1);
+  }
+
+  set someField(int value) {
+    _lib._objc_msgSend_558(_id, _lib._sel_setSomeField_1, value);
+  }
+
+  @override
+  SwiftClass init() {
+    final _ret = _lib._objc_msgSend_2(_id, _lib._sel_init1);
+    return SwiftClass._(_ret, _lib, retain: true, release: true);
+  }
+
+  static SwiftClass new1(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(_lib._class_SwiftClass1, _lib._sel_new1);
+    return SwiftClass._(_ret, _lib, retain: false, release: true);
+  }
+
+  static SwiftClass alloc(SwiftLibrary _lib) {
+    final _ret =
+        _lib._objc_msgSend_2(_lib._class_SwiftClass1, _lib._sel_alloc1);
+    return SwiftClass._(_ret, _lib, retain: false, release: true);
+  }
+
+  static void cancelPreviousPerformRequestsWithTarget_selector_object_(
+      SwiftLibrary _lib,
+      NSObject aTarget,
+      ffi.Pointer<ObjCSel> aSelector,
+      NSObject anArgument) {
+    return _lib._objc_msgSend_14(
+        _lib._class_SwiftClass1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_selector_object_1,
+        aTarget._id,
+        aSelector,
+        anArgument._id);
+  }
+
+  static void cancelPreviousPerformRequestsWithTarget_(
+      SwiftLibrary _lib, NSObject aTarget) {
+    return _lib._objc_msgSend_15(_lib._class_SwiftClass1,
+        _lib._sel_cancelPreviousPerformRequestsWithTarget_1, aTarget._id);
+  }
+
+  static bool getAccessInstanceVariablesDirectly(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_SwiftClass1, _lib._sel_accessInstanceVariablesDirectly1);
+  }
+
+  static bool useStoredAccessor(SwiftLibrary _lib) {
+    return _lib._objc_msgSend_12(
+        _lib._class_SwiftClass1, _lib._sel_useStoredAccessor1);
+  }
+
+  static NSSet keyPathsForValuesAffectingValueForKey_(
+      SwiftLibrary _lib, NSString? key) {
+    final _ret = _lib._objc_msgSend_58(
+        _lib._class_SwiftClass1,
+        _lib._sel_keyPathsForValuesAffectingValueForKey_1,
+        key?._id ?? ffi.nullptr);
+    return NSSet._(_ret, _lib, retain: true, release: true);
+  }
+
+  static bool automaticallyNotifiesObserversForKey_(
+      SwiftLibrary _lib, NSString? key) {
+    return _lib._objc_msgSend_59(
+        _lib._class_SwiftClass1,
+        _lib._sel_automaticallyNotifiesObserversForKey_1,
+        key?._id ?? ffi.nullptr);
+  }
+
+  static void setKeys_triggerChangeNotificationsForDependentKey_(
+      SwiftLibrary _lib, NSArray? keys, NSString? dependentKey) {
+    return _lib._objc_msgSend_79(
+        _lib._class_SwiftClass1,
+        _lib._sel_setKeys_triggerChangeNotificationsForDependentKey_1,
+        keys?._id ?? ffi.nullptr,
+        dependentKey?._id ?? ffi.nullptr);
+  }
+
+  static NSArray classFallbacksForKeyedArchiver(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_80(
+        _lib._class_SwiftClass1, _lib._sel_classFallbacksForKeyedArchiver1);
+    return NSArray._(_ret, _lib, retain: true, release: true);
+  }
+
+  static NSObject classForKeyedUnarchiver(SwiftLibrary _lib) {
+    final _ret = _lib._objc_msgSend_2(
+        _lib._class_SwiftClass1, _lib._sel_classForKeyedUnarchiver1);
+    return NSObject._(_ret, _lib, retain: true, release: true);
+  }
+}
diff --git a/pkgs/ffigen/example/swift/third_party/swift_api.h b/pkgs/ffigen/example/swift/third_party/swift_api.h
new file mode 100644
index 0000000..14ebedf
--- /dev/null
+++ b/pkgs/ffigen/example/swift/third_party/swift_api.h
@@ -0,0 +1,298 @@
+// Generated by Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)
+#ifndef SWIFT_MODULE_SWIFT_H
+#define SWIFT_MODULE_SWIFT_H
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wgcc-compat"
+
+#if !defined(__has_include)
+# define __has_include(x) 0
+#endif
+#if !defined(__has_attribute)
+# define __has_attribute(x) 0
+#endif
+#if !defined(__has_feature)
+# define __has_feature(x) 0
+#endif
+#if !defined(__has_warning)
+# define __has_warning(x) 0
+#endif
+
+#if __has_include(<swift/objc-prologue.h>)
+# include <swift/objc-prologue.h>
+#endif
+
+#pragma clang diagnostic ignored "-Wauto-import"
+#if defined(__OBJC__)
+#include <Foundation/Foundation.h>
+#endif
+#if defined(__cplusplus)
+#include <cstdint>
+#include <cstddef>
+#include <cstdbool>
+#include <cstring>
+#include <stdlib.h>
+#include <new>
+#include <type_traits>
+#else
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#endif
+#if defined(__cplusplus)
+#if __has_include(<ptrauth.h>)
+# include <ptrauth.h>
+#else
+# ifndef __ptrauth_swift_value_witness_function_pointer
+#  define __ptrauth_swift_value_witness_function_pointer(x)
+# endif
+#endif
+#endif
+
+#if !defined(SWIFT_TYPEDEFS)
+# define SWIFT_TYPEDEFS 1
+# if __has_include(<uchar.h>)
+#  include <uchar.h>
+# elif !defined(__cplusplus)
+typedef uint_least16_t char16_t;
+typedef uint_least32_t char32_t;
+# endif
+typedef float swift_float2  __attribute__((__ext_vector_type__(2)));
+typedef float swift_float3  __attribute__((__ext_vector_type__(3)));
+typedef float swift_float4  __attribute__((__ext_vector_type__(4)));
+typedef double swift_double2  __attribute__((__ext_vector_type__(2)));
+typedef double swift_double3  __attribute__((__ext_vector_type__(3)));
+typedef double swift_double4  __attribute__((__ext_vector_type__(4)));
+typedef int swift_int2  __attribute__((__ext_vector_type__(2)));
+typedef int swift_int3  __attribute__((__ext_vector_type__(3)));
+typedef int swift_int4  __attribute__((__ext_vector_type__(4)));
+typedef unsigned int swift_uint2  __attribute__((__ext_vector_type__(2)));
+typedef unsigned int swift_uint3  __attribute__((__ext_vector_type__(3)));
+typedef unsigned int swift_uint4  __attribute__((__ext_vector_type__(4)));
+#endif
+
+#if !defined(SWIFT_PASTE)
+# define SWIFT_PASTE_HELPER(x, y) x##y
+# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
+#endif
+#if !defined(SWIFT_METATYPE)
+# define SWIFT_METATYPE(X) Class
+#endif
+#if !defined(SWIFT_CLASS_PROPERTY)
+# if __has_feature(objc_class_property)
+#  define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
+# else
+#  define SWIFT_CLASS_PROPERTY(...) 
+# endif
+#endif
+#if !defined(SWIFT_RUNTIME_NAME)
+# if __has_attribute(objc_runtime_name)
+#  define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
+# else
+#  define SWIFT_RUNTIME_NAME(X) 
+# endif
+#endif
+#if !defined(SWIFT_COMPILE_NAME)
+# if __has_attribute(swift_name)
+#  define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
+# else
+#  define SWIFT_COMPILE_NAME(X) 
+# endif
+#endif
+#if !defined(SWIFT_METHOD_FAMILY)
+# if __has_attribute(objc_method_family)
+#  define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
+# else
+#  define SWIFT_METHOD_FAMILY(X) 
+# endif
+#endif
+#if !defined(SWIFT_NOESCAPE)
+# if __has_attribute(noescape)
+#  define SWIFT_NOESCAPE __attribute__((noescape))
+# else
+#  define SWIFT_NOESCAPE 
+# endif
+#endif
+#if !defined(SWIFT_RELEASES_ARGUMENT)
+# if __has_attribute(ns_consumed)
+#  define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed))
+# else
+#  define SWIFT_RELEASES_ARGUMENT 
+# endif
+#endif
+#if !defined(SWIFT_WARN_UNUSED_RESULT)
+# if __has_attribute(warn_unused_result)
+#  define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+# else
+#  define SWIFT_WARN_UNUSED_RESULT 
+# endif
+#endif
+#if !defined(SWIFT_NORETURN)
+# if __has_attribute(noreturn)
+#  define SWIFT_NORETURN __attribute__((noreturn))
+# else
+#  define SWIFT_NORETURN 
+# endif
+#endif
+#if !defined(SWIFT_CLASS_EXTRA)
+# define SWIFT_CLASS_EXTRA 
+#endif
+#if !defined(SWIFT_PROTOCOL_EXTRA)
+# define SWIFT_PROTOCOL_EXTRA 
+#endif
+#if !defined(SWIFT_ENUM_EXTRA)
+# define SWIFT_ENUM_EXTRA 
+#endif
+#if !defined(SWIFT_CLASS)
+# if __has_attribute(objc_subclassing_restricted)
+#  define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
+#  define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
+# else
+#  define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
+#  define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
+# endif
+#endif
+#if !defined(SWIFT_RESILIENT_CLASS)
+# if __has_attribute(objc_class_stub)
+#  define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub))
+#  define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME)
+# else
+#  define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME)
+#  define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME)
+# endif
+#endif
+#if !defined(SWIFT_PROTOCOL)
+# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
+# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
+#endif
+#if !defined(SWIFT_EXTENSION)
+# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
+#endif
+#if !defined(OBJC_DESIGNATED_INITIALIZER)
+# if __has_attribute(objc_designated_initializer)
+#  define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
+# else
+#  define OBJC_DESIGNATED_INITIALIZER 
+# endif
+#endif
+#if !defined(SWIFT_ENUM_ATTR)
+# if __has_attribute(enum_extensibility)
+#  define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility)))
+# else
+#  define SWIFT_ENUM_ATTR(_extensibility) 
+# endif
+#endif
+#if !defined(SWIFT_ENUM)
+# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
+# if __has_feature(generalized_swift_name)
+#  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
+# else
+#  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility)
+# endif
+#endif
+#if !defined(SWIFT_UNAVAILABLE)
+# define SWIFT_UNAVAILABLE __attribute__((unavailable))
+#endif
+#if !defined(SWIFT_UNAVAILABLE_MSG)
+# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
+#endif
+#if !defined(SWIFT_AVAILABILITY)
+# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
+#endif
+#if !defined(SWIFT_WEAK_IMPORT)
+# define SWIFT_WEAK_IMPORT __attribute__((weak_import))
+#endif
+#if !defined(SWIFT_DEPRECATED)
+# define SWIFT_DEPRECATED __attribute__((deprecated))
+#endif
+#if !defined(SWIFT_DEPRECATED_MSG)
+# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
+#endif
+#if !defined(SWIFT_DEPRECATED_OBJC)
+# if __has_feature(attribute_diagnose_if_objc)
+#  define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning")))
+# else
+#  define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg)
+# endif
+#endif
+#if defined(__OBJC__)
+#if !defined(IBSegueAction)
+# define IBSegueAction 
+#endif
+#endif
+#if !defined(SWIFT_EXTERN)
+# if defined(__cplusplus)
+#  define SWIFT_EXTERN extern "C"
+# else
+#  define SWIFT_EXTERN extern
+# endif
+#endif
+#if !defined(SWIFT_CALL)
+# define SWIFT_CALL __attribute__((swiftcall))
+#endif
+#if !defined(SWIFT_INDIRECT_RESULT)
+# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result))
+#endif
+#if !defined(SWIFT_CONTEXT)
+# define SWIFT_CONTEXT __attribute__((swift_context))
+#endif
+#if !defined(SWIFT_ERROR_RESULT)
+# define SWIFT_ERROR_RESULT __attribute__((swift_error_result))
+#endif
+#if defined(__cplusplus)
+# define SWIFT_NOEXCEPT noexcept
+#else
+# define SWIFT_NOEXCEPT 
+#endif
+#if defined(_WIN32)
+#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL)
+# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport)
+#endif
+#else
+#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL)
+# define SWIFT_IMPORT_STDLIB_SYMBOL 
+#endif
+#endif
+#if defined(__OBJC__)
+#if __has_feature(objc_modules)
+#if __has_warning("-Watimport-in-framework-header")
+#pragma clang diagnostic ignored "-Watimport-in-framework-header"
+#endif
+@import ObjectiveC;
+#endif
+
+#endif
+#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
+#pragma clang diagnostic ignored "-Wduplicate-method-arg"
+#if __has_warning("-Wpragma-clang-attribute")
+# pragma clang diagnostic ignored "-Wpragma-clang-attribute"
+#endif
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+#pragma clang diagnostic ignored "-Wnullability"
+#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
+
+#if __has_attribute(external_source_symbol)
+# pragma push_macro("any")
+# undef any
+# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="swift_module",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol))
+# pragma pop_macro("any")
+#endif
+
+#if defined(__OBJC__)
+@class NSString;
+
+SWIFT_CLASS("_TtC12swift_module10SwiftClass")
+@interface SwiftClass : NSObject
+- (NSString * _Nonnull)sayHello SWIFT_WARN_UNUSED_RESULT;
+@property (nonatomic) NSInteger someField;
+- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
+@end
+
+#endif
+#if defined(__cplusplus)
+#endif
+#if __has_attribute(external_source_symbol)
+# pragma clang attribute pop
+#endif
+#pragma clang diagnostic pop
+#endif
diff --git a/pkgs/ffigen/ffigen.schema.json b/pkgs/ffigen/ffigen.schema.json
new file mode 100644
index 0000000..5c196f1
--- /dev/null
+++ b/pkgs/ffigen/ffigen.schema.json
@@ -0,0 +1,524 @@
+{
+  "$id": "https://json.schemastore.org/ffigen",
+  "$comment": "This file is generated. To regenerate run: dart tool/generate_json_schema.dart in github.com/dart-lang/ffigen",
+  "$schema": "https://json-schema.org/draft/2020-12/schema",
+  "type": "object",
+  "additionalProperties": false,
+  "properties": {
+    "llvm-path": {
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "output": {
+      "$oneOf": [
+        {
+          "$ref": "#/$defs/filePath"
+        },
+        {
+          "type": "object",
+          "additionalProperties": false,
+          "properties": {
+            "bindings": {
+              "$ref": "#/$defs/filePath"
+            },
+            "symbol-file": {
+              "type": "object",
+              "additionalProperties": false,
+              "properties": {
+                "output": {
+                  "$ref": "#/$defs/filePath"
+                },
+                "import-path": {
+                  "type": "string"
+                }
+              },
+              "required": [
+                "output",
+                "import-path"
+              ]
+            }
+          },
+          "required": [
+            "bindings"
+          ]
+        }
+      ]
+    },
+    "language": {
+      "enum": [
+        "c",
+        "objc"
+      ]
+    },
+    "headers": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "entry-points": {
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        },
+        "include-directives": {
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        }
+      },
+      "required": [
+        "entry-points"
+      ]
+    },
+    "compiler-opts": {
+      "$oneOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        }
+      ]
+    },
+    "compiler-opts-automatic": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "macos": {
+          "type": "object",
+          "additionalProperties": false,
+          "properties": {
+            "include-c-standard-library": {
+              "type": "boolean"
+            }
+          }
+        }
+      }
+    },
+    "library-imports": {
+      "type": "object",
+      "patternProperties": {
+        ".*": {
+          "type": "string"
+        }
+      }
+    },
+    "functions": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "include": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "exclude": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "rename": {
+          "$ref": "#/$defs/rename"
+        },
+        "member-rename": {
+          "$ref": "#/$defs/memberRename"
+        },
+        "symbol-address": {
+          "$ref": "#/$defs/includeExclude"
+        },
+        "expose-typedefs": {
+          "$ref": "#/$defs/includeExclude"
+        },
+        "leaf": {
+          "$ref": "#/$defs/includeExclude"
+        },
+        "variadic-arguments": {
+          "type": "object",
+          "patternProperties": {
+            ".*": {
+              "type": "array",
+              "items": {
+                "$oneOf": [
+                  {
+                    "type": "array",
+                    "items": {
+                      "type": "string"
+                    }
+                  },
+                  {
+                    "type": "object",
+                    "additionalProperties": false,
+                    "properties": {
+                      "types": {
+                        "type": "array",
+                        "items": {
+                          "type": "string"
+                        }
+                      },
+                      "postfix": {
+                        "type": "string"
+                      }
+                    },
+                    "required": [
+                      "types"
+                    ]
+                  }
+                ]
+              }
+            }
+          }
+        }
+      }
+    },
+    "structs": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "include": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "exclude": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "rename": {
+          "$ref": "#/$defs/rename"
+        },
+        "member-rename": {
+          "$ref": "#/$defs/memberRename"
+        },
+        "dependency-only": {
+          "$ref": "#/$defs/dependencyOnly"
+        },
+        "pack": {
+          "type": "object",
+          "patternProperties": {
+            ".*": {
+              "enum": [
+                "none",
+                1,
+                2,
+                4,
+                8,
+                16
+              ]
+            }
+          }
+        }
+      }
+    },
+    "unions": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "include": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "exclude": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "rename": {
+          "$ref": "#/$defs/rename"
+        },
+        "member-rename": {
+          "$ref": "#/$defs/memberRename"
+        },
+        "dependency-only": {
+          "$ref": "#/$defs/dependencyOnly"
+        }
+      }
+    },
+    "enums": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "include": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "exclude": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "rename": {
+          "$ref": "#/$defs/rename"
+        },
+        "member-rename": {
+          "$ref": "#/$defs/memberRename"
+        }
+      }
+    },
+    "unnamed-enums": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "include": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "exclude": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "rename": {
+          "$ref": "#/$defs/rename"
+        }
+      }
+    },
+    "globals": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "include": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "exclude": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "rename": {
+          "$ref": "#/$defs/rename"
+        },
+        "symbol-address": {
+          "$ref": "#/$defs/includeExclude"
+        }
+      }
+    },
+    "macros": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "include": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "exclude": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "rename": {
+          "$ref": "#/$defs/rename"
+        }
+      }
+    },
+    "typedefs": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "include": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "exclude": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "rename": {
+          "$ref": "#/$defs/rename"
+        }
+      }
+    },
+    "objc-interfaces": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "include": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "exclude": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "rename": {
+          "$ref": "#/$defs/rename"
+        },
+        "member-rename": {
+          "$ref": "#/$defs/memberRename"
+        },
+        "module": {
+          "$ref": "#/$defs/objcInterfaceModule"
+        }
+      }
+    },
+    "import": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "symbol-files": {
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        }
+      }
+    },
+    "type-map": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "typedefs": {
+          "$ref": "#/$defs/mappedTypes"
+        },
+        "structs": {
+          "$ref": "#/$defs/mappedTypes"
+        },
+        "unions": {
+          "$ref": "#/$defs/mappedTypes"
+        },
+        "native-types": {
+          "$ref": "#/$defs/mappedTypes"
+        }
+      }
+    },
+    "exclude-all-by-default": {
+      "type": "boolean"
+    },
+    "sort": {
+      "type": "boolean"
+    },
+    "use-supported-typedefs": {
+      "type": "boolean"
+    },
+    "comments": {
+      "$oneOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "object",
+          "additionalProperties": false,
+          "properties": {
+            "style": {
+              "enum": [
+                "doxygen",
+                "any"
+              ]
+            },
+            "length": {
+              "enum": [
+                "brief",
+                "full"
+              ]
+            }
+          }
+        }
+      ]
+    },
+    "name": {
+      "$ref": "#/$defs/publicDartClass"
+    },
+    "description": {
+      "$ref": "#/$defs/nonEmptyString"
+    },
+    "preamble": {
+      "type": "string"
+    },
+    "use-dart-handle": {
+      "type": "boolean"
+    },
+    "ffi-native": {
+      "$oneOf": [
+        {
+          "enum": [
+            null
+          ]
+        },
+        {
+          "type": "object",
+          "additionalProperties": false,
+          "properties": {
+            "assetId": {
+              "type": "string"
+            }
+          },
+          "required": [
+            "assetId"
+          ]
+        }
+      ]
+    }
+  },
+  "required": [
+    "output",
+    "headers"
+  ],
+  "$defs": {
+    "filePath": {
+      "type": "string",
+      "description": "A file path"
+    },
+    "fullMatchOrRegexpList": {
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "rename": {
+      "type": "object",
+      "patternProperties": {
+        ".*": {
+          "type": "string"
+        }
+      }
+    },
+    "memberRename": {
+      "type": "object",
+      "patternProperties": {
+        ".*": {
+          "type": "object",
+          "patternProperties": {
+            ".*": {
+              "type": "string"
+            }
+          }
+        }
+      }
+    },
+    "includeExclude": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "include": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        },
+        "exclude": {
+          "$ref": "#/$defs/fullMatchOrRegexpList"
+        }
+      }
+    },
+    "dependencyOnly": {
+      "enum": [
+        "full",
+        "opaque"
+      ]
+    },
+    "objcInterfaceModule": {
+      "type": "object",
+      "patternProperties": {
+        ".*": {
+          "type": "string"
+        }
+      }
+    },
+    "mappedTypes": {
+      "type": "object",
+      "patternProperties": {
+        ".*": {
+          "type": "object",
+          "additionalProperties": false,
+          "properties": {
+            "lib": {
+              "type": "string"
+            },
+            "c-type": {
+              "type": "string"
+            },
+            "dart-type": {
+              "type": "string"
+            }
+          }
+        }
+      }
+    },
+    "publicDartClass": {
+      "type": "string",
+      "description": "A public dart class name.",
+      "pattern": "^[a-zA-Z]+[_a-zA-Z0-9]*$"
+    },
+    "nonEmptyString": {
+      "type": "string",
+      "pattern": ".+"
+    }
+  }
+}
\ No newline at end of file
diff --git a/pkgs/ffigen/lib/ffigen.dart b/pkgs/ffigen/lib/ffigen.dart
new file mode 100644
index 0000000..3425eec
--- /dev/null
+++ b/pkgs/ffigen/lib/ffigen.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A bindings generator for dart.
+///
+/// See complete usage at - https://pub.dev/packages/ffigen.
+library ffigen;
+
+export 'src/code_generator.dart' show Library;
+export 'src/config_provider.dart' show Config;
+export 'src/header_parser.dart' show parse;
diff --git a/pkgs/ffigen/lib/src/README.md b/pkgs/ffigen/lib/src/README.md
new file mode 100644
index 0000000..2b20f84
--- /dev/null
+++ b/pkgs/ffigen/lib/src/README.md
@@ -0,0 +1,41 @@
+# **_package:ffigen_**: Internal Working
+## Table of Contents -
+1. [Overview](#overview)
+2. [LibClang](#LibClang)
+    1. [Bindings](#Bindings)
+3. [Scripts](#scripts)
+    1. [ffigen.dart](#ffigen.dart)
+4. [Components](#components)
+    1. [Config Provider](#Config-Provider)
+    2. [Header Parser](#Header-Parser)
+    3. [Code Generator](#Code-Generator)
+# Overview
+`package:ffigen` simplifies the process of generating `dart:ffi` bindings from C header files. It is simple to use, with the input being a small YAML config file. It requires LLVM (9+) to work. This document tries to give a complete overview of every component without going into too many details about every single class/file.
+# LibClang
+`package:ffigen` binds to LibClang using `dart:ffi` for parsing C header files. 
+## Bindings
+The config file for generating bindings is `tool/libclang_config.yaml`. The bindings are generated to `lib/src/header_parser/clang_bindings/clang_bindings.dart`. These are used by [Header Parser](#header-parser) for calling libclang functions.
+# Scripts
+## ffigen.dart
+This is the main entry point for the user-  `dart run ffigen`.
+- Command-line options:
+    - `--verbose`: Sets log level.
+    - `--config`: Specifies a config file.
+- The internal modules are called by `ffigen.dart` in the following way:
+- `ffigen.dart` will try to find dynamic library in default locations. If that fails, the user must excplicitly specify location in ffigen's config under the key `llvm-path`.
+    - It first creates a `Config` object from an input Yaml file. This is used by other modules.
+    - The `parse` method is then invoked to generate a `Library` object.
+    - Finally, the code is generated from the `Library` object to the specified file.
+# Components
+## Config Provider
+The Config Provider holds all the configurations required by other modules.
+- Config Provider handles validation and extraction of configurations from YAML files.
+- Config Provider converts configurations to the format required by other modules. This object is passed around to every other module.
+## Header Parser
+The Header Parser parses C header files and converts them into a `Library` object.
+- Header Parser handles including/excluding/renaming of declarations.
+- Header Parser also filters out any _unimplemented_ or _unsupported_ declarations before generating a `Library` object.
+## Code Generator
+The Code Generator generates the actual string bindings.
+- Code generator handles all external name collisions, while internal name conflicts are handled by each specific `Binding`.
+- Code Generator also handles how workarounds for arrays and bools are generated.
diff --git a/pkgs/ffigen/lib/src/code_generator.dart b/pkgs/ffigen/lib/src/code_generator.dart
new file mode 100644
index 0000000..5977439
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Generates FFI bindings for a given [Library].
+library code_generator;
+
+export 'code_generator/binding.dart';
+export 'code_generator/compound.dart';
+export 'code_generator/constant.dart';
+export 'code_generator/enum_class.dart';
+export 'code_generator/func.dart';
+export 'code_generator/func_type.dart';
+export 'code_generator/global.dart';
+export 'code_generator/handle.dart';
+export 'code_generator/imports.dart';
+export 'code_generator/library.dart';
+export 'code_generator/native_type.dart';
+export 'code_generator/objc_block.dart';
+export 'code_generator/objc_built_in_functions.dart';
+export 'code_generator/objc_interface.dart';
+export 'code_generator/objc_nullable.dart';
+export 'code_generator/pointer.dart';
+export 'code_generator/struct.dart';
+export 'code_generator/type.dart';
+export 'code_generator/typealias.dart';
+export 'code_generator/union.dart';
diff --git a/pkgs/ffigen/lib/src/code_generator/binding.dart b/pkgs/ffigen/lib/src/code_generator/binding.dart
new file mode 100644
index 0000000..6ad26ba
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/binding.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'binding_string.dart';
+import 'writer.dart';
+
+/// Base class for all Bindings.
+///
+/// Do not extend directly, use [LookUpBinding] or [NoLookUpBinding].
+abstract class Binding {
+  /// Holds the Unified Symbol Resolution string obtained from libclang.
+  final String usr;
+
+  /// The name as it was in C.
+  final String originalName;
+
+  /// Binding name to generate, may get changed to resolve name conflicts.
+  String name;
+
+  final String? dartDoc;
+  final bool isInternal;
+
+  Binding({
+    required this.usr,
+    required this.originalName,
+    required this.name,
+    this.dartDoc,
+    this.isInternal = false,
+  });
+
+  /// Get all dependencies, including itself and save them in [dependencies].
+  void addDependencies(Set<Binding> dependencies);
+
+  /// Converts a Binding to its actual string representation.
+  ///
+  /// Note: This does not print the typedef dependencies.
+  /// Must call [getTypedefDependencies] first.
+  BindingString toBindingString(Writer w);
+}
+
+/// Base class for bindings which look up symbols in dynamic library.
+abstract class LookUpBinding extends Binding {
+  LookUpBinding({
+    String? usr,
+    String? originalName,
+    required super.name,
+    super.dartDoc,
+    super.isInternal,
+  }) : super(
+          usr: usr ?? name,
+          originalName: originalName ?? name,
+        );
+}
+
+/// Base class for bindings which don't look up symbols in dynamic library.
+abstract class NoLookUpBinding extends Binding {
+  NoLookUpBinding({
+    String? usr,
+    String? originalName,
+    required super.name,
+    super.dartDoc,
+    super.isInternal,
+  }) : super(
+          usr: usr ?? name,
+          originalName: originalName ?? name,
+        );
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/binding_string.dart b/pkgs/ffigen/lib/src/code_generator/binding_string.dart
new file mode 100644
index 0000000..decfd6f
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/binding_string.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A Binding's String representation.
+class BindingString {
+  // Meta data, (not used for generation).
+  final BindingStringType type;
+  final String string;
+
+  const BindingString({required this.type, required this.string});
+
+  @override
+  String toString() => string;
+}
+
+/// A [BindingString]'s type.
+enum BindingStringType {
+  func,
+  struct,
+  union,
+  constant,
+  global,
+  enumClass,
+  typeDef,
+  objcInterface,
+  objcBlock,
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/compound.dart b/pkgs/ffigen/lib/src/code_generator/compound.dart
new file mode 100644
index 0000000..1f9706e
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/compound.dart
@@ -0,0 +1,186 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+
+import 'binding_string.dart';
+import 'utils.dart';
+import 'writer.dart';
+
+enum CompoundType { struct, union }
+
+/// A binding for Compound type - Struct/Union.
+abstract class Compound extends BindingType {
+  /// Marker for if a struct definition is complete.
+  ///
+  /// A function can be safely pass this struct by value if it's complete.
+  bool isIncomplete;
+
+  List<Member> members;
+
+  bool get isOpaque => members.isEmpty;
+
+  /// Value for `@Packed(X)` annotation. Can be null (no packing), 1, 2, 4, 8,
+  /// or 16.
+  ///
+  /// Only supported for [CompoundType.struct].
+  int? pack;
+
+  /// Marker for checking if the dependencies are parsed.
+  bool parsedDependencies = false;
+
+  CompoundType compoundType;
+  bool get isStruct => compoundType == CompoundType.struct;
+  bool get isUnion => compoundType == CompoundType.union;
+
+  Compound({
+    super.usr,
+    super.originalName,
+    required super.name,
+    required this.compoundType,
+    this.isIncomplete = false,
+    this.pack,
+    super.dartDoc,
+    List<Member>? members,
+    super.isInternal,
+  }) : members = members ?? [];
+
+  factory Compound.fromType({
+    required CompoundType type,
+    String? usr,
+    String? originalName,
+    required String name,
+    bool isIncomplete = false,
+    int? pack,
+    String? dartDoc,
+    List<Member>? members,
+  }) {
+    switch (type) {
+      case CompoundType.struct:
+        return Struct(
+          usr: usr,
+          originalName: originalName,
+          name: name,
+          isIncomplete: isIncomplete,
+          pack: pack,
+          dartDoc: dartDoc,
+          members: members,
+        );
+      case CompoundType.union:
+        return Union(
+          usr: usr,
+          originalName: originalName,
+          name: name,
+          isIncomplete: isIncomplete,
+          pack: pack,
+          dartDoc: dartDoc,
+          members: members,
+        );
+    }
+  }
+
+  List<int> _getArrayDimensionLengths(Type type) {
+    final array = <int>[];
+    var startType = type;
+    while (startType is ConstantArray) {
+      array.add(startType.length);
+      startType = startType.child;
+    }
+    return array;
+  }
+
+  String _getInlineArrayTypeString(Type type, Writer w) {
+    if (type is ConstantArray) {
+      return '${w.ffiLibraryPrefix}.Array<'
+          '${_getInlineArrayTypeString(type.child, w)}>';
+    }
+    return type.getCType(w);
+  }
+
+  @override
+  BindingString toBindingString(Writer w) {
+    final s = StringBuffer();
+    final enclosingClassName = name;
+    if (dartDoc != null) {
+      s.write(makeDartDoc(dartDoc!));
+    }
+
+    /// Adding [enclosingClassName] because dart doesn't allow class member
+    /// to have the same name as the class.
+    final localUniqueNamer = UniqueNamer({enclosingClassName});
+
+    /// Marking type names because dart doesn't allow class member to have the
+    /// same name as a type name used internally.
+    for (final m in members) {
+      localUniqueNamer.markUsed(m.type.getFfiDartType(w));
+    }
+
+    /// Write @Packed(X) annotation if struct is packed.
+    if (isStruct && pack != null) {
+      s.write('@${w.ffiLibraryPrefix}.Packed($pack)\n');
+    }
+    final dartClassName = isStruct ? 'Struct' : 'Union';
+    // Write class declaration.
+    s.write('final class $enclosingClassName extends ');
+    s.write('${w.ffiLibraryPrefix}.${isOpaque ? 'Opaque' : dartClassName}{\n');
+    const depth = '  ';
+    for (final m in members) {
+      m.name = localUniqueNamer.makeUnique(m.name);
+      if (m.dartDoc != null) {
+        s.write('$depth/// ');
+        s.writeAll(m.dartDoc!.split('\n'), '\n$depth/// ');
+        s.write('\n');
+      }
+      if (m.type is ConstantArray) {
+        s.write('$depth@${w.ffiLibraryPrefix}.Array.multi(');
+        s.write('${_getArrayDimensionLengths(m.type)})\n');
+        s.write('${depth}external ${_getInlineArrayTypeString(m.type, w)} ');
+        s.write('${m.name};\n\n');
+      } else {
+        if (!m.type.sameFfiDartAndCType) {
+          s.write('$depth@${m.type.getCType(w)}()\n');
+        }
+        s.write('${depth}external ${m.type.getFfiDartType(w)} ${m.name};\n\n');
+      }
+    }
+    s.write('}\n\n');
+
+    return BindingString(
+        type: isStruct ? BindingStringType.struct : BindingStringType.union,
+        string: s.toString());
+  }
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    if (dependencies.contains(this)) return;
+
+    dependencies.add(this);
+    for (final m in members) {
+      m.type.addDependencies(dependencies);
+    }
+  }
+
+  @override
+  bool get isIncompleteCompound => isIncomplete;
+
+  @override
+  String getCType(Writer w) => name;
+
+  @override
+  bool get sameFfiDartAndCType => true;
+}
+
+class Member {
+  final String? dartDoc;
+  final String originalName;
+  String name;
+  final Type type;
+
+  Member({
+    String? originalName,
+    required this.name,
+    required this.type,
+    this.dartDoc,
+  }) : originalName = originalName ?? name;
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/constant.dart b/pkgs/ffigen/lib/src/code_generator/constant.dart
new file mode 100644
index 0000000..1f4c8d5
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/constant.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'binding.dart';
+import 'binding_string.dart';
+import 'utils.dart';
+import 'writer.dart';
+
+/// A simple Constant.
+///
+/// Expands to -
+/// ```dart
+/// const <type> <name> = <rawValue>;
+/// ```
+///
+/// Example -
+/// ```dart
+/// const int name = 10;
+/// ```
+class Constant extends NoLookUpBinding {
+  /// The rawType is pasted as it is. E.g 'int', 'String', 'double'
+  final String rawType;
+
+  /// The rawValue is pasted as it is.
+  ///
+  /// Put quotes if type is a string.
+  final String rawValue;
+
+  Constant({
+    super.usr,
+    super.originalName,
+    required super.name,
+    super.dartDoc,
+    required this.rawType,
+    required this.rawValue,
+  });
+
+  @override
+  BindingString toBindingString(Writer w) {
+    final s = StringBuffer();
+    final constantName = name;
+
+    if (dartDoc != null) {
+      s.write(makeDartDoc(dartDoc!));
+    }
+
+    s.write('\nconst $rawType $constantName = $rawValue;\n\n');
+
+    return BindingString(
+        type: BindingStringType.constant, string: s.toString());
+  }
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    if (dependencies.contains(this)) return;
+
+    dependencies.add(this);
+  }
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/dart_keywords.dart b/pkgs/ffigen/lib/src/code_generator/dart_keywords.dart
new file mode 100644
index 0000000..93d5877
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/dart_keywords.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Dart reserved keywords, used for resolving conflict with a name.
+///
+/// Source: https://dart.dev/guides/language/language-tour#keywords.
+const keywords = {
+  'abstract',
+  'as',
+  'assert',
+  'async',
+  'await',
+  'break',
+  'case',
+  'catch',
+  'class',
+  'const',
+  'continue',
+  'covariant',
+  'default',
+  'deferred',
+  'do',
+  'dynamic',
+  'else',
+  'enum',
+  'export',
+  'extends',
+  'extension',
+  'external',
+  'factory',
+  'false',
+  'final',
+  'finally',
+  'for',
+  'Function',
+  'get',
+  'hide',
+  'if',
+  'implements',
+  'import',
+  'in',
+  'interface',
+  'is',
+  'late',
+  'library',
+  'mixin',
+  'new',
+  'null',
+  'on',
+  'operator',
+  'part',
+  'required',
+  'rethrow',
+  'return',
+  'set',
+  'show',
+  'static',
+  'super',
+  'switch',
+  'sync',
+  'this',
+  'throw',
+  'true',
+  'try',
+  'typedef',
+  'var',
+  'void',
+  'while',
+  'with',
+  'yield',
+};
diff --git a/pkgs/ffigen/lib/src/code_generator/enum_class.dart b/pkgs/ffigen/lib/src/code_generator/enum_class.dart
new file mode 100644
index 0000000..92ffbfa
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/enum_class.dart
@@ -0,0 +1,105 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'binding.dart';
+import 'binding_string.dart';
+import 'native_type.dart';
+import 'type.dart';
+import 'utils.dart';
+import 'writer.dart';
+
+/// A binding for enums in C.
+///
+/// For a C enum -
+/// ```c
+/// enum Fruits {apple, banana = 10};
+/// ```
+/// The generated dart code is
+///
+/// ```dart
+/// class Fruits {
+///   static const apple = 0;
+///   static const banana = 10;
+/// }
+/// ```
+class EnumClass extends BindingType {
+  static final nativeType = NativeType(SupportedNativeType.Int32);
+
+  final List<EnumConstant> enumConstants;
+
+  EnumClass({
+    super.usr,
+    super.originalName,
+    required super.name,
+    super.dartDoc,
+    List<EnumConstant>? enumConstants,
+  }) : enumConstants = enumConstants ?? [];
+
+  @override
+  BindingString toBindingString(Writer w) {
+    final s = StringBuffer();
+    final enclosingClassName = name;
+
+    if (dartDoc != null) {
+      s.write(makeDartDoc(dartDoc!));
+    }
+
+    /// Adding [enclosingClassName] because dart doesn't allow class member
+    /// to have the same name as the class.
+    final localUniqueNamer = UniqueNamer({enclosingClassName});
+
+    // Print enclosing class.
+    s.write('abstract class $enclosingClassName {\n');
+    const depth = '  ';
+    for (final ec in enumConstants) {
+      final enumValueName = localUniqueNamer.makeUnique(ec.name);
+      if (ec.dartDoc != null) {
+        s.write('$depth/// ');
+        s.writeAll(ec.dartDoc!.split('\n'), '\n$depth/// ');
+        s.write('\n');
+      }
+      s.write('${depth}static const int $enumValueName = ${ec.value};\n');
+    }
+    s.write('}\n\n');
+
+    return BindingString(
+        type: BindingStringType.enumClass, string: s.toString());
+  }
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    if (dependencies.contains(this)) return;
+
+    dependencies.add(this);
+  }
+
+  @override
+  String getCType(Writer w) => nativeType.getCType(w);
+
+  @override
+  String getFfiDartType(Writer w) => nativeType.getFfiDartType(w);
+
+  @override
+  bool get sameFfiDartAndCType => nativeType.sameFfiDartAndCType;
+
+  @override
+  bool get sameDartAndCType => nativeType.sameDartAndCType;
+
+  @override
+  String? getDefaultValue(Writer w, String nativeLib) => '0';
+}
+
+/// Represents a single value in an enum.
+class EnumConstant {
+  final String? originalName;
+  final String? dartDoc;
+  final String name;
+  final int value;
+  const EnumConstant({
+    String? originalName,
+    required this.name,
+    required this.value,
+    this.dartDoc,
+  }) : originalName = originalName ?? name;
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/func.dart b/pkgs/ffigen/lib/src/code_generator/func.dart
new file mode 100644
index 0000000..766cc28
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/func.dart
@@ -0,0 +1,223 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/config_provider/config_types.dart';
+
+import 'binding_string.dart';
+import 'utils.dart';
+import 'writer.dart';
+
+/// A binding for C function.
+///
+/// For example, take the following C function.
+///
+/// ```c
+/// int sum(int a, int b);
+/// ```
+///
+/// The generated Dart code for this function (without `FfiNative`) is as follows.
+///
+/// ```dart
+/// int sum(int a, int b) {
+///   return _sum(a, b);
+/// }
+///
+/// final _dart_sum _sum = _dylib.lookupFunction<_c_sum, _dart_sum>('sum');
+///
+/// typedef _c_sum = ffi.Int32 Function(ffi.Int32 a, ffi.Int32 b);
+///
+/// typedef _dart_sum = int Function(int a, int b);
+/// ```
+///
+/// When using `Native`, the code is as follows.
+///
+/// ```dart
+/// @ffi.Native<ffi.Int32 Function(ffi.Int32 a, ffi.Int32 b)>('sum')
+/// external int sum(int a, int b);
+/// ```
+class Func extends LookUpBinding {
+  final FunctionType functionType;
+  final bool exposeSymbolAddress;
+  final bool exposeFunctionTypedefs;
+  final bool isLeaf;
+  final bool objCReturnsRetained;
+  final FfiNativeConfig ffiNativeConfig;
+  late final String funcPointerName;
+
+  /// Contains typealias for function type if [exposeFunctionTypedefs] is true.
+  Typealias? _exposedFunctionTypealias;
+
+  /// [originalName] is looked up in dynamic library, if not
+  /// provided, takes the value of [name].
+  Func({
+    super.usr,
+    required String name,
+    super.originalName,
+    super.dartDoc,
+    required Type returnType,
+    List<Parameter>? parameters,
+    List<Parameter>? varArgParameters,
+    this.exposeSymbolAddress = false,
+    this.exposeFunctionTypedefs = false,
+    this.isLeaf = false,
+    this.objCReturnsRetained = false,
+    super.isInternal,
+    this.ffiNativeConfig = const FfiNativeConfig(enabled: false),
+  })  : functionType = FunctionType(
+          returnType: returnType,
+          parameters: parameters ?? const [],
+          varArgParameters: varArgParameters ?? const [],
+        ),
+        super(
+          name: name,
+        ) {
+    for (var i = 0; i < functionType.parameters.length; i++) {
+      if (functionType.parameters[i].name.trim() == '') {
+        functionType.parameters[i].name = 'arg$i';
+      }
+    }
+
+    // Get function name with first letter in upper case.
+    final upperCaseName = name[0].toUpperCase() + name.substring(1);
+    if (exposeFunctionTypedefs) {
+      _exposedFunctionTypealias = Typealias(
+        name: upperCaseName,
+        type: functionType,
+        genFfiDartType: true,
+        isInternal: true,
+      );
+    }
+  }
+
+  @override
+  BindingString toBindingString(Writer w) {
+    final s = StringBuffer();
+    final enclosingFuncName = name;
+
+    if (dartDoc != null) {
+      s.write(makeDartDoc(dartDoc!));
+    }
+    // Resolve name conflicts in function parameter names.
+    final paramNamer = UniqueNamer({});
+    for (final p in functionType.dartTypeParameters) {
+      p.name = paramNamer.makeUnique(p.name);
+    }
+
+    final cType = _exposedFunctionTypealias?.getCType(w) ??
+        functionType.getCType(w, writeArgumentNames: false);
+    final dartType = _exposedFunctionTypealias?.getFfiDartType(w) ??
+        functionType.getFfiDartType(w, writeArgumentNames: false);
+    final needsWrapper = !functionType.sameDartAndFfiDartType && !isInternal;
+
+    final isLeafString = isLeaf ? 'isLeaf:true' : '';
+    final funcVarName = w.wrapperLevelUniqueNamer.makeUnique('_$name');
+    final ffiReturnType = functionType.returnType.getFfiDartType(w);
+    final ffiArgDeclString = functionType.dartTypeParameters
+        .map((p) => '${p.type.getFfiDartType(w)} ${p.name},\n')
+        .join('');
+
+    late final String dartReturnType;
+    late final String dartArgDeclString;
+    late final String funcImplCall;
+    if (needsWrapper) {
+      dartReturnType = functionType.returnType.getDartType(w);
+      dartArgDeclString = functionType.dartTypeParameters
+          .map((p) => '${p.type.getDartType(w)} ${p.name},\n')
+          .join('');
+
+      final argString = functionType.dartTypeParameters
+          .map((p) =>
+              '${p.type.convertDartTypeToFfiDartType(w, p.name, objCRetain: false)},\n')
+          .join('');
+      funcImplCall = functionType.returnType.convertFfiDartTypeToDartType(
+        w,
+        '$funcVarName($argString)',
+        ffiNativeConfig.enabled ? 'lib' : 'this',
+        objCRetain: !objCReturnsRetained,
+      );
+    } else {
+      dartReturnType = ffiReturnType;
+      dartArgDeclString = ffiArgDeclString;
+      final argString =
+          functionType.dartTypeParameters.map((p) => '${p.name},\n').join('');
+      funcImplCall = '$funcVarName($argString)';
+    }
+
+    if (ffiNativeConfig.enabled) {
+      final assetString = ffiNativeConfig.assetId != null
+          ? ", assetId: '${ffiNativeConfig.assetId}'"
+          : '';
+      final nativeFuncName = needsWrapper ? funcVarName : enclosingFuncName;
+      s.write('''
+@${w.ffiLibraryPrefix}.Native<$cType>(symbol: '$originalName'$assetString$isLeafString)
+external $ffiReturnType $nativeFuncName($ffiArgDeclString);
+
+''');
+      if (needsWrapper) {
+        final libArg = functionType.returnType.sameDartAndFfiDartType
+            ? ''
+            : '${w.className} lib, ';
+        s.write('''
+$dartReturnType $enclosingFuncName($libArg$dartArgDeclString) => $funcImplCall;
+
+''');
+      }
+    } else {
+      funcPointerName = w.wrapperLevelUniqueNamer.makeUnique('_${name}Ptr');
+
+      // Write enclosing function.
+      s.write('''
+$dartReturnType $enclosingFuncName($dartArgDeclString) {
+  return $funcImplCall;
+}
+
+''');
+
+      if (exposeSymbolAddress) {
+        // Add to SymbolAddress in writer.
+        w.symbolAddressWriter.addSymbol(
+          type:
+              '${w.ffiLibraryPrefix}.Pointer<${w.ffiLibraryPrefix}.NativeFunction<$cType>>',
+          name: name,
+          ptrName: funcPointerName,
+        );
+      }
+
+      // Write function pointer.
+      s.write('''
+late final $funcPointerName = ${w.lookupFuncIdentifier}<
+    ${w.ffiLibraryPrefix}.NativeFunction<$cType>>('$originalName');
+late final $funcVarName = $funcPointerName.asFunction<$dartType>($isLeafString);
+
+''');
+    }
+
+    return BindingString(type: BindingStringType.func, string: s.toString());
+  }
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    if (dependencies.contains(this)) return;
+
+    dependencies.add(this);
+    functionType.addDependencies(dependencies);
+    if (exposeFunctionTypedefs) {
+      _exposedFunctionTypealias!.addDependencies(dependencies);
+    }
+  }
+}
+
+/// Represents a Parameter, used in [Func] and [Typealias].
+class Parameter {
+  final String? originalName;
+  String name;
+  final Type type;
+
+  Parameter({String? originalName, this.name = '', required Type type})
+      : originalName = originalName ?? name,
+        // A [NativeFunc] is wrapped with a pointer because this is a shorthand
+        // used in C for Pointer to function.
+        type = type.typealiasType is NativeFunc ? PointerType(type) : type;
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/func_type.dart b/pkgs/ffigen/lib/src/code_generator/func_type.dart
new file mode 100644
index 0000000..49dcf60
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/func_type.dart
@@ -0,0 +1,152 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/code_generator/utils.dart';
+
+import 'writer.dart';
+
+/// Represents a function type.
+class FunctionType extends Type {
+  final Type returnType;
+  final List<Parameter> parameters;
+  final List<Parameter> varArgParameters;
+
+  /// Get all the parameters for generating the dart type. This includes both
+  /// [parameters] and [varArgParameters].
+  List<Parameter> get dartTypeParameters => parameters + varArgParameters;
+
+  FunctionType({
+    required this.returnType,
+    required this.parameters,
+    this.varArgParameters = const [],
+  });
+
+  String _getTypeImpl(
+      bool writeArgumentNames, String Function(Type) typeToString,
+      {String? varArgWrapper}) {
+    final params = varArgWrapper != null ? parameters : dartTypeParameters;
+    String? varArgPack;
+    if (varArgWrapper != null && varArgParameters.isNotEmpty) {
+      final varArgPackBuf = StringBuffer();
+      varArgPackBuf.write("$varArgWrapper<(");
+      varArgPackBuf.write((varArgParameters).map<String>((p) {
+        return '${typeToString(p.type)} ${writeArgumentNames ? p.name : ""}';
+      }).join(', '));
+      varArgPackBuf.write(",)>");
+      varArgPack = varArgPackBuf.toString();
+    }
+
+    // Write return Type.
+    final sb = StringBuffer();
+    sb.write(typeToString(returnType));
+
+    // Write Function.
+    sb.write(' Function(');
+    sb.write([
+      ...params.map<String>((p) {
+        return '${typeToString(p.type)} ${writeArgumentNames ? p.name : ""}';
+      }),
+      if (varArgPack != null) varArgPack,
+    ].join(', '));
+    sb.write(')');
+
+    return sb.toString();
+  }
+
+  @override
+  String getCType(Writer w, {bool writeArgumentNames = true}) =>
+      _getTypeImpl(writeArgumentNames, (Type t) => t.getCType(w),
+          varArgWrapper: '${w.ffiLibraryPrefix}.VarArgs');
+
+  @override
+  String getFfiDartType(Writer w, {bool writeArgumentNames = true}) =>
+      _getTypeImpl(writeArgumentNames, (Type t) => t.getFfiDartType(w));
+
+  @override
+  String getDartType(Writer w, {bool writeArgumentNames = true}) =>
+      _getTypeImpl(writeArgumentNames, (Type t) => t.getDartType(w));
+
+  @override
+  bool get sameFfiDartAndCType =>
+      returnType.sameFfiDartAndCType &&
+      dartTypeParameters.every((p) => p.type.sameFfiDartAndCType);
+
+  @override
+  bool get sameDartAndCType =>
+      returnType.sameDartAndCType &&
+      dartTypeParameters.every((p) => p.type.sameDartAndCType);
+
+  @override
+  bool get sameDartAndFfiDartType =>
+      returnType.sameDartAndFfiDartType &&
+      dartTypeParameters.every((p) => p.type.sameDartAndFfiDartType);
+
+  @override
+  String toString() => _getTypeImpl(false, (Type t) => t.toString());
+
+  @override
+  String cacheKey() => _getTypeImpl(false, (Type t) => t.cacheKey());
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    returnType.addDependencies(dependencies);
+    for (final p in parameters) {
+      p.type.addDependencies(dependencies);
+    }
+  }
+
+  void addParameterNames(List<String> names) {
+    if (names.length != parameters.length) {
+      return;
+    }
+    final paramNamer = UniqueNamer({});
+    for (int i = 0; i < parameters.length; i++) {
+      final finalName = paramNamer.makeUnique(names[i]);
+      parameters[i] = Parameter(
+        type: parameters[i].type,
+        originalName: names[i],
+        name: finalName,
+      );
+    }
+  }
+}
+
+/// Represents a NativeFunction<Function>.
+class NativeFunc extends Type {
+  // Either a FunctionType or a Typealias of a FunctionType.
+  final Type _type;
+
+  NativeFunc(this._type) {
+    assert(_type is FunctionType || _type is Typealias);
+  }
+
+  FunctionType get type {
+    if (_type is Typealias) {
+      return _type.typealiasType as FunctionType;
+    }
+    return _type as FunctionType;
+  }
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    _type.addDependencies(dependencies);
+  }
+
+  @override
+  String getCType(Writer w) =>
+      '${w.ffiLibraryPrefix}.NativeFunction<${_type.getCType(w)}>';
+
+  @override
+  String getFfiDartType(Writer w) => getCType(w);
+
+  @override
+  bool get sameFfiDartAndCType => true;
+
+  @override
+  String toString() => 'NativeFunction<${_type.toString()}>';
+
+  @override
+  String cacheKey() => 'NatFn(${_type.cacheKey()})';
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/global.dart b/pkgs/ffigen/lib/src/code_generator/global.dart
new file mode 100644
index 0000000..81f61a8
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/global.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'binding.dart';
+import 'binding_string.dart';
+import 'compound.dart';
+import 'type.dart';
+import 'utils.dart';
+import 'writer.dart';
+
+/// A binding to a global variable
+///
+/// For a C global variable -
+/// ```c
+/// int a;
+/// ```
+/// The generated dart code is -
+/// ```dart
+/// final int a = _dylib.lookup<ffi.Int32>('a').value;
+/// ```
+class Global extends LookUpBinding {
+  final Type type;
+  final bool exposeSymbolAddress;
+
+  Global({
+    super.usr,
+    super.originalName,
+    required super.name,
+    required this.type,
+    super.dartDoc,
+    this.exposeSymbolAddress = false,
+  });
+
+  @override
+  BindingString toBindingString(Writer w) {
+    final s = StringBuffer();
+    final globalVarName = name;
+    if (dartDoc != null) {
+      s.write(makeDartDoc(dartDoc!));
+    }
+    final pointerName = w.wrapperLevelUniqueNamer.makeUnique('_$globalVarName');
+    final dartType = type.getFfiDartType(w);
+    final cType = type.getCType(w);
+
+    s.write(
+        "late final ${w.ffiLibraryPrefix}.Pointer<$cType> $pointerName = ${w.lookupFuncIdentifier}<$cType>('$originalName');\n\n");
+    final baseTypealiasType = type.typealiasType;
+    if (baseTypealiasType is Compound) {
+      if (baseTypealiasType.isOpaque) {
+        s.write(
+            '${w.ffiLibraryPrefix}.Pointer<$cType> get $globalVarName => $pointerName;\n\n');
+      } else {
+        s.write('$dartType get $globalVarName => $pointerName.ref;\n\n');
+      }
+    } else {
+      s.write('$dartType get $globalVarName => $pointerName.value;\n\n');
+      s.write(
+          'set $globalVarName($dartType value) => $pointerName.value = value;\n\n');
+    }
+
+    if (exposeSymbolAddress) {
+      // Add to SymbolAddress in writer.
+      w.symbolAddressWriter.addSymbol(
+        type: '${w.ffiLibraryPrefix}.Pointer<$cType>',
+        name: name,
+        ptrName: pointerName,
+      );
+    }
+
+    return BindingString(type: BindingStringType.global, string: s.toString());
+  }
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    if (dependencies.contains(this)) return;
+
+    dependencies.add(this);
+    type.addDependencies(dependencies);
+  }
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/handle.dart b/pkgs/ffigen/lib/src/code_generator/handle.dart
new file mode 100644
index 0000000..aaa0649
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/handle.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+
+import 'writer.dart';
+
+/// Represents a Dart_Handle.
+class HandleType extends Type {
+  const HandleType._();
+  static const _handle = HandleType._();
+  factory HandleType() => _handle;
+
+  @override
+  String getCType(Writer w) => '${w.ffiLibraryPrefix}.Handle';
+
+  @override
+  String getFfiDartType(Writer w) => 'Object';
+
+  @override
+  bool get sameFfiDartAndCType => false;
+
+  @override
+  String toString() => 'Handle';
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/imports.dart b/pkgs/ffigen/lib/src/code_generator/imports.dart
new file mode 100644
index 0000000..e9dda1c
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/imports.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'struct.dart';
+import 'type.dart';
+import 'writer.dart';
+
+/// A library import which will be written as an import in the generated file.
+class LibraryImport {
+  final String name;
+  final String importPath;
+  String prefix;
+
+  LibraryImport(this.name, this.importPath) : prefix = name;
+
+  @override
+  bool operator ==(other) {
+    return other is LibraryImport && name == other.name;
+  }
+
+  @override
+  int get hashCode => name.hashCode;
+}
+
+/// An imported type which will be used in the generated code.
+class ImportedType extends Type {
+  final LibraryImport libraryImport;
+  final String cType;
+  final String dartType;
+  final String? defaultValue;
+
+  ImportedType(this.libraryImport, this.cType, this.dartType,
+      [this.defaultValue]);
+
+  @override
+  String getCType(Writer w) {
+    w.markImportUsed(libraryImport);
+    return '${libraryImport.prefix}.$cType';
+  }
+
+  @override
+  String getFfiDartType(Writer w) => cType == dartType ? getCType(w) : dartType;
+
+  @override
+  bool get sameFfiDartAndCType => cType == dartType;
+
+  @override
+  String toString() => '${libraryImport.name}.$cType';
+
+  @override
+  String? getDefaultValue(Writer w, String nativeLib) => defaultValue;
+}
+
+/// An unchecked type similar to [ImportedType] which exists in the generated
+/// binding itself.
+class SelfImportedType extends Type {
+  final String cType;
+  final String dartType;
+  final String? defaultValue;
+
+  SelfImportedType(this.cType, this.dartType, [this.defaultValue]);
+
+  @override
+  String getCType(Writer w) => cType;
+
+  @override
+  String getFfiDartType(Writer w) => dartType;
+
+  @override
+  bool get sameFfiDartAndCType => cType == dartType;
+
+  @override
+  String toString() => cType;
+}
+
+final ffiImport = LibraryImport('ffi', 'dart:ffi');
+final ffiPkgImport = LibraryImport('pkg_ffi', 'package:ffi/ffi.dart');
+
+final voidType = ImportedType(ffiImport, 'Void', 'void');
+
+final unsignedCharType = ImportedType(ffiImport, 'UnsignedChar', 'int', '0');
+final signedCharType = ImportedType(ffiImport, 'SignedChar', 'int', '0');
+final charType = ImportedType(ffiImport, 'Char', 'int', '0');
+final unsignedShortType = ImportedType(ffiImport, 'UnsignedShort', 'int', '0');
+final shortType = ImportedType(ffiImport, 'Short', 'int', '0');
+final unsignedIntType = ImportedType(ffiImport, 'UnsignedInt', 'int', '0');
+final intType = ImportedType(ffiImport, 'Int', 'int', '0');
+final unsignedLongType = ImportedType(ffiImport, 'UnsignedLong', 'int', '0');
+final longType = ImportedType(ffiImport, 'Long', 'int', '0');
+final unsignedLongLongType =
+    ImportedType(ffiImport, 'UnsignedLongLong', 'int', '0');
+final longLongType = ImportedType(ffiImport, 'LongLong', 'int', '0');
+
+final floatType = ImportedType(ffiImport, 'Float', 'double', '0.0');
+final doubleType = ImportedType(ffiImport, 'Double', 'double', '0.0');
+
+final sizeType = ImportedType(ffiImport, 'Size', 'int', '0');
+final wCharType = ImportedType(ffiImport, 'WChar', 'int', '0');
+
+final objCObjectType = Struct(name: 'ObjCObject');
+final objCSelType = Struct(name: 'ObjCSel');
diff --git a/pkgs/ffigen/lib/src/code_generator/library.dart b/pkgs/ffigen/lib/src/code_generator/library.dart
new file mode 100644
index 0000000..befdfce
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/library.dart
@@ -0,0 +1,177 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:cli_util/cli_util.dart';
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/config_provider/config_types.dart';
+import 'package:logging/logging.dart';
+import 'package:path/path.dart' as p;
+import 'package:yaml_edit/yaml_edit.dart';
+
+import '../strings.dart' as strings;
+import 'utils.dart';
+import 'writer.dart';
+
+final _logger = Logger('ffigen.code_generator.library');
+
+/// Container for all Bindings.
+class Library {
+  /// List of bindings in this library.
+  late List<Binding> bindings;
+
+  late Writer _writer;
+  Writer get writer => _writer;
+
+  Library({
+    required String name,
+    String? description,
+    required List<Binding> bindings,
+    String? header,
+    bool sort = false,
+    StructPackingOverride? packingOverride,
+    Set<LibraryImport>? libraryImports,
+  }) {
+    /// Get all dependencies (includes itself).
+    final dependencies = <Binding>{};
+    for (final b in bindings) {
+      b.addDependencies(dependencies);
+    }
+
+    /// Save bindings.
+    this.bindings = dependencies.toList();
+
+    if (sort) {
+      _sort();
+    }
+
+    /// Handle any declaration-declaration name conflicts and emit warnings.
+    final declConflictHandler = UniqueNamer({});
+    for (final b in this.bindings) {
+      _warnIfPrivateDeclaration(b);
+      _resolveIfNameConflicts(declConflictHandler, b);
+      _warnIfExposeSymbolAddressAndFfiNative(b);
+    }
+
+    // Override pack values according to config. We do this after declaration
+    // conflicts have been handled so that users can target the generated names.
+    if (packingOverride != null) {
+      for (final b in this.bindings) {
+        if (b is Struct && packingOverride.isOverriden(b.name)) {
+          b.pack = packingOverride.getOverridenPackValue(b.name);
+        }
+      }
+    }
+
+    // Seperate bindings which require lookup.
+    final lookUpBindings = this.bindings.whereType<LookUpBinding>().where((e) {
+      if (e is Func) {
+        return !e.ffiNativeConfig.enabled;
+      }
+      return true;
+    }).toList();
+    final ffiNativeBindings = this
+        .bindings
+        .whereType<Func>()
+        .where((e) => e.ffiNativeConfig.enabled)
+        .toList();
+    final noLookUpBindings =
+        this.bindings.whereType<NoLookUpBinding>().toList();
+
+    _writer = Writer(
+      lookUpBindings: lookUpBindings,
+      ffiNativeBindings: ffiNativeBindings,
+      noLookUpBindings: noLookUpBindings,
+      className: name,
+      classDocComment: description,
+      header: header,
+      additionalImports: libraryImports,
+    );
+  }
+
+  /// Logs a warning if generated declaration will be private.
+  void _warnIfPrivateDeclaration(Binding b) {
+    if (b.name.startsWith('_') && !b.isInternal) {
+      _logger.warning(
+          "Generated declaration '${b.name}' start's with '_' and therefore will be private.");
+    }
+  }
+
+  /// Resolves name conflict(if any) and logs a warning.
+  void _resolveIfNameConflicts(UniqueNamer namer, Binding b) {
+    // Print warning if name was conflicting and has been changed.
+    if (namer.isUsed(b.name)) {
+      final oldName = b.name;
+      b.name = namer.makeUnique(b.name);
+
+      _logger.warning(
+          "Resolved name conflict: Declaration '$oldName' and has been renamed to '${b.name}'.");
+    } else {
+      namer.markUsed(b.name);
+    }
+  }
+
+  /// Logs a warning if generated declaration will be private.
+  void _warnIfExposeSymbolAddressAndFfiNative(Binding b) {
+    if (b is Func) {
+      if (b.exposeSymbolAddress && b.ffiNativeConfig.enabled) {
+        _logger.warning(
+            "Ignoring ${strings.symbolAddress} for '${b.name}' because it is generated as FfiNative.");
+      }
+    }
+  }
+
+  /// Sort all bindings in alphabetical order.
+  void _sort() {
+    bindings.sort((b1, b2) => b1.name.compareTo(b2.name));
+  }
+
+  /// Generates [file] by generating C bindings.
+  ///
+  /// If format is true(default), the formatter will be called to format the generated file.
+  void generateFile(File file, {bool format = true}) {
+    if (!file.existsSync()) file.createSync(recursive: true);
+    file.writeAsStringSync(generate());
+    if (format) {
+      _dartFormat(file.path);
+    }
+  }
+
+  /// Generates [file] with symbol output yaml.
+  void generateSymbolOutputFile(File file, String importPath) {
+    if (!file.existsSync()) file.createSync(recursive: true);
+    final symbolFileYamlMap = writer.generateSymbolOutputYamlMap(importPath);
+    final yamlEditor = YamlEditor("");
+    yamlEditor.update([], wrapAsYamlNode(symbolFileYamlMap));
+    var yamlString = yamlEditor.toString();
+    if (!yamlString.endsWith('\n')) {
+      yamlString += "\n";
+    }
+    file.writeAsStringSync(yamlString);
+  }
+
+  /// Formats a file using the Dart formatter.
+  void _dartFormat(String path) {
+    final sdkPath = getSdkPath();
+    final result = Process.runSync(
+        p.join(sdkPath, 'bin', 'dart'), ['format', path],
+        runInShell: Platform.isWindows);
+    if (result.stderr.toString().isNotEmpty) {
+      _logger.severe(result.stderr);
+      throw FormatException('Unable to format generated file: $path.');
+    }
+  }
+
+  /// Generates the bindings.
+  String generate() {
+    return writer.generate();
+  }
+
+  @override
+  bool operator ==(other) => other is Library && other.generate() == generate();
+
+  @override
+  int get hashCode => bindings.hashCode;
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/native_type.dart b/pkgs/ffigen/lib/src/code_generator/native_type.dart
new file mode 100644
index 0000000..93ed356
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/native_type.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+
+import 'writer.dart';
+
+enum SupportedNativeType {
+  Void,
+  Char,
+  Int8,
+  Int16,
+  Int32,
+  Int64,
+  Uint8,
+  Uint16,
+  Uint32,
+  Uint64,
+  Float,
+  Double,
+  IntPtr,
+  UintPtr,
+}
+
+/// Represents a primitive native type, such as float.
+class NativeType extends Type {
+  static const _primitives = <SupportedNativeType, NativeType>{
+    SupportedNativeType.Void: NativeType._('Void', 'void', null),
+    SupportedNativeType.Char: NativeType._('Uint8', 'int', '0'),
+    SupportedNativeType.Int8: NativeType._('Int8', 'int', '0'),
+    SupportedNativeType.Int16: NativeType._('Int16', 'int', '0'),
+    SupportedNativeType.Int32: NativeType._('Int32', 'int', '0'),
+    SupportedNativeType.Int64: NativeType._('Int64', 'int', '0'),
+    SupportedNativeType.Uint8: NativeType._('Uint8', 'int', '0'),
+    SupportedNativeType.Uint16: NativeType._('Uint16', 'int', '0'),
+    SupportedNativeType.Uint32: NativeType._('Uint32', 'int', '0'),
+    SupportedNativeType.Uint64: NativeType._('Uint64', 'int', '0'),
+    SupportedNativeType.Float: NativeType._('Float', 'double', '0.0'),
+    SupportedNativeType.Double: NativeType._('Double', 'double', '0.0'),
+    SupportedNativeType.IntPtr: NativeType._('IntPtr', 'int', '0'),
+    SupportedNativeType.UintPtr: NativeType._('UintPtr', 'int', '0'),
+  };
+
+  final String _cType;
+  final String _dartType;
+  final String? _defaultValue;
+
+  const NativeType._(this._cType, this._dartType, this._defaultValue);
+
+  factory NativeType(SupportedNativeType type) => _primitives[type]!;
+
+  @override
+  String getCType(Writer w) => '${w.ffiLibraryPrefix}.$_cType';
+
+  @override
+  String getFfiDartType(Writer w) => _dartType;
+
+  @override
+  bool get sameFfiDartAndCType => _cType == _dartType;
+
+  @override
+  String toString() => _cType;
+
+  @override
+  String cacheKey() => _cType;
+
+  @override
+  String? getDefaultValue(Writer w, String nativeLib) => _defaultValue;
+}
+
+class BooleanType extends NativeType {
+  const BooleanType._() : super._('Bool', 'bool', 'false');
+  static const _boolean = BooleanType._();
+  factory BooleanType() => _boolean;
+
+  @override
+  String toString() => 'bool';
+
+  @override
+  String cacheKey() => 'bool';
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_block.dart b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
new file mode 100644
index 0000000..d16ab11
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
@@ -0,0 +1,254 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+
+import 'binding_string.dart';
+import 'writer.dart';
+
+class ObjCBlock extends BindingType {
+  final Type returnType;
+  final List<Type> argTypes;
+  final ObjCBuiltInFunctions builtInFunctions;
+
+  ObjCBlock({
+    required String usr,
+    required Type returnType,
+    required List<Type> argTypes,
+    required ObjCBuiltInFunctions builtInFunctions,
+  }) : this._(
+          usr: usr,
+          name: _getBlockName(returnType, argTypes),
+          returnType: returnType,
+          argTypes: argTypes,
+          builtInFunctions: builtInFunctions,
+        );
+
+  ObjCBlock._({
+    required String super.usr,
+    required super.name,
+    required this.returnType,
+    required this.argTypes,
+    required this.builtInFunctions,
+  }) : super(originalName: name);
+
+  // Generates a human readable name for the block based on the args and return
+  // type. These names will be pretty verbose and unweildy, but they're at least
+  // sensible and stable. Users can always add their own typedef with a simpler
+  // name if necessary.
+  static String _getBlockName(Type returnType, List<Type> argTypes) =>
+      'ObjCBlock_${[returnType, ...argTypes].map(_typeName).join('_')}';
+  static String _typeName(Type type) =>
+      type.toString().replaceAll(_illegalNameChar, '');
+  static final _illegalNameChar = RegExp(r'[^0-9a-zA-Z]');
+
+  @override
+  BindingString toBindingString(Writer w) {
+    final s = StringBuffer();
+
+    builtInFunctions.ensureBlockUtilsExist(w, s);
+
+    final params = <Parameter>[];
+    for (int i = 0; i < argTypes.length; ++i) {
+      params.add(Parameter(name: 'arg$i', type: argTypes[i]));
+    }
+
+    final isVoid = returnType == voidType;
+    final voidPtr = PointerType(voidType).getCType(w);
+    final blockPtr = PointerType(builtInFunctions.blockStruct);
+    final funcType = FunctionType(returnType: returnType, parameters: params);
+    final natFnType = NativeFunc(funcType);
+    final natFnPtr = PointerType(natFnType).getCType(w);
+    final funcPtrTrampoline =
+        w.topLevelUniqueNamer.makeUnique('_${name}_fnPtrTrampoline');
+    final closureTrampoline =
+        w.topLevelUniqueNamer.makeUnique('_${name}_closureTrampoline');
+    final registerClosure =
+        w.topLevelUniqueNamer.makeUnique('_${name}_registerClosure');
+    final closureRegistry =
+        w.topLevelUniqueNamer.makeUnique('_${name}_closureRegistry');
+    final closureRegistryIndex =
+        w.topLevelUniqueNamer.makeUnique('_${name}_closureRegistryIndex');
+    final trampFuncType = FunctionType(
+        returnType: returnType,
+        parameters: [Parameter(type: blockPtr, name: 'block'), ...params]);
+    final trampFuncCType = trampFuncType.getCType(w, writeArgumentNames: false);
+    final trampFuncFfiDartType =
+        trampFuncType.getFfiDartType(w, writeArgumentNames: false);
+    final natTrampFnType = NativeFunc(trampFuncType).getCType(w);
+    final nativeCallableType =
+        '${w.ffiLibraryPrefix}.NativeCallable<$trampFuncCType>';
+    final funcDartType = funcType.getDartType(w, writeArgumentNames: false);
+    final funcFfiDartType =
+        funcType.getFfiDartType(w, writeArgumentNames: false);
+    final returnFfiDartType = returnType.getFfiDartType(w);
+    final blockCType = blockPtr.getCType(w);
+
+    final paramsNameOnly = params.map((p) => p.name).join(', ');
+    final paramsFfiDartType =
+        params.map((p) => '${p.type.getFfiDartType(w)} ${p.name}').join(', ');
+    final paramsDartType =
+        params.map((p) => '${p.type.getDartType(w)} ${p.name}').join(', ');
+
+    // Write the function pointer based trampoline function.
+    s.write('''
+$returnFfiDartType $funcPtrTrampoline($blockCType block, $paramsFfiDartType) =>
+    block.ref.target.cast<${natFnType.getFfiDartType(w)}>()
+        .asFunction<$funcFfiDartType>()($paramsNameOnly);
+''');
+
+    // Write the closure registry function.
+    s.write('''
+final $closureRegistry = <int, $funcFfiDartType>{};
+int $closureRegistryIndex = 0;
+$voidPtr $registerClosure($funcFfiDartType fn) {
+  final id = ++$closureRegistryIndex;
+  $closureRegistry[id] = fn;
+  return $voidPtr.fromAddress(id);
+}
+''');
+
+    // Write the closure based trampoline function.
+    s.write('''
+$returnFfiDartType $closureTrampoline($blockCType block, $paramsFfiDartType) =>
+    $closureRegistry[block.ref.target.address]!($paramsNameOnly);
+''');
+
+    // Snippet that converts a Dart typed closure to FfiDart type. This snippet
+    // is used below. Note that the closure being converted is called `fn`.
+    final convertedFnArgs = params
+        .map((p) => p.type
+            .convertFfiDartTypeToDartType(w, p.name, 'lib', objCRetain: true))
+        .join(', ');
+    final convFnInvocation = returnType.convertDartTypeToFfiDartType(
+        w, 'fn($convertedFnArgs)',
+        objCRetain: true);
+    final convFn = '($paramsFfiDartType) => $convFnInvocation';
+
+    // Write the wrapper class.
+    final defaultValue = returnType.getDefaultValue(w, '_lib');
+    final exceptionalReturn = defaultValue == null ? '' : ', $defaultValue';
+    s.write('''
+class $name extends _ObjCBlockBase {
+  $name._($blockCType id, ${w.className} lib,
+      {bool retain = false, bool release = true}) :
+          super._(id, lib, retain: retain, release: release);
+
+  /// Creates a block from a C function pointer.
+  ///
+  /// This block must be invoked by native code running on the same thread as
+  /// the isolate that registered it. Invoking the block on the wrong thread
+  /// will result in a crash.
+  $name.fromFunctionPointer(${w.className} lib, $natFnPtr ptr) :
+      this._(lib.${builtInFunctions.newBlock.name}(
+          _cFuncTrampoline ??= ${w.ffiLibraryPrefix}.Pointer.fromFunction<
+              $trampFuncCType>($funcPtrTrampoline
+                  $exceptionalReturn).cast(), ptr.cast()), lib);
+  static $voidPtr? _cFuncTrampoline;
+
+  /// Creates a block from a Dart function.
+  ///
+  /// This block must be invoked by native code running on the same thread as
+  /// the isolate that registered it. Invoking the block on the wrong thread
+  /// will result in a crash.
+  $name.fromFunction(${w.className} lib, $funcDartType fn) :
+      this._(lib.${builtInFunctions.newBlock.name}(
+          _dartFuncTrampoline ??= ${w.ffiLibraryPrefix}.Pointer.fromFunction<
+              $trampFuncCType>($closureTrampoline
+                  $exceptionalReturn).cast(), $registerClosure($convFn)), lib);
+  static $voidPtr? _dartFuncTrampoline;
+
+''');
+
+    // Listener block constructor is only available for void blocks.
+    if (isVoid) {
+      s.write('''
+  /// Creates a listener block from a Dart function.
+  ///
+  /// This is based on FFI's NativeCallable.listener, and has the same
+  /// capabilities and limitations. This block can be invoked from any thread,
+  /// but only supports void functions, and is not run synchronously. See
+  /// NativeCallable.listener for more details.
+  ///
+  /// Note that unlike the default behavior of NativeCallable.listener, listener
+  /// blocks do not keep the isolate alive.
+  $name.listener(${w.className} lib, $funcDartType fn) :
+      this._(lib.${builtInFunctions.newBlock.name}(
+          (_dartFuncListenerTrampoline ??= $nativeCallableType.listener(
+              $closureTrampoline $exceptionalReturn)..keepIsolateAlive =
+                  false).nativeFunction.cast(),
+          $registerClosure($convFn)), lib);
+  static $nativeCallableType? _dartFuncListenerTrampoline;
+
+''');
+    }
+
+    // Call method.
+    s.write('  ${returnType.getDartType(w)} call($paramsDartType) =>');
+    final callMethodArgs = params
+        .map((p) =>
+            p.type.convertDartTypeToFfiDartType(w, p.name, objCRetain: false))
+        .join(', ');
+    final callMethodInvocation = '''
+_id.ref.invoke.cast<$natTrampFnType>().asFunction<$trampFuncFfiDartType>()(
+    _id, $callMethodArgs)''';
+    s.write(returnType.convertFfiDartTypeToDartType(
+        w, callMethodInvocation, '_lib',
+        objCRetain: false));
+    s.write(';\n');
+
+    s.write('}\n');
+    return BindingString(
+        type: BindingStringType.objcBlock, string: s.toString());
+  }
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    if (dependencies.contains(this)) return;
+    dependencies.add(this);
+
+    returnType.addDependencies(dependencies);
+    for (final t in argTypes) {
+      t.addDependencies(dependencies);
+    }
+    builtInFunctions.addBlockDependencies(dependencies);
+  }
+
+  @override
+  String getCType(Writer w) =>
+      PointerType(builtInFunctions.blockStruct).getCType(w);
+
+  @override
+  String getDartType(Writer w) => name;
+
+  @override
+  bool get sameFfiDartAndCType => true;
+
+  @override
+  bool get sameDartAndCType => false;
+
+  @override
+  bool get sameDartAndFfiDartType => false;
+
+  @override
+  String convertDartTypeToFfiDartType(
+    Writer w,
+    String value, {
+    required bool objCRetain,
+  }) =>
+      ObjCInterface.generateGetId(value, objCRetain);
+
+  @override
+  String convertFfiDartTypeToDartType(
+    Writer w,
+    String value,
+    String library, {
+    required bool objCRetain,
+    String? objCEnclosingClass,
+  }) =>
+      ObjCInterface.generateConstructor(name, value, library, objCRetain);
+
+  @override
+  String toString() => '($returnType (^)(${argTypes.join(', ')}))';
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart b/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart
new file mode 100644
index 0000000..60c998b
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart
@@ -0,0 +1,444 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+
+import 'binding_string.dart';
+import 'writer.dart';
+
+/// Built in functions used by the Objective C bindings.
+class ObjCBuiltInFunctions {
+  late final _registerNameFunc = Func(
+    name: '_sel_registerName',
+    originalName: 'sel_registerName',
+    returnType: PointerType(objCSelType),
+    parameters: [Parameter(name: 'str', type: PointerType(charType))],
+    isInternal: true,
+  );
+  late final registerName = ObjCInternalFunction(
+      '_registerName', _registerNameFunc, (Writer w, String name) {
+    final selType = _registerNameFunc.functionType.returnType.getCType(w);
+    return '''
+$selType $name(String name) {
+  final cstr = name.toNativeUtf8();
+  final sel = ${_registerNameFunc.name}(cstr.cast());
+  ${w.ffiPkgLibraryPrefix}.calloc.free(cstr);
+  return sel;
+}
+''';
+  });
+
+  late final _getClassFunc = Func(
+    name: '_objc_getClass',
+    originalName: 'objc_getClass',
+    returnType: PointerType(objCObjectType),
+    parameters: [Parameter(name: 'str', type: PointerType(charType))],
+    isInternal: true,
+  );
+  late final getClass =
+      ObjCInternalFunction('_getClass', _getClassFunc, (Writer w, String name) {
+    final objType = _getClassFunc.functionType.returnType.getCType(w);
+    return '''
+$objType $name(String name) {
+  final cstr = name.toNativeUtf8();
+  final clazz = ${_getClassFunc.name}(cstr.cast());
+  ${w.ffiPkgLibraryPrefix}.calloc.free(cstr);
+  if (clazz == ${w.ffiLibraryPrefix}.nullptr) {
+    throw Exception('Failed to load Objective-C class: \$name');
+  }
+  return clazz;
+}
+''';
+  });
+
+  late final _retainFunc = Func(
+    name: '_objc_retain',
+    originalName: 'objc_retain',
+    returnType: PointerType(objCObjectType),
+    parameters: [Parameter(name: 'value', type: PointerType(objCObjectType))],
+    isInternal: true,
+  );
+  late final _releaseFunc = Func(
+    name: '_objc_release',
+    originalName: 'objc_release',
+    returnType: voidType,
+    parameters: [Parameter(name: 'value', type: PointerType(objCObjectType))],
+    isInternal: true,
+  );
+  late final _releaseFinalizer = ObjCInternalGlobal(
+    '_objc_releaseFinalizer',
+    (Writer w) => '${w.ffiLibraryPrefix}.NativeFinalizer('
+        '${_releaseFunc.funcPointerName}.cast())',
+    _releaseFunc,
+  );
+
+  late final _blockCopyFunc = Func(
+    name: '_Block_copy',
+    originalName: '_Block_copy',
+    returnType: PointerType(voidType),
+    parameters: [Parameter(name: 'value', type: PointerType(voidType))],
+    isInternal: true,
+  );
+  late final _blockReleaseFunc = Func(
+    name: '_Block_release',
+    originalName: '_Block_release',
+    returnType: voidType,
+    parameters: [Parameter(name: 'value', type: PointerType(voidType))],
+    isInternal: true,
+  );
+  late final _blockReleaseFinalizer = ObjCInternalGlobal(
+    '_objc_releaseFinalizer',
+    (Writer w) => '${w.ffiLibraryPrefix}.NativeFinalizer('
+        '${_blockReleaseFunc.funcPointerName}.cast())',
+    _blockReleaseFunc,
+  );
+
+  // We need to load a separate instance of objc_msgSend for each signature. If
+  // the return type is a struct, we need to use objc_msgSend_stret instead, and
+  // for float return types we need objc_msgSend_fpret.
+  final _msgSendFuncs = <String, ObjCMsgSendFunc>{};
+  ObjCMsgSendFunc getMsgSendFunc(
+      Type returnType, List<ObjCMethodParam> params) {
+    var key = returnType.cacheKey();
+    for (final p in params) {
+      key += ' ${p.type.cacheKey()}';
+    }
+    return _msgSendFuncs[key] ??= ObjCMsgSendFunc(
+        '_objc_msgSend_${_msgSendFuncs.length}', returnType, params);
+  }
+
+  final _selObjects = <String, ObjCInternalGlobal>{};
+  ObjCInternalGlobal getSelObject(String methodName) {
+    return _selObjects[methodName] ??= ObjCInternalGlobal(
+      '_sel_${methodName.replaceAll(":", "_")}',
+      (Writer w) => '${registerName.name}("$methodName")',
+      registerName,
+    );
+  }
+
+  // See https://clang.llvm.org/docs/Block-ABI-Apple.html
+  late final blockStruct = Struct(
+    name: '_ObjCBlock',
+    isInternal: true,
+    members: [
+      Member(name: 'isa', type: PointerType(voidType)),
+      Member(name: 'flags', type: intType),
+      Member(name: 'reserved', type: intType),
+      Member(name: 'invoke', type: PointerType(voidType)),
+      Member(name: 'descriptor', type: PointerType(blockDescStruct)),
+      Member(name: 'target', type: PointerType(voidType)),
+    ],
+  );
+  late final blockDescStruct = Struct(
+    name: '_ObjCBlockDesc',
+    isInternal: true,
+    members: [
+      Member(name: 'reserved', type: unsignedLongType),
+      Member(name: 'size', type: unsignedLongType),
+      Member(name: 'copy_helper', type: PointerType(voidType)),
+      Member(name: 'dispose_helper', type: PointerType(voidType)),
+      Member(name: 'signature', type: PointerType(charType)),
+    ],
+  );
+  late final newBlockDesc =
+      ObjCInternalFunction('_newBlockDesc', null, (Writer w, String name) {
+    final blockType = blockStruct.getCType(w);
+    final descType = blockDescStruct.getCType(w);
+    final descPtr = PointerType(blockDescStruct).getCType(w);
+    return '''
+$descPtr $name() {
+  final d = ${w.ffiPkgLibraryPrefix}.calloc.allocate<$descType>(
+      ${w.ffiLibraryPrefix}.sizeOf<$descType>());
+  d.ref.reserved = 0;
+  d.ref.size = ${w.ffiLibraryPrefix}.sizeOf<$blockType>();
+  d.ref.copy_helper = ${w.ffiLibraryPrefix}.nullptr;
+  d.ref.dispose_helper = ${w.ffiLibraryPrefix}.nullptr;
+  d.ref.signature = ${w.ffiLibraryPrefix}.nullptr;
+  return d;
+}
+''';
+  });
+  late final blockDescSingleton = ObjCInternalGlobal(
+    '_objc_block_desc',
+    (Writer w) => '${newBlockDesc.name}()',
+    blockDescStruct,
+  );
+  late final concreteGlobalBlock = ObjCInternalGlobal(
+    '_objc_concrete_global_block',
+    (Writer w) => '${w.lookupFuncIdentifier}<${voidType.getCType(w)}>('
+        "'_NSConcreteGlobalBlock')",
+  );
+  late final newBlock = ObjCInternalFunction('_newBlock', _blockCopyFunc,
+      (Writer w, String name) {
+    final blockType = blockStruct.getCType(w);
+    final blockPtr = PointerType(blockStruct).getCType(w);
+    final voidPtr = PointerType(voidType).getCType(w);
+    return '''
+$blockPtr $name($voidPtr invoke, $voidPtr target) {
+  final b = ${w.ffiPkgLibraryPrefix}.calloc.allocate<$blockType>(
+      ${w.ffiLibraryPrefix}.sizeOf<$blockType>());
+  b.ref.isa = ${concreteGlobalBlock.name};
+  b.ref.flags = 0;
+  b.ref.reserved = 0;
+  b.ref.invoke = invoke;
+  b.ref.target = target;
+  b.ref.descriptor = ${blockDescSingleton.name};
+  final copy = ${_blockCopyFunc.name}(b.cast()).cast<$blockType>();
+  ${w.ffiPkgLibraryPrefix}.calloc.free(b);
+  return copy;
+}
+''';
+  });
+
+  void _writeFinalizableClass(
+      Writer w,
+      StringBuffer s,
+      String name,
+      String kind,
+      String idType,
+      String retain,
+      String release,
+      String finalizer) {
+    s.write('''
+class $name implements ${w.ffiLibraryPrefix}.Finalizable {
+  final $idType _id;
+  final ${w.className} _lib;
+  bool _pendingRelease;
+
+  $name._(this._id, this._lib,
+      {bool retain = false, bool release = false}) : _pendingRelease = release {
+    if (retain) {
+      _lib.$retain(_id.cast());
+    }
+    if (release) {
+      _lib.$finalizer.attach(this, _id.cast(), detach: this);
+    }
+  }
+
+  /// Releases the reference to the underlying ObjC $kind held by this wrapper.
+  /// Throws a StateError if this wrapper doesn't currently hold a reference.
+  void release() {
+    if (_pendingRelease) {
+      _pendingRelease = false;
+      _lib.$release(_id.cast());
+      _lib.$finalizer.detach(this);
+    } else {
+      throw StateError(
+          'Released an ObjC $kind that was unowned or already released.');
+    }
+  }
+
+  @override
+  bool operator ==(Object other) {
+    return other is $name && _id == other._id;
+  }
+
+  @override
+  int get hashCode => _id.hashCode;
+
+  /// Return a pointer to this object.
+  $idType get pointer => _id;
+
+  $idType _retainAndReturnId() {
+    _lib.$retain(_id.cast());
+    return _id;
+  }
+}
+''');
+  }
+
+  bool utilsExist = false;
+  void ensureUtilsExist(Writer w, StringBuffer s) {
+    if (utilsExist) return;
+    utilsExist = true;
+    _writeFinalizableClass(
+        w,
+        s,
+        '_ObjCWrapper',
+        'object',
+        PointerType(objCObjectType).getCType(w),
+        _retainFunc.name,
+        _releaseFunc.name,
+        _releaseFinalizer.name);
+  }
+
+  bool blockUtilsExist = false;
+  void ensureBlockUtilsExist(Writer w, StringBuffer s) {
+    if (blockUtilsExist) return;
+    blockUtilsExist = true;
+    _writeFinalizableClass(
+        w,
+        s,
+        '_ObjCBlockBase',
+        'block',
+        PointerType(blockStruct).getCType(w),
+        _blockCopyFunc.name,
+        _blockReleaseFunc.name,
+        _blockReleaseFinalizer.name);
+  }
+
+  void addDependencies(Set<Binding> dependencies) {
+    registerName.addDependencies(dependencies);
+    getClass.addDependencies(dependencies);
+    _retainFunc.addDependencies(dependencies);
+    _releaseFunc.addDependencies(dependencies);
+    _releaseFinalizer.addDependencies(dependencies);
+    for (final msgSendFunc in _msgSendFuncs.values) {
+      msgSendFunc.func.addDependencies(dependencies);
+    }
+    for (final sel in _selObjects.values) {
+      sel.addDependencies(dependencies);
+    }
+  }
+
+  void addBlockDependencies(Set<Binding> dependencies) {
+    newBlockDesc.addDependencies(dependencies);
+    blockDescSingleton.addDependencies(dependencies);
+    blockStruct.addDependencies(dependencies);
+    concreteGlobalBlock.addDependencies(dependencies);
+    newBlock.addDependencies(dependencies);
+    _blockCopyFunc.addDependencies(dependencies);
+    _blockReleaseFunc.addDependencies(dependencies);
+    _blockReleaseFinalizer.addDependencies(dependencies);
+  }
+
+  final _interfaceRegistry = <String, ObjCInterface>{};
+  void registerInterface(ObjCInterface interface) {
+    _interfaceRegistry[interface.originalName] = interface;
+  }
+
+  ObjCInterface get nsData {
+    return _interfaceRegistry["NSData"] ??
+        (ObjCInterface(
+          originalName: "NSData",
+          builtInFunctions: this,
+        ));
+  }
+
+  void generateNSStringUtils(Writer w, StringBuffer s) {
+    // Generate a constructor that wraps stringWithCharacters, and a toString
+    // method that wraps dataUsingEncoding.
+    s.write('''
+  factory NSString(${w.className} _lib, String str) {
+    final cstr = str.toNativeUtf16();
+    final nsstr = stringWithCharacters_length_(_lib, cstr.cast(), str.length);
+    ${w.ffiPkgLibraryPrefix}.calloc.free(cstr);
+    return nsstr;
+  }
+
+  @override
+  String toString() {
+    final data = dataUsingEncoding_(
+        0x94000100 /* NSUTF16LittleEndianStringEncoding */);
+    return data!.bytes.cast<${w.ffiPkgLibraryPrefix}.Utf16>().toDartString(
+        length: length);
+  }
+''');
+  }
+
+  void generateStringUtils(Writer w, StringBuffer s) {
+    // Generate an extension on String to convert to NSString
+    s.write('''
+extension StringToNSString on String {
+  NSString toNSString(${w.className} lib) => NSString(lib, this);
+}
+''');
+  }
+}
+
+/// Functions only used internally by ObjC bindings, which may or may not wrap a
+/// native function, such as getClass.
+class ObjCInternalFunction extends LookUpBinding {
+  final Func? _wrappedFunction;
+  final String Function(Writer, String) _toBindingString;
+
+  ObjCInternalFunction(
+      String name, this._wrappedFunction, this._toBindingString)
+      : super(originalName: name, name: name, isInternal: true);
+
+  @override
+  BindingString toBindingString(Writer w) {
+    name = w.wrapperLevelUniqueNamer.makeUnique(name);
+    return BindingString(
+        type: BindingStringType.func, string: _toBindingString(w, name));
+  }
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    if (dependencies.contains(this)) return;
+    dependencies.add(this);
+    _wrappedFunction?.addDependencies(dependencies);
+  }
+}
+
+/// Globals only used internally by ObjC bindings, such as classes and SELs.
+class ObjCInternalGlobal extends LookUpBinding {
+  final String Function(Writer) makeValue;
+  Binding? binding;
+
+  ObjCInternalGlobal(String name, this.makeValue, [this.binding])
+      : super(originalName: name, name: name, isInternal: true);
+
+  @override
+  BindingString toBindingString(Writer w) {
+    final s = StringBuffer();
+    name = w.wrapperLevelUniqueNamer.makeUnique(name);
+    s.write('late final $name = ${makeValue(w)};');
+    return BindingString(type: BindingStringType.global, string: s.toString());
+  }
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    if (dependencies.contains(this)) return;
+    dependencies.add(this);
+    binding?.addDependencies(dependencies);
+  }
+}
+
+enum ObjCMsgSendVariant {
+  normal('objc_msgSend'),
+  stret('objc_msgSend_stret'),
+  fpret('objc_msgSend_fpret');
+
+  final String name;
+  const ObjCMsgSendVariant(this.name);
+
+  static ObjCMsgSendVariant fromReturnType(Type returnType) {
+    if (returnType is Compound && returnType.isStruct) {
+      return ObjCMsgSendVariant.stret;
+    } else if (returnType == floatType || returnType == doubleType) {
+      return ObjCMsgSendVariant.fpret;
+    }
+    return ObjCMsgSendVariant.normal;
+  }
+}
+
+/// A wrapper around the objc_msgSend function, or the stret or fpret variants.
+class ObjCMsgSendFunc {
+  final ObjCMsgSendVariant variant;
+  late final Func func;
+
+  ObjCMsgSendFunc(String name, Type returnType, List<ObjCMethodParam> params)
+      : variant = ObjCMsgSendVariant.fromReturnType(returnType) {
+    func = Func(
+      name: name,
+      originalName: variant.name,
+      returnType: isStret ? voidType : returnType,
+      parameters: [
+        if (isStret) Parameter(name: 'stret', type: PointerType(returnType)),
+        Parameter(name: 'obj', type: PointerType(objCObjectType)),
+        Parameter(name: 'sel', type: PointerType(objCSelType)),
+        for (final p in params) Parameter(name: p.name, type: p.type),
+      ],
+      isInternal: true,
+    );
+  }
+
+  String get name => func.name;
+  bool get isStret => variant == ObjCMsgSendVariant.stret;
+
+  void addDependencies(Set<Binding> dependencies) {
+    func.addDependencies(dependencies);
+  }
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_interface.dart b/pkgs/ffigen/lib/src/code_generator/objc_interface.dart
new file mode 100644
index 0000000..495cdf1
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/objc_interface.dart
@@ -0,0 +1,554 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:logging/logging.dart';
+
+import 'binding_string.dart';
+import 'utils.dart';
+import 'writer.dart';
+
+// Class methods defined on NSObject that we don't want to copy to child objects
+// by default.
+const _excludedNSObjectClassMethods = {
+  'allocWithZone:',
+  'class',
+  'conformsToProtocol:',
+  'copyWithZone:',
+  'debugDescription',
+  'description',
+  'hash',
+  'initialize',
+  'instanceMethodForSelector:',
+  'instanceMethodSignatureForSelector:',
+  'instancesRespondToSelector:',
+  'isSubclassOfClass:',
+  'load',
+  'mutableCopyWithZone:',
+  'poseAsClass:',
+  'resolveClassMethod:',
+  'resolveInstanceMethod:',
+  'setVersion:',
+  'superclass',
+  'version',
+};
+
+final _logger = Logger('ffigen.code_generator.objc_interface');
+
+class ObjCInterface extends BindingType {
+  ObjCInterface? superType;
+  final methods = <String, ObjCMethod>{};
+  bool filled = false;
+
+  final String lookupName;
+  final ObjCBuiltInFunctions builtInFunctions;
+  late final ObjCInternalGlobal _classObject;
+  late final ObjCInternalGlobal _isKindOfClass;
+  late final ObjCMsgSendFunc _isKindOfClassMsgSend;
+
+  ObjCInterface({
+    super.usr,
+    required String super.originalName,
+    String? name,
+    String? lookupName,
+    super.dartDoc,
+    required this.builtInFunctions,
+  })  : lookupName = lookupName ?? originalName,
+        super(
+          name: name ?? originalName,
+        ) {
+    builtInFunctions.registerInterface(this);
+  }
+
+  bool get isNSString => originalName == "NSString";
+  bool get isNSData => originalName == "NSData";
+
+  @override
+  BindingString toBindingString(Writer w) {
+    String paramsToString(List<ObjCMethodParam> params,
+        {required bool isStatic}) {
+      final List<String> stringParams = [];
+
+      if (isStatic) {
+        stringParams.add('${w.className} _lib');
+      }
+      stringParams.addAll(
+          params.map((p) => '${_getConvertedType(p.type, w, name)} ${p.name}'));
+      return '(${stringParams.join(", ")})';
+    }
+
+    final s = StringBuffer();
+    if (dartDoc != null) {
+      s.write(makeDartDoc(dartDoc!));
+    }
+
+    final uniqueNamer = UniqueNamer({name, '_id', '_lib'});
+    final natLib = w.className;
+
+    builtInFunctions.ensureUtilsExist(w, s);
+    final objType = PointerType(objCObjectType).getCType(w);
+
+    // Class declaration.
+    s.write('''
+class $name extends ${superType?.name ?? '_ObjCWrapper'} {
+  $name._($objType id, $natLib lib,
+      {bool retain = false, bool release = false}) :
+          super._(id, lib, retain: retain, release: release);
+
+  /// Returns a [$name] that points to the same underlying object as [other].
+  static $name castFrom<T extends _ObjCWrapper>(T other) {
+    return $name._(other._id, other._lib, retain: true, release: true);
+  }
+
+  /// Returns a [$name] that wraps the given raw object pointer.
+  static $name castFromPointer($natLib lib, $objType other,
+      {bool retain = false, bool release = false}) {
+    return $name._(other, lib, retain: retain, release: release);
+  }
+
+  /// Returns whether [obj] is an instance of [$name].
+  static bool isInstance(_ObjCWrapper obj) {
+    return obj._lib.${_isKindOfClassMsgSend.name}(
+        obj._id, obj._lib.${_isKindOfClass.name},
+        obj._lib.${_classObject.name});
+  }
+
+''');
+
+    if (isNSString) {
+      builtInFunctions.generateNSStringUtils(w, s);
+    }
+
+    // Methods.
+    for (final m in methods.values) {
+      final methodName = m._getDartMethodName(uniqueNamer);
+      final isStatic = m.isClass;
+      final isStret = m.msgSend!.isStret;
+
+      var returnType = m.returnType;
+      var params = m.params;
+      if (isStret) {
+        params = [ObjCMethodParam(PointerType(returnType), 'stret'), ...params];
+        returnType = voidType;
+      }
+
+      // The method declaration.
+      if (m.dartDoc != null) {
+        s.write(makeDartDoc(m.dartDoc!));
+      }
+
+      s.write('  ');
+      if (isStatic) {
+        s.write('static ');
+        s.write(_getConvertedType(returnType, w, name));
+
+        switch (m.kind) {
+          case ObjCMethodKind.method:
+            // static returnType methodName(NativeLibrary _lib, ...)
+            s.write(' $methodName');
+            break;
+          case ObjCMethodKind.propertyGetter:
+            // static returnType getMethodName(NativeLibrary _lib)
+            s.write(' get');
+            s.write(methodName[0].toUpperCase() + methodName.substring(1));
+            break;
+          case ObjCMethodKind.propertySetter:
+            // static void setMethodName(NativeLibrary _lib, ...)
+            s.write(' set');
+            s.write(methodName[0].toUpperCase() + methodName.substring(1));
+            break;
+        }
+        s.write(paramsToString(params, isStatic: true));
+      } else {
+        if (superType?.methods[m.originalName]?.sameAs(m) ?? false) {
+          s.write('@override\n  ');
+        }
+        switch (m.kind) {
+          case ObjCMethodKind.method:
+            // returnType methodName(...)
+            s.write(_getConvertedType(returnType, w, name));
+            s.write(' $methodName');
+            s.write(paramsToString(params, isStatic: false));
+            break;
+          case ObjCMethodKind.propertyGetter:
+            s.write(_getConvertedType(returnType, w, name));
+            if (isStret) {
+              // void getMethodName(Pointer<returnType> stret, NativeLibrary _lib)
+              s.write(' get');
+              s.write(methodName[0].toUpperCase() + methodName.substring(1));
+              s.write(paramsToString(params, isStatic: false));
+            } else {
+              // returnType get methodName
+              s.write(' get $methodName');
+            }
+            break;
+          case ObjCMethodKind.propertySetter:
+            // set methodName(...)
+            s.write(' set $methodName');
+            s.write(paramsToString(params, isStatic: false));
+            break;
+        }
+      }
+
+      s.write(' {\n');
+
+      // Implementation.
+      final convertReturn = m.kind != ObjCMethodKind.propertySetter &&
+          _needsConverting(returnType);
+
+      if (returnType != voidType) {
+        s.write('    ${convertReturn ? 'final _ret = ' : 'return '}');
+      }
+      s.write('_lib.${m.msgSend!.name}(');
+      if (isStret) {
+        s.write('stret, ');
+      }
+      s.write(isStatic ? '_lib.${_classObject.name}' : '_id');
+      s.write(', _lib.${m.selObject!.name}');
+      for (final p in m.params) {
+        final convertedParam =
+            p.type.convertDartTypeToFfiDartType(w, p.name, objCRetain: false);
+        s.write(', $convertedParam');
+      }
+      s.write(');\n');
+      if (convertReturn) {
+        final result = returnType.convertFfiDartTypeToDartType(
+          w,
+          '_ret',
+          '_lib',
+          objCRetain: !m.isOwnedReturn,
+          objCEnclosingClass: name,
+        );
+        s.write('    return $result;');
+      }
+
+      s.write('  }\n\n');
+    }
+
+    s.write('}\n\n');
+
+    if (isNSString) {
+      builtInFunctions.generateStringUtils(w, s);
+    }
+
+    return BindingString(
+        type: BindingStringType.objcInterface, string: s.toString());
+  }
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    if (dependencies.contains(this)) return;
+    dependencies.add(this);
+    builtInFunctions.addDependencies(dependencies);
+
+    _classObject = ObjCInternalGlobal(
+        '_class_$originalName',
+        (Writer w) => '${builtInFunctions.getClass.name}("$lookupName")',
+        builtInFunctions.getClass)
+      ..addDependencies(dependencies);
+    _isKindOfClass = builtInFunctions.getSelObject('isKindOfClass:');
+    _isKindOfClassMsgSend = builtInFunctions.getMsgSendFunc(
+        BooleanType(), [ObjCMethodParam(PointerType(objCObjectType), 'clazz')]);
+
+    if (isNSString) {
+      _addNSStringMethods();
+    }
+
+    if (isNSData) {
+      _addNSDataMethods();
+    }
+
+    if (superType != null) {
+      superType!.addDependencies(dependencies);
+      _copyMethodsFromSuperType();
+      _fixNullabilityOfOverriddenMethods();
+    }
+
+    for (final m in methods.values) {
+      m.addDependencies(dependencies, builtInFunctions);
+    }
+  }
+
+  void _copyMethodsFromSuperType() {
+    // We need to copy certain methods from the super type:
+    //  - Class methods, because Dart classes don't inherit static methods.
+    //  - Methods that return instancetype, because the subclass's copy of the
+    //    method needs to return the subclass, not the super class.
+    //    Note: instancetype is only allowed as a return type, not an arg type.
+    for (final m in superType!.methods.values) {
+      if (m.isClass &&
+          !_excludedNSObjectClassMethods.contains(m.originalName)) {
+        addMethod(m);
+      } else if (_isInstanceType(m.returnType)) {
+        addMethod(m);
+      }
+    }
+  }
+
+  void _fixNullabilityOfOverriddenMethods() {
+    // ObjC ignores nullability when deciding if an override for an inherited
+    // method is valid. But in Dart it's invalid to override a method and change
+    // it's return type from non-null to nullable, or its arg type from nullable
+    // to non-null. So in these cases we have to make the non-null type
+    // nullable, to avoid Dart compile errors.
+    var superType_ = superType;
+    while (superType_ != null) {
+      for (final method in methods.values) {
+        final superMethod = superType_.methods[method.originalName];
+        if (superMethod != null && !superMethod.isClass && !method.isClass) {
+          if (superMethod.returnType.typealiasType is! ObjCNullable &&
+              method.returnType.typealiasType is ObjCNullable) {
+            superMethod.returnType = ObjCNullable(superMethod.returnType);
+          }
+          final numArgs = method.params.length < superMethod.params.length
+              ? method.params.length
+              : superMethod.params.length;
+          for (int i = 0; i < numArgs; ++i) {
+            final param = method.params[i];
+            final superParam = superMethod.params[i];
+            if (superParam.type.typealiasType is ObjCNullable &&
+                param.type.typealiasType is! ObjCNullable) {
+              param.type = ObjCNullable(param.type);
+            }
+          }
+        }
+      }
+      superType_ = superType_.superType;
+    }
+  }
+
+  static bool _isInstanceType(Type type) {
+    if (type is ObjCInstanceType) return true;
+    final baseType = type.typealiasType;
+    return baseType is ObjCNullable && baseType.child is ObjCInstanceType;
+  }
+
+  void addMethod(ObjCMethod method) {
+    final oldMethod = methods[method.originalName];
+    if (oldMethod != null) {
+      // Typically we ignore duplicate methods. However, property setters and
+      // getters are duplicated in the AST. One copy is marked with
+      // ObjCMethodKind.propertyGetter/Setter. The other copy is missing
+      // important information, and is a plain old instanceMethod. So if the
+      // existing method is an instanceMethod, and the new one is a property,
+      // override it.
+      if (method.isProperty && !oldMethod.isProperty) {
+        // Fallthrough.
+      } else if (!method.isProperty && oldMethod.isProperty) {
+        // Don't override, but also skip the same method check below.
+        return;
+      } else {
+        // Check duplicate is the same method.
+        if (!method.sameAs(oldMethod)) {
+          _logger.severe('Duplicate methods with different signatures: '
+              '$originalName.${method.originalName}');
+        }
+        return;
+      }
+    }
+    methods[method.originalName] = method;
+  }
+
+  void _addNSStringMethods() {
+    addMethod(ObjCMethod(
+      originalName: 'stringWithCharacters:length:',
+      kind: ObjCMethodKind.method,
+      isClass: true,
+      returnType: this,
+      params_: [
+        ObjCMethodParam(PointerType(wCharType), 'characters'),
+        ObjCMethodParam(unsignedIntType, 'length'),
+      ],
+    ));
+    addMethod(ObjCMethod(
+      originalName: 'dataUsingEncoding:',
+      kind: ObjCMethodKind.method,
+      isClass: false,
+      returnType: builtInFunctions.nsData,
+      params_: [
+        ObjCMethodParam(unsignedIntType, 'encoding'),
+      ],
+    ));
+    addMethod(ObjCMethod(
+      originalName: 'length',
+      kind: ObjCMethodKind.propertyGetter,
+      isClass: false,
+      returnType: unsignedIntType,
+      params_: [],
+    ));
+  }
+
+  void _addNSDataMethods() {
+    addMethod(ObjCMethod(
+      originalName: 'bytes',
+      kind: ObjCMethodKind.propertyGetter,
+      isClass: false,
+      returnType: PointerType(voidType),
+      params_: [],
+    ));
+  }
+
+  @override
+  String getCType(Writer w) => PointerType(objCObjectType).getCType(w);
+
+  @override
+  String getDartType(Writer w) => name;
+
+  @override
+  bool get sameFfiDartAndCType => true;
+
+  @override
+  bool get sameDartAndCType => false;
+
+  @override
+  bool get sameDartAndFfiDartType => false;
+
+  @override
+  String convertDartTypeToFfiDartType(
+    Writer w,
+    String value, {
+    required bool objCRetain,
+  }) =>
+      ObjCInterface.generateGetId(value, objCRetain);
+
+  static String generateGetId(String value, bool objCRetain) =>
+      objCRetain ? '$value._retainAndReturnId()' : '$value._id';
+
+  @override
+  String convertFfiDartTypeToDartType(
+    Writer w,
+    String value,
+    String library, {
+    required bool objCRetain,
+    String? objCEnclosingClass,
+  }) =>
+      ObjCInterface.generateConstructor(name, value, library, objCRetain);
+
+  static String generateConstructor(
+    String className,
+    String value,
+    String library,
+    bool objCRetain,
+  ) {
+    final ownershipFlags = 'retain: $objCRetain, release: true';
+    return '$className._($value, $library, $ownershipFlags)';
+  }
+
+  // Utils for converting between the internal types passed to native code, and
+  // the external types visible to the user. For example, ObjCInterfaces are
+  // passed to native as Pointer<ObjCObject>, but the user sees the Dart wrapper
+  // class. These methods need to be kept in sync.
+  bool _needsConverting(Type type) =>
+      type is ObjCInstanceType ||
+      type.typealiasType is ObjCInterface ||
+      type.typealiasType is ObjCBlock ||
+      type.typealiasType is ObjCObjectPointer ||
+      type.typealiasType is ObjCNullable;
+
+  String _getConvertedType(Type type, Writer w, String enclosingClass) {
+    if (type is ObjCInstanceType) return enclosingClass;
+    final baseType = type.typealiasType;
+    if (baseType is ObjCNullable && baseType.child is ObjCInstanceType) {
+      return '$enclosingClass?';
+    }
+    return type.getDartType(w);
+  }
+}
+
+enum ObjCMethodKind {
+  method,
+  propertyGetter,
+  propertySetter,
+}
+
+class ObjCProperty {
+  final String originalName;
+  String? dartName;
+
+  ObjCProperty(this.originalName);
+}
+
+class ObjCMethod {
+  final String? dartDoc;
+  final String originalName;
+  final ObjCProperty? property;
+  Type returnType;
+  final List<ObjCMethodParam> params;
+  final ObjCMethodKind kind;
+  final bool isClass;
+  bool returnsRetained = false;
+  ObjCInternalGlobal? selObject;
+  ObjCMsgSendFunc? msgSend;
+
+  ObjCMethod({
+    required this.originalName,
+    this.property,
+    this.dartDoc,
+    required this.kind,
+    required this.isClass,
+    required this.returnType,
+    List<ObjCMethodParam>? params_,
+  }) : params = params_ ?? [];
+
+  bool get isProperty =>
+      kind == ObjCMethodKind.propertyGetter ||
+      kind == ObjCMethodKind.propertySetter;
+
+  void addDependencies(
+      Set<Binding> dependencies, ObjCBuiltInFunctions builtInFunctions) {
+    returnType.addDependencies(dependencies);
+    for (final p in params) {
+      p.type.addDependencies(dependencies);
+    }
+    selObject ??= builtInFunctions.getSelObject(originalName)
+      ..addDependencies(dependencies);
+    msgSend ??= builtInFunctions.getMsgSendFunc(returnType, params)
+      ..addDependencies(dependencies);
+  }
+
+  String _getDartMethodName(UniqueNamer uniqueNamer) {
+    if (property != null) {
+      // A getter and a setter are allowed to have the same name, so we can't
+      // just run the name through uniqueNamer. Instead they need to share
+      // the dartName, which is run through uniqueNamer.
+      if (property!.dartName == null) {
+        property!.dartName = uniqueNamer.makeUnique(property!.originalName);
+      }
+      return property!.dartName!;
+    }
+    // Objective C methods can look like:
+    // foo
+    // foo:
+    // foo:someArgName:
+    // So replace all ':' with '_'.
+    return uniqueNamer.makeUnique(originalName.replaceAll(":", "_"));
+  }
+
+  bool sameAs(ObjCMethod other) {
+    if (originalName != other.originalName) return false;
+    if (kind != other.kind) return false;
+    if (isClass != other.isClass) return false;
+    // msgSend is deduped by signature, so this check covers the signature.
+    return msgSend == other.msgSend;
+  }
+
+  static final _copyRegExp = RegExp('[cC]opy');
+  bool get isOwnedReturn =>
+      returnsRetained ||
+      originalName.startsWith('new') ||
+      originalName.startsWith('alloc') ||
+      originalName.contains(_copyRegExp);
+
+  @override
+  String toString() => '$returnType $originalName(${params.join(', ')})';
+}
+
+class ObjCMethodParam {
+  Type type;
+  final String name;
+  ObjCMethodParam(this.type, this.name);
+
+  @override
+  String toString() => '$type $name';
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_nullable.dart b/pkgs/ffigen/lib/src/code_generator/objc_nullable.dart
new file mode 100644
index 0000000..f3c0b87
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/objc_nullable.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+
+import 'writer.dart';
+
+/// An ObjC type annotated with nullable. Eg:
+/// +(nullable NSObject*) methodWithNullableResult;
+class ObjCNullable extends Type {
+  Type child;
+
+  ObjCNullable(this.child) {
+    assert(isSupported(child));
+  }
+
+  static bool isSupported(Type type) =>
+      type is ObjCInterface ||
+      type is ObjCBlock ||
+      type is ObjCObjectPointer ||
+      type is ObjCInstanceType;
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    child.addDependencies(dependencies);
+  }
+
+  @override
+  Type get baseType => child.baseType;
+
+  @override
+  String getCType(Writer w) => child.getCType(w);
+
+  @override
+  String getFfiDartType(Writer w) => child.getFfiDartType(w);
+
+  @override
+  String getDartType(Writer w) => '${child.getDartType(w)}?';
+
+  @override
+  bool get sameFfiDartAndCType => child.sameFfiDartAndCType;
+
+  @override
+  bool get sameDartAndCType => false;
+
+  @override
+  bool get sameDartAndFfiDartType => false;
+
+  @override
+  String convertDartTypeToFfiDartType(
+    Writer w,
+    String value, {
+    required bool objCRetain,
+  }) {
+    // This is a bit of a hack, but works for all the types that are allowed to
+    // be a child type. If we add more allowed child types, we may have to start
+    // special casing each type. Turns value._id into value?._id ?? nullptr.
+    final convertedValue = child.convertDartTypeToFfiDartType(w, '$value?',
+        objCRetain: objCRetain);
+    return '$convertedValue ?? ${w.ffiLibraryPrefix}.nullptr';
+  }
+
+  @override
+  String convertFfiDartTypeToDartType(
+    Writer w,
+    String value,
+    String library, {
+    required bool objCRetain,
+    String? objCEnclosingClass,
+  }) {
+    // All currently supported child types have a Pointer as their FfiDartType.
+    final convertedValue = child.convertFfiDartTypeToDartType(
+      w,
+      value,
+      library,
+      objCRetain: objCRetain,
+      objCEnclosingClass: objCEnclosingClass,
+    );
+    return '$value.address == 0 ? null : $convertedValue';
+  }
+
+  @override
+  String toString() => '$child?';
+
+  @override
+  String cacheKey() => '${child.cacheKey()}?';
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/pointer.dart b/pkgs/ffigen/lib/src/code_generator/pointer.dart
new file mode 100644
index 0000000..30e2e6b
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/pointer.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+
+import 'writer.dart';
+
+/// Represents a pointer.
+class PointerType extends Type {
+  final Type child;
+
+  PointerType._(this.child);
+
+  factory PointerType(Type child) {
+    if (child == objCObjectType) {
+      return ObjCObjectPointer();
+    }
+    return PointerType._(child);
+  }
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    child.addDependencies(dependencies);
+  }
+
+  @override
+  Type get baseType => child.baseType;
+
+  @override
+  String getCType(Writer w) =>
+      '${w.ffiLibraryPrefix}.Pointer<${child.getCType(w)}>';
+
+  // Both the C type and the FFI Dart type are 'Pointer<$cType>'.
+  @override
+  bool get sameFfiDartAndCType => true;
+
+  @override
+  String toString() => '$child*';
+
+  @override
+  String cacheKey() => '${child.cacheKey()}*';
+}
+
+/// Represents a constant array, which has a fixed size.
+class ConstantArray extends PointerType {
+  final int length;
+  ConstantArray(this.length, Type child) : super._(child);
+
+  @override
+  Type get baseArrayType => child.baseArrayType;
+
+  @override
+  bool get isIncompleteCompound => baseArrayType.isIncompleteCompound;
+
+  @override
+  String toString() => '$child[$length]';
+
+  @override
+  String cacheKey() => '${child.cacheKey()}[$length]';
+}
+
+/// Represents an incomplete array, which has an unknown size.
+class IncompleteArray extends PointerType {
+  IncompleteArray(super.child) : super._();
+
+  @override
+  Type get baseArrayType => child.baseArrayType;
+
+  @override
+  String toString() => '$child[]';
+
+  @override
+  String cacheKey() => '${child.cacheKey()}[]';
+}
+
+/// A pointer to an NSObject.
+class ObjCObjectPointer extends PointerType {
+  factory ObjCObjectPointer() => _inst;
+
+  static final _inst = ObjCObjectPointer._();
+  ObjCObjectPointer._() : super._(objCObjectType);
+
+  @override
+  String getDartType(Writer w) => 'NSObject';
+
+  @override
+  bool get sameDartAndCType => false;
+
+  @override
+  bool get sameDartAndFfiDartType => false;
+
+  @override
+  String convertDartTypeToFfiDartType(
+    Writer w,
+    String value, {
+    required bool objCRetain,
+  }) =>
+      ObjCInterface.generateGetId(value, objCRetain);
+
+  @override
+  String convertFfiDartTypeToDartType(
+    Writer w,
+    String value,
+    String library, {
+    required bool objCRetain,
+    String? objCEnclosingClass,
+  }) =>
+      ObjCInterface.generateConstructor('NSObject', value, library, objCRetain);
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/struct.dart b/pkgs/ffigen/lib/src/code_generator/struct.dart
new file mode 100644
index 0000000..7a95d67
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/struct.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator/compound.dart';
+
+/// A binding for C Struct.
+///
+/// For a C structure -
+/// ```c
+/// struct C {
+///   int a;
+///   double b;
+///   int c;
+/// };
+/// ```
+/// The generated dart code is -
+/// ```dart
+/// final class Struct extends ffi.Struct {
+///  @ffi.Int32()
+///  int a;
+///
+///  @ffi.Double()
+///  double b;
+///
+///  @ffi.Uint8()
+///  int c;
+///
+/// }
+/// ```
+class Struct extends Compound {
+  Struct({
+    super.usr,
+    super.originalName,
+    required super.name,
+    super.isIncomplete,
+    super.pack,
+    super.dartDoc,
+    super.members,
+    super.isInternal,
+  }) : super(compoundType: CompoundType.struct);
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/type.dart b/pkgs/ffigen/lib/src/code_generator/type.dart
new file mode 100644
index 0000000..c1d1e22
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/type.dart
@@ -0,0 +1,186 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+
+import 'writer.dart';
+
+/// Type class for return types, variable types, etc.
+///
+/// Implementers should extend either Type, or BindingType if the type is also a
+/// binding, and override at least getCType and toString.
+abstract class Type {
+  const Type();
+
+  /// Get all dependencies of this type and save them in [dependencies].
+  void addDependencies(Set<Binding> dependencies) {}
+
+  /// Get base type for any type.
+  ///
+  /// E.g int** has base [Type] of int.
+  /// double[2][3] has base [Type] of double.
+  Type get baseType => this;
+
+  /// Get base Array type.
+  ///
+  /// Returns itself if it's not an Array Type.
+  Type get baseArrayType => this;
+
+  /// Get base typealias type.
+  ///
+  /// Returns itself if it's not a Typealias.
+  Type get typealiasType => this;
+
+  /// Returns true if the type is a [Compound] and is incomplete.
+  bool get isIncompleteCompound => false;
+
+  /// Returns the C type of the Type. This is the FFI compatible type that is
+  /// passed to native code.
+  String getCType(Writer w) => throw 'No mapping for type: $this';
+
+  /// Returns the Dart type of the Type. This is the type that is passed from
+  /// FFI to Dart code.
+  String getFfiDartType(Writer w) => getCType(w);
+
+  /// Returns the user type of the Type. This is the type that is presented to
+  /// users by the ffigened API to users. For C bindings this is always the same
+  /// as getFfiDartType. For ObjC bindings this refers to the wrapper object.
+  String getDartType(Writer w) => getFfiDartType(w);
+
+  /// Returns whether the FFI dart type and C type string are same.
+  bool get sameFfiDartAndCType;
+
+  /// Returns whether the dart type and C type string are same.
+  bool get sameDartAndCType => sameFfiDartAndCType;
+
+  /// Returns whether the dart type and FFI dart type string are same.
+  bool get sameDartAndFfiDartType => true;
+
+  /// Returns generated Dart code that converts the given value from its
+  /// DartType to its FfiDartType.
+  ///
+  /// [value] is the value to be converted. If [objCRetain] is true, the ObjC
+  /// object will be reained (ref count incremented) during conversion.
+  String convertDartTypeToFfiDartType(
+    Writer w,
+    String value, {
+    required bool objCRetain,
+  }) =>
+      value;
+
+  /// Returns generated Dart code that converts the given value from its
+  /// FfiDartType to its DartType.
+  ///
+  /// [value] is the value to be converted, and [library] is an instance of the
+  /// native library object. If [objCRetain] is true, the ObjC wrapper object
+  /// will retain (ref count increment) the wrapped object pointer. If this
+  /// conversion is occuring in the context of an ObjC class, then
+  /// [objCEnclosingClass] should be the name of the Dart wrapper class (this is
+  /// used by instancetype).
+  String convertFfiDartTypeToDartType(
+    Writer w,
+    String value,
+    String library, {
+    required bool objCRetain,
+    String? objCEnclosingClass,
+  }) =>
+      value;
+
+  /// Returns a human readable string representation of the Type. This is mostly
+  /// just for debugging, but it may also be used for non-functional code (eg to
+  /// name a variable or type in generated code).
+  @override
+  String toString();
+
+  /// Cache key used in various places to dedupe Types. By default this is just
+  /// the hash of the Type, but in many cases this does not dedupe sufficiently.
+  /// So Types that may be duplicated should override this to return a more
+  /// specific key. Types that are already deduped don't need to override this.
+  /// toString() is not a valid cache key as there may be name collisions.
+  String cacheKey() => hashCode.toRadixString(36);
+
+  /// Returns a string of code that creates a default value for this type. For
+  /// example, for int types this returns the string '0'. A null return means
+  /// that default values aren't supported for this type, eg void.
+  String? getDefaultValue(Writer w, String nativeLib) => null;
+}
+
+/// Base class for all Type bindings.
+///
+/// Since Dart doesn't have multiple inheritance, this type exists so that we
+/// don't have to reimplement the default methods in all the classes that want
+/// to extend both NoLookUpBinding and Type.
+abstract class BindingType extends NoLookUpBinding implements Type {
+  BindingType({
+    super.usr,
+    super.originalName,
+    required super.name,
+    super.dartDoc,
+    super.isInternal,
+  });
+
+  @override
+  Type get baseType => this;
+
+  @override
+  Type get baseArrayType => this;
+
+  @override
+  Type get typealiasType => this;
+
+  @override
+  bool get isIncompleteCompound => false;
+
+  @override
+  String getFfiDartType(Writer w) => getCType(w);
+
+  @override
+  String getDartType(Writer w) => getFfiDartType(w);
+
+  @override
+  bool get sameDartAndCType => sameFfiDartAndCType;
+
+  @override
+  bool get sameDartAndFfiDartType => true;
+
+  @override
+  String convertDartTypeToFfiDartType(
+    Writer w,
+    String value, {
+    required bool objCRetain,
+  }) =>
+      value;
+
+  @override
+  String convertFfiDartTypeToDartType(
+    Writer w,
+    String value,
+    String library, {
+    required bool objCRetain,
+    String? objCEnclosingClass,
+  }) =>
+      value;
+
+  @override
+  String toString() => originalName;
+
+  @override
+  String cacheKey() => hashCode.toRadixString(36);
+
+  @override
+  String? getDefaultValue(Writer w, String nativeLib) => null;
+}
+
+/// Represents an unimplemented type. Used as a marker, so that declarations
+/// having these can exclude them.
+class UnimplementedType extends Type {
+  String reason;
+  UnimplementedType(this.reason);
+
+  @override
+  String toString() => '(Unimplemented: $reason)';
+
+  @override
+  bool get sameFfiDartAndCType => true;
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/typealias.dart b/pkgs/ffigen/lib/src/code_generator/typealias.dart
new file mode 100644
index 0000000..e31d148
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/typealias.dart
@@ -0,0 +1,232 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+
+import '../strings.dart' as strings;
+import 'binding_string.dart';
+import 'utils.dart';
+import 'writer.dart';
+
+/// A simple Typealias, Expands to -
+///
+/// ```dart
+/// typedef $name = $type;
+/// );
+/// ```
+class Typealias extends BindingType {
+  final Type type;
+  String? _ffiDartAliasName;
+  String? _dartAliasName;
+
+  /// Creates a Typealias.
+  ///
+  /// If [genFfiDartType] is true, a binding is generated for the Ffi Dart type
+  /// in addition to the C type. See [Type.getFfiDartType].
+  factory Typealias({
+    String? usr,
+    String? originalName,
+    String? dartDoc,
+    required String name,
+    required Type type,
+    bool genFfiDartType = false,
+    bool isInternal = false,
+  }) {
+    final funcType = _getFunctionTypeFromPointer(type);
+    if (funcType != null) {
+      type = PointerType(NativeFunc(Typealias._(
+        name: '${name}Function',
+        type: funcType,
+        genFfiDartType: genFfiDartType,
+        isInternal: isInternal,
+      )));
+    }
+    if ((originalName ?? name) == strings.objcInstanceType &&
+        type is ObjCObjectPointer) {
+      return ObjCInstanceType._(
+        usr: usr,
+        originalName: originalName,
+        dartDoc: dartDoc,
+        name: name,
+        type: type,
+        genFfiDartType: genFfiDartType,
+        isInternal: isInternal,
+      );
+    }
+    return Typealias._(
+      usr: usr,
+      originalName: originalName,
+      dartDoc: dartDoc,
+      name: name,
+      type: type,
+      genFfiDartType: genFfiDartType,
+      isInternal: isInternal,
+    );
+  }
+
+  Typealias._({
+    super.usr,
+    super.originalName,
+    super.dartDoc,
+    required String name,
+    required this.type,
+    bool genFfiDartType = false,
+    super.isInternal,
+  })  : _ffiDartAliasName = genFfiDartType ? 'Dart$name' : null,
+        _dartAliasName =
+            (!genFfiDartType && type is! Typealias && !type.sameDartAndCType)
+                ? 'Dart$name'
+                : null,
+        super(
+          name: genFfiDartType ? 'Native$name' : name,
+        );
+
+  @override
+  void addDependencies(Set<Binding> dependencies) {
+    if (dependencies.contains(this)) return;
+
+    dependencies.add(this);
+    type.addDependencies(dependencies);
+  }
+
+  static FunctionType? _getFunctionTypeFromPointer(Type type) {
+    if (type is! PointerType) return null;
+    final pointee = type.child;
+    if (pointee is! NativeFunc) return null;
+    return pointee.type;
+  }
+
+  @override
+  BindingString toBindingString(Writer w) {
+    if (_ffiDartAliasName != null) {
+      _ffiDartAliasName = w.topLevelUniqueNamer.makeUnique(_ffiDartAliasName!);
+    }
+    if (_dartAliasName != null) {
+      _dartAliasName = w.topLevelUniqueNamer.makeUnique(_dartAliasName!);
+    }
+
+    final sb = StringBuffer();
+    if (dartDoc != null) {
+      sb.write(makeDartDoc(dartDoc!));
+    }
+    sb.write('typedef $name = ${type.getCType(w)};\n');
+    if (_ffiDartAliasName != null) {
+      sb.write('typedef $_ffiDartAliasName = ${type.getFfiDartType(w)};\n');
+    }
+    if (_dartAliasName != null) {
+      sb.write('typedef $_dartAliasName = ${type.getDartType(w)};\n');
+    }
+    return BindingString(
+        type: BindingStringType.typeDef, string: sb.toString());
+  }
+
+  @override
+  Type get typealiasType => type.typealiasType;
+
+  @override
+  bool get isIncompleteCompound => type.isIncompleteCompound;
+
+  @override
+  String getCType(Writer w) => name;
+
+  @override
+  String getFfiDartType(Writer w) {
+    if (_ffiDartAliasName != null) {
+      return _ffiDartAliasName!;
+    } else if (type.sameFfiDartAndCType) {
+      return name;
+    } else {
+      return type.getFfiDartType(w);
+    }
+  }
+
+  @override
+  String getDartType(Writer w) {
+    if (_dartAliasName != null) {
+      return _dartAliasName!;
+    } else if (type.sameDartAndCType) {
+      return getFfiDartType(w);
+    } else {
+      return type.getDartType(w);
+    }
+  }
+
+  @override
+  bool get sameFfiDartAndCType => type.sameFfiDartAndCType;
+
+  @override
+  bool get sameDartAndCType => type.sameDartAndCType;
+
+  @override
+  bool get sameDartAndFfiDartType => type.sameDartAndFfiDartType;
+
+  @override
+  String convertDartTypeToFfiDartType(
+    Writer w,
+    String value, {
+    required bool objCRetain,
+  }) =>
+      type.convertDartTypeToFfiDartType(w, value, objCRetain: objCRetain);
+
+  @override
+  String convertFfiDartTypeToDartType(
+    Writer w,
+    String value,
+    String library, {
+    required bool objCRetain,
+    String? objCEnclosingClass,
+  }) =>
+      type.convertFfiDartTypeToDartType(
+        w,
+        value,
+        library,
+        objCRetain: objCRetain,
+        objCEnclosingClass: objCEnclosingClass,
+      );
+
+  @override
+  String cacheKey() => type.cacheKey();
+
+  @override
+  String? getDefaultValue(Writer w, String nativeLib) =>
+      type.getDefaultValue(w, nativeLib);
+}
+
+/// Objective C's instancetype.
+///
+/// This is an alias for an NSObject* that is special cased in code generation.
+/// It's only valid as the return type of a method, and always appears as the
+/// enclosing class's type, even in inherited methods.
+class ObjCInstanceType extends Typealias {
+  ObjCInstanceType._({
+    super.usr,
+    super.originalName,
+    super.dartDoc,
+    required super.name,
+    required super.type,
+    super.genFfiDartType,
+    super.isInternal,
+  }) : super._();
+
+  @override
+  String convertDartTypeToFfiDartType(
+    Writer w,
+    String value, {
+    required bool objCRetain,
+  }) =>
+      ObjCInterface.generateGetId(value, objCRetain);
+
+  @override
+  String convertFfiDartTypeToDartType(
+    Writer w,
+    String value,
+    String library, {
+    required bool objCRetain,
+    String? objCEnclosingClass,
+  }) =>
+      // objCEnclosingClass must be present, because instancetype can only
+      // occur inside a class.
+      ObjCInterface.generateConstructor(
+          objCEnclosingClass!, value, library, objCRetain);
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/union.dart b/pkgs/ffigen/lib/src/code_generator/union.dart
new file mode 100644
index 0000000..65d9afb
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/union.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator/compound.dart';
+
+/// A binding for a C union -
+///
+/// ```c
+/// union C {
+///   int a;
+///   double b;
+///   float c;
+/// };
+/// ```
+/// The generated dart code is -
+/// ```dart
+/// final class Union extends ffi.Union{
+///  @ffi.Int32()
+///  int a;
+///
+///  @ffi.Double()
+///  double b;
+///
+///  @ffi.Float()
+///  float c;
+///
+/// }
+/// ```
+class Union extends Compound {
+  Union({
+    super.usr,
+    super.originalName,
+    required super.name,
+    super.isIncomplete,
+    super.pack,
+    super.dartDoc,
+    super.members,
+  }) : super(compoundType: CompoundType.union);
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/utils.dart b/pkgs/ffigen/lib/src/code_generator/utils.dart
new file mode 100644
index 0000000..5c18c7f
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/utils.dart
@@ -0,0 +1,77 @@
+import 'dart_keywords.dart';
+
+class UniqueNamer {
+  final Set<String> _usedUpNames;
+
+  /// Creates a UniqueNamer with given [usedUpNames] and Dart reserved keywords.
+  UniqueNamer(Set<String> usedUpNames)
+      : assert(keywords.intersection(usedUpNames).isEmpty),
+        _usedUpNames = {...keywords, ...usedUpNames};
+
+  /// Creates a UniqueNamer with given [usedUpNames] only.
+  UniqueNamer._raw(this._usedUpNames);
+
+  /// Returns a unique name by appending `<int>` to it if necessary.
+  ///
+  /// Adds the resulting name to the used names by default.
+  String makeUnique(String name, [bool addToUsedUpNames = true]) {
+    // For example, nested structures/unions may not have a name
+    if (name.isEmpty) {
+      name = 'unnamed';
+    }
+
+    var crName = name;
+    var i = 1;
+    while (_usedUpNames.contains(crName)) {
+      crName = '$name$i';
+      i++;
+    }
+    if (addToUsedUpNames) {
+      _usedUpNames.add(crName);
+    }
+    return crName;
+  }
+
+  /// Adds a name to used names.
+  ///
+  /// Note: [makeUnique] also adds the name by default.
+  void markUsed(String name) {
+    _usedUpNames.add(name);
+  }
+
+  /// Returns true if a name has been used before.
+  bool isUsed(String name) {
+    return _usedUpNames.contains(name);
+  }
+
+  /// Returns true if a name has not been used before.
+  bool isUnique(String name) {
+    return !_usedUpNames.contains(name);
+  }
+
+  UniqueNamer clone() => UniqueNamer._raw({..._usedUpNames});
+}
+
+/// Converts [text] to a dart doc comment(`///`).
+///
+/// Comment is split on new lines only.
+String makeDartDoc(String text) {
+  final s = StringBuffer();
+  s.write('/// ');
+  s.writeAll(text.split('\n'), '\n/// ');
+  s.write('\n');
+
+  return s.toString();
+}
+
+/// Converts [text] to a dart comment (`//`).
+///
+/// Comment is split on new lines only.
+String makeDoc(String text) {
+  final s = StringBuffer();
+  s.write('// ');
+  s.writeAll(text.split('\n'), '\n// ');
+  s.write('\n');
+
+  return s.toString();
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/writer.dart b/pkgs/ffigen/lib/src/code_generator/writer.dart
new file mode 100644
index 0000000..d20db66
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/writer.dart
@@ -0,0 +1,366 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/code_generator/utils.dart';
+import 'package:logging/logging.dart';
+
+import '../strings.dart' as strings;
+
+final _logger = Logger('ffigen.code_generator.writer');
+
+/// To store generated String bindings.
+class Writer {
+  final String? header;
+
+  /// Holds bindings, which lookup symbols.
+  final List<Binding> lookUpBindings;
+
+  /// Holds bindings, which lookup symbols through `FfiNative`.
+  final List<Binding> ffiNativeBindings;
+
+  /// Holds bindings which don't lookup symbols.
+  final List<Binding> noLookUpBindings;
+
+  /// Manages the `_SymbolAddress` class.
+  final symbolAddressWriter = SymbolAddressWriter();
+
+  late String _className;
+  String get className => _className;
+
+  final String? classDocComment;
+
+  String? _ffiLibraryPrefix;
+  String get ffiLibraryPrefix {
+    if (_ffiLibraryPrefix != null) {
+      return _ffiLibraryPrefix!;
+    }
+
+    final import = _usedImports.firstWhere(
+        (element) => element.name == ffiImport.name,
+        orElse: () => ffiImport);
+    _usedImports.add(import);
+    return _ffiLibraryPrefix = import.prefix;
+  }
+
+  String? _ffiPkgLibraryPrefix;
+  String get ffiPkgLibraryPrefix {
+    if (_ffiPkgLibraryPrefix != null) {
+      return _ffiPkgLibraryPrefix!;
+    }
+
+    final import = _usedImports.firstWhere(
+        (element) => element.name == ffiPkgImport.name,
+        orElse: () => ffiPkgImport);
+    _usedImports.add(import);
+    return _ffiPkgLibraryPrefix = import.prefix;
+  }
+
+  final Set<LibraryImport> _usedImports = {};
+
+  late String _lookupFuncIdentifier;
+  String get lookupFuncIdentifier => _lookupFuncIdentifier;
+
+  late String _symbolAddressClassName;
+  late String _symbolAddressVariableName;
+  late String _symbolAddressLibraryVarName;
+
+  /// Initial namers set after running constructor. Namers are reset to this
+  /// initial state everytime [generate] is called.
+  late UniqueNamer _initialTopLevelUniqueNamer, _initialWrapperLevelUniqueNamer;
+
+  /// Used by [Binding]s for generating required code.
+  late UniqueNamer _topLevelUniqueNamer, _wrapperLevelUniqueNamer;
+  UniqueNamer get topLevelUniqueNamer => _topLevelUniqueNamer;
+  UniqueNamer get wrapperLevelUniqueNamer => _wrapperLevelUniqueNamer;
+
+  late String _arrayHelperClassPrefix;
+
+  /// Guaranteed to be a unique prefix.
+  String get arrayHelperClassPrefix => _arrayHelperClassPrefix;
+
+  /// Set true after calling [generate]. Indicates if
+  /// [generateSymbolOutputYamlMap] can be called.
+  bool get canGenerateSymbolOutput => _canGenerateSymbolOutput;
+  bool _canGenerateSymbolOutput = false;
+
+  /// [_usedUpNames] should contain names of all the declarations which are
+  /// already used. This is used to avoid name collisions.
+  Writer({
+    required this.lookUpBindings,
+    required this.ffiNativeBindings,
+    required this.noLookUpBindings,
+    required String className,
+    Set<LibraryImport>? additionalImports,
+    this.classDocComment,
+    this.header,
+  }) {
+    final globalLevelNameSet = noLookUpBindings.map((e) => e.name).toSet();
+    final wrapperLevelNameSet = lookUpBindings.map((e) => e.name).toSet();
+    final allNameSet = <String>{}
+      ..addAll(globalLevelNameSet)
+      ..addAll(wrapperLevelNameSet);
+
+    _initialTopLevelUniqueNamer = UniqueNamer(globalLevelNameSet);
+    _initialWrapperLevelUniqueNamer = UniqueNamer(wrapperLevelNameSet);
+    final allLevelsUniqueNamer = UniqueNamer(allNameSet);
+
+    /// Wrapper class name must be unique among all names.
+    _className = _resolveNameConflict(
+      name: className,
+      makeUnique: allLevelsUniqueNamer,
+      markUsed: [_initialWrapperLevelUniqueNamer, _initialTopLevelUniqueNamer],
+    );
+
+    /// Library imports prefix should be unique unique among all names.
+    if (additionalImports != null) {
+      for (final lib in additionalImports) {
+        lib.prefix = _resolveNameConflict(
+          name: lib.prefix,
+          makeUnique: allLevelsUniqueNamer,
+          markUsed: [
+            _initialWrapperLevelUniqueNamer,
+            _initialTopLevelUniqueNamer
+          ],
+        );
+      }
+    }
+
+    /// [_lookupFuncIdentifier] should be unique in top level.
+    _lookupFuncIdentifier = _resolveNameConflict(
+      name: '_lookup',
+      makeUnique: _initialTopLevelUniqueNamer,
+      markUsed: [_initialTopLevelUniqueNamer],
+    );
+
+    /// Resolve name conflicts of identifiers used for SymbolAddresses.
+    _symbolAddressClassName = _resolveNameConflict(
+      name: '_SymbolAddresses',
+      makeUnique: allLevelsUniqueNamer,
+      markUsed: [_initialWrapperLevelUniqueNamer, _initialTopLevelUniqueNamer],
+    );
+    _symbolAddressVariableName = _resolveNameConflict(
+      name: 'addresses',
+      makeUnique: _initialWrapperLevelUniqueNamer,
+      markUsed: [_initialWrapperLevelUniqueNamer],
+    );
+    _symbolAddressLibraryVarName = _resolveNameConflict(
+      name: '_library',
+      makeUnique: _initialWrapperLevelUniqueNamer,
+      markUsed: [_initialWrapperLevelUniqueNamer],
+    );
+
+    /// Finding a unique prefix for Array Helper Classes and store into
+    /// [_arrayHelperClassPrefix].
+    final base = 'ArrayHelper';
+    _arrayHelperClassPrefix = base;
+    var suffixInt = 0;
+    for (var i = 0; i < allNameSet.length; i++) {
+      if (allNameSet.elementAt(i).startsWith(_arrayHelperClassPrefix)) {
+        // Not a unique prefix, start over with a new suffix.
+        i = -1;
+        suffixInt++;
+        _arrayHelperClassPrefix = '$base$suffixInt';
+      }
+    }
+
+    _resetUniqueNamersNamers();
+  }
+
+  /// Resolved name conflict using [makeUnique] and marks the result as used in
+  /// all [markUsed].
+  String _resolveNameConflict({
+    required String name,
+    required UniqueNamer makeUnique,
+    List<UniqueNamer> markUsed = const [],
+  }) {
+    final s = makeUnique.makeUnique(name);
+    for (final un in markUsed) {
+      un.markUsed(s);
+    }
+    return s;
+  }
+
+  /// Resets the namers to initial state. Namers are reset before generating.
+  void _resetUniqueNamersNamers() {
+    _topLevelUniqueNamer = _initialTopLevelUniqueNamer.clone();
+    _wrapperLevelUniqueNamer = _initialWrapperLevelUniqueNamer.clone();
+  }
+
+  void markImportUsed(LibraryImport import) {
+    _usedImports.add(import);
+  }
+
+  /// Writes all bindings to a String.
+  String generate() {
+    final s = StringBuffer();
+
+    // We write the source first to determine which imports are actually
+    // referenced. Headers and [s] are then combined into the final result.
+    final result = StringBuffer();
+
+    // Reset unique namers to initial state.
+    _resetUniqueNamersNamers();
+
+    // Write file header (if any).
+    if (header != null) {
+      result.writeln(header);
+    }
+
+    // Write auto generated declaration.
+    result.write(makeDoc(
+        'AUTO GENERATED FILE, DO NOT EDIT.\n\nGenerated by `package:ffigen`.'));
+
+    // Write lint ignore if not specified by user already.
+    if (!RegExp(r'ignore_for_file:\s*type\s*=\s*lint').hasMatch(header ?? '')) {
+      result.write(makeDoc('ignore_for_file: type=lint'));
+    }
+
+    /// Write [lookUpBindings].
+    if (lookUpBindings.isNotEmpty) {
+      // Write doc comment for wrapper class.
+      if (classDocComment != null) {
+        s.write(makeDartDoc(classDocComment!));
+      }
+      // Write wrapper classs.
+      s.write('class $_className{\n');
+      // Write dylib.
+      s.write('/// Holds the symbol lookup function.\n');
+      s.write(
+          'final $ffiLibraryPrefix.Pointer<T> Function<T extends $ffiLibraryPrefix.NativeType>(String symbolName) $lookupFuncIdentifier;\n');
+      s.write('\n');
+      //Write doc comment for wrapper class constructor.
+      s.write(makeDartDoc('The symbols are looked up in [dynamicLibrary].'));
+      // Write wrapper class constructor.
+      s.write(
+          '$_className($ffiLibraryPrefix.DynamicLibrary dynamicLibrary): $lookupFuncIdentifier = dynamicLibrary.lookup;\n\n');
+      //Write doc comment for wrapper class named constructor.
+      s.write(makeDartDoc('The symbols are looked up with [lookup].'));
+      // Write wrapper class named constructor.
+      s.write(
+          '$_className.fromLookup($ffiLibraryPrefix.Pointer<T> Function<T extends $ffiLibraryPrefix.NativeType>(String symbolName) lookup): $lookupFuncIdentifier = lookup;\n\n');
+      for (final b in lookUpBindings) {
+        s.write(b.toBindingString(this).string);
+      }
+      if (symbolAddressWriter.shouldGenerate) {
+        s.write(symbolAddressWriter.writeObject(this));
+      }
+
+      s.write('}\n\n');
+    }
+
+    for (final b in ffiNativeBindings) {
+      s.write(b.toBindingString(this).string);
+    }
+
+    if (symbolAddressWriter.shouldGenerate) {
+      s.write(symbolAddressWriter.writeClass(this));
+    }
+
+    /// Write [noLookUpBindings].
+    for (final b in noLookUpBindings) {
+      s.write(b.toBindingString(this).string);
+    }
+
+    // Write neccesary imports.
+    for (final lib in _usedImports) {
+      result
+        ..write("import '${lib.importPath}' as ${lib.prefix};")
+        ..write('\n');
+    }
+    result.write(s);
+
+    _canGenerateSymbolOutput = true;
+    return result.toString();
+  }
+
+  Map<String, dynamic> generateSymbolOutputYamlMap(String importFilePath) {
+    final bindings = <Binding>[
+      ...noLookUpBindings,
+      ...ffiNativeBindings,
+      ...lookUpBindings
+    ];
+    if (!canGenerateSymbolOutput) {
+      throw Exception(
+          "Invalid state: generateSymbolOutputYamlMap() called before generate()");
+    }
+    final result = <String, dynamic>{};
+
+    result[strings.formatVersion] = strings.symbolFileFormatVersion;
+    result[strings.files] = <String, dynamic>{};
+    result[strings.files][importFilePath] = <String, dynamic>{};
+
+    final fileConfig = result[strings.files][importFilePath];
+    fileConfig[strings.usedConfig] = <String, dynamic>{};
+
+    // Warn for macros.
+    final hasMacroBindings = bindings.any(
+        (element) => element is Constant && element.usr.contains('@macro@'));
+    if (hasMacroBindings) {
+      _logger.info(
+          'Removing all Macros from symbol file since they cannot be cross referenced reliably.');
+    }
+    // Remove internal bindings and macros.
+    bindings.removeWhere((element) {
+      return element.isInternal ||
+          (element is Constant && element.usr.contains('@macro@'));
+    });
+    // Sort bindings alphabetically by USR.
+    bindings.sort((a, b) => a.usr.compareTo(b.usr));
+    fileConfig[strings.usedConfig][strings.ffiNative] = bindings
+        .whereType<Func>()
+        .any((element) => element.ffiNativeConfig.enabled);
+    fileConfig[strings.symbols] = <String, dynamic>{};
+    final symbolConfig = fileConfig[strings.symbols];
+    for (final binding in bindings) {
+      symbolConfig[binding.usr] = {
+        strings.name: binding.name,
+      };
+    }
+    return result;
+  }
+}
+
+/// Manages the generated `_SymbolAddress` class.
+class SymbolAddressWriter {
+  final List<_SymbolAddressUnit> _addresses = [];
+
+  /// Used to check if we need to generate `_SymbolAddress` class.
+  bool get shouldGenerate => _addresses.isNotEmpty;
+
+  void addSymbol({
+    required String type,
+    required String name,
+    required String ptrName,
+  }) {
+    _addresses.add(_SymbolAddressUnit(type, name, ptrName));
+  }
+
+  String writeObject(Writer w) {
+    return 'late final ${w._symbolAddressVariableName} = ${w._symbolAddressClassName}(this);';
+  }
+
+  String writeClass(Writer w) {
+    final sb = StringBuffer();
+    sb.write('class ${w._symbolAddressClassName} {\n');
+    // Write Library object.
+    sb.write('final ${w._className} ${w._symbolAddressLibraryVarName};\n');
+    // Write Constructor.
+    sb.write(
+        '${w._symbolAddressClassName}(this.${w._symbolAddressLibraryVarName});\n');
+    for (final address in _addresses) {
+      sb.write(
+          '${address.type} get ${address.name} => ${w._symbolAddressLibraryVarName}.${address.ptrName};\n');
+    }
+    sb.write('}\n');
+    return sb.toString();
+  }
+}
+
+/// Holds the data for a single symbol address.
+class _SymbolAddressUnit {
+  final String type, name, ptrName;
+
+  _SymbolAddressUnit(this.type, this.name, this.ptrName);
+}
diff --git a/pkgs/ffigen/lib/src/config_provider.dart b/pkgs/ffigen/lib/src/config_provider.dart
new file mode 100644
index 0000000..990e137
--- /dev/null
+++ b/pkgs/ffigen/lib/src/config_provider.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Creates config object used by other sub_modules.
+library config_provider;
+
+export 'config_provider/config.dart';
diff --git a/pkgs/ffigen/lib/src/config_provider/config.dart b/pkgs/ffigen/lib/src/config_provider/config.dart
new file mode 100644
index 0000000..5109a0c
--- /dev/null
+++ b/pkgs/ffigen/lib/src/config_provider/config.dart
@@ -0,0 +1,916 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Validates the yaml input by the user, prints useful info for the user
+
+import 'dart:io';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:logging/logging.dart';
+import 'package:package_config/package_config_types.dart';
+import 'package:yaml/yaml.dart';
+
+import '../strings.dart' as strings;
+import 'config_spec.dart';
+import 'config_types.dart';
+import 'spec_utils.dart';
+
+final _logger = Logger('ffigen.config_provider.config');
+
+/// Provides configurations to other modules.
+///
+/// Handles validation, extraction of configurations from a yaml file.
+class Config {
+  /// Input filename.
+  final String? filename;
+
+  /// Package config.
+  final PackageConfig? packageConfig;
+
+  /// Location for llvm/lib folder.
+  String get libclangDylib => _libclangDylib;
+  late String _libclangDylib;
+
+  /// Output file name.
+  String get output => _output;
+  late String _output;
+
+  /// Symbol file config.
+  SymbolFile? get symbolFile => _symbolFile;
+  late SymbolFile? _symbolFile;
+
+  /// Language that ffigen is consuming.
+  Language get language => _language;
+  late Language _language;
+
+  // Holds headers and filters for header.
+  Headers get headers => _headers;
+  late Headers _headers;
+
+  /// CommandLine Arguments to pass to clang_compiler.
+  List<String> get compilerOpts => _compilerOpts;
+  late List<String> _compilerOpts;
+
+  /// VarArg function handling.
+  Map<String, List<VarArgFunction>> get varArgFunctions => _varArgFunctions;
+  late Map<String, List<VarArgFunction>> _varArgFunctions = {};
+
+  /// Declaration config for Functions.
+  Declaration get functionDecl => _functionDecl;
+  late Declaration _functionDecl;
+
+  /// Declaration config for Structs.
+  Declaration get structDecl => _structDecl;
+  late Declaration _structDecl;
+
+  /// Declaration config for Unions.
+  Declaration get unionDecl => _unionDecl;
+  late Declaration _unionDecl;
+
+  /// Declaration config for Enums.
+  Declaration get enumClassDecl => _enumClassDecl;
+  late Declaration _enumClassDecl;
+
+  /// Declaration config for Unnamed enum constants.
+  Declaration get unnamedEnumConstants => _unnamedEnumConstants;
+  late Declaration _unnamedEnumConstants;
+
+  /// Declaration config for Globals.
+  Declaration get globals => _globals;
+  late Declaration _globals;
+
+  /// Declaration config for Macro constants.
+  Declaration get macroDecl => _macroDecl;
+  late Declaration _macroDecl;
+
+  /// Declaration config for Typedefs.
+  Declaration get typedefs => _typedefs;
+  late Declaration _typedefs;
+
+  /// Declaration config for Objective C interfaces.
+  Declaration get objcInterfaces => _objcInterfaces;
+  late Declaration _objcInterfaces;
+
+  /// If enabled, the default behavior of all declaration filters is to exclude
+  /// everything, rather than include everything.
+  bool get excludeAllByDefault => _excludeAllByDefault;
+  late bool _excludeAllByDefault;
+
+  /// If generated bindings should be sorted alphabetically.
+  bool get sort => _sort;
+  late bool _sort;
+
+  /// If typedef of supported types(int8_t) should be directly used.
+  bool get useSupportedTypedefs => _useSupportedTypedefs;
+  late bool _useSupportedTypedefs;
+
+  /// Stores all the library imports specified by user including those for ffi
+  /// and pkg_ffi.
+  Map<String, LibraryImport> get libraryImports => _libraryImports;
+  late Map<String, LibraryImport> _libraryImports;
+
+  /// Stores all the symbol file maps name to ImportedType mappings specified by user.
+  Map<String, ImportedType> get usrTypeMappings => _usrTypeMappings;
+  late Map<String, ImportedType> _usrTypeMappings;
+
+  /// Stores typedef name to ImportedType mappings specified by user.
+  Map<String, ImportedType> get typedefTypeMappings => _typedefTypeMappings;
+  late Map<String, ImportedType> _typedefTypeMappings;
+
+  /// Stores struct name to ImportedType mappings specified by user.
+  Map<String, ImportedType> get structTypeMappings => _structTypeMappings;
+  late Map<String, ImportedType> _structTypeMappings;
+
+  /// Stores union name to ImportedType mappings specified by user.
+  Map<String, ImportedType> get unionTypeMappings => _unionTypeMappings;
+  late Map<String, ImportedType> _unionTypeMappings;
+
+  /// Stores native int name to ImportedType mappings specified by user.
+  Map<String, ImportedType> get nativeTypeMappings => _nativeTypeMappings;
+  late Map<String, ImportedType> _nativeTypeMappings;
+
+  /// Extracted Doc comment type.
+  CommentType get commentType => _commentType;
+  late CommentType _commentType;
+
+  /// Whether structs that are dependencies should be included.
+  CompoundDependencies get structDependencies => _structDependencies;
+  late CompoundDependencies _structDependencies;
+
+  /// Whether unions that are dependencies should be included.
+  CompoundDependencies get unionDependencies => _unionDependencies;
+  late CompoundDependencies _unionDependencies;
+
+  /// Holds config for how struct packing should be overriden.
+  StructPackingOverride get structPackingOverride => _structPackingOverride;
+  late StructPackingOverride _structPackingOverride;
+
+  /// Module prefixes for ObjC interfaces.
+  ObjCModulePrefixer get objcModulePrefixer => _objcModulePrefixer;
+  late ObjCModulePrefixer _objcModulePrefixer;
+
+  /// Name of the wrapper class.
+  String get wrapperName => _wrapperName;
+  late String _wrapperName;
+
+  /// Doc comment for the wrapper class.
+  String? get wrapperDocComment => _wrapperDocComment;
+  String? _wrapperDocComment;
+
+  /// Header of the generated bindings.
+  String? get preamble => _preamble;
+  String? _preamble;
+
+  /// If `Dart_Handle` should be mapped with Handle/Object.
+  bool get useDartHandle => _useDartHandle;
+  late bool _useDartHandle;
+
+  Includer get exposeFunctionTypedefs => _exposeFunctionTypedefs;
+  late Includer _exposeFunctionTypedefs;
+
+  Includer get leafFunctions => _leafFunctions;
+  late Includer _leafFunctions;
+
+  FfiNativeConfig get ffiNativeConfig => _ffiNativeConfig;
+  late FfiNativeConfig _ffiNativeConfig;
+
+  Config._({required this.filename, required this.packageConfig});
+
+  /// Create config from Yaml map.
+  factory Config.fromYaml(YamlMap map,
+      {String? filename, PackageConfig? packageConfig}) {
+    final config = Config._(filename: filename, packageConfig: packageConfig);
+    _logger.finest('Config Map: $map');
+
+    final ffigenConfigSpec = config._getRootConfigSpec();
+    final result = ffigenConfigSpec.validate(map);
+    if (!result) {
+      throw FormatException('Invalid configurations provided.');
+    }
+
+    ffigenConfigSpec.extract(map);
+    return config;
+  }
+
+  /// Create config from a file.
+  factory Config.fromFile(File file, {PackageConfig? packageConfig}) {
+    // Throws a [YamlException] if it's unable to parse the Yaml.
+    final configYaml = loadYaml(file.readAsStringSync()) as YamlMap;
+
+    return Config.fromYaml(configYaml,
+        filename: file.path, packageConfig: packageConfig);
+  }
+
+  /// Returns the root ConfigSpec object.
+  static ConfigSpec getsRootConfigSpec() {
+    final configspecs = Config._(filename: null, packageConfig: null);
+    return configspecs._getRootConfigSpec();
+  }
+
+  /// Add compiler options for clang. If [highPriority] is true these are added
+  /// to the front of the list.
+  void addCompilerOpts(String compilerOpts, {bool highPriority = false}) {
+    if (highPriority) {
+      _compilerOpts.insertAll(
+          0, compilerOptsToList(compilerOpts)); // Inserts at the front.
+    } else {
+      _compilerOpts.addAll(compilerOptsToList(compilerOpts));
+    }
+  }
+
+  ConfigSpec _getRootConfigSpec() {
+    return HeterogeneousMapConfigSpec(
+      entries: [
+        HeterogeneousMapEntry(
+          key: strings.llvmPath,
+          valueConfigSpec: ListConfigSpec<String, String>(
+            childConfigSpec: StringConfigSpec(),
+            transform: (node) => llvmPathExtractor(node.value),
+          ),
+          defaultValue: (node) => findDylibAtDefaultLocations(),
+          resultOrDefault: (node) => _libclangDylib = node.value as String,
+        ),
+        HeterogeneousMapEntry(
+            key: strings.output,
+            required: true,
+            valueConfigSpec: OneOfConfigSpec(
+              childConfigSpecs: [
+                _filePathStringConfigSpec(),
+                _outputFullConfigSpec(),
+              ],
+              transform: (node) =>
+                  outputExtractor(node.value, filename, packageConfig),
+              result: (node) {
+                _output = (node.value as OutputConfig).output;
+                _symbolFile = (node.value as OutputConfig).symbolFile;
+              },
+            )),
+        HeterogeneousMapEntry(
+          key: strings.language,
+          valueConfigSpec: EnumConfigSpec(
+            allowedValues: {strings.langC, strings.langObjC},
+            transform: (node) {
+              if ((node.value == strings.langObjC)) {
+                _logger.severe(
+                    'Objective C support is EXPERIMENTAL. The API may change '
+                    'in a breaking way without notice.');
+                return Language.objc;
+              } else {
+                return Language.c;
+              }
+            },
+          ),
+          defaultValue: (node) => Language.c,
+          resultOrDefault: (node) => _language = node.value as Language,
+        ),
+        HeterogeneousMapEntry(
+            key: strings.headers,
+            required: true,
+            valueConfigSpec: HeterogeneousMapConfigSpec<List<String>, Headers>(
+              entries: [
+                HeterogeneousMapEntry(
+                  key: strings.entryPoints,
+                  valueConfigSpec: ListConfigSpec<String, List<String>>(
+                      childConfigSpec: StringConfigSpec()),
+                  required: true,
+                ),
+                HeterogeneousMapEntry(
+                  key: strings.includeDirectives,
+                  valueConfigSpec: ListConfigSpec<String, List<String>>(
+                      childConfigSpec: StringConfigSpec()),
+                ),
+              ],
+              transform: (node) => headersExtractor(node.value, filename),
+              result: (node) => _headers = node.value,
+            )),
+        HeterogeneousMapEntry(
+          key: strings.compilerOpts,
+          valueConfigSpec: OneOfConfigSpec<List<String>, List<String>>(
+            childConfigSpecs: [
+              StringConfigSpec(
+                transform: (node) => [node.value],
+              ),
+              ListConfigSpec<String, List<String>>(
+                  childConfigSpec: StringConfigSpec())
+            ],
+            transform: (node) => compilerOptsExtractor(node.value),
+          ),
+          defaultValue: (node) => <String>[],
+          resultOrDefault: (node) => _compilerOpts = node.value as List<String>,
+        ),
+        HeterogeneousMapEntry(
+            key: strings.compilerOptsAuto,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                HeterogeneousMapEntry(
+                  key: strings.macos,
+                  valueConfigSpec: HeterogeneousMapConfigSpec(
+                    entries: [
+                      HeterogeneousMapEntry(
+                        key: strings.includeCStdLib,
+                        valueConfigSpec: BoolConfigSpec(),
+                        defaultValue: (node) => true,
+                      )
+                    ],
+                  ),
+                )
+              ],
+              transform: (node) => CompilerOptsAuto(
+                macIncludeStdLib: ((node.value)[strings.macos]
+                    as Map?)?[strings.includeCStdLib] as bool,
+              ),
+              result: (node) => _compilerOpts.addAll(
+                  (node.value as CompilerOptsAuto).extractCompilerOpts()),
+            )),
+        HeterogeneousMapEntry(
+          key: strings.libraryImports,
+          valueConfigSpec: MapConfigSpec<String, Map<String, LibraryImport>>(
+            keyValueConfigSpecs: [
+              (keyRegexp: ".*", valueConfigSpec: StringConfigSpec()),
+            ],
+            customValidation: _libraryImportsPredefinedValidation,
+            transform: (node) => libraryImportsExtractor(node.value.cast()),
+          ),
+          defaultValue: (node) => <String, LibraryImport>{},
+          resultOrDefault: (node) =>
+              _libraryImports = (node.value) as Map<String, LibraryImport>,
+        ),
+        HeterogeneousMapEntry(
+            key: strings.functions,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                ..._includeExcludeProperties(),
+                ..._renameProperties(),
+                ..._memberRenameProperties(),
+                HeterogeneousMapEntry(
+                  key: strings.symbolAddress,
+                  valueConfigSpec: _includeExcludeObject(),
+                  defaultValue: (node) => Includer.excludeByDefault(),
+                ),
+                HeterogeneousMapEntry(
+                  key: strings.exposeFunctionTypedefs,
+                  valueConfigSpec: _includeExcludeObject(),
+                  defaultValue: (node) => Includer.excludeByDefault(),
+                ),
+                HeterogeneousMapEntry(
+                  key: strings.leafFunctions,
+                  valueConfigSpec: _includeExcludeObject(),
+                  defaultValue: (node) => Includer.excludeByDefault(),
+                ),
+                HeterogeneousMapEntry(
+                  key: strings.varArgFunctions,
+                  valueConfigSpec: _functionVarArgsConfigSpec(),
+                  defaultValue: (node) => <String, List<RawVarArgFunction>>{},
+                  resultOrDefault: (node) {
+                    _varArgFunctions = makeVarArgFunctionsMapping(
+                        node.value as Map<String, List<RawVarArgFunction>>,
+                        _libraryImports);
+                  },
+                ),
+              ],
+              result: (node) {
+                _functionDecl = declarationConfigExtractor(
+                    node.value as Map<dynamic, dynamic>);
+                _exposeFunctionTypedefs = (node.value
+                    as Map)[strings.exposeFunctionTypedefs] as Includer;
+                _leafFunctions =
+                    (node.value as Map)[strings.leafFunctions] as Includer;
+              },
+            )),
+        HeterogeneousMapEntry(
+            key: strings.structs,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                ..._includeExcludeProperties(),
+                ..._renameProperties(),
+                ..._memberRenameProperties(),
+                _dependencyOnlyHeterogeneousMapKey(),
+                HeterogeneousMapEntry(
+                  key: strings.structPack,
+                  valueConfigSpec: MapConfigSpec(
+                    keyValueConfigSpecs: [
+                      (
+                        keyRegexp: '.*',
+                        valueConfigSpec: EnumConfigSpec(
+                          allowedValues: {'none', 1, 2, 4, 8, 16},
+                          transform: (node) =>
+                              node.value == 'none' ? null : node.value,
+                        ),
+                      )
+                    ],
+                    transform: (node) =>
+                        structPackingOverrideExtractor(node.value),
+                  ),
+                  defaultValue: (node) => StructPackingOverride(),
+                  resultOrDefault: (node) => _structPackingOverride =
+                      node.value as StructPackingOverride,
+                ),
+              ],
+              result: (node) {
+                _structDecl = declarationConfigExtractor(
+                    node.value as Map<dynamic, dynamic>);
+                _structDependencies = (node.value
+                    as Map)[strings.dependencyOnly] as CompoundDependencies;
+              },
+            )),
+        HeterogeneousMapEntry(
+            key: strings.unions,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                ..._includeExcludeProperties(),
+                ..._renameProperties(),
+                ..._memberRenameProperties(),
+                _dependencyOnlyHeterogeneousMapKey(),
+              ],
+              result: (node) {
+                _unionDecl = declarationConfigExtractor(
+                    node.value as Map<dynamic, dynamic>);
+                _unionDependencies = (node.value as Map)[strings.dependencyOnly]
+                    as CompoundDependencies;
+              },
+            )),
+        HeterogeneousMapEntry(
+            key: strings.enums,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                ..._includeExcludeProperties(),
+                ..._renameProperties(),
+                ..._memberRenameProperties(),
+              ],
+              result: (node) {
+                _enumClassDecl = declarationConfigExtractor(
+                    node.value as Map<dynamic, dynamic>);
+              },
+            )),
+        HeterogeneousMapEntry(
+            key: strings.unnamedEnums,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                ..._includeExcludeProperties(),
+                ..._renameProperties(),
+              ],
+              result: (node) {
+                _unnamedEnumConstants = declarationConfigExtractor(
+                    node.value as Map<dynamic, dynamic>);
+              },
+            )),
+        HeterogeneousMapEntry(
+            key: strings.globals,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                ..._includeExcludeProperties(),
+                ..._renameProperties(),
+                HeterogeneousMapEntry(
+                  key: strings.symbolAddress,
+                  valueConfigSpec: _includeExcludeObject(),
+                  defaultValue: (node) => Includer.excludeByDefault(),
+                )
+              ],
+              result: (node) {
+                _globals = declarationConfigExtractor(
+                    node.value as Map<dynamic, dynamic>);
+              },
+            )),
+        HeterogeneousMapEntry(
+            key: strings.macros,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                ..._includeExcludeProperties(),
+                ..._renameProperties(),
+              ],
+              result: (node) {
+                _macroDecl = declarationConfigExtractor(
+                    node.value as Map<dynamic, dynamic>);
+              },
+            )),
+        HeterogeneousMapEntry(
+            key: strings.typedefs,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                ..._includeExcludeProperties(),
+                ..._renameProperties(),
+              ],
+              result: (node) {
+                _typedefs = declarationConfigExtractor(
+                    node.value as Map<dynamic, dynamic>);
+              },
+            )),
+        HeterogeneousMapEntry(
+            key: strings.objcInterfaces,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                ..._includeExcludeProperties(),
+                ..._renameProperties(),
+                ..._memberRenameProperties(),
+                HeterogeneousMapEntry(
+                  key: strings.objcModule,
+                  valueConfigSpec: _objcInterfaceModuleObject(),
+                  defaultValue: (node) => ObjCModulePrefixer({}),
+                )
+              ],
+              result: (node) {
+                _objcInterfaces = declarationConfigExtractor(
+                    node.value as Map<dynamic, dynamic>);
+                _objcModulePrefixer = (node.value as Map)[strings.objcModule]
+                    as ObjCModulePrefixer;
+              },
+            )),
+        HeterogeneousMapEntry(
+            key: strings.import,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                HeterogeneousMapEntry(
+                  key: strings.symbolFilesImport,
+                  valueConfigSpec:
+                      ListConfigSpec<String, Map<String, ImportedType>>(
+                    childConfigSpec: StringConfigSpec(),
+                    transform: (node) => symbolFileImportExtractor(
+                        node.value, _libraryImports, filename, packageConfig),
+                  ),
+                  defaultValue: (node) => <String, ImportedType>{},
+                  resultOrDefault: (node) => _usrTypeMappings =
+                      node.value as Map<String, ImportedType>,
+                )
+              ],
+            )),
+        HeterogeneousMapEntry(
+            key: strings.typeMap,
+            valueConfigSpec: HeterogeneousMapConfigSpec(
+              entries: [
+                HeterogeneousMapEntry(
+                  key: strings.typeMapTypedefs,
+                  valueConfigSpec: _mappedTypeObject(),
+                  defaultValue: (node) => <String, List<String>>{},
+                ),
+                HeterogeneousMapEntry(
+                  key: strings.typeMapStructs,
+                  valueConfigSpec: _mappedTypeObject(),
+                  defaultValue: (node) => <String, List<String>>{},
+                ),
+                HeterogeneousMapEntry(
+                  key: strings.typeMapUnions,
+                  valueConfigSpec: _mappedTypeObject(),
+                  defaultValue: (node) => <String, List<String>>{},
+                ),
+                HeterogeneousMapEntry(
+                  key: strings.typeMapNativeTypes,
+                  valueConfigSpec: _mappedTypeObject(),
+                  defaultValue: (node) => <String, List<String>>{},
+                ),
+              ],
+              result: (node) {
+                final nodeValue = node.value as Map;
+                _typedefTypeMappings = makeImportTypeMapping(
+                  (nodeValue[strings.typeMapTypedefs])
+                      as Map<String, List<String>>,
+                  _libraryImports,
+                );
+                _structTypeMappings = makeImportTypeMapping(
+                  (nodeValue[strings.typeMapStructs])
+                      as Map<String, List<String>>,
+                  _libraryImports,
+                );
+                _unionTypeMappings = makeImportTypeMapping(
+                  (nodeValue[strings.typeMapUnions])
+                      as Map<String, List<String>>,
+                  _libraryImports,
+                );
+                _nativeTypeMappings = makeImportTypeMapping(
+                  (nodeValue[strings.typeMapNativeTypes])
+                      as Map<String, List<String>>,
+                  _libraryImports,
+                );
+              },
+            )),
+        HeterogeneousMapEntry(
+          key: strings.excludeAllByDefault,
+          valueConfigSpec: BoolConfigSpec(),
+          defaultValue: (node) => false,
+          resultOrDefault: (node) => _excludeAllByDefault = node.value as bool,
+        ),
+        HeterogeneousMapEntry(
+          key: strings.sort,
+          valueConfigSpec: BoolConfigSpec(),
+          defaultValue: (node) => false,
+          resultOrDefault: (node) => _sort = node.value as bool,
+        ),
+        HeterogeneousMapEntry(
+          key: strings.useSupportedTypedefs,
+          valueConfigSpec: BoolConfigSpec(),
+          defaultValue: (node) => true,
+          resultOrDefault: (node) => _useSupportedTypedefs = node.value as bool,
+        ),
+        HeterogeneousMapEntry(
+          key: strings.comments,
+          valueConfigSpec: _commentConfigSpec(),
+          defaultValue: (node) => CommentType.def(),
+          resultOrDefault: (node) => _commentType = node.value as CommentType,
+        ),
+        HeterogeneousMapEntry(
+          key: strings.name,
+          valueConfigSpec: _dartClassNameStringConfigSpec(),
+          defaultValue: (node) {
+            _logger.warning(
+                "Prefer adding Key '${node.pathString}' to your config.");
+            return 'NativeLibrary';
+          },
+          resultOrDefault: (node) => _wrapperName = node.value as String,
+        ),
+        HeterogeneousMapEntry(
+          key: strings.description,
+          valueConfigSpec: _nonEmptyStringConfigSpec(),
+          defaultValue: (node) {
+            _logger.warning(
+                "Prefer adding Key '${node.pathString}' to your config.");
+            return null;
+          },
+          resultOrDefault: (node) => _wrapperDocComment = node.value as String?,
+        ),
+        HeterogeneousMapEntry(
+            key: strings.preamble,
+            valueConfigSpec: StringConfigSpec(
+              result: (node) => _preamble = node.value as String?,
+            )),
+        HeterogeneousMapEntry(
+          key: strings.useDartHandle,
+          valueConfigSpec: BoolConfigSpec(),
+          defaultValue: (node) => true,
+          resultOrDefault: (node) => _useDartHandle = node.value as bool,
+        ),
+        HeterogeneousMapEntry(
+          key: strings.ffiNative,
+          valueConfigSpec: OneOfConfigSpec(
+            childConfigSpecs: [
+              EnumConfigSpec(allowedValues: {null}),
+              HeterogeneousMapConfigSpec(
+                entries: [
+                  HeterogeneousMapEntry(
+                    key: strings.ffiNativeAsset,
+                    valueConfigSpec: StringConfigSpec(),
+                    required: true,
+                  )
+                ],
+              )
+            ],
+            transform: (node) => ffiNativeExtractor(node.value),
+          ),
+          defaultValue: (node) => FfiNativeConfig(enabled: false),
+          resultOrDefault: (node) =>
+              _ffiNativeConfig = (node.value) as FfiNativeConfig,
+        ),
+      ],
+    );
+  }
+
+  bool _libraryImportsPredefinedValidation(ConfigValue node) {
+    if (node.value is YamlMap) {
+      return (node.value as YamlMap).keys.where((key) {
+        if (strings.predefinedLibraryImports.containsKey(key)) {
+          _logger.severe(
+              '${node.pathString} -> $key should not collide with any predefined imports - ${strings.predefinedLibraryImports.keys}.');
+          return true;
+        }
+        return false;
+      }).isEmpty;
+    }
+    return true;
+  }
+
+  OneOfConfigSpec _commentConfigSpec() {
+    return OneOfConfigSpec(
+      childConfigSpecs: [
+        BoolConfigSpec(
+          transform: (node) =>
+              (node.value == true) ? CommentType.def() : CommentType.none(),
+        ),
+        HeterogeneousMapConfigSpec(
+          entries: [
+            HeterogeneousMapEntry(
+              key: strings.style,
+              valueConfigSpec: EnumConfigSpec(
+                allowedValues: {strings.doxygen, strings.any},
+                transform: (node) => node.value == strings.doxygen
+                    ? CommentStyle.doxygen
+                    : CommentStyle.any,
+              ),
+              defaultValue: (node) => CommentStyle.doxygen,
+            ),
+            HeterogeneousMapEntry(
+              key: strings.length,
+              valueConfigSpec: EnumConfigSpec(
+                allowedValues: {strings.brief, strings.full},
+                transform: (node) => node.value == strings.brief
+                    ? CommentLength.brief
+                    : CommentLength.full,
+              ),
+              defaultValue: (node) => CommentLength.full,
+            ),
+          ],
+          transform: (node) => CommentType(
+            (node.value)[strings.style] as CommentStyle,
+            (node.value)[strings.length] as CommentLength,
+          ),
+        ),
+      ],
+    );
+  }
+
+  MapConfigSpec _functionVarArgsConfigSpec() {
+    return MapConfigSpec(
+      keyValueConfigSpecs: [
+        (
+          keyRegexp: ".*",
+          valueConfigSpec: ListConfigSpec(
+            childConfigSpec: OneOfConfigSpec(
+              childConfigSpecs: [
+                ListConfigSpec(childConfigSpec: StringConfigSpec()),
+                HeterogeneousMapConfigSpec(
+                  entries: [
+                    HeterogeneousMapEntry(
+                      key: strings.types,
+                      valueConfigSpec: ListConfigSpec<String, List<String>>(
+                          childConfigSpec: StringConfigSpec()),
+                      required: true,
+                    ),
+                    HeterogeneousMapEntry(
+                      key: strings.postfix,
+                      valueConfigSpec: StringConfigSpec(),
+                    ),
+                  ],
+                )
+              ],
+            ),
+          )
+        )
+      ],
+      transform: (node) => varArgFunctionConfigExtractor(node.value),
+    );
+  }
+
+  HeterogeneousMapConfigSpec _outputFullConfigSpec() {
+    return HeterogeneousMapConfigSpec(
+      entries: [
+        HeterogeneousMapEntry(
+          key: strings.bindings,
+          valueConfigSpec: _filePathStringConfigSpec(),
+          required: true,
+        ),
+        HeterogeneousMapEntry(
+          key: strings.symbolFile,
+          valueConfigSpec: HeterogeneousMapConfigSpec(
+            entries: [
+              HeterogeneousMapEntry(
+                key: strings.output,
+                valueConfigSpec: _filePathStringConfigSpec(),
+                required: true,
+              ),
+              HeterogeneousMapEntry(
+                key: strings.importPath,
+                valueConfigSpec: StringConfigSpec(),
+                required: true,
+              ),
+            ],
+          ),
+        ),
+      ],
+    );
+  }
+
+  StringConfigSpec _filePathStringConfigSpec() {
+    return StringConfigSpec(
+      schemaDefName: 'filePath',
+      schemaDescription: "A file path",
+    );
+  }
+
+  StringConfigSpec _nonEmptyStringConfigSpec() {
+    return StringConfigSpec(
+      schemaDefName: 'nonEmptyString',
+      pattern: r'.+',
+    );
+  }
+
+  StringConfigSpec _dartClassNameStringConfigSpec() {
+    return StringConfigSpec(
+      schemaDefName: 'publicDartClass',
+      schemaDescription: "A public dart class name.",
+      pattern: r'^[a-zA-Z]+[_a-zA-Z0-9]*$',
+    );
+  }
+
+  List<HeterogeneousMapEntry> _includeExcludeProperties() {
+    return [
+      HeterogeneousMapEntry(
+        key: strings.include,
+        valueConfigSpec: _fullMatchOrRegexpList(),
+      ),
+      HeterogeneousMapEntry(
+        key: strings.exclude,
+        valueConfigSpec: _fullMatchOrRegexpList(),
+        defaultValue: (node) => <String>[],
+      ),
+    ];
+  }
+
+  ListConfigSpec<String, List<String>> _fullMatchOrRegexpList() {
+    return ListConfigSpec(
+      schemaDefName: "fullMatchOrRegexpList",
+      childConfigSpec: StringConfigSpec(),
+    );
+  }
+
+  List<HeterogeneousMapEntry> _renameProperties() {
+    return [
+      HeterogeneousMapEntry(
+        key: strings.rename,
+        valueConfigSpec: MapConfigSpec<String, dynamic>(
+          schemaDefName: "rename",
+          keyValueConfigSpecs: [
+            (keyRegexp: ".*", valueConfigSpec: StringConfigSpec()),
+          ],
+        ),
+      ),
+    ];
+  }
+
+  List<HeterogeneousMapEntry> _memberRenameProperties() {
+    return [
+      HeterogeneousMapEntry(
+        key: strings.memberRename,
+        valueConfigSpec: MapConfigSpec<Map<dynamic, String>,
+            Map<dynamic, Map<dynamic, String>>>(
+          schemaDefName: "memberRename",
+          keyValueConfigSpecs: [
+            (
+              keyRegexp: ".*",
+              valueConfigSpec: MapConfigSpec<String, Map<dynamic, String>>(
+                keyValueConfigSpecs: [
+                  (keyRegexp: ".*", valueConfigSpec: StringConfigSpec())
+                ],
+              ),
+            ),
+          ],
+        ),
+      ),
+    ];
+  }
+
+  HeterogeneousMapConfigSpec<List<String>, Includer> _includeExcludeObject() {
+    return HeterogeneousMapConfigSpec(
+      schemaDefName: "includeExclude",
+      entries: [
+        ..._includeExcludeProperties(),
+      ],
+      transform: (node) => extractIncluderFromYaml(node.value),
+    );
+  }
+
+  HeterogeneousMapEntry _dependencyOnlyHeterogeneousMapKey() {
+    return HeterogeneousMapEntry(
+      key: strings.dependencyOnly,
+      valueConfigSpec: EnumConfigSpec<String, CompoundDependencies>(
+        schemaDefName: "dependencyOnly",
+        allowedValues: {
+          strings.fullCompoundDependencies,
+          strings.opaqueCompoundDependencies,
+        },
+        transform: (node) => node.value == strings.opaqueCompoundDependencies
+            ? CompoundDependencies.opaque
+            : CompoundDependencies.full,
+      ),
+      defaultValue: (node) => CompoundDependencies.full,
+    );
+  }
+
+  MapConfigSpec _mappedTypeObject() {
+    return MapConfigSpec(
+      schemaDefName: "mappedTypes",
+      keyValueConfigSpecs: [
+        (
+          keyRegexp: ".*",
+          valueConfigSpec: HeterogeneousMapConfigSpec(entries: [
+            HeterogeneousMapEntry(
+                key: strings.lib, valueConfigSpec: StringConfigSpec()),
+            HeterogeneousMapEntry(
+                key: strings.cType, valueConfigSpec: StringConfigSpec()),
+            HeterogeneousMapEntry(
+                key: strings.dartType, valueConfigSpec: StringConfigSpec()),
+          ]),
+        )
+      ],
+      transform: (node) => typeMapExtractor(node.value),
+    );
+  }
+
+  MapConfigSpec _objcInterfaceModuleObject() {
+    return MapConfigSpec(
+      schemaDefName: "objcInterfaceModule",
+      keyValueConfigSpecs: [
+        (keyRegexp: ".*", valueConfigSpec: StringConfigSpec()),
+      ],
+      transform: (node) =>
+          ObjCModulePrefixer(node.value.cast<String, String>()),
+    );
+  }
+}
diff --git a/pkgs/ffigen/lib/src/config_provider/config_spec.dart b/pkgs/ffigen/lib/src/config_provider/config_spec.dart
new file mode 100644
index 0000000..3d67be9
--- /dev/null
+++ b/pkgs/ffigen/lib/src/config_provider/config_spec.dart
@@ -0,0 +1,822 @@
+import 'package:logging/logging.dart';
+import 'package:yaml/yaml.dart';
+
+final _logger = Logger('ffigen.config_provider.config');
+
+/// Base class for all ConfigSpecs to extend.
+///
+/// [TE] - type input for [transform], [RE] - type input for [result].
+///
+/// Validation -
+///
+/// - [customValidation] is called after the ConfigSpec hierarchical validations
+/// are completed.
+///
+/// Extraction -
+///
+/// - The data is first validated, if invalid it throws a
+/// ConfigSpecExtractionError.
+/// - The extracted data from the child(s) is collected and the value is
+/// transformed via [transform] (if specified).
+/// - Finally the [result] closure is called (if specified).
+abstract class ConfigSpec<TE extends Object?, RE extends Object?> {
+  /// Used to generate and refer the reference definition generated in json
+  /// schema. Must be unique for a nested Schema.
+  String? schemaDefName;
+
+  /// Used to generate the description field in json schema.
+  String? schemaDescription;
+
+  /// Custom validation hook, called post validation if successful.
+  bool Function(ConfigValue node)? customValidation;
+
+  /// Used to transform the payload to another type before passing to parent
+  /// nodes and [result].
+  RE Function(ConfigValue<TE> node)? transform;
+
+  /// Called when final result is prepared via [_extractNode].
+  void Function(ConfigValue<RE> node)? result;
+  ConfigSpec({
+    required this.schemaDefName,
+    required this.schemaDescription,
+    required this.customValidation,
+    required this.transform,
+    required this.result,
+  });
+
+  bool _validateNode(ConfigValue o, {bool log = true});
+
+  ConfigValue<RE> _extractNode(ConfigValue o);
+
+  /// ConfigSpec objects should call [_getJsonRefOrSchemaNode] instead to get the
+  /// child json schema.
+  Map<String, dynamic> _generateJsonSchemaNode(Map<String, dynamic> defs);
+
+  Map<String, dynamic> _getJsonRefOrSchemaNode(Map<String, dynamic> defs) {
+    if (schemaDefName == null) {
+      return _generateJsonSchemaNode(defs);
+    }
+    defs.putIfAbsent(schemaDefName!, () => _generateJsonSchemaNode(defs));
+    return {r"$ref": "#/\$defs/$schemaDefName"};
+  }
+
+  Map<String, dynamic> generateJsonSchema(String schemaId) {
+    final defs = <String, dynamic>{};
+    final schemaMap = _generateJsonSchemaNode(defs);
+    return {
+      r"$id": schemaId,
+      r"$comment":
+          "This file is generated. To regenerate run: dart tool/generate_json_schema.dart in github.com/dart-lang/ffigen",
+      r"$schema": "https://json-schema.org/draft/2020-12/schema",
+      ...schemaMap,
+      r"$defs": defs,
+    };
+  }
+
+  /// Run validation on an object [value].
+  bool validate(dynamic value) {
+    return _validateNode(ConfigValue(path: [], value: value));
+  }
+
+  /// Extract ConfigSpecNode from [value]. This will call the [transform] for all
+  /// underlying ConfigSpecs if valid.
+  /// Should ideally only be called if [validate] returns True. Throws
+  /// [ConfigSpecExtractionError] if any validation fails.
+  ConfigValue extract(dynamic value) {
+    return _extractNode(ConfigValue(path: [], value: value));
+  }
+}
+
+/// An individual value in a config for a specific [path] instantiated from a [ConfigSpec].
+///
+/// A config value contains both the [value] that users of the configuration would want
+/// to use, as well as the [rawValue] that was provided as input to the configuration.
+class ConfigValue<TE> {
+  /// The path to this node.
+  ///
+  /// E.g - ["path", "to", "arr", "[1]", "item"]
+  final List<String> path;
+
+  /// Get a string representation for path.
+  ///
+  /// E.g - "path -> to -> arr -> [1] -> item"
+  String get pathString => path.join(" -> ");
+
+  /// Contains the underlying node value after all transformations and
+  /// default values have been applied.
+  final TE value;
+
+  /// Contains the raw underlying node value. Would be null for fields populated
+  /// but default values
+  final Object? rawValue;
+
+  ConfigValue({
+    required this.path,
+    required this.value,
+    Object? rawValue,
+    bool nullRawValue = false,
+  }) : rawValue = nullRawValue ? null : (rawValue ?? value);
+
+  /// Copy object with a different value.
+  ConfigValue<T> withValue<T>(T value, Object? rawValue) {
+    return ConfigValue<T>(
+      path: path,
+      value: value,
+      rawValue: rawValue,
+      nullRawValue: rawValue == null,
+    );
+  }
+
+  /// Transforms this with a nullable [transform] or return itself
+  /// and calls the [result] callback
+  ConfigValue<RE> transformOrThis<RE extends Object?>(
+    RE Function(ConfigValue<TE> value)? transform,
+    void Function(ConfigValue<RE> node)? resultCallback,
+  ) {
+    ConfigValue<RE> returnValue;
+    if (transform != null) {
+      returnValue = this.withValue(transform.call(this), rawValue);
+    } else {
+      returnValue = this.withValue(this.value as RE, rawValue);
+    }
+    resultCallback?.call(returnValue);
+    return returnValue;
+  }
+
+  /// Returns true if [value] is of Type [T].
+  bool checkType<T>({bool log = true}) {
+    if (value is! T) {
+      if (log) {
+        _logger.severe(
+            "Expected value of key '$pathString' to be of type '$T' (Got ${value.runtimeType}).");
+      }
+      return false;
+    }
+    return true;
+  }
+}
+
+class ConfigSpecExtractionError extends Error {
+  final ConfigValue? item;
+  final String message;
+  ConfigSpecExtractionError(this.item, [this.message = "Invalid ConfigSpec"]);
+
+  @override
+  String toString() {
+    if (item != null) {
+      return "$runtimeType: $message @ ${item!.pathString}";
+    }
+    return "$runtimeType: $message";
+  }
+}
+
+class HeterogeneousMapEntry {
+  final String key;
+  final ConfigSpec valueConfigSpec;
+  final Object? Function(ConfigValue<void> o)? defaultValue;
+  void Function(ConfigValue<Object?> node)? resultOrDefault;
+  final bool required;
+
+  HeterogeneousMapEntry({
+    required this.key,
+    required this.valueConfigSpec,
+    this.defaultValue,
+    this.resultOrDefault,
+    this.required = false,
+  });
+}
+
+enum AdditionalProperties { Allow, Warn, Error }
+
+/// ConfigSpec for a Map which has a fixed set of known keys.
+///
+/// [CE] typecasts result from entries->{}->valueConfigSpec.
+///
+/// [RE] typecasts result returned by this node.
+class HeterogeneousMapConfigSpec<CE extends Object?, RE extends Object?>
+    extends ConfigSpec<Map<dynamic, CE>, RE> {
+  final List<HeterogeneousMapEntry> entries;
+  final Set<String> allKeys;
+  final Set<String> requiredKeys;
+  final AdditionalProperties additionalProperties;
+
+  HeterogeneousMapConfigSpec({
+    required this.entries,
+    super.schemaDefName,
+    super.schemaDescription,
+    super.customValidation,
+    super.transform,
+    super.result,
+    this.additionalProperties = AdditionalProperties.Warn,
+  })  : requiredKeys = {
+          for (final kv in entries.where((kv) => kv.required)) kv.key
+        },
+        allKeys = {for (final kv in entries) kv.key};
+
+  @override
+  bool _validateNode(ConfigValue o, {bool log = true}) {
+    if (!o.checkType<Map>(log: log)) {
+      return false;
+    }
+
+    var result = true;
+    final inputMap = (o.value as Map);
+
+    for (final requiredKey in requiredKeys) {
+      if (!inputMap.containsKey(requiredKey)) {
+        if (log) {
+          _logger.severe(
+              "Key '${[...o.path, requiredKey].join(' -> ')}' is required.");
+        }
+        result = false;
+      }
+    }
+
+    for (final entry in entries) {
+      final path = [...o.path, entry.key.toString()];
+      if (!inputMap.containsKey(entry.key)) {
+        continue;
+      }
+      final configSpecNode =
+          ConfigValue(path: path, value: inputMap[entry.key]);
+      if (!entry.valueConfigSpec._validateNode(configSpecNode, log: log)) {
+        result = false;
+        continue;
+      }
+    }
+
+    if (additionalProperties != AdditionalProperties.Allow) {
+      for (final key in inputMap.keys) {
+        if (!allKeys.contains(key)) {
+          if (log) {
+            _logger.severe("Unknown key - '${[...o.path, key].join(' -> ')}'.");
+          }
+          if (additionalProperties == AdditionalProperties.Error) {
+            result = false;
+          }
+        }
+      }
+    }
+
+    if (!result && customValidation != null) {
+      return customValidation!.call(o);
+    }
+    return result;
+  }
+
+  dynamic _getAllDefaults(ConfigValue o) {
+    final result = <dynamic, CE>{};
+    for (final entry in entries) {
+      final path = [...o.path, entry.key];
+      if (entry.defaultValue != null) {
+        result[entry.key] = entry.defaultValue!
+            .call(ConfigValue(path: path, value: null)) as CE;
+      } else if (entry.valueConfigSpec is HeterogeneousMapConfigSpec) {
+        final defaultValue =
+            (entry.valueConfigSpec as HeterogeneousMapConfigSpec)
+                ._getAllDefaults(ConfigValue(path: path, value: null));
+        if (defaultValue != null) {
+          result[entry.key] =
+              (entry.valueConfigSpec as HeterogeneousMapConfigSpec)
+                  ._getAllDefaults(ConfigValue(path: path, value: null)) as CE;
+        }
+      }
+      if (result.containsKey(entry.key) && entry.resultOrDefault != null) {
+        // Call resultOrDefault hook for HeterogeneousMapEntry.
+        entry.resultOrDefault!.call(ConfigValue(
+            path: path, value: result[entry.key], nullRawValue: true));
+      }
+    }
+    return result.isEmpty
+        ? null
+        : o
+            .withValue(result, null)
+            .transformOrThis(transform, this.result)
+            .value;
+  }
+
+  @override
+  ConfigValue<RE> _extractNode(ConfigValue o) {
+    if (!o.checkType<Map>(log: false)) {
+      throw ConfigSpecExtractionError(o);
+    }
+
+    final inputMap = (o.value as Map);
+    final childExtracts = <dynamic, CE>{};
+
+    for (final requiredKey in requiredKeys) {
+      if (!inputMap.containsKey(requiredKey)) {
+        throw ConfigSpecExtractionError(
+            null, "Invalid config spec, missing required key - $requiredKey.");
+      }
+    }
+
+    for (final entry in entries) {
+      final path = [...o.path, entry.key.toString()];
+      if (!inputMap.containsKey(entry.key)) {
+        // No value specified, fill in with default value instead.
+        if (entry.defaultValue != null) {
+          childExtracts[entry.key] = entry.defaultValue!
+              .call(ConfigValue(path: path, value: null)) as CE;
+        } else if (entry.valueConfigSpec is HeterogeneousMapConfigSpec) {
+          final defaultValue =
+              (entry.valueConfigSpec as HeterogeneousMapConfigSpec)
+                  ._getAllDefaults(ConfigValue(path: path, value: null));
+          if (defaultValue != null) {
+            childExtracts[entry.key] = (entry.valueConfigSpec
+                    as HeterogeneousMapConfigSpec)
+                ._getAllDefaults(ConfigValue(path: path, value: null)) as CE;
+          }
+        }
+      } else {
+        // Extract value from node.
+        final configSpecNode =
+            ConfigValue(path: path, value: inputMap[entry.key]);
+        if (!entry.valueConfigSpec._validateNode(configSpecNode, log: false)) {
+          throw ConfigSpecExtractionError(configSpecNode);
+        }
+        childExtracts[entry.key] =
+            entry.valueConfigSpec._extractNode(configSpecNode).value as CE;
+      }
+
+      if (childExtracts.containsKey(entry.key) &&
+          entry.resultOrDefault != null) {
+        // Call resultOrDefault hook for HeterogeneousMapEntry.
+        entry.resultOrDefault!.call(ConfigValue(
+            path: path, value: childExtracts[entry.key], nullRawValue: true));
+      }
+    }
+
+    if (additionalProperties == AdditionalProperties.Error) {
+      for (final key in inputMap.keys) {
+        if (!allKeys.contains(key)) {
+          throw ConfigSpecExtractionError(
+              o, "Invalid ConfigSpec: additional properties not allowed.");
+        }
+      }
+    }
+
+    return o
+        .withValue(childExtracts, o.rawValue)
+        .transformOrThis(transform, result);
+  }
+
+  @override
+  Map<String, dynamic> _generateJsonSchemaNode(Map<String, dynamic> defs) {
+    return {
+      "type": "object",
+      if (additionalProperties != AdditionalProperties.Allow)
+        "additionalProperties": false,
+      if (schemaDescription != null) "description": schemaDescription!,
+      if (entries.isNotEmpty)
+        "properties": {
+          for (final kv in entries)
+            kv.key: kv.valueConfigSpec._getJsonRefOrSchemaNode(defs)
+        },
+      if (requiredKeys.isNotEmpty) "required": requiredKeys.toList(),
+    };
+  }
+}
+
+/// ConfigSpec for a Map that can have any number of keys.
+///
+/// [CE] typecasts result from keyValueConfigSpecs->{}->valueConfigSpec.
+///
+/// [RE] typecasts result returned by this node.
+class MapConfigSpec<CE extends Object?, RE extends Object?>
+    extends ConfigSpec<Map<dynamic, CE>, RE> {
+  /// Both [keyRegexp] - [valueConfigSpec] pair is used to match a set of
+  /// key-value input. Atleast one entry must match against an input for it
+  /// to be considered valid.
+  ///
+  /// Note: [keyRegexp] will be matched against key.toString()
+  final List<({String keyRegexp, ConfigSpec valueConfigSpec})>
+      keyValueConfigSpecs;
+
+  MapConfigSpec({
+    required this.keyValueConfigSpecs,
+    super.schemaDefName,
+    super.schemaDescription,
+    super.customValidation,
+    super.transform,
+    super.result,
+  });
+
+  @override
+  bool _validateNode(ConfigValue o, {bool log = true}) {
+    if (!o.checkType<Map>(log: log)) {
+      return false;
+    }
+
+    var result = true;
+    final inputMap = (o.value as Map);
+
+    for (final MapEntry(key: key, value: value) in inputMap.entries) {
+      final configSpecNode =
+          ConfigValue(path: [...o.path, key.toString()], value: value);
+      var keyValueMatch = false;
+
+      /// Running first time with no logs.
+      for (final (keyRegexp: keyRegexp, valueConfigSpec: valueConfigSpec)
+          in keyValueConfigSpecs) {
+        if (RegExp(keyRegexp, dotAll: true).hasMatch(key.toString()) &&
+            valueConfigSpec._validateNode(configSpecNode, log: false)) {
+          keyValueMatch = true;
+          break;
+        }
+      }
+      if (!keyValueMatch) {
+        result = false;
+        // No configSpec matched, running again to print logs this time.
+        if (log) {
+          _logger.severe(
+              "'${configSpecNode.pathString}' must match atleast one of the allowed key regex and configSpec.");
+          for (final (keyRegexp: keyRegexp, valueConfigSpec: valueConfigSpec)
+              in keyValueConfigSpecs) {
+            if (!RegExp(keyRegexp, dotAll: true).hasMatch(key.toString())) {
+              _logger.severe(
+                  "'${configSpecNode.pathString}' does not match regex - '$keyRegexp' (Input - $key)");
+              continue;
+            }
+            if (valueConfigSpec._validateNode(configSpecNode, log: log)) {
+              continue;
+            }
+          }
+        }
+      }
+    }
+
+    if (!result && customValidation != null) {
+      return customValidation!.call(o);
+    }
+    return result;
+  }
+
+  @override
+  ConfigValue<RE> _extractNode(ConfigValue o) {
+    if (!o.checkType<Map>(log: false)) {
+      throw ConfigSpecExtractionError(o);
+    }
+
+    final inputMap = (o.value as Map);
+    final childExtracts = <dynamic, CE>{};
+    for (final MapEntry(key: key, value: value) in inputMap.entries) {
+      final configSpecNode =
+          ConfigValue(path: [...o.path, key.toString()], value: value);
+      var keyValueMatch = false;
+      for (final (keyRegexp: keyRegexp, valueConfigSpec: valueConfigSpec)
+          in keyValueConfigSpecs) {
+        if (RegExp(keyRegexp, dotAll: true).hasMatch(key.toString()) &&
+            valueConfigSpec._validateNode(configSpecNode, log: false)) {
+          childExtracts[key] =
+              valueConfigSpec._extractNode(configSpecNode).value as CE;
+          keyValueMatch = true;
+          break;
+        }
+      }
+      if (!keyValueMatch) {
+        throw ConfigSpecExtractionError(configSpecNode);
+      }
+    }
+
+    return o
+        .withValue(childExtracts, o.rawValue)
+        .transformOrThis(transform, result);
+  }
+
+  @override
+  Map<String, dynamic> _generateJsonSchemaNode(Map<String, dynamic> defs) {
+    return {
+      "type": "object",
+      if (schemaDescription != null) "description": schemaDescription!,
+      if (keyValueConfigSpecs.isNotEmpty)
+        "patternProperties": {
+          for (final (keyRegexp: keyRegexp, valueConfigSpec: valueConfigSpec)
+              in keyValueConfigSpecs)
+            keyRegexp: valueConfigSpec._getJsonRefOrSchemaNode(defs)
+        }
+    };
+  }
+}
+
+/// ConfigSpec for a List.
+///
+/// [CE] typecasts result from [childConfigSpec].
+///
+/// [RE] typecasts result returned by this node.
+class ListConfigSpec<CE extends Object?, RE extends Object?>
+    extends ConfigSpec<List<CE>, RE> {
+  final ConfigSpec childConfigSpec;
+
+  ListConfigSpec({
+    required this.childConfigSpec,
+    super.schemaDefName,
+    super.schemaDescription,
+    super.customValidation,
+    super.transform,
+    super.result,
+  });
+
+  @override
+  bool _validateNode(ConfigValue o, {bool log = true}) {
+    if (!o.checkType<YamlList>(log: log)) {
+      return false;
+    }
+    final inputList = (o.value as YamlList).cast<dynamic>();
+    var result = true;
+    for (final (i, input) in inputList.indexed) {
+      final configSpecNode =
+          ConfigValue(path: [...o.path, "[$i]"], value: input);
+      if (!childConfigSpec._validateNode(configSpecNode, log: log)) {
+        result = false;
+        continue;
+      }
+    }
+
+    if (!result && customValidation != null) {
+      return customValidation!.call(o);
+    }
+    return result;
+  }
+
+  @override
+  ConfigValue<RE> _extractNode(ConfigValue o) {
+    if (!o.checkType<YamlList>(log: false)) {
+      throw ConfigSpecExtractionError(o);
+    }
+    final inputList = (o.value as YamlList).cast<dynamic>();
+    final childExtracts = <CE>[];
+    for (final (i, input) in inputList.indexed) {
+      final configSpecNode =
+          ConfigValue(path: [...o.path, i.toString()], value: input);
+      if (!childConfigSpec._validateNode(configSpecNode, log: false)) {
+        throw ConfigSpecExtractionError(configSpecNode);
+      }
+      childExtracts
+          .add(childConfigSpec._extractNode(configSpecNode).value as CE);
+    }
+    return o
+        .withValue(childExtracts, o.rawValue)
+        .transformOrThis(transform, result);
+  }
+
+  @override
+  Map<String, dynamic> _generateJsonSchemaNode(Map<String, dynamic> defs) {
+    return {
+      "type": "array",
+      if (schemaDescription != null) "description": schemaDescription!,
+      "items": childConfigSpec._getJsonRefOrSchemaNode(defs),
+    };
+  }
+}
+
+/// ConfigSpec for a String.
+///
+/// [RE] typecasts result returned by this node.
+class StringConfigSpec<RE extends Object?> extends ConfigSpec<String, RE> {
+  final String? pattern;
+  final RegExp? _regexp;
+
+  StringConfigSpec({
+    super.schemaDefName,
+    super.schemaDescription,
+    super.customValidation,
+    super.transform,
+    super.result,
+    this.pattern,
+  }) : _regexp = pattern == null ? null : RegExp(pattern, dotAll: true);
+
+  @override
+  bool _validateNode(ConfigValue o, {bool log = true}) {
+    if (!o.checkType<String>(log: log)) {
+      return false;
+    }
+    if (!(_regexp?.hasMatch(o.value as String) ?? true)) {
+      if (log) {
+        _logger.severe(
+            "Expected value of key '${o.pathString}' to match pattern $pattern (Input - ${o.value}).");
+      }
+      return false;
+    }
+    if (customValidation != null) {
+      return customValidation!.call(o);
+    }
+    return true;
+  }
+
+  @override
+  ConfigValue<RE> _extractNode(ConfigValue o) {
+    if (!o.checkType<String>(log: false)) {
+      throw ConfigSpecExtractionError(o);
+    }
+    return o
+        .withValue(o.value as String, o.rawValue)
+        .transformOrThis(transform, result);
+  }
+
+  @override
+  Map<String, dynamic> _generateJsonSchemaNode(Map<String, dynamic> defs) {
+    return {
+      "type": "string",
+      if (schemaDescription != null) "description": schemaDescription!,
+      if (pattern != null) "pattern": pattern,
+    };
+  }
+}
+
+/// ConfigSpec for an Int.
+///
+/// [RE] typecasts result returned by this node.
+class IntConfigSpec<RE extends Object?> extends ConfigSpec<int, RE> {
+  IntConfigSpec({
+    super.schemaDefName,
+    super.schemaDescription,
+    super.customValidation,
+    super.transform,
+    super.result,
+  });
+
+  @override
+  bool _validateNode(ConfigValue o, {bool log = true}) {
+    if (!o.checkType<int>(log: log)) {
+      return false;
+    }
+    if (customValidation != null) {
+      return customValidation!.call(o);
+    }
+    return true;
+  }
+
+  @override
+  ConfigValue<RE> _extractNode(ConfigValue o) {
+    if (!o.checkType<int>(log: false)) {
+      throw ConfigSpecExtractionError(o);
+    }
+    return o
+        .withValue(o.value as int, o.rawValue)
+        .transformOrThis(transform, result);
+  }
+
+  @override
+  Map<String, dynamic> _generateJsonSchemaNode(Map<String, dynamic> defs) {
+    return {
+      "type": "integer",
+      if (schemaDescription != null) "description": schemaDescription!,
+    };
+  }
+}
+
+/// ConfigSpec for an object where only specific values are allowed.
+/// [CE] is the type for elements in [allowedValues].
+///
+/// [RE] typecasts result returned by this node.
+class EnumConfigSpec<CE extends Object?, RE extends Object?>
+    extends ConfigSpec<CE, RE> {
+  Set<CE> allowedValues;
+  EnumConfigSpec({
+    required this.allowedValues,
+    super.schemaDefName,
+    super.schemaDescription,
+    super.customValidation,
+    super.transform,
+    super.result,
+  });
+
+  @override
+  bool _validateNode(ConfigValue o, {bool log = true}) {
+    if (!allowedValues.contains(o.value)) {
+      if (log) {
+        _logger.severe(
+            "'${o.pathString}' must be one of the following - $allowedValues (Got ${o.value})");
+      }
+      return false;
+    }
+    if (customValidation != null) {
+      return customValidation!.call(o);
+    }
+    return true;
+  }
+
+  @override
+  ConfigValue<RE> _extractNode(ConfigValue o) {
+    if (!allowedValues.contains(o.value)) {
+      throw ConfigSpecExtractionError(o);
+    }
+    return o
+        .withValue(o.value as CE, o.rawValue)
+        .transformOrThis(transform, result);
+  }
+
+  @override
+  Map<String, dynamic> _generateJsonSchemaNode(Map<String, dynamic> defs) {
+    return {
+      "enum": allowedValues.toList(),
+      if (schemaDescription != null) "description": schemaDescription!,
+    };
+  }
+}
+
+/// ConfigSpec for a bool.
+///
+/// [RE] typecasts result returned by this node.
+class BoolConfigSpec<RE> extends ConfigSpec<bool, RE> {
+  BoolConfigSpec({
+    super.schemaDefName,
+    super.schemaDescription,
+    super.customValidation,
+    super.transform,
+    super.result,
+  });
+
+  @override
+  bool _validateNode(ConfigValue o, {bool log = true}) {
+    if (!o.checkType<bool>(log: log)) {
+      return false;
+    }
+    if (customValidation != null) {
+      return customValidation!.call(o);
+    }
+    return true;
+  }
+
+  @override
+  ConfigValue<RE> _extractNode(ConfigValue o) {
+    if (!o.checkType<bool>(log: false)) {
+      throw ConfigSpecExtractionError(o);
+    }
+    return o
+        .withValue(o.value as bool, o.rawValue)
+        .transformOrThis(transform, result);
+  }
+
+  @override
+  Map<String, dynamic> _generateJsonSchemaNode(Map<String, dynamic> defs) {
+    return {
+      "type": "boolean",
+      if (schemaDescription != null) "description": schemaDescription!,
+    };
+  }
+}
+
+/// ConfigSpec that requires atleast one underlying match.
+///
+/// [TE] typecasts the result returned by the the first valid [childConfigSpecs].
+///
+/// [RE] typecasts result returned by this node.
+class OneOfConfigSpec<TE extends Object?, RE extends Object?>
+    extends ConfigSpec<TE, RE> {
+  final List<ConfigSpec> childConfigSpecs;
+
+  OneOfConfigSpec({
+    required this.childConfigSpecs,
+    super.schemaDefName,
+    super.schemaDescription,
+    super.customValidation,
+    super.transform,
+    super.result,
+  });
+
+  @override
+  bool _validateNode(ConfigValue o, {bool log = true}) {
+    // Running first time with no logs.
+    for (final spec in childConfigSpecs) {
+      if (spec._validateNode(o, log: false)) {
+        if (customValidation != null) {
+          return customValidation!.call(o);
+        }
+        return true;
+      }
+    }
+    // No configSpec matched, running again to print logs this time.
+    if (log) {
+      _logger.severe(
+          "'${o.pathString}' must match atleast one of the allowed configSpec -");
+      for (final spec in childConfigSpecs) {
+        spec._validateNode(o, log: log);
+      }
+    }
+    return false;
+  }
+
+  @override
+  ConfigValue<RE> _extractNode(ConfigValue o) {
+    for (final spec in childConfigSpecs) {
+      if (spec._validateNode(o, log: false)) {
+        return o
+            .withValue(spec._extractNode(o).value as TE, o.rawValue)
+            .transformOrThis(transform, result);
+      }
+    }
+    throw ConfigSpecExtractionError(o);
+  }
+
+  @override
+  Map<String, dynamic> _generateJsonSchemaNode(Map<String, dynamic> defs) {
+    return {
+      if (schemaDescription != null) "description": schemaDescription!,
+      r"$oneOf": childConfigSpecs
+          .map((child) => child._getJsonRefOrSchemaNode(defs))
+          .toList(),
+    };
+  }
+}
diff --git a/pkgs/ffigen/lib/src/config_provider/config_types.dart b/pkgs/ffigen/lib/src/config_provider/config_types.dart
new file mode 100644
index 0000000..a4cf142
--- /dev/null
+++ b/pkgs/ffigen/lib/src/config_provider/config_types.dart
@@ -0,0 +1,418 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Contains all the neccesary classes required by config.
+import 'dart:io';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:quiver/pattern.dart' as quiver;
+
+import 'path_finder.dart';
+
+enum Language { c, objc }
+
+class CommentType {
+  CommentStyle style;
+  CommentLength length;
+  CommentType(this.style, this.length);
+
+  /// Sets default style as [CommentStyle.doxygen], default length as
+  /// [CommentLength.full].
+  CommentType.def()
+      : style = CommentStyle.doxygen,
+        length = CommentLength.full;
+
+  /// Disables any comments.
+  CommentType.none()
+      : style = CommentStyle.doxygen,
+        length = CommentLength.none;
+}
+
+enum CommentStyle { doxygen, any }
+
+enum CommentLength { none, brief, full }
+
+enum CompoundDependencies { full, opaque }
+
+/// Holds config for how Structs Packing will be overriden.
+class StructPackingOverride {
+  final Map<RegExp, int?> _matcherMap;
+
+  StructPackingOverride({Map<RegExp, int?>? matcherMap})
+      : _matcherMap = matcherMap ?? {};
+
+  /// Returns true if the user has overriden the pack value.
+  bool isOverriden(String name) {
+    for (final key in _matcherMap.keys) {
+      if (quiver.matchesFull(key, name)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Returns pack value for [name]. Ensure that value [isOverriden] before
+  /// using the returned value.
+  int? getOverridenPackValue(String name) {
+    for (final opv in _matcherMap.entries) {
+      if (quiver.matchesFull(opv.key, name)) {
+        return opv.value;
+      }
+    }
+    return null;
+  }
+}
+
+// Holds headers and filters for header.
+class Headers {
+  /// Path to headers.
+  ///
+  /// This contains all the headers, after extraction from Globs.
+  final List<String> entryPoints;
+
+  /// Include filter for headers.
+  final HeaderIncludeFilter includeFilter;
+
+  Headers({List<String>? entryPoints, HeaderIncludeFilter? includeFilter})
+      : entryPoints = entryPoints ?? [],
+        includeFilter = includeFilter ?? GlobHeaderFilter();
+}
+
+abstract class HeaderIncludeFilter {
+  bool shouldInclude(String headerSourceFile);
+}
+
+class GlobHeaderFilter extends HeaderIncludeFilter {
+  List<quiver.Glob>? includeGlobs = [];
+
+  GlobHeaderFilter({
+    this.includeGlobs,
+  });
+
+  @override
+  bool shouldInclude(String headerSourceFile) {
+    // Return true if header was included.
+    for (final globPattern in includeGlobs!) {
+      if (quiver.matchesFull(globPattern, headerSourceFile)) {
+        return true;
+      }
+    }
+
+    // If any includedInclusionHeaders is provided, return false.
+    if (includeGlobs!.isNotEmpty) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+}
+
+/// A generic declaration config, used for Functions, Structs, Enums, Macros,
+/// unnamed Enums and Globals.
+class Declaration {
+  final Includer _includer;
+  final Renamer _renamer;
+  final MemberRenamer _memberRenamer;
+  final Includer _symbolAddressIncluder;
+
+  Declaration({
+    Includer? includer,
+    Renamer? renamer,
+    MemberRenamer? memberRenamer,
+    Includer? symbolAddressIncluder,
+  })  : _includer = includer ?? Includer(),
+        _renamer = renamer ?? Renamer(),
+        _memberRenamer = memberRenamer ?? MemberRenamer(),
+        _symbolAddressIncluder =
+            symbolAddressIncluder ?? Includer.excludeByDefault();
+
+  /// Applies renaming and returns the result.
+  String renameUsingConfig(String name) => _renamer.rename(name);
+
+  /// Applies member renaming and returns the result.
+  String renameMemberUsingConfig(String declaration, String member) =>
+      _memberRenamer.rename(declaration, member);
+
+  /// Checks if a name is allowed by a filter.
+  bool shouldInclude(String name, bool excludeAllByDefault) =>
+      _includer.shouldInclude(name, excludeAllByDefault);
+
+  /// Checks if the symbol address should be included for this name.
+  bool shouldIncludeSymbolAddress(String name) =>
+      _symbolAddressIncluder.shouldInclude(name);
+}
+
+/// Matches `$<single_digit_int>`, value can be accessed in group 1 of match.
+final replaceGroupRegexp = RegExp(r'\$([0-9])');
+
+/// Match/rename using [regExp].
+class RegExpRenamer {
+  final RegExp regExp;
+  final String replacementPattern;
+
+  RegExpRenamer(this.regExp, this.replacementPattern);
+
+  /// Returns true if [str] has a full match with [regExp].
+  bool matches(String str) => quiver.matchesFull(regExp, str);
+
+  /// Renames [str] according to [replacementPattern].
+  ///
+  /// Returns [str] if [regExp] doesn't have a full match.
+  String rename(String str) {
+    if (matches(str)) {
+      // Get match.
+      final regExpMatch = regExp.firstMatch(str)!;
+
+      /// Get group values.
+      /// E.g for `str`: `clang_dispose` and `regExp`: `clang_(.*)`
+      /// groups will be `0`: `clang_disponse`, `1`: `dispose`.
+      final groups = regExpMatch.groups(
+          List.generate(regExpMatch.groupCount, (index) => index) +
+              [regExpMatch.groupCount]);
+
+      /// Replace all `$<int>` symbols with respective groups (if any).
+      final result =
+          replacementPattern.replaceAllMapped(replaceGroupRegexp, (match) {
+        final groupInt = int.parse(match.group(1)!);
+        return groups[groupInt]!;
+      });
+      return result;
+    } else {
+      return str;
+    }
+  }
+
+  @override
+  String toString() {
+    return 'Regexp: $regExp, ReplacementPattern: $replacementPattern';
+  }
+}
+
+/// Handles `include/exclude` logic for a declaration.
+class Includer {
+  final List<RegExp> _includeMatchers;
+  final Set<String> _includeFull;
+  final List<RegExp> _excludeMatchers;
+  final Set<String> _excludeFull;
+
+  Includer({
+    List<RegExp>? includeMatchers,
+    Set<String>? includeFull,
+    List<RegExp>? excludeMatchers,
+    Set<String>? excludeFull,
+  })  : _includeMatchers = includeMatchers ?? [],
+        _includeFull = includeFull ?? {},
+        _excludeMatchers = excludeMatchers ?? [],
+        _excludeFull = excludeFull ?? {};
+
+  Includer.excludeByDefault()
+      : _includeMatchers = [],
+        _includeFull = {},
+        _excludeMatchers = [RegExp('.*', dotAll: true)],
+        _excludeFull = {};
+
+  /// Returns true if [name] is allowed.
+  ///
+  /// Exclude overrides include.
+  bool shouldInclude(String name, [bool excludeAllByDefault = false]) {
+    if (_excludeFull.contains(name)) {
+      return false;
+    }
+
+    for (final em in _excludeMatchers) {
+      if (quiver.matchesFull(em, name)) {
+        return false;
+      }
+    }
+
+    if (_includeFull.contains(name)) {
+      return true;
+    }
+
+    for (final im in _includeMatchers) {
+      if (quiver.matchesFull(im, name)) {
+        return true;
+      }
+    }
+
+    // If user has provided 'include' field in the filter, then default
+    // matching is false.
+    if (_includeMatchers.isNotEmpty || _includeFull.isNotEmpty) {
+      return false;
+    } else {
+      // Otherwise, fall back to the default behavior for empty filters.
+      return !excludeAllByDefault;
+    }
+  }
+}
+
+/// Handles `full/regexp` renaming logic.
+class Renamer {
+  final Map<String, String> _renameFull;
+  final List<RegExpRenamer> _renameMatchers;
+
+  Renamer({
+    List<RegExpRenamer>? renamePatterns,
+    Map<String, String>? renameFull,
+  })  : _renameMatchers = renamePatterns ?? [],
+        _renameFull = renameFull ?? {};
+
+  Renamer.noRename()
+      : _renameMatchers = [],
+        _renameFull = {};
+
+  String rename(String name) {
+    // Apply full rename (if any).
+    if (_renameFull.containsKey(name)) {
+      return _renameFull[name]!;
+    }
+
+    // Apply rename regexp (if matches).
+    for (final renamer in _renameMatchers) {
+      if (renamer.matches(name)) {
+        return renamer.rename(name);
+      }
+    }
+
+    // No renaming is provided for this declaration, return unchanged.
+    return name;
+  }
+}
+
+/// Match declaration name using [declarationRegExp].
+class RegExpMemberRenamer {
+  final RegExp declarationRegExp;
+  final Renamer memberRenamer;
+
+  RegExpMemberRenamer(this.declarationRegExp, this.memberRenamer);
+
+  /// Returns true if [declaration] has a full match with [regExp].
+  bool matchesDeclarationName(String declaration) =>
+      quiver.matchesFull(declarationRegExp, declaration);
+
+  @override
+  String toString() {
+    return 'DeclarationRegExp: $declarationRegExp, MemberRenamer: $memberRenamer';
+  }
+}
+
+/// Handles `full/regexp` member renaming.
+class MemberRenamer {
+  final Map<String, Renamer> _memberRenameFull;
+  final List<RegExpMemberRenamer> _memberRenameMatchers;
+
+  final Map<String, Renamer> _cache = {};
+
+  MemberRenamer({
+    Map<String, Renamer>? memberRenameFull,
+    List<RegExpMemberRenamer>? memberRenamePattern,
+  })  : _memberRenameFull = memberRenameFull ?? {},
+        _memberRenameMatchers = memberRenamePattern ?? [];
+
+  String rename(String declaration, String member) {
+    if (_cache.containsKey(declaration)) {
+      return _cache[declaration]!.rename(member);
+    }
+
+    // Apply full rename (if any).
+    if (_memberRenameFull.containsKey(declaration)) {
+      // Add to cache.
+      _cache[declaration] = _memberRenameFull[declaration]!;
+      return _cache[declaration]!.rename(member);
+    }
+
+    // Apply rename regexp (if matches).
+    for (final renamer in _memberRenameMatchers) {
+      if (renamer.matchesDeclarationName(declaration)) {
+        // Add to cache.
+        _cache[declaration] = renamer.memberRenamer;
+        return _cache[declaration]!.rename(member);
+      }
+    }
+
+    // No renaming is provided for this declaration, return unchanged.
+    return member;
+  }
+}
+
+/// Handles config for automatically added compiler options.
+class CompilerOptsAuto {
+  final bool macIncludeStdLib;
+
+  CompilerOptsAuto({bool? macIncludeStdLib})
+      : macIncludeStdLib = macIncludeStdLib ?? true;
+
+  /// Extracts compiler options based on OS and config.
+  List<String> extractCompilerOpts() {
+    if (Platform.isMacOS && macIncludeStdLib) {
+      return getCStandardLibraryHeadersForMac();
+    }
+
+    return [];
+  }
+}
+
+class _ObjCModulePrefixerEntry {
+  final RegExp pattern;
+  final String moduleName;
+
+  _ObjCModulePrefixerEntry(this.pattern, this.moduleName);
+}
+
+/// Handles applying module prefixes to ObjC classes.
+class ObjCModulePrefixer {
+  final _prefixes = <_ObjCModulePrefixerEntry>[];
+
+  ObjCModulePrefixer(Map<String, String> prefixes) {
+    for (final entry in prefixes.entries) {
+      _prefixes.add(_ObjCModulePrefixerEntry(RegExp(entry.key), entry.value));
+    }
+  }
+
+  /// If any of the prefixing patterns match, applies that module prefix.
+  /// Otherwise returns the class name unmodified.
+  String applyPrefix(String className) {
+    for (final entry in _prefixes) {
+      if (quiver.matchesFull(entry.pattern, className)) {
+        return '${entry.moduleName}.$className';
+      }
+    }
+    return className;
+  }
+}
+
+class FfiNativeConfig {
+  final bool enabled;
+  final String? assetId;
+
+  const FfiNativeConfig({required this.enabled, this.assetId});
+}
+
+class SymbolFile {
+  final String importPath;
+  final String output;
+
+  SymbolFile(this.importPath, this.output);
+}
+
+class OutputConfig {
+  final String output;
+  final SymbolFile? symbolFile;
+
+  OutputConfig(this.output, this.symbolFile);
+}
+
+class RawVarArgFunction {
+  String? postfix;
+  final List<String> rawTypeStrings;
+
+  RawVarArgFunction(this.postfix, this.rawTypeStrings);
+}
+
+class VarArgFunction {
+  final String postfix;
+  final List<Type> types;
+
+  VarArgFunction(this.postfix, this.types);
+}
diff --git a/pkgs/ffigen/lib/src/config_provider/path_finder.dart b/pkgs/ffigen/lib/src/config_provider/path_finder.dart
new file mode 100644
index 0000000..715e1ac
--- /dev/null
+++ b/pkgs/ffigen/lib/src/config_provider/path_finder.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Utils for finding header paths on system.
+
+import 'dart:io';
+
+import 'package:logging/logging.dart';
+import 'package:path/path.dart' as p;
+
+final _logger = Logger('ffigen.config_provider.path_finder');
+
+/// This will return include path from either LLVM, XCode or CommandLineTools.
+List<String> getCStandardLibraryHeadersForMac() {
+  final includePaths = <String>[];
+
+  /// Add system headers.
+  const systemHeaders =
+      '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include';
+  if (Directory(systemHeaders).existsSync()) {
+    _logger.fine('Added $systemHeaders to compiler-opts.');
+    includePaths.add('-I$systemHeaders');
+  }
+
+  /// Find headers from XCode or LLVM installed via brew.
+  const brewLlvmPath = '/usr/local/opt/llvm/lib/clang';
+  const xcodeClangPath =
+      '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/';
+  const searchPaths = [brewLlvmPath, xcodeClangPath];
+  for (final searchPath in searchPaths) {
+    if (!Directory(searchPath).existsSync()) continue;
+
+    final result = Process.runSync('ls', [searchPath]);
+    final stdout = result.stdout as String;
+    if (stdout != '') {
+      final versions = stdout.split('\n').where((s) => s != '');
+      for (final version in versions) {
+        final path = p.join(searchPath, version, 'include');
+        if (Directory(path).existsSync()) {
+          _logger.fine('Added stdlib path: $path to compiler-opts.');
+          includePaths.add('-I$path');
+          return includePaths;
+        }
+      }
+    }
+  }
+
+  /// If CommandLineTools are installed use those headers.
+  const cmdLineToolHeaders =
+      '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Kernel.framework/Headers/';
+  if (Directory(cmdLineToolHeaders).existsSync()) {
+    _logger.fine('Added stdlib path: $cmdLineToolHeaders to compiler-opts.');
+    includePaths.add('-I$cmdLineToolHeaders');
+    return includePaths;
+  }
+
+  // Warnings for missing headers are printed by libclang while parsing.
+  _logger.fine('Couldn\'t find stdlib headers in default locations.');
+  _logger.fine('Paths searched: ${[cmdLineToolHeaders, ...searchPaths]}');
+
+  return [];
+}
diff --git a/pkgs/ffigen/lib/src/config_provider/spec_utils.dart b/pkgs/ffigen/lib/src/config_provider/spec_utils.dart
new file mode 100644
index 0000000..86a4bc5
--- /dev/null
+++ b/pkgs/ffigen/lib/src/config_provider/spec_utils.dart
@@ -0,0 +1,607 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/code_generator/utils.dart';
+import 'package:ffigen/src/header_parser/type_extractor/cxtypekindmap.dart';
+import 'package:file/local.dart';
+import 'package:glob/glob.dart';
+import 'package:logging/logging.dart';
+import 'package:package_config/package_config.dart';
+import 'package:path/path.dart' as p;
+import 'package:quiver/pattern.dart' as quiver;
+import 'package:yaml/yaml.dart';
+
+import '../strings.dart' as strings;
+import 'config_types.dart';
+
+final _logger = Logger('ffigen.config_provider.spec_utils');
+
+/// Replaces the path separators according to current platform.
+String _replaceSeparators(String path) {
+  if (Platform.isWindows) {
+    return path.replaceAll(p.posix.separator, p.windows.separator);
+  } else {
+    return path.replaceAll(p.windows.separator, p.posix.separator);
+  }
+}
+
+/// Replaces the path separators according to current platform. If a relative
+/// path is passed in, it is resolved relative to the config path, and the
+/// absolute path is returned.
+String _normalizePath(String path, String? configFilename) {
+  final skipNormalization =
+      (configFilename == null) || p.isAbsolute(path) || path.startsWith("**");
+  return _replaceSeparators(
+      skipNormalization ? path : p.join(p.dirname(configFilename), path));
+}
+
+Map<String, LibraryImport> libraryImportsExtractor(
+    Map<String, String>? typeMap) {
+  final resultMap = <String, LibraryImport>{};
+  if (typeMap != null) {
+    for (final typeName in typeMap.keys) {
+      resultMap[typeName] =
+          LibraryImport(typeName, typeMap[typeName] as String);
+    }
+  }
+  return resultMap;
+}
+
+void loadImportedTypes(YamlMap fileConfig,
+    Map<String, ImportedType> usrTypeMappings, LibraryImport libraryImport) {
+  final symbols = fileConfig['symbols'] as YamlMap;
+  for (final key in symbols.keys) {
+    final usr = key as String;
+    final value = symbols[usr]! as YamlMap;
+    usrTypeMappings[usr] = ImportedType(
+        libraryImport, value['name'] as String, value['name'] as String);
+  }
+}
+
+YamlMap loadSymbolFile(String symbolFilePath, String? configFileName,
+    PackageConfig? packageConfig) {
+  final path = symbolFilePath.startsWith('package:')
+      ? packageConfig!.resolve(Uri.parse(symbolFilePath))!.toFilePath()
+      : _normalizePath(symbolFilePath, configFileName);
+
+  return loadYaml(File(path).readAsStringSync()) as YamlMap;
+}
+
+Map<String, ImportedType> symbolFileImportExtractor(
+    List<String> yamlConfig,
+    Map<String, LibraryImport> libraryImports,
+    String? configFileName,
+    PackageConfig? packageConfig) {
+  final resultMap = <String, ImportedType>{};
+  for (final item in yamlConfig) {
+    String symbolFilePath;
+    symbolFilePath = item;
+    final symbolFile =
+        loadSymbolFile(symbolFilePath, configFileName, packageConfig);
+    final formatVersion = symbolFile[strings.formatVersion] as String;
+    if (formatVersion.split('.')[0] !=
+        strings.symbolFileFormatVersion.split('.')[0]) {
+      _logger.severe(
+          'Incompatible format versions for file $symbolFilePath: ${strings.symbolFileFormatVersion}(ours), $formatVersion(theirs).');
+      exit(1);
+    }
+    final uniqueNamer = UniqueNamer(libraryImports.keys
+        .followedBy([strings.defaultSymbolFileImportPrefix]).toSet());
+    for (final file in (symbolFile[strings.files] as YamlMap).keys) {
+      final existingImports =
+          libraryImports.values.where((element) => element.importPath == file);
+      if (existingImports.isEmpty) {
+        final name =
+            uniqueNamer.makeUnique(strings.defaultSymbolFileImportPrefix);
+        libraryImports[name] = LibraryImport(name, file as String);
+      }
+      final libraryImport = libraryImports.values.firstWhere(
+        (element) => element.importPath == file,
+      );
+      loadImportedTypes(
+          symbolFile[strings.files][file] as YamlMap, resultMap, libraryImport);
+    }
+  }
+  return resultMap;
+}
+
+Map<String, List<String>> typeMapExtractor(Map<dynamic, dynamic>? yamlConfig) {
+  // Key - type_name, Value - [lib, cType, dartType].
+  final resultMap = <String, List<String>>{};
+  final typeMap = yamlConfig;
+  if (typeMap != null) {
+    for (final typeName in typeMap.keys) {
+      final typeConfigItem = typeMap[typeName] as Map;
+      resultMap[typeName as String] = [
+        typeConfigItem[strings.lib] as String,
+        typeConfigItem[strings.cType] as String,
+        typeConfigItem[strings.dartType] as String,
+      ];
+    }
+  }
+  return resultMap;
+}
+
+Map<String, ImportedType> makeImportTypeMapping(
+    Map<String, List<String>> rawTypeMappings,
+    Map<String, LibraryImport> libraryImportsMap) {
+  final typeMappings = <String, ImportedType>{};
+  for (final key in rawTypeMappings.keys) {
+    final lib = rawTypeMappings[key]![0];
+    final cType = rawTypeMappings[key]![1];
+    final dartType = rawTypeMappings[key]![2];
+    if (strings.predefinedLibraryImports.containsKey(lib)) {
+      typeMappings[key] =
+          ImportedType(strings.predefinedLibraryImports[lib]!, cType, dartType);
+    } else if (libraryImportsMap.containsKey(lib)) {
+      typeMappings[key] =
+          ImportedType(libraryImportsMap[lib]!, cType, dartType);
+    } else {
+      throw Exception("Please declare $lib under library-imports.");
+    }
+  }
+  return typeMappings;
+}
+
+Type makePointerToType(Type type, int pointerCount) {
+  for (var i = 0; i < pointerCount; i++) {
+    type = PointerType(type);
+  }
+  return type;
+}
+
+String makePostfixFromRawVarArgType(List<String> rawVarArgType) {
+  return rawVarArgType
+      .map((e) => e
+          .replaceAll('*', 'Ptr')
+          .replaceAll(RegExp(r'_t$'), '')
+          .replaceAll(' ', '')
+          .replaceAll(RegExp('[^A-Za-z0-9_]'), ''))
+      .map((e) => e.length > 1 ? '${e[0].toUpperCase()}${e.substring(1)}' : e)
+      .join('');
+}
+
+Type makeTypeFromRawVarArgType(
+    String rawVarArgType, Map<String, LibraryImport> libraryImportsMap) {
+  Type baseType;
+  var rawBaseType = rawVarArgType.trim();
+  // Split the raw type based on pointer usage. E.g -
+  // int => [int]
+  // char* => [char,*]
+  // ffi.Hello ** => [ffi.Hello,**]
+  final typeStringRegexp = RegExp(r'([a-zA-Z0-9_\s\.]+)(\**)$');
+  if (!typeStringRegexp.hasMatch(rawBaseType)) {
+    throw Exception('Cannot parse variadic argument type - $rawVarArgType.');
+  }
+  final regExpMatch = typeStringRegexp.firstMatch(rawBaseType)!;
+  final groups = regExpMatch.groups([1, 2]);
+  rawBaseType = groups[0]!;
+  // Handle basic supported types.
+  if (cxTypeKindToImportedTypes.containsKey(rawBaseType)) {
+    baseType = cxTypeKindToImportedTypes[rawBaseType]!;
+  } else if (supportedTypedefToImportedType.containsKey(rawBaseType)) {
+    baseType = supportedTypedefToImportedType[rawBaseType]!;
+  } else if (suportedTypedefToSuportedNativeType.containsKey(rawBaseType)) {
+    baseType = NativeType(suportedTypedefToSuportedNativeType[rawBaseType]!);
+  } else {
+    // Use library import if specified (E.g - ffi.UintPtr or custom.MyStruct)
+    final rawVarArgTypeSplit = rawBaseType.split('.');
+    if (rawVarArgTypeSplit.length == 1) {
+      final typeName = rawVarArgTypeSplit[0].replaceAll(' ', '');
+      baseType = SelfImportedType(typeName, typeName);
+    } else if (rawVarArgTypeSplit.length == 2) {
+      final lib = rawVarArgTypeSplit[0];
+      final libraryImport = strings.predefinedLibraryImports[lib] ??
+          libraryImportsMap[rawVarArgTypeSplit[0]];
+      if (libraryImport == null) {
+        throw Exception('Please declare $lib in library-imports.');
+      }
+      final typeName = rawVarArgTypeSplit[1].replaceAll(' ', '');
+      baseType = ImportedType(libraryImport, typeName, typeName);
+    } else {
+      throw Exception(
+          'Invalid type $rawVarArgType : Expected 0 or 1 .(dot) separators.');
+    }
+  }
+
+  // Handle pointers
+  final pointerCount = groups[1]!.length;
+  return makePointerToType(baseType, pointerCount);
+}
+
+Map<String, List<VarArgFunction>> makeVarArgFunctionsMapping(
+    Map<String, List<RawVarArgFunction>> rawVarArgMappings,
+    Map<String, LibraryImport> libraryImportsMap) {
+  final mappings = <String, List<VarArgFunction>>{};
+  for (final key in rawVarArgMappings.keys) {
+    final varArgList = <VarArgFunction>[];
+    for (final rawVarArg in rawVarArgMappings[key]!) {
+      var postfix = rawVarArg.postfix ?? '';
+      final types = <Type>[];
+      for (final rva in rawVarArg.rawTypeStrings) {
+        types.add(makeTypeFromRawVarArgType(rva, libraryImportsMap));
+      }
+      if (postfix.isEmpty) {
+        if (rawVarArgMappings[key]!.length == 1) {
+          postfix = '';
+        } else {
+          postfix = makePostfixFromRawVarArgType(rawVarArg.rawTypeStrings);
+        }
+      }
+      // Extract postfix from config and/or deduce from var names.
+      varArgList.add(VarArgFunction(postfix, types));
+    }
+    mappings[key] = varArgList;
+  }
+  return mappings;
+}
+
+final _quoteMatcher = RegExp(r'''^["'](.*)["']$''', dotAll: true);
+final _cmdlineArgMatcher = RegExp(r'''['"](\\"|[^"])*?['"]|[^ ]+''');
+List<String> compilerOptsToList(String compilerOpts) {
+  final list = <String>[];
+  _cmdlineArgMatcher.allMatches(compilerOpts).forEach((element) {
+    var match = element.group(0);
+    if (match != null) {
+      if (quiver.matchesFull(_quoteMatcher, match)) {
+        match = _quoteMatcher.allMatches(match).first.group(1)!;
+      }
+      list.add(match);
+    }
+  });
+
+  return list;
+}
+
+List<String> compilerOptsExtractor(List<String> value) {
+  final list = <String>[];
+  for (final el in (value)) {
+    list.addAll(compilerOptsToList(el));
+  }
+  return list;
+}
+
+Headers headersExtractor(
+    Map<dynamic, List<String>> yamlConfig, String? configFilename) {
+  final entryPoints = <String>[];
+  final includeGlobs = <quiver.Glob>[];
+  for (final key in yamlConfig.keys) {
+    if (key == strings.entryPoints) {
+      for (final h in (yamlConfig[key]!)) {
+        final headerGlob = _normalizePath(h, configFilename);
+        // Add file directly to header if it's not a Glob but a File.
+        if (File(headerGlob).existsSync()) {
+          final osSpecificPath = headerGlob;
+          entryPoints.add(osSpecificPath);
+          _logger.fine('Adding header/file: $headerGlob');
+        } else {
+          final glob = Glob(headerGlob);
+          for (final file in glob.listFileSystemSync(const LocalFileSystem(),
+              followLinks: true)) {
+            final fixedPath = file.path;
+            entryPoints.add(fixedPath);
+            _logger.fine('Adding header/file: $fixedPath');
+          }
+        }
+      }
+    }
+    if (key == strings.includeDirectives) {
+      for (final h in yamlConfig[key]!) {
+        final headerGlob = h;
+        final fixedGlob = _normalizePath(headerGlob, configFilename);
+        includeGlobs.add(quiver.Glob(fixedGlob));
+      }
+    }
+  }
+  return Headers(
+    entryPoints: entryPoints,
+    includeFilter: GlobHeaderFilter(
+      includeGlobs: includeGlobs,
+    ),
+  );
+}
+
+/// Returns location of dynamic library by searching default locations. Logs
+/// error and throws an Exception if not found.
+String findDylibAtDefaultLocations() {
+  String? k;
+  if (Platform.isLinux) {
+    for (final l in strings.linuxDylibLocations) {
+      k = findLibclangDylib(l);
+      if (k != null) return k;
+    }
+    Process.runSync('ldconfig', ['-p']);
+    final ldConfigResult = Process.runSync('ldconfig', ['-p']);
+    if (ldConfigResult.exitCode == 0) {
+      final lines = (ldConfigResult.stdout as String).split('\n');
+      final paths = [
+        for (final line in lines)
+          if (line.contains('libclang')) line.split(' => ')[1],
+      ];
+      for (final location in paths) {
+        if (File(location).existsSync()) {
+          return location;
+        }
+      }
+    }
+  } else if (Platform.isWindows) {
+    final dylibLocations = strings.windowsDylibLocations.toList();
+    final userHome = Platform.environment['USERPROFILE'];
+    if (userHome != null) {
+      dylibLocations
+          .add(p.join(userHome, 'scoop', 'apps', 'llvm', 'current', 'bin'));
+    }
+    for (final l in dylibLocations) {
+      k = findLibclangDylib(l);
+      if (k != null) return k;
+    }
+  } else if (Platform.isMacOS) {
+    for (final l in strings.macOsDylibLocations) {
+      k = findLibclangDylib(l);
+      if (k != null) return k;
+    }
+    final findLibraryResult =
+        Process.runSync('xcodebuild', ['-find-library', 'libclang.dylib']);
+    if (findLibraryResult.exitCode == 0) {
+      final location = (findLibraryResult.stdout as String).split('\n').first;
+      if (File(location).existsSync()) {
+        return location;
+      }
+    }
+    final xcodePathResult = Process.runSync('xcode-select', ['-print-path']);
+    if (xcodePathResult.exitCode == 0) {
+      final xcodePath = (xcodePathResult.stdout as String).split('\n').first;
+      final location =
+          p.join(xcodePath, strings.xcodeDylibLocation, strings.dylibFileName);
+      if (File(location).existsSync()) {
+        return location;
+      }
+    }
+  } else {
+    throw Exception('Unsupported Platform.');
+  }
+
+  _logger.severe("Couldn't find dynamic library in default locations.");
+  _logger.severe(
+      "Please supply one or more path/to/llvm in ffigen's config under the key '${strings.llvmPath}'.");
+  throw Exception("Couldn't find dynamic library in default locations.");
+}
+
+String? findLibclangDylib(String parentFolder) {
+  final location = p.join(parentFolder, strings.dylibFileName);
+  if (File(location).existsSync()) {
+    return location;
+  } else {
+    return null;
+  }
+}
+
+String llvmPathExtractor(List<String> value) {
+  // Extract libclang's dylib from user specified paths.
+  for (final path in value) {
+    final dylibPath =
+        findLibclangDylib(p.join(path, strings.dynamicLibParentName));
+    if (dylibPath != null) {
+      _logger.fine('Found dynamic library at: $dylibPath');
+      return dylibPath;
+    }
+    // Check if user has specified complete path to dylib.
+    final completeDylibPath = path;
+    if (p.extension(completeDylibPath).isNotEmpty &&
+        File(completeDylibPath).existsSync()) {
+      _logger.info(
+          'Using complete dylib path: $completeDylibPath from llvm-path.');
+      return completeDylibPath;
+    }
+  }
+  _logger.fine(
+      "Couldn't find dynamic library under paths specified by ${strings.llvmPath}.");
+  // Extract path from default locations.
+  try {
+    final res = findDylibAtDefaultLocations();
+    return res;
+  } catch (e) {
+    _logger.severe(
+        "Couldn't find ${p.join(strings.dynamicLibParentName, strings.dylibFileName)} in specified locations.");
+    exit(1);
+  }
+}
+
+OutputConfig outputExtractor(
+    dynamic value, String? configFilename, PackageConfig? packageConfig) {
+  if (value is String) {
+    return OutputConfig(_normalizePath(value, configFilename), null);
+  }
+  value = value as Map;
+  return OutputConfig(
+    _normalizePath((value)[strings.bindings] as String, configFilename),
+    value.containsKey(strings.symbolFile)
+        ? symbolFileOutputExtractor(
+            value[strings.symbolFile], configFilename, packageConfig)
+        : null,
+  );
+}
+
+SymbolFile symbolFileOutputExtractor(
+    dynamic value, String? configFilename, PackageConfig? packageConfig) {
+  value = value as Map;
+  var output = value[strings.output] as String;
+  if (Uri.parse(output).scheme != "package") {
+    _logger.warning(
+        'Consider using a Package Uri for ${strings.symbolFile} -> ${strings.output}: $output so that external packages can use it.');
+    output = _normalizePath(output, configFilename);
+  } else {
+    output = packageConfig!.resolve(Uri.parse(output))!.toFilePath();
+  }
+  final importPath = value[strings.importPath] as String;
+  if (Uri.parse(importPath).scheme != "package") {
+    _logger.warning(
+        'Consider using a Package Uri for ${strings.symbolFile} -> ${strings.importPath}: $importPath so that external packages can use it.');
+  }
+  return SymbolFile(importPath, output);
+}
+
+/// Returns true if [str] is not a full name.
+///
+/// E.g `abc` is a full name, `abc.*` is not.
+bool isFullDeclarationName(String str) =>
+    quiver.matchesFull(RegExp('[a-zA-Z_0-9]*'), str);
+
+Includer extractIncluderFromYaml(Map<dynamic, dynamic> yamlMap) {
+  final includeMatchers = <RegExp>[],
+      includeFull = <String>{},
+      excludeMatchers = <RegExp>[],
+      excludeFull = <String>{};
+
+  final include = yamlMap[strings.include] as List<String>?;
+  if (include != null) {
+    if (include.isEmpty) {
+      return Includer.excludeByDefault();
+    }
+    for (final str in include) {
+      if (isFullDeclarationName(str)) {
+        includeFull.add(str);
+      } else {
+        includeMatchers.add(RegExp(str, dotAll: true));
+      }
+    }
+  }
+
+  final exclude = yamlMap[strings.exclude] as List<String>?;
+  if (exclude != null) {
+    for (final str in exclude) {
+      if (isFullDeclarationName(str)) {
+        excludeFull.add(str);
+      } else {
+        excludeMatchers.add(RegExp(str, dotAll: true));
+      }
+    }
+  }
+
+  return Includer(
+    includeMatchers: includeMatchers,
+    includeFull: includeFull,
+    excludeMatchers: excludeMatchers,
+    excludeFull: excludeFull,
+  );
+}
+
+Map<String, List<RawVarArgFunction>> varArgFunctionConfigExtractor(
+    Map<dynamic, dynamic> yamlMap) {
+  final result = <String, List<RawVarArgFunction>>{};
+  final configMap = yamlMap;
+  for (final key in configMap.keys) {
+    final List<RawVarArgFunction> vafuncs = [];
+    for (final rawVaFunc in (configMap[key] as List)) {
+      if (rawVaFunc is List) {
+        vafuncs.add(RawVarArgFunction(null, rawVaFunc.cast()));
+      } else if (rawVaFunc is Map) {
+        vafuncs.add(RawVarArgFunction(rawVaFunc[strings.postfix] as String?,
+            (rawVaFunc[strings.types] as List).cast()));
+      } else {
+        throw Exception("Unexpected type in variadic-argument config.");
+      }
+    }
+    result[key as String] = vafuncs;
+  }
+
+  return result;
+}
+
+Declaration declarationConfigExtractor(Map<dynamic, dynamic> yamlMap) {
+  final renamePatterns = <RegExpRenamer>[];
+  final renameFull = <String, String>{};
+  final memberRenamePatterns = <RegExpMemberRenamer>[];
+  final memberRenamerFull = <String, Renamer>{};
+
+  final includer = extractIncluderFromYaml(yamlMap);
+
+  final symbolIncluder = yamlMap[strings.symbolAddress] as Includer?;
+
+  final rename = yamlMap[strings.rename] as Map<dynamic, String>?;
+
+  if (rename != null) {
+    for (final key in rename.keys) {
+      final str = key.toString();
+      if (isFullDeclarationName(str)) {
+        renameFull[str] = rename[str]!;
+      } else {
+        renamePatterns
+            .add(RegExpRenamer(RegExp(str, dotAll: true), rename[str]!));
+      }
+    }
+  }
+
+  final memberRename =
+      yamlMap[strings.memberRename] as Map<dynamic, Map<dynamic, String>>?;
+
+  if (memberRename != null) {
+    for (final key in memberRename.keys) {
+      final decl = key.toString();
+      final renamePatterns = <RegExpRenamer>[];
+      final renameFull = <String, String>{};
+
+      final memberRenameMap = memberRename[decl]!;
+      for (final member in memberRenameMap.keys) {
+        final memberStr = member.toString();
+        if (isFullDeclarationName(memberStr)) {
+          renameFull[memberStr] = memberRenameMap[member]!;
+        } else {
+          renamePatterns.add(RegExpRenamer(
+              RegExp(memberStr, dotAll: true), memberRenameMap[member]!));
+        }
+      }
+      if (isFullDeclarationName(decl)) {
+        memberRenamerFull[decl] = Renamer(
+          renameFull: renameFull,
+          renamePatterns: renamePatterns,
+        );
+      } else {
+        memberRenamePatterns.add(
+          RegExpMemberRenamer(
+            RegExp(decl, dotAll: true),
+            Renamer(
+              renameFull: renameFull,
+              renamePatterns: renamePatterns,
+            ),
+          ),
+        );
+      }
+    }
+  }
+
+  return Declaration(
+    includer: includer,
+    renamer: Renamer(
+      renameFull: renameFull,
+      renamePatterns: renamePatterns,
+    ),
+    memberRenamer: MemberRenamer(
+      memberRenameFull: memberRenamerFull,
+      memberRenamePattern: memberRenamePatterns,
+    ),
+    symbolAddressIncluder: symbolIncluder,
+  );
+}
+
+StructPackingOverride structPackingOverrideExtractor(
+    Map<dynamic, dynamic> value) {
+  final matcherMap = <RegExp, int?>{};
+  for (final key in value.keys) {
+    matcherMap[RegExp(key as String, dotAll: true)] =
+        strings.packingValuesMap[value[key]];
+  }
+  return StructPackingOverride(matcherMap: matcherMap);
+}
+
+FfiNativeConfig ffiNativeExtractor(dynamic yamlConfig) {
+  final yamlMap = yamlConfig as Map?;
+  return FfiNativeConfig(
+    enabled: true,
+    assetId: yamlMap?[strings.ffiNativeAsset] as String?,
+  );
+}
diff --git a/pkgs/ffigen/lib/src/executables/ffigen.dart b/pkgs/ffigen/lib/src/executables/ffigen.dart
new file mode 100644
index 0000000..c37cb4f
--- /dev/null
+++ b/pkgs/ffigen/lib/src/executables/ffigen.dart
@@ -0,0 +1,229 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Executable script to generate bindings for some C library.
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:cli_util/cli_logging.dart' show Ansi;
+import 'package:ffigen/ffigen.dart';
+import 'package:logging/logging.dart';
+import 'package:package_config/package_config.dart';
+import 'package:yaml/yaml.dart' as yaml;
+
+final _logger = Logger('ffigen.ffigen');
+final _ansi = Ansi(Ansi.terminalSupportsAnsi);
+
+const compilerOpts = 'compiler-opts';
+const conf = 'config';
+const help = 'help';
+const verbose = 'verbose';
+const pubspecName = 'pubspec.yaml';
+const configKey = 'ffigen';
+const logAll = 'all';
+const logFine = 'fine';
+const logInfo = 'info';
+const logWarning = 'warning';
+const logSevere = 'severe';
+
+String successPen(String str) {
+  return '${_ansi.green}$str${_ansi.none}';
+}
+
+String errorPen(String str) {
+  return '${_ansi.red}$str${_ansi.none}';
+}
+
+void main(List<String> args) async {
+  // Parses the cmd args. This will print usage and exit if --help was passed.
+  final argResult = getArgResults(args);
+
+  // Setup logging level and printing.
+  setupLogger(argResult);
+
+  // Create a config object.
+  Config config;
+  try {
+    config = getConfig(argResult, await findPackageConfig(Directory.current));
+  } on FormatException {
+    _logger.severe('Please fix configuration errors and re-run the tool.');
+    exit(1);
+  }
+
+  // Parse the bindings according to config object provided.
+  final library = parse(config);
+
+  // Generate file for the parsed bindings.
+  final gen = File(config.output);
+  library.generateFile(gen);
+  _logger
+      .info(successPen('Finished, Bindings generated in ${gen.absolute.path}'));
+
+  if (config.symbolFile != null) {
+    final symbolFileGen = File(config.symbolFile!.output);
+    library.generateSymbolOutputFile(
+        symbolFileGen, config.symbolFile!.importPath);
+    _logger.info(successPen(
+        'Finished, Symbol Output generated in ${symbolFileGen.absolute.path}'));
+  }
+}
+
+Config getConfig(ArgResults result, PackageConfig? packageConfig) {
+  _logger.info('Running in ${Directory.current}');
+  Config config;
+
+  // Parse config from yaml.
+  if (result.wasParsed(conf)) {
+    config = getConfigFromCustomYaml(result[conf] as String, packageConfig);
+  } else {
+    config = getConfigFromPubspec(packageConfig);
+  }
+
+  // Add compiler options from command line.
+  if (result.wasParsed(compilerOpts)) {
+    _logger.fine('Passed compiler opts - "${result[compilerOpts]}"');
+    config.addCompilerOpts((result[compilerOpts] as String),
+        highPriority: true);
+  }
+
+  return config;
+}
+
+/// Extracts configuration from pubspec file.
+Config getConfigFromPubspec(PackageConfig? packageConfig) {
+  final pubspecFile = File(pubspecName);
+
+  if (!pubspecFile.existsSync()) {
+    _logger.severe(
+        'Error: $pubspecName not found, please run this tool from the root of your package.');
+    exit(1);
+  }
+
+  // Casting this because pubspec is expected to be a YamlMap.
+
+  // Throws a [YamlException] if it's unable to parse the Yaml.
+  final bindingsConfigMap =
+      yaml.loadYaml(pubspecFile.readAsStringSync())[configKey] as yaml.YamlMap?;
+
+  if (bindingsConfigMap == null) {
+    _logger.severe("Couldn't find an entry for '$configKey' in $pubspecName.");
+    exit(1);
+  }
+  return Config.fromYaml(bindingsConfigMap,
+      filename: pubspecFile.path, packageConfig: packageConfig);
+}
+
+/// Extracts configuration from a custom yaml file.
+Config getConfigFromCustomYaml(String yamlPath, PackageConfig? packageConfig) {
+  final yamlFile = File(yamlPath);
+
+  if (!yamlFile.existsSync()) {
+    _logger.severe('Error: $yamlPath not found.');
+    exit(1);
+  }
+
+  return Config.fromFile(yamlFile, packageConfig: packageConfig);
+}
+
+/// Parses the cmd line arguments.
+ArgResults getArgResults(List<String> args) {
+  final parser = ArgParser(allowTrailingOptions: true);
+
+  parser.addSeparator(
+      'FFIGEN: Generate dart bindings from C header files\nUsage:');
+  parser.addOption(
+    conf,
+    help: 'Path to Yaml file containing configurations if not in pubspec.yaml',
+  );
+  parser.addOption(
+    verbose,
+    abbr: 'v',
+    defaultsTo: logInfo,
+    allowed: [
+      logAll,
+      logFine,
+      logInfo,
+      logWarning,
+      logSevere,
+    ],
+  );
+  parser.addFlag(
+    help,
+    abbr: 'h',
+    help: 'Prints this usage',
+    negatable: false,
+  );
+  parser.addOption(
+    compilerOpts,
+    help: 'Compiler options for clang. (E.g --$compilerOpts "-I/headers -W")',
+  );
+
+  ArgResults results;
+  try {
+    results = parser.parse(args);
+
+    if (results.wasParsed(help)) {
+      print(parser.usage);
+      exit(0);
+    }
+  } catch (e) {
+    print(e);
+    print(parser.usage);
+    exit(1);
+  }
+
+  return results;
+}
+
+/// Sets up the logging level and printing.
+void setupLogger(ArgResults result) {
+  if (result.wasParsed(verbose)) {
+    switch (result[verbose] as String?) {
+      case logAll:
+        // Logs everything, the entire AST touched by our parser.
+        Logger.root.level = Level.ALL;
+        break;
+      case logFine:
+        // Logs AST parts relevant to user (i.e those included in filters).
+        Logger.root.level = Level.FINE;
+        break;
+      case logInfo:
+        // Logs relevant info for general user (default).
+        Logger.root.level = Level.INFO;
+        break;
+      case logWarning:
+        // Logs warnings for relevant stuff.
+        Logger.root.level = Level.WARNING;
+        break;
+      case logSevere:
+        // Logs severe warnings and errors.
+        Logger.root.level = Level.SEVERE;
+        break;
+    }
+    // Setup logger for printing (if verbosity was set by user).
+    Logger.root.onRecord.listen((record) {
+      final level = '[${record.level.name}]'.padRight(9);
+      printLog('$level: ${record.message}', record.level);
+    });
+  } else {
+    // Setup logger for printing (if verbosity was not set by user).
+    Logger.root.onRecord.listen((record) {
+      if (record.level.value > Level.INFO.value) {
+        final level = '[${record.level.name}]'.padRight(9);
+        printLog('$level: ${record.message}', record.level);
+      } else {
+        printLog(record.message, record.level);
+      }
+    });
+  }
+}
+
+void printLog(String log, Level level) {
+  // Prints text in red for Severe logs only.
+  if (level < Level.SEVERE) {
+    print(log);
+  } else {
+    print(errorPen(log));
+  }
+}
diff --git a/pkgs/ffigen/lib/src/header_parser.dart b/pkgs/ffigen/lib/src/header_parser.dart
new file mode 100644
index 0000000..e4dc2c9
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Generates a [Library] (code_generator)
+///
+/// Parses the header files AST using clang_bindings.
+library header_parser;
+
+export 'header_parser/parser.dart' show parse;
diff --git a/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart b/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
new file mode 100644
index 0000000..d5431a9
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
@@ -0,0 +1,2689 @@
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
+// Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// ignore_for_file: camel_case_types, non_constant_identifier_names
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Holds bindings to LibClang.
+class Clang {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  Clang(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  Clang.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  /// Retrieve the character data associated with the given string.
+  ffi.Pointer<ffi.Char> clang_getCString(
+    CXString string,
+  ) {
+    return _clang_getCString(
+      string,
+    );
+  }
+
+  late final _clang_getCStringPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(CXString)>>(
+          'clang_getCString');
+  late final _clang_getCString = _clang_getCStringPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(CXString)>();
+
+  /// Free the given string.
+  void clang_disposeString(
+    CXString string,
+  ) {
+    return _clang_disposeString(
+      string,
+    );
+  }
+
+  late final _clang_disposeStringPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXString)>>(
+          'clang_disposeString');
+  late final _clang_disposeString =
+      _clang_disposeStringPtr.asFunction<void Function(CXString)>();
+
+  /// Provides a shared context for creating translation units.
+  ///
+  /// It provides two options:
+  ///
+  /// - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local"
+  /// declarations (when loading any new translation units). A "local" declaration
+  /// is one that belongs in the translation unit itself and not in a precompiled
+  /// header that was used by the translation unit. If zero, all declarations
+  /// will be enumerated.
+  ///
+  /// Here is an example:
+  ///
+  /// \code
+  /// // excludeDeclsFromPCH = 1, displayDiagnostics=1
+  /// Idx = clang_createIndex(1, 1);
+  ///
+  /// // IndexTest.pch was produced with the following command:
+  /// // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
+  /// TU = clang_createTranslationUnit(Idx, "IndexTest.pch");
+  ///
+  /// // This will load all the symbols from 'IndexTest.pch'
+  /// clang_visitChildren(clang_getTranslationUnitCursor(TU),
+  /// TranslationUnitVisitor, 0);
+  /// clang_disposeTranslationUnit(TU);
+  ///
+  /// // This will load all the symbols from 'IndexTest.c', excluding symbols
+  /// // from 'IndexTest.pch'.
+  /// char *args[] = { "-Xclang", "-include-pch=IndexTest.pch" };
+  /// TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args,
+  /// 0, 0);
+  /// clang_visitChildren(clang_getTranslationUnitCursor(TU),
+  /// TranslationUnitVisitor, 0);
+  /// clang_disposeTranslationUnit(TU);
+  /// \endcode
+  ///
+  /// This process of creating the 'pch', loading it separately, and using it (via
+  /// -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
+  /// (which gives the indexer the same performance benefit as the compiler).
+  CXIndex clang_createIndex(
+    int excludeDeclarationsFromPCH,
+    int displayDiagnostics,
+  ) {
+    return _clang_createIndex(
+      excludeDeclarationsFromPCH,
+      displayDiagnostics,
+    );
+  }
+
+  late final _clang_createIndexPtr =
+      _lookup<ffi.NativeFunction<CXIndex Function(ffi.Int, ffi.Int)>>(
+          'clang_createIndex');
+  late final _clang_createIndex =
+      _clang_createIndexPtr.asFunction<CXIndex Function(int, int)>();
+
+  /// Destroy the given index.
+  ///
+  /// The index must not be destroyed until all of the translation units created
+  /// within that index have been destroyed.
+  void clang_disposeIndex(
+    CXIndex index,
+  ) {
+    return _clang_disposeIndex(
+      index,
+    );
+  }
+
+  late final _clang_disposeIndexPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXIndex)>>(
+          'clang_disposeIndex');
+  late final _clang_disposeIndex =
+      _clang_disposeIndexPtr.asFunction<void Function(CXIndex)>();
+
+  /// Retrieve the complete file and path name of the given file.
+  CXString clang_getFileName(
+    CXFile SFile,
+  ) {
+    return _clang_getFileName(
+      SFile,
+    );
+  }
+
+  late final _clang_getFileNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXFile)>>(
+          'clang_getFileName');
+  late final _clang_getFileName =
+      _clang_getFileNamePtr.asFunction<CXString Function(CXFile)>();
+
+  /// Returns non-zero if the given source location is in a system header.
+  int clang_Location_isInSystemHeader(
+    CXSourceLocation location,
+  ) {
+    return _clang_Location_isInSystemHeader(
+      location,
+    );
+  }
+
+  late final _clang_Location_isInSystemHeaderPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXSourceLocation)>>(
+          'clang_Location_isInSystemHeader');
+  late final _clang_Location_isInSystemHeader =
+      _clang_Location_isInSystemHeaderPtr
+          .asFunction<int Function(CXSourceLocation)>();
+
+  /// Determine whether two ranges are equivalent.
+  ///
+  /// \returns non-zero if the ranges are the same, zero if they differ.
+  int clang_equalRanges(
+    CXSourceRange range1,
+    CXSourceRange range2,
+  ) {
+    return _clang_equalRanges(
+      range1,
+      range2,
+    );
+  }
+
+  late final _clang_equalRangesPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.UnsignedInt Function(
+              CXSourceRange, CXSourceRange)>>('clang_equalRanges');
+  late final _clang_equalRanges = _clang_equalRangesPtr
+      .asFunction<int Function(CXSourceRange, CXSourceRange)>();
+
+  /// Retrieve the file, line, column, and offset represented by
+  /// the given source location.
+  ///
+  /// If the location refers into a macro expansion, return where the macro was
+  /// expanded or where the macro argument was written, if the location points at
+  /// a macro argument.
+  ///
+  /// \param location the location within a source file that will be decomposed
+  /// into its parts.
+  ///
+  /// \param file [out] if non-NULL, will be set to the file to which the given
+  /// source location points.
+  ///
+  /// \param line [out] if non-NULL, will be set to the line to which the given
+  /// source location points.
+  ///
+  /// \param column [out] if non-NULL, will be set to the column to which the given
+  /// source location points.
+  ///
+  /// \param offset [out] if non-NULL, will be set to the offset into the
+  /// buffer to which the given source location points.
+  void clang_getFileLocation(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset,
+  ) {
+    return _clang_getFileLocation(
+      location,
+      file,
+      line,
+      column,
+      offset,
+    );
+  }
+
+  late final _clang_getFileLocationPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              CXSourceLocation,
+              ffi.Pointer<CXFile>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>>('clang_getFileLocation');
+  late final _clang_getFileLocation = _clang_getFileLocationPtr.asFunction<
+      void Function(
+          CXSourceLocation,
+          ffi.Pointer<CXFile>,
+          ffi.Pointer<ffi.UnsignedInt>,
+          ffi.Pointer<ffi.UnsignedInt>,
+          ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Determine the number of diagnostics produced for the given
+  /// translation unit.
+  int clang_getNumDiagnostics(
+    CXTranslationUnit Unit,
+  ) {
+    return _clang_getNumDiagnostics(
+      Unit,
+    );
+  }
+
+  late final _clang_getNumDiagnosticsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXTranslationUnit)>>(
+          'clang_getNumDiagnostics');
+  late final _clang_getNumDiagnostics =
+      _clang_getNumDiagnosticsPtr.asFunction<int Function(CXTranslationUnit)>();
+
+  /// Retrieve a diagnostic associated with the given translation unit.
+  ///
+  /// \param Unit the translation unit to query.
+  /// \param Index the zero-based diagnostic number to retrieve.
+  ///
+  /// \returns the requested diagnostic. This diagnostic must be freed
+  /// via a call to \c clang_disposeDiagnostic().
+  CXDiagnostic clang_getDiagnostic(
+    CXTranslationUnit Unit,
+    int Index,
+  ) {
+    return _clang_getDiagnostic(
+      Unit,
+      Index,
+    );
+  }
+
+  late final _clang_getDiagnosticPtr = _lookup<
+      ffi.NativeFunction<
+          CXDiagnostic Function(
+              CXTranslationUnit, ffi.UnsignedInt)>>('clang_getDiagnostic');
+  late final _clang_getDiagnostic = _clang_getDiagnosticPtr
+      .asFunction<CXDiagnostic Function(CXTranslationUnit, int)>();
+
+  /// Destroy a diagnostic.
+  void clang_disposeDiagnostic(
+    CXDiagnostic Diagnostic,
+  ) {
+    return _clang_disposeDiagnostic(
+      Diagnostic,
+    );
+  }
+
+  late final _clang_disposeDiagnosticPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXDiagnostic)>>(
+          'clang_disposeDiagnostic');
+  late final _clang_disposeDiagnostic =
+      _clang_disposeDiagnosticPtr.asFunction<void Function(CXDiagnostic)>();
+
+  /// Format the given diagnostic in a manner that is suitable for display.
+  ///
+  /// This routine will format the given diagnostic to a string, rendering
+  /// the diagnostic according to the various options given. The
+  /// \c clang_defaultDiagnosticDisplayOptions() function returns the set of
+  /// options that most closely mimics the behavior of the clang compiler.
+  ///
+  /// \param Diagnostic The diagnostic to print.
+  ///
+  /// \param Options A set of options that control the diagnostic display,
+  /// created by combining \c CXDiagnosticDisplayOptions values.
+  ///
+  /// \returns A new string containing for formatted diagnostic.
+  CXString clang_formatDiagnostic(
+    CXDiagnostic Diagnostic,
+    int Options,
+  ) {
+    return _clang_formatDiagnostic(
+      Diagnostic,
+      Options,
+    );
+  }
+
+  late final _clang_formatDiagnosticPtr = _lookup<
+          ffi.NativeFunction<CXString Function(CXDiagnostic, ffi.UnsignedInt)>>(
+      'clang_formatDiagnostic');
+  late final _clang_formatDiagnostic = _clang_formatDiagnosticPtr
+      .asFunction<CXString Function(CXDiagnostic, int)>();
+
+  /// Same as \c clang_parseTranslationUnit2, but returns
+  /// the \c CXTranslationUnit instead of an error code.  In case of an error this
+  /// routine returns a \c NULL \c CXTranslationUnit, without further detailed
+  /// error codes.
+  CXTranslationUnit clang_parseTranslationUnit(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options,
+  ) {
+    return _clang_parseTranslationUnit(
+      CIdx,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      unsaved_files,
+      num_unsaved_files,
+      options,
+    );
+  }
+
+  late final _clang_parseTranslationUnitPtr = _lookup<
+      ffi.NativeFunction<
+          CXTranslationUnit Function(
+              CXIndex,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Int,
+              ffi.Pointer<CXUnsavedFile>,
+              ffi.UnsignedInt,
+              ffi.UnsignedInt)>>('clang_parseTranslationUnit');
+  late final _clang_parseTranslationUnit =
+      _clang_parseTranslationUnitPtr.asFunction<
+          CXTranslationUnit Function(
+              CXIndex,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              int,
+              ffi.Pointer<CXUnsavedFile>,
+              int,
+              int)>();
+
+  /// Destroy the specified CXTranslationUnit object.
+  void clang_disposeTranslationUnit(
+    CXTranslationUnit arg0,
+  ) {
+    return _clang_disposeTranslationUnit(
+      arg0,
+    );
+  }
+
+  late final _clang_disposeTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXTranslationUnit)>>(
+          'clang_disposeTranslationUnit');
+  late final _clang_disposeTranslationUnit = _clang_disposeTranslationUnitPtr
+      .asFunction<void Function(CXTranslationUnit)>();
+
+  /// Retrieve the cursor that represents the given translation unit.
+  ///
+  /// The translation unit cursor can be used to start traversing the
+  /// various declarations within the given translation unit.
+  CXCursor clang_getTranslationUnitCursor(
+    CXTranslationUnit arg0,
+  ) {
+    return _clang_getTranslationUnitCursor(
+      arg0,
+    );
+  }
+
+  late final _clang_getTranslationUnitCursorPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXTranslationUnit)>>(
+          'clang_getTranslationUnitCursor');
+  late final _clang_getTranslationUnitCursor =
+      _clang_getTranslationUnitCursorPtr
+          .asFunction<CXCursor Function(CXTranslationUnit)>();
+
+  /// Returns non-zero if \p cursor is null.
+  int clang_Cursor_isNull(
+    CXCursor cursor,
+  ) {
+    return _clang_Cursor_isNull(
+      cursor,
+    );
+  }
+
+  late final _clang_Cursor_isNullPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXCursor)>>(
+          'clang_Cursor_isNull');
+  late final _clang_Cursor_isNull =
+      _clang_Cursor_isNullPtr.asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the kind of the given cursor.
+  int clang_getCursorKind(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorKind(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorKindPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>(
+          'clang_getCursorKind');
+  late final _clang_getCursorKind =
+      _clang_getCursorKindPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether the given cursor has any attributes.
+  int clang_Cursor_hasAttrs(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_hasAttrs(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_hasAttrsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_hasAttrs');
+  late final _clang_Cursor_hasAttrs =
+      _clang_Cursor_hasAttrsPtr.asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the physical location of the source constructor referenced
+  /// by the given cursor.
+  ///
+  /// The location of a declaration is typically the location of the name of that
+  /// declaration, where the name of that declaration would occur if it is
+  /// unnamed, or some keyword that introduces that particular declaration.
+  /// The location of a reference is where that reference occurs within the
+  /// source code.
+  CXSourceLocation clang_getCursorLocation(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorLocation(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorLocationPtr =
+      _lookup<ffi.NativeFunction<CXSourceLocation Function(CXCursor)>>(
+          'clang_getCursorLocation');
+  late final _clang_getCursorLocation = _clang_getCursorLocationPtr
+      .asFunction<CXSourceLocation Function(CXCursor)>();
+
+  /// Retrieve the type of a CXCursor (if any).
+  CXType clang_getCursorType(
+    CXCursor C,
+  ) {
+    return _clang_getCursorType(
+      C,
+    );
+  }
+
+  late final _clang_getCursorTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXCursor)>>(
+          'clang_getCursorType');
+  late final _clang_getCursorType =
+      _clang_getCursorTypePtr.asFunction<CXType Function(CXCursor)>();
+
+  /// Pretty-print the underlying type using the rules of the
+  /// language of the translation unit from which it came.
+  ///
+  /// If the type is invalid, an empty string is returned.
+  CXString clang_getTypeSpelling(
+    CXType CT,
+  ) {
+    return _clang_getTypeSpelling(
+      CT,
+    );
+  }
+
+  late final _clang_getTypeSpellingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXType)>>(
+          'clang_getTypeSpelling');
+  late final _clang_getTypeSpelling =
+      _clang_getTypeSpellingPtr.asFunction<CXString Function(CXType)>();
+
+  /// Retrieve the underlying type of a typedef declaration.
+  ///
+  /// If the cursor does not reference a typedef declaration, an invalid type is
+  /// returned.
+  CXType clang_getTypedefDeclUnderlyingType(
+    CXCursor C,
+  ) {
+    return _clang_getTypedefDeclUnderlyingType(
+      C,
+    );
+  }
+
+  late final _clang_getTypedefDeclUnderlyingTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXCursor)>>(
+          'clang_getTypedefDeclUnderlyingType');
+  late final _clang_getTypedefDeclUnderlyingType =
+      _clang_getTypedefDeclUnderlyingTypePtr
+          .asFunction<CXType Function(CXCursor)>();
+
+  /// Retrieve the integer value of an enum constant declaration as a signed
+  /// long long.
+  ///
+  /// If the cursor does not reference an enum constant declaration, LLONG_MIN is returned.
+  /// Since this is also potentially a valid constant value, the kind of the cursor
+  /// must be verified before calling this function.
+  int clang_getEnumConstantDeclValue(
+    CXCursor C,
+  ) {
+    return _clang_getEnumConstantDeclValue(
+      C,
+    );
+  }
+
+  late final _clang_getEnumConstantDeclValuePtr =
+      _lookup<ffi.NativeFunction<ffi.LongLong Function(CXCursor)>>(
+          'clang_getEnumConstantDeclValue');
+  late final _clang_getEnumConstantDeclValue =
+      _clang_getEnumConstantDeclValuePtr.asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the bit width of a bit field declaration as an integer.
+  ///
+  /// If a cursor that is not a bit field declaration is passed in, -1 is returned.
+  int clang_getFieldDeclBitWidth(
+    CXCursor C,
+  ) {
+    return _clang_getFieldDeclBitWidth(
+      C,
+    );
+  }
+
+  late final _clang_getFieldDeclBitWidthPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXCursor)>>(
+          'clang_getFieldDeclBitWidth');
+  late final _clang_getFieldDeclBitWidth =
+      _clang_getFieldDeclBitWidthPtr.asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the number of non-variadic arguments associated with a given
+  /// cursor.
+  ///
+  /// The number of arguments can be determined for calls as well as for
+  /// declarations of functions or methods. For other cursors -1 is returned.
+  int clang_Cursor_getNumArguments(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getNumArguments(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getNumArgumentsPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXCursor)>>(
+          'clang_Cursor_getNumArguments');
+  late final _clang_Cursor_getNumArguments =
+      _clang_Cursor_getNumArgumentsPtr.asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the argument cursor of a function or method.
+  ///
+  /// The argument cursor can be determined for calls as well as for declarations
+  /// of functions or methods. For other cursors and for invalid indices, an
+  /// invalid cursor is returned.
+  CXCursor clang_Cursor_getArgument(
+    CXCursor C,
+    int i,
+  ) {
+    return _clang_Cursor_getArgument(
+      C,
+      i,
+    );
+  }
+
+  late final _clang_Cursor_getArgumentPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXCursor, ffi.UnsignedInt)>>(
+          'clang_Cursor_getArgument');
+  late final _clang_Cursor_getArgument = _clang_Cursor_getArgumentPtr
+      .asFunction<CXCursor Function(CXCursor, int)>();
+
+  /// Return the canonical type for a CXType.
+  ///
+  /// Clang's type system explicitly models typedefs and all the ways
+  /// a specific type can be represented.  The canonical type is the underlying
+  /// type with all the "sugar" removed.  For example, if 'T' is a typedef
+  /// for 'int', the canonical type for 'T' would be 'int'.
+  CXType clang_getCanonicalType(
+    CXType T,
+  ) {
+    return _clang_getCanonicalType(
+      T,
+    );
+  }
+
+  late final _clang_getCanonicalTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_getCanonicalType');
+  late final _clang_getCanonicalType =
+      _clang_getCanonicalTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Determine whether a  CXCursor that is a macro, is
+  /// function like.
+  int clang_Cursor_isMacroFunctionLike(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isMacroFunctionLike(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isMacroFunctionLikePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isMacroFunctionLike');
+  late final _clang_Cursor_isMacroFunctionLike =
+      _clang_Cursor_isMacroFunctionLikePtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether a  CXCursor that is a macro, is a
+  /// builtin one.
+  int clang_Cursor_isMacroBuiltin(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isMacroBuiltin(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isMacroBuiltinPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isMacroBuiltin');
+  late final _clang_Cursor_isMacroBuiltin =
+      _clang_Cursor_isMacroBuiltinPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether a  CXCursor that is a function declaration, is an
+  /// inline declaration.
+  int clang_Cursor_isFunctionInlined(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isFunctionInlined(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isFunctionInlinedPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isFunctionInlined');
+  late final _clang_Cursor_isFunctionInlined =
+      _clang_Cursor_isFunctionInlinedPtr.asFunction<int Function(CXCursor)>();
+
+  /// Returns the typedef name of the given type.
+  CXString clang_getTypedefName(
+    CXType CT,
+  ) {
+    return _clang_getTypedefName(
+      CT,
+    );
+  }
+
+  late final _clang_getTypedefNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXType)>>(
+          'clang_getTypedefName');
+  late final _clang_getTypedefName =
+      _clang_getTypedefNamePtr.asFunction<CXString Function(CXType)>();
+
+  /// For pointer types, returns the type of the pointee.
+  CXType clang_getPointeeType(
+    CXType T,
+  ) {
+    return _clang_getPointeeType(
+      T,
+    );
+  }
+
+  late final _clang_getPointeeTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_getPointeeType');
+  late final _clang_getPointeeType =
+      _clang_getPointeeTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Return the cursor for the declaration of the given type.
+  CXCursor clang_getTypeDeclaration(
+    CXType T,
+  ) {
+    return _clang_getTypeDeclaration(
+      T,
+    );
+  }
+
+  late final _clang_getTypeDeclarationPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXType)>>(
+          'clang_getTypeDeclaration');
+  late final _clang_getTypeDeclaration =
+      _clang_getTypeDeclarationPtr.asFunction<CXCursor Function(CXType)>();
+
+  /// Retrieve the spelling of a given CXTypeKind.
+  CXString clang_getTypeKindSpelling(
+    int K,
+  ) {
+    return _clang_getTypeKindSpelling(
+      K,
+    );
+  }
+
+  late final _clang_getTypeKindSpellingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(ffi.Int32)>>(
+          'clang_getTypeKindSpelling');
+  late final _clang_getTypeKindSpelling =
+      _clang_getTypeKindSpellingPtr.asFunction<CXString Function(int)>();
+
+  /// Retrieve the return type associated with a function type.
+  ///
+  /// If a non-function type is passed in, an invalid type is returned.
+  CXType clang_getResultType(
+    CXType T,
+  ) {
+    return _clang_getResultType(
+      T,
+    );
+  }
+
+  late final _clang_getResultTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_getResultType');
+  late final _clang_getResultType =
+      _clang_getResultTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Retrieve the number of non-variadic parameters associated with a
+  /// function type.
+  ///
+  /// If a non-function type is passed in, -1 is returned.
+  int clang_getNumArgTypes(
+    CXType T,
+  ) {
+    return _clang_getNumArgTypes(
+      T,
+    );
+  }
+
+  late final _clang_getNumArgTypesPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXType)>>(
+          'clang_getNumArgTypes');
+  late final _clang_getNumArgTypes =
+      _clang_getNumArgTypesPtr.asFunction<int Function(CXType)>();
+
+  /// Retrieve the type of a parameter of a function type.
+  ///
+  /// If a non-function type is passed in or the function does not have enough
+  /// parameters, an invalid type is returned.
+  CXType clang_getArgType(
+    CXType T,
+    int i,
+  ) {
+    return _clang_getArgType(
+      T,
+      i,
+    );
+  }
+
+  late final _clang_getArgTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType, ffi.UnsignedInt)>>(
+          'clang_getArgType');
+  late final _clang_getArgType =
+      _clang_getArgTypePtr.asFunction<CXType Function(CXType, int)>();
+
+  /// Retrieves the base type of the ObjCObjectType.
+  ///
+  /// If the type is not an ObjC object, an invalid type is returned.
+  CXType clang_Type_getObjCObjectBaseType(
+    CXType T,
+  ) {
+    return _clang_Type_getObjCObjectBaseType(
+      T,
+    );
+  }
+
+  late final _clang_Type_getObjCObjectBaseTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_Type_getObjCObjectBaseType');
+  late final _clang_Type_getObjCObjectBaseType =
+      _clang_Type_getObjCObjectBaseTypePtr
+          .asFunction<CXType Function(CXType)>();
+
+  /// Return 1 if the CXType is a variadic function type, and 0 otherwise.
+  int clang_isFunctionTypeVariadic(
+    CXType T,
+  ) {
+    return _clang_isFunctionTypeVariadic(
+      T,
+    );
+  }
+
+  late final _clang_isFunctionTypeVariadicPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXType)>>(
+          'clang_isFunctionTypeVariadic');
+  late final _clang_isFunctionTypeVariadic =
+      _clang_isFunctionTypeVariadicPtr.asFunction<int Function(CXType)>();
+
+  /// Retrieve the return type associated with a given cursor.
+  ///
+  /// This only returns a valid type if the cursor refers to a function or method.
+  CXType clang_getCursorResultType(
+    CXCursor C,
+  ) {
+    return _clang_getCursorResultType(
+      C,
+    );
+  }
+
+  late final _clang_getCursorResultTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXCursor)>>(
+          'clang_getCursorResultType');
+  late final _clang_getCursorResultType =
+      _clang_getCursorResultTypePtr.asFunction<CXType Function(CXCursor)>();
+
+  /// Return the number of elements of an array or vector type.
+  ///
+  /// If a type is passed in that is not an array or vector type,
+  /// -1 is returned.
+  int clang_getNumElements(
+    CXType T,
+  ) {
+    return _clang_getNumElements(
+      T,
+    );
+  }
+
+  late final _clang_getNumElementsPtr =
+      _lookup<ffi.NativeFunction<ffi.LongLong Function(CXType)>>(
+          'clang_getNumElements');
+  late final _clang_getNumElements =
+      _clang_getNumElementsPtr.asFunction<int Function(CXType)>();
+
+  /// Return the element type of an array type.
+  ///
+  /// If a non-array type is passed in, an invalid type is returned.
+  CXType clang_getArrayElementType(
+    CXType T,
+  ) {
+    return _clang_getArrayElementType(
+      T,
+    );
+  }
+
+  late final _clang_getArrayElementTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_getArrayElementType');
+  late final _clang_getArrayElementType =
+      _clang_getArrayElementTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Retrieve the type named by the qualified-id.
+  ///
+  /// If a non-elaborated type is passed in, an invalid type is returned.
+  CXType clang_Type_getNamedType(
+    CXType T,
+  ) {
+    return _clang_Type_getNamedType(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNamedTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_Type_getNamedType');
+  late final _clang_Type_getNamedType =
+      _clang_Type_getNamedTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Retrieve the nullability kind of a pointer type.
+  int clang_Type_getNullability(
+    CXType T,
+  ) {
+    return _clang_Type_getNullability(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNullabilityPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXType)>>(
+          'clang_Type_getNullability');
+  late final _clang_Type_getNullability =
+      _clang_Type_getNullabilityPtr.asFunction<int Function(CXType)>();
+
+  /// Return the alignment of a type in bytes as per C++[expr.alignof]
+  /// standard.
+  ///
+  /// If the type declaration is invalid, CXTypeLayoutError_Invalid is returned.
+  /// If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete
+  /// is returned.
+  /// If the type declaration is a dependent type, CXTypeLayoutError_Dependent is
+  /// returned.
+  /// If the type declaration is not a constant size type,
+  /// CXTypeLayoutError_NotConstantSize is returned.
+  int clang_Type_getAlignOf(
+    CXType T,
+  ) {
+    return _clang_Type_getAlignOf(
+      T,
+    );
+  }
+
+  late final _clang_Type_getAlignOfPtr =
+      _lookup<ffi.NativeFunction<ffi.LongLong Function(CXType)>>(
+          'clang_Type_getAlignOf');
+  late final _clang_Type_getAlignOf =
+      _clang_Type_getAlignOfPtr.asFunction<int Function(CXType)>();
+
+  /// Return the type that was modified by this attributed type.
+  ///
+  /// If the type is not an attributed type, an invalid type is returned.
+  CXType clang_Type_getModifiedType(
+    CXType T,
+  ) {
+    return _clang_Type_getModifiedType(
+      T,
+    );
+  }
+
+  late final _clang_Type_getModifiedTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_Type_getModifiedType');
+  late final _clang_Type_getModifiedType =
+      _clang_Type_getModifiedTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Determine whether the given cursor represents an anonymous
+  /// tag or namespace
+  int clang_Cursor_isAnonymous(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isAnonymous(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isAnonymousPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isAnonymous');
+  late final _clang_Cursor_isAnonymous =
+      _clang_Cursor_isAnonymousPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether the given cursor represents an anonymous record
+  /// declaration.
+  int clang_Cursor_isAnonymousRecordDecl(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isAnonymousRecordDecl(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isAnonymousRecordDeclPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isAnonymousRecordDecl');
+  late final _clang_Cursor_isAnonymousRecordDecl =
+      _clang_Cursor_isAnonymousRecordDeclPtr
+          .asFunction<int Function(CXCursor)>();
+
+  /// Returns the storage class for a function or variable declaration.
+  ///
+  /// If the passed in Cursor is not a function or variable declaration,
+  /// CX_SC_Invalid is returned else the storage class.
+  int clang_Cursor_getStorageClass(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getStorageClass(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getStorageClassPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>(
+          'clang_Cursor_getStorageClass');
+  late final _clang_Cursor_getStorageClass =
+      _clang_Cursor_getStorageClassPtr.asFunction<int Function(CXCursor)>();
+
+  /// Visit the children of a particular cursor.
+  ///
+  /// This function visits all the direct children of the given cursor,
+  /// invoking the given \p visitor function with the cursors of each
+  /// visited child. The traversal may be recursive, if the visitor returns
+  /// \c CXChildVisit_Recurse. The traversal may also be ended prematurely, if
+  /// the visitor returns \c CXChildVisit_Break.
+  ///
+  /// \param parent the cursor whose child may be visited. All kinds of
+  /// cursors can be visited, including invalid cursors (which, by
+  /// definition, have no children).
+  ///
+  /// \param visitor the visitor function that will be invoked for each
+  /// child of \p parent.
+  ///
+  /// \param client_data pointer data supplied by the client, which will
+  /// be passed to the visitor each time it is invoked.
+  ///
+  /// \returns a non-zero value if the traversal was terminated
+  /// prematurely by the visitor returning \c CXChildVisit_Break.
+  int clang_visitChildren(
+    CXCursor parent,
+    CXCursorVisitor visitor,
+    CXClientData client_data,
+  ) {
+    return _clang_visitChildren(
+      parent,
+      visitor,
+      client_data,
+    );
+  }
+
+  late final _clang_visitChildrenPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.UnsignedInt Function(
+              CXCursor, CXCursorVisitor, CXClientData)>>('clang_visitChildren');
+  late final _clang_visitChildren = _clang_visitChildrenPtr
+      .asFunction<int Function(CXCursor, CXCursorVisitor, CXClientData)>();
+
+  /// Retrieve a Unified Symbol Resolution (USR) for the entity referenced
+  /// by the given cursor.
+  ///
+  /// A Unified Symbol Resolution (USR) is a string that identifies a particular
+  /// entity (function, class, variable, etc.) within a program. USRs can be
+  /// compared across translation units to determine, e.g., when references in
+  /// one translation refer to an entity defined in another translation unit.
+  CXString clang_getCursorUSR(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorUSR(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorUSRPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_getCursorUSR');
+  late final _clang_getCursorUSR =
+      _clang_getCursorUSRPtr.asFunction<CXString Function(CXCursor)>();
+
+  /// Retrieve a name for the entity referenced by this cursor.
+  CXString clang_getCursorSpelling(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorSpelling(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorSpellingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_getCursorSpelling');
+  late final _clang_getCursorSpelling =
+      _clang_getCursorSpellingPtr.asFunction<CXString Function(CXCursor)>();
+
+  /// For a cursor that is either a reference to or a declaration
+  /// of some entity, retrieve a cursor that describes the definition of
+  /// that entity.
+  ///
+  /// Some entities can be declared multiple times within a translation
+  /// unit, but only one of those declarations can also be a
+  /// definition. For example, given:
+  ///
+  /// \code
+  /// int f(int, int);
+  /// int g(int x, int y) { return f(x, y); }
+  /// int f(int a, int b) { return a + b; }
+  /// int f(int, int);
+  /// \endcode
+  ///
+  /// there are three declarations of the function "f", but only the
+  /// second one is a definition. The clang_getCursorDefinition()
+  /// function will take any cursor pointing to a declaration of "f"
+  /// (the first or fourth lines of the example) or a cursor referenced
+  /// that uses "f" (the call to "f' inside "g") and will return a
+  /// declaration cursor pointing to the definition (the second "f"
+  /// declaration).
+  ///
+  /// If given a cursor for which there is no corresponding definition,
+  /// e.g., because there is no definition of that entity within this
+  /// translation unit, returns a NULL cursor.
+  CXCursor clang_getCursorDefinition(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorDefinition(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorDefinitionPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXCursor)>>(
+          'clang_getCursorDefinition');
+  late final _clang_getCursorDefinition =
+      _clang_getCursorDefinitionPtr.asFunction<CXCursor Function(CXCursor)>();
+
+  /// Given a cursor that represents a property declaration, return the
+  /// associated property attributes. The bits are formed from
+  /// \c CXObjCPropertyAttrKind.
+  ///
+  /// \param reserved Reserved for future use, pass 0.
+  int clang_Cursor_getObjCPropertyAttributes(
+    CXCursor C,
+    int reserved,
+  ) {
+    return _clang_Cursor_getObjCPropertyAttributes(
+      C,
+      reserved,
+    );
+  }
+
+  late final _clang_Cursor_getObjCPropertyAttributesPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.UnsignedInt Function(CXCursor, ffi.UnsignedInt)>>(
+      'clang_Cursor_getObjCPropertyAttributes');
+  late final _clang_Cursor_getObjCPropertyAttributes =
+      _clang_Cursor_getObjCPropertyAttributesPtr
+          .asFunction<int Function(CXCursor, int)>();
+
+  /// Given a cursor that represents a property declaration, return the
+  /// name of the method that implements the getter.
+  CXString clang_Cursor_getObjCPropertyGetterName(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getObjCPropertyGetterName(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getObjCPropertyGetterNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_Cursor_getObjCPropertyGetterName');
+  late final _clang_Cursor_getObjCPropertyGetterName =
+      _clang_Cursor_getObjCPropertyGetterNamePtr
+          .asFunction<CXString Function(CXCursor)>();
+
+  /// Given a cursor that represents a property declaration, return the
+  /// name of the method that implements the setter, if any.
+  CXString clang_Cursor_getObjCPropertySetterName(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getObjCPropertySetterName(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getObjCPropertySetterNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_Cursor_getObjCPropertySetterName');
+  late final _clang_Cursor_getObjCPropertySetterName =
+      _clang_Cursor_getObjCPropertySetterNamePtr
+          .asFunction<CXString Function(CXCursor)>();
+
+  /// Given a cursor that represents a declaration, return the associated
+  /// comment's source range.  The range may include multiple consecutive comments
+  /// with whitespace in between.
+  CXSourceRange clang_Cursor_getCommentRange(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getCommentRange(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getCommentRangePtr =
+      _lookup<ffi.NativeFunction<CXSourceRange Function(CXCursor)>>(
+          'clang_Cursor_getCommentRange');
+  late final _clang_Cursor_getCommentRange = _clang_Cursor_getCommentRangePtr
+      .asFunction<CXSourceRange Function(CXCursor)>();
+
+  /// Given a cursor that represents a declaration, return the associated
+  /// comment text, including comment markers.
+  CXString clang_Cursor_getRawCommentText(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getRawCommentText(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getRawCommentTextPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_Cursor_getRawCommentText');
+  late final _clang_Cursor_getRawCommentText =
+      _clang_Cursor_getRawCommentTextPtr
+          .asFunction<CXString Function(CXCursor)>();
+
+  /// Given a cursor that represents a documentable entity (e.g.,
+  /// declaration), return the associated \paragraph; otherwise return the
+  /// first paragraph.
+  CXString clang_Cursor_getBriefCommentText(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getBriefCommentText(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getBriefCommentTextPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_Cursor_getBriefCommentText');
+  late final _clang_Cursor_getBriefCommentText =
+      _clang_Cursor_getBriefCommentTextPtr
+          .asFunction<CXString Function(CXCursor)>();
+
+  /// \defgroup CINDEX_DEBUG Debugging facilities
+  ///
+  /// These routines are used for testing and debugging, only, and should not
+  /// be relied upon.
+  ///
+  /// @{
+  CXString clang_getCursorKindSpelling(
+    int Kind,
+  ) {
+    return _clang_getCursorKindSpelling(
+      Kind,
+    );
+  }
+
+  late final _clang_getCursorKindSpellingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(ffi.Int32)>>(
+          'clang_getCursorKindSpelling');
+  late final _clang_getCursorKindSpelling =
+      _clang_getCursorKindSpellingPtr.asFunction<CXString Function(int)>();
+
+  /// Return a version string, suitable for showing to a user, but not
+  /// intended to be parsed (the format is not guaranteed to be stable).
+  CXString clang_getClangVersion() {
+    return _clang_getClangVersion();
+  }
+
+  late final _clang_getClangVersionPtr =
+      _lookup<ffi.NativeFunction<CXString Function()>>('clang_getClangVersion');
+  late final _clang_getClangVersion =
+      _clang_getClangVersionPtr.asFunction<CXString Function()>();
+
+  /// If cursor is a statement declaration tries to evaluate the
+  /// statement and if its variable, tries to evaluate its initializer,
+  /// into its corresponding type.
+  CXEvalResult clang_Cursor_Evaluate(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_Evaluate(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_EvaluatePtr =
+      _lookup<ffi.NativeFunction<CXEvalResult Function(CXCursor)>>(
+          'clang_Cursor_Evaluate');
+  late final _clang_Cursor_Evaluate =
+      _clang_Cursor_EvaluatePtr.asFunction<CXEvalResult Function(CXCursor)>();
+
+  /// Returns the kind of the evaluated result.
+  int clang_EvalResult_getKind(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getKind(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getKindPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXEvalResult)>>(
+          'clang_EvalResult_getKind');
+  late final _clang_EvalResult_getKind =
+      _clang_EvalResult_getKindPtr.asFunction<int Function(CXEvalResult)>();
+
+  /// Returns the evaluation result as integer if the
+  /// kind is Int.
+  int clang_EvalResult_getAsInt(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsInt(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsIntPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXEvalResult)>>(
+          'clang_EvalResult_getAsInt');
+  late final _clang_EvalResult_getAsInt =
+      _clang_EvalResult_getAsIntPtr.asFunction<int Function(CXEvalResult)>();
+
+  /// Returns the evaluation result as a long long integer if the
+  /// kind is Int. This prevents overflows that may happen if the result is
+  /// returned with clang_EvalResult_getAsInt.
+  int clang_EvalResult_getAsLongLong(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsLongLong(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsLongLongPtr =
+      _lookup<ffi.NativeFunction<ffi.LongLong Function(CXEvalResult)>>(
+          'clang_EvalResult_getAsLongLong');
+  late final _clang_EvalResult_getAsLongLong =
+      _clang_EvalResult_getAsLongLongPtr
+          .asFunction<int Function(CXEvalResult)>();
+
+  /// Returns the evaluation result as double if the
+  /// kind is double.
+  double clang_EvalResult_getAsDouble(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsDouble(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsDoublePtr =
+      _lookup<ffi.NativeFunction<ffi.Double Function(CXEvalResult)>>(
+          'clang_EvalResult_getAsDouble');
+  late final _clang_EvalResult_getAsDouble = _clang_EvalResult_getAsDoublePtr
+      .asFunction<double Function(CXEvalResult)>();
+
+  /// Returns the evaluation result as a constant string if the
+  /// kind is other than Int or float. User must not free this pointer,
+  /// instead call clang_EvalResult_dispose on the CXEvalResult returned
+  /// by clang_Cursor_Evaluate.
+  ffi.Pointer<ffi.Char> clang_EvalResult_getAsStr(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsStr(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsStrPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(CXEvalResult)>>(
+          'clang_EvalResult_getAsStr');
+  late final _clang_EvalResult_getAsStr = _clang_EvalResult_getAsStrPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(CXEvalResult)>();
+
+  /// Disposes the created Eval memory.
+  void clang_EvalResult_dispose(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_dispose(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_disposePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXEvalResult)>>(
+          'clang_EvalResult_dispose');
+  late final _clang_EvalResult_dispose =
+      _clang_EvalResult_disposePtr.asFunction<void Function(CXEvalResult)>();
+}
+
+/// A character string.
+///
+/// The \c CXString type is used to return strings from the interface when
+/// the ownership of that string might differ from one call to the next.
+/// Use \c clang_getCString() to retrieve the string data and, once finished
+/// with the string data, call \c clang_disposeString() to free the string.
+final class CXString extends ffi.Struct {
+  external ffi.Pointer<ffi.Void> data;
+
+  @ffi.UnsignedInt()
+  external int private_flags;
+}
+
+final class CXTranslationUnitImpl extends ffi.Opaque {}
+
+/// Provides the contents of a file that has not yet been saved to disk.
+///
+/// Each CXUnsavedFile instance provides the name of a file on the
+/// system along with the current contents of that file that have not
+/// yet been saved to disk.
+final class CXUnsavedFile extends ffi.Struct {
+  /// The file whose contents have not yet been saved.
+  ///
+  /// This file must already exist in the file system.
+  external ffi.Pointer<ffi.Char> Filename;
+
+  /// A buffer containing the unsaved contents of this file.
+  external ffi.Pointer<ffi.Char> Contents;
+
+  /// The length of the unsaved contents of this buffer.
+  @ffi.UnsignedLong()
+  external int Length;
+}
+
+/// An "index" that consists of a set of translation units that would
+/// typically be linked together into an executable or library.
+typedef CXIndex = ffi.Pointer<ffi.Void>;
+
+/// A particular source file that is part of a translation unit.
+typedef CXFile = ffi.Pointer<ffi.Void>;
+
+/// Identifies a specific source location within a translation
+/// unit.
+///
+/// Use clang_getExpansionLocation() or clang_getSpellingLocation()
+/// to map a source location to a particular file, line, and column.
+final class CXSourceLocation extends ffi.Struct {
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
+
+  @ffi.UnsignedInt()
+  external int int_data;
+}
+
+/// Identifies a half-open character range in the source code.
+///
+/// Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
+/// starting and end locations from a source range, respectively.
+final class CXSourceRange extends ffi.Struct {
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
+
+  @ffi.UnsignedInt()
+  external int begin_int_data;
+
+  @ffi.UnsignedInt()
+  external int end_int_data;
+}
+
+/// A single translation unit, which resides in an index.
+typedef CXTranslationUnit = ffi.Pointer<CXTranslationUnitImpl>;
+
+/// A single diagnostic, containing the diagnostic's severity,
+/// location, text, source ranges, and fix-it hints.
+typedef CXDiagnostic = ffi.Pointer<ffi.Void>;
+
+/// Options to control the display of diagnostics.
+///
+/// The values in this enum are meant to be combined to customize the
+/// behavior of \c clang_formatDiagnostic().
+abstract class CXDiagnosticDisplayOptions {
+  /// Display the source-location information where the
+  /// diagnostic was located.
+  ///
+  /// When set, diagnostics will be prefixed by the file, line, and
+  /// (optionally) column to which the diagnostic refers. For example,
+  ///
+  /// \code
+  /// test.c:28: warning: extra tokens at end of #endif directive
+  /// \endcode
+  ///
+  /// This option corresponds to the clang flag \c -fshow-source-location.
+  static const int CXDiagnostic_DisplaySourceLocation = 1;
+
+  /// If displaying the source-location information of the
+  /// diagnostic, also include the column number.
+  ///
+  /// This option corresponds to the clang flag \c -fshow-column.
+  static const int CXDiagnostic_DisplayColumn = 2;
+
+  /// If displaying the source-location information of the
+  /// diagnostic, also include information about source ranges in a
+  /// machine-parsable format.
+  ///
+  /// This option corresponds to the clang flag
+  /// \c -fdiagnostics-print-source-range-info.
+  static const int CXDiagnostic_DisplaySourceRanges = 4;
+
+  /// Display the option name associated with this diagnostic, if any.
+  ///
+  /// The option name displayed (e.g., -Wconversion) will be placed in brackets
+  /// after the diagnostic text. This option corresponds to the clang flag
+  /// \c -fdiagnostics-show-option.
+  static const int CXDiagnostic_DisplayOption = 8;
+
+  /// Display the category number associated with this diagnostic, if any.
+  ///
+  /// The category number is displayed within brackets after the diagnostic text.
+  /// This option corresponds to the clang flag
+  /// \c -fdiagnostics-show-category=id.
+  static const int CXDiagnostic_DisplayCategoryId = 16;
+
+  /// Display the category name associated with this diagnostic, if any.
+  ///
+  /// The category name is displayed within brackets after the diagnostic text.
+  /// This option corresponds to the clang flag
+  /// \c -fdiagnostics-show-category=name.
+  static const int CXDiagnostic_DisplayCategoryName = 32;
+}
+
+/// Flags that control the creation of translation units.
+///
+/// The enumerators in this enumeration type are meant to be bitwise
+/// ORed together to specify which options should be used when
+/// constructing the translation unit.
+abstract class CXTranslationUnit_Flags {
+  /// Used to indicate that no special translation-unit options are
+  /// needed.
+  static const int CXTranslationUnit_None = 0;
+
+  /// Used to indicate that the parser should construct a "detailed"
+  /// preprocessing record, including all macro definitions and instantiations.
+  ///
+  /// Constructing a detailed preprocessing record requires more memory
+  /// and time to parse, since the information contained in the record
+  /// is usually not retained. However, it can be useful for
+  /// applications that require more detailed information about the
+  /// behavior of the preprocessor.
+  static const int CXTranslationUnit_DetailedPreprocessingRecord = 1;
+
+  /// Used to indicate that the translation unit is incomplete.
+  ///
+  /// When a translation unit is considered "incomplete", semantic
+  /// analysis that is typically performed at the end of the
+  /// translation unit will be suppressed. For example, this suppresses
+  /// the completion of tentative declarations in C and of
+  /// instantiation of implicitly-instantiation function templates in
+  /// C++. This option is typically used when parsing a header with the
+  /// intent of producing a precompiled header.
+  static const int CXTranslationUnit_Incomplete = 2;
+
+  /// Used to indicate that the translation unit should be built with an
+  /// implicit precompiled header for the preamble.
+  ///
+  /// An implicit precompiled header is used as an optimization when a
+  /// particular translation unit is likely to be reparsed many times
+  /// when the sources aren't changing that often. In this case, an
+  /// implicit precompiled header will be built containing all of the
+  /// initial includes at the top of the main file (what we refer to as
+  /// the "preamble" of the file). In subsequent parses, if the
+  /// preamble or the files in it have not changed, \c
+  /// clang_reparseTranslationUnit() will re-use the implicit
+  /// precompiled header to improve parsing performance.
+  static const int CXTranslationUnit_PrecompiledPreamble = 4;
+
+  /// Used to indicate that the translation unit should cache some
+  /// code-completion results with each reparse of the source file.
+  ///
+  /// Caching of code-completion results is a performance optimization that
+  /// introduces some overhead to reparsing but improves the performance of
+  /// code-completion operations.
+  static const int CXTranslationUnit_CacheCompletionResults = 8;
+
+  /// Used to indicate that the translation unit will be serialized with
+  /// \c clang_saveTranslationUnit.
+  ///
+  /// This option is typically used when parsing a header with the intent of
+  /// producing a precompiled header.
+  static const int CXTranslationUnit_ForSerialization = 16;
+
+  /// DEPRECATED: Enabled chained precompiled preambles in C++.
+  ///
+  /// Note: this is a *temporary* option that is available only while
+  /// we are testing C++ precompiled preamble support. It is deprecated.
+  static const int CXTranslationUnit_CXXChainedPCH = 32;
+
+  /// Used to indicate that function/method bodies should be skipped while
+  /// parsing.
+  ///
+  /// This option can be used to search for declarations/definitions while
+  /// ignoring the usages.
+  static const int CXTranslationUnit_SkipFunctionBodies = 64;
+
+  /// Used to indicate that brief documentation comments should be
+  /// included into the set of code completions returned from this translation
+  /// unit.
+  static const int CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 128;
+
+  /// Used to indicate that the precompiled preamble should be created on
+  /// the first parse. Otherwise it will be created on the first reparse. This
+  /// trades runtime on the first parse (serializing the preamble takes time) for
+  /// reduced runtime on the second parse (can now reuse the preamble).
+  static const int CXTranslationUnit_CreatePreambleOnFirstParse = 256;
+
+  /// Do not stop processing when fatal errors are encountered.
+  ///
+  /// When fatal errors are encountered while parsing a translation unit,
+  /// semantic analysis is typically stopped early when compiling code. A common
+  /// source for fatal errors are unresolvable include files. For the
+  /// purposes of an IDE, this is undesirable behavior and as much information
+  /// as possible should be reported. Use this flag to enable this behavior.
+  static const int CXTranslationUnit_KeepGoing = 512;
+
+  /// Sets the preprocessor in a mode for parsing a single file only.
+  static const int CXTranslationUnit_SingleFileParse = 1024;
+
+  /// Used in combination with CXTranslationUnit_SkipFunctionBodies to
+  /// constrain the skipping of function bodies to the preamble.
+  ///
+  /// The function bodies of the main file are not skipped.
+  static const int CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 2048;
+
+  /// Used to indicate that attributed types should be included in CXType.
+  static const int CXTranslationUnit_IncludeAttributedTypes = 4096;
+
+  /// Used to indicate that implicit attributes should be visited.
+  static const int CXTranslationUnit_VisitImplicitAttributes = 8192;
+
+  /// Used to indicate that non-errors from included files should be ignored.
+  ///
+  /// If set, clang_getDiagnosticSetFromTU() will not report e.g. warnings from
+  /// included files anymore. This speeds up clang_getDiagnosticSetFromTU() for
+  /// the case where these warnings are not of interest, as for an IDE for
+  /// example, which typically shows only the diagnostics in the main file.
+  static const int CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles = 16384;
+
+  /// Tells the preprocessor not to skip excluded conditional blocks.
+  static const int CXTranslationUnit_RetainExcludedConditionalBlocks = 32768;
+}
+
+/// Describes the kind of entity that a cursor refers to.
+abstract class CXCursorKind {
+  /// A declaration whose specific kind is not exposed via this
+  /// interface.
+  ///
+  /// Unexposed declarations have the same operations as any other kind
+  /// of declaration; one can extract their location information,
+  /// spelling, find their definitions, etc. However, the specific kind
+  /// of the declaration is not reported.
+  static const int CXCursor_UnexposedDecl = 1;
+
+  /// A C or C++ struct.
+  static const int CXCursor_StructDecl = 2;
+
+  /// A C or C++ union.
+  static const int CXCursor_UnionDecl = 3;
+
+  /// A C++ class.
+  static const int CXCursor_ClassDecl = 4;
+
+  /// An enumeration.
+  static const int CXCursor_EnumDecl = 5;
+
+  /// A field (in C) or non-static data member (in C++) in a
+  /// struct, union, or C++ class.
+  static const int CXCursor_FieldDecl = 6;
+
+  /// An enumerator constant.
+  static const int CXCursor_EnumConstantDecl = 7;
+
+  /// A function.
+  static const int CXCursor_FunctionDecl = 8;
+
+  /// A variable.
+  static const int CXCursor_VarDecl = 9;
+
+  /// A function or method parameter.
+  static const int CXCursor_ParmDecl = 10;
+
+  /// An Objective-C \@interface.
+  static const int CXCursor_ObjCInterfaceDecl = 11;
+
+  /// An Objective-C \@interface for a category.
+  static const int CXCursor_ObjCCategoryDecl = 12;
+
+  /// An Objective-C \@protocol declaration.
+  static const int CXCursor_ObjCProtocolDecl = 13;
+
+  /// An Objective-C \@property declaration.
+  static const int CXCursor_ObjCPropertyDecl = 14;
+
+  /// An Objective-C instance variable.
+  static const int CXCursor_ObjCIvarDecl = 15;
+
+  /// An Objective-C instance method.
+  static const int CXCursor_ObjCInstanceMethodDecl = 16;
+
+  /// An Objective-C class method.
+  static const int CXCursor_ObjCClassMethodDecl = 17;
+
+  /// An Objective-C \@implementation.
+  static const int CXCursor_ObjCImplementationDecl = 18;
+
+  /// An Objective-C \@implementation for a category.
+  static const int CXCursor_ObjCCategoryImplDecl = 19;
+
+  /// A typedef.
+  static const int CXCursor_TypedefDecl = 20;
+
+  /// A C++ class method.
+  static const int CXCursor_CXXMethod = 21;
+
+  /// A C++ namespace.
+  static const int CXCursor_Namespace = 22;
+
+  /// A linkage specification, e.g. 'extern "C"'.
+  static const int CXCursor_LinkageSpec = 23;
+
+  /// A C++ constructor.
+  static const int CXCursor_Constructor = 24;
+
+  /// A C++ destructor.
+  static const int CXCursor_Destructor = 25;
+
+  /// A C++ conversion function.
+  static const int CXCursor_ConversionFunction = 26;
+
+  /// A C++ template type parameter.
+  static const int CXCursor_TemplateTypeParameter = 27;
+
+  /// A C++ non-type template parameter.
+  static const int CXCursor_NonTypeTemplateParameter = 28;
+
+  /// A C++ template template parameter.
+  static const int CXCursor_TemplateTemplateParameter = 29;
+
+  /// A C++ function template.
+  static const int CXCursor_FunctionTemplate = 30;
+
+  /// A C++ class template.
+  static const int CXCursor_ClassTemplate = 31;
+
+  /// A C++ class template partial specialization.
+  static const int CXCursor_ClassTemplatePartialSpecialization = 32;
+
+  /// A C++ namespace alias declaration.
+  static const int CXCursor_NamespaceAlias = 33;
+
+  /// A C++ using directive.
+  static const int CXCursor_UsingDirective = 34;
+
+  /// A C++ using declaration.
+  static const int CXCursor_UsingDeclaration = 35;
+
+  /// A C++ alias declaration
+  static const int CXCursor_TypeAliasDecl = 36;
+
+  /// An Objective-C \@synthesize definition.
+  static const int CXCursor_ObjCSynthesizeDecl = 37;
+
+  /// An Objective-C \@dynamic definition.
+  static const int CXCursor_ObjCDynamicDecl = 38;
+
+  /// An access specifier.
+  static const int CXCursor_CXXAccessSpecifier = 39;
+  static const int CXCursor_FirstDecl = 1;
+  static const int CXCursor_LastDecl = 39;
+  static const int CXCursor_FirstRef = 40;
+  static const int CXCursor_ObjCSuperClassRef = 40;
+  static const int CXCursor_ObjCProtocolRef = 41;
+  static const int CXCursor_ObjCClassRef = 42;
+
+  /// A reference to a type declaration.
+  ///
+  /// A type reference occurs anywhere where a type is named but not
+  /// declared. For example, given:
+  ///
+  /// \code
+  /// typedef unsigned size_type;
+  /// size_type size;
+  /// \endcode
+  ///
+  /// The typedef is a declaration of size_type (CXCursor_TypedefDecl),
+  /// while the type of the variable "size" is referenced. The cursor
+  /// referenced by the type of size is the typedef for size_type.
+  static const int CXCursor_TypeRef = 43;
+  static const int CXCursor_CXXBaseSpecifier = 44;
+
+  /// A reference to a class template, function template, template
+  /// template parameter, or class template partial specialization.
+  static const int CXCursor_TemplateRef = 45;
+
+  /// A reference to a namespace or namespace alias.
+  static const int CXCursor_NamespaceRef = 46;
+
+  /// A reference to a member of a struct, union, or class that occurs in
+  /// some non-expression context, e.g., a designated initializer.
+  static const int CXCursor_MemberRef = 47;
+
+  /// A reference to a labeled statement.
+  ///
+  /// This cursor kind is used to describe the jump to "start_over" in the
+  /// goto statement in the following example:
+  ///
+  /// \code
+  /// start_over:
+  /// ++counter;
+  ///
+  /// goto start_over;
+  /// \endcode
+  ///
+  /// A label reference cursor refers to a label statement.
+  static const int CXCursor_LabelRef = 48;
+
+  /// A reference to a set of overloaded functions or function templates
+  /// that has not yet been resolved to a specific function or function template.
+  ///
+  /// An overloaded declaration reference cursor occurs in C++ templates where
+  /// a dependent name refers to a function. For example:
+  ///
+  /// \code
+  /// template<typename T> void swap(T&, T&);
+  ///
+  /// struct X { ... };
+  /// void swap(X&, X&);
+  ///
+  /// template<typename T>
+  /// void reverse(T* first, T* last) {
+  /// while (first < last - 1) {
+  /// swap(*first, *--last);
+  /// ++first;
+  /// }
+  /// }
+  ///
+  /// struct Y { };
+  /// void swap(Y&, Y&);
+  /// \endcode
+  ///
+  /// Here, the identifier "swap" is associated with an overloaded declaration
+  /// reference. In the template definition, "swap" refers to either of the two
+  /// "swap" functions declared above, so both results will be available. At
+  /// instantiation time, "swap" may also refer to other functions found via
+  /// argument-dependent lookup (e.g., the "swap" function at the end of the
+  /// example).
+  ///
+  /// The functions \c clang_getNumOverloadedDecls() and
+  /// \c clang_getOverloadedDecl() can be used to retrieve the definitions
+  /// referenced by this cursor.
+  static const int CXCursor_OverloadedDeclRef = 49;
+
+  /// A reference to a variable that occurs in some non-expression
+  /// context, e.g., a C++ lambda capture list.
+  static const int CXCursor_VariableRef = 50;
+  static const int CXCursor_LastRef = 50;
+  static const int CXCursor_FirstInvalid = 70;
+  static const int CXCursor_InvalidFile = 70;
+  static const int CXCursor_NoDeclFound = 71;
+  static const int CXCursor_NotImplemented = 72;
+  static const int CXCursor_InvalidCode = 73;
+  static const int CXCursor_LastInvalid = 73;
+  static const int CXCursor_FirstExpr = 100;
+
+  /// An expression whose specific kind is not exposed via this
+  /// interface.
+  ///
+  /// Unexposed expressions have the same operations as any other kind
+  /// of expression; one can extract their location information,
+  /// spelling, children, etc. However, the specific kind of the
+  /// expression is not reported.
+  static const int CXCursor_UnexposedExpr = 100;
+
+  /// An expression that refers to some value declaration, such
+  /// as a function, variable, or enumerator.
+  static const int CXCursor_DeclRefExpr = 101;
+
+  /// An expression that refers to a member of a struct, union,
+  /// class, Objective-C class, etc.
+  static const int CXCursor_MemberRefExpr = 102;
+
+  /// An expression that calls a function.
+  static const int CXCursor_CallExpr = 103;
+
+  /// An expression that sends a message to an Objective-C
+  /// object or class.
+  static const int CXCursor_ObjCMessageExpr = 104;
+
+  /// An expression that represents a block literal.
+  static const int CXCursor_BlockExpr = 105;
+
+  /// An integer literal.
+  static const int CXCursor_IntegerLiteral = 106;
+
+  /// A floating point number literal.
+  static const int CXCursor_FloatingLiteral = 107;
+
+  /// An imaginary number literal.
+  static const int CXCursor_ImaginaryLiteral = 108;
+
+  /// A string literal.
+  static const int CXCursor_StringLiteral = 109;
+
+  /// A character literal.
+  static const int CXCursor_CharacterLiteral = 110;
+
+  /// A parenthesized expression, e.g. "(1)".
+  ///
+  /// This AST node is only formed if full location information is requested.
+  static const int CXCursor_ParenExpr = 111;
+
+  /// This represents the unary-expression's (except sizeof and
+  /// alignof).
+  static const int CXCursor_UnaryOperator = 112;
+
+  /// [C99 6.5.2.1] Array Subscripting.
+  static const int CXCursor_ArraySubscriptExpr = 113;
+
+  /// A builtin binary operation expression such as "x + y" or
+  /// "x <= y".
+  static const int CXCursor_BinaryOperator = 114;
+
+  /// Compound assignment such as "+=".
+  static const int CXCursor_CompoundAssignOperator = 115;
+
+  /// The ?: ternary operator.
+  static const int CXCursor_ConditionalOperator = 116;
+
+  /// An explicit cast in C (C99 6.5.4) or a C-style cast in C++
+  /// (C++ [expr.cast]), which uses the syntax (Type)expr.
+  ///
+  /// For example: (int)f.
+  static const int CXCursor_CStyleCastExpr = 117;
+
+  /// [C99 6.5.2.5]
+  static const int CXCursor_CompoundLiteralExpr = 118;
+
+  /// Describes an C or C++ initializer list.
+  static const int CXCursor_InitListExpr = 119;
+
+  /// The GNU address of label extension, representing &&label.
+  static const int CXCursor_AddrLabelExpr = 120;
+
+  /// This is the GNU Statement Expression extension: ({int X=4; X;})
+  static const int CXCursor_StmtExpr = 121;
+
+  /// Represents a C11 generic selection.
+  static const int CXCursor_GenericSelectionExpr = 122;
+
+  /// Implements the GNU __null extension, which is a name for a null
+  /// pointer constant that has integral type (e.g., int or long) and is the same
+  /// size and alignment as a pointer.
+  ///
+  /// The __null extension is typically only used by system headers, which define
+  /// NULL as __null in C++ rather than using 0 (which is an integer that may not
+  /// match the size of a pointer).
+  static const int CXCursor_GNUNullExpr = 123;
+
+  /// C++'s static_cast<> expression.
+  static const int CXCursor_CXXStaticCastExpr = 124;
+
+  /// C++'s dynamic_cast<> expression.
+  static const int CXCursor_CXXDynamicCastExpr = 125;
+
+  /// C++'s reinterpret_cast<> expression.
+  static const int CXCursor_CXXReinterpretCastExpr = 126;
+
+  /// C++'s const_cast<> expression.
+  static const int CXCursor_CXXConstCastExpr = 127;
+
+  /// Represents an explicit C++ type conversion that uses "functional"
+  /// notion (C++ [expr.type.conv]).
+  ///
+  /// Example:
+  /// \code
+  /// x = int(0.5);
+  /// \endcode
+  static const int CXCursor_CXXFunctionalCastExpr = 128;
+
+  /// A C++ typeid expression (C++ [expr.typeid]).
+  static const int CXCursor_CXXTypeidExpr = 129;
+
+  /// [C++ 2.13.5] C++ Boolean Literal.
+  static const int CXCursor_CXXBoolLiteralExpr = 130;
+
+  /// [C++0x 2.14.7] C++ Pointer Literal.
+  static const int CXCursor_CXXNullPtrLiteralExpr = 131;
+
+  /// Represents the "this" expression in C++
+  static const int CXCursor_CXXThisExpr = 132;
+
+  /// [C++ 15] C++ Throw Expression.
+  ///
+  /// This handles 'throw' and 'throw' assignment-expression. When
+  /// assignment-expression isn't present, Op will be null.
+  static const int CXCursor_CXXThrowExpr = 133;
+
+  /// A new expression for memory allocation and constructor calls, e.g:
+  /// "new CXXNewExpr(foo)".
+  static const int CXCursor_CXXNewExpr = 134;
+
+  /// A delete expression for memory deallocation and destructor calls,
+  /// e.g. "delete[] pArray".
+  static const int CXCursor_CXXDeleteExpr = 135;
+
+  /// A unary expression. (noexcept, sizeof, or other traits)
+  static const int CXCursor_UnaryExpr = 136;
+
+  /// An Objective-C string literal i.e. @"foo".
+  static const int CXCursor_ObjCStringLiteral = 137;
+
+  /// An Objective-C \@encode expression.
+  static const int CXCursor_ObjCEncodeExpr = 138;
+
+  /// An Objective-C \@selector expression.
+  static const int CXCursor_ObjCSelectorExpr = 139;
+
+  /// An Objective-C \@protocol expression.
+  static const int CXCursor_ObjCProtocolExpr = 140;
+
+  /// An Objective-C "bridged" cast expression, which casts between
+  /// Objective-C pointers and C pointers, transferring ownership in the process.
+  ///
+  /// \code
+  /// NSString *str = (__bridge_transfer NSString *)CFCreateString();
+  /// \endcode
+  static const int CXCursor_ObjCBridgedCastExpr = 141;
+
+  /// Represents a C++0x pack expansion that produces a sequence of
+  /// expressions.
+  ///
+  /// A pack expansion expression contains a pattern (which itself is an
+  /// expression) followed by an ellipsis. For example:
+  ///
+  /// \code
+  /// template<typename F, typename ...Types>
+  /// void forward(F f, Types &&...args) {
+  /// f(static_cast<Types&&>(args)...);
+  /// }
+  /// \endcode
+  static const int CXCursor_PackExpansionExpr = 142;
+
+  /// Represents an expression that computes the length of a parameter
+  /// pack.
+  ///
+  /// \code
+  /// template<typename ...Types>
+  /// struct count {
+  /// static const unsigned value = sizeof...(Types);
+  /// };
+  /// \endcode
+  static const int CXCursor_SizeOfPackExpr = 143;
+  static const int CXCursor_LambdaExpr = 144;
+
+  /// Objective-c Boolean Literal.
+  static const int CXCursor_ObjCBoolLiteralExpr = 145;
+
+  /// Represents the "self" expression in an Objective-C method.
+  static const int CXCursor_ObjCSelfExpr = 146;
+
+  /// OpenMP 4.0 [2.4, Array Section].
+  static const int CXCursor_OMPArraySectionExpr = 147;
+
+  /// Represents an @available(...) check.
+  static const int CXCursor_ObjCAvailabilityCheckExpr = 148;
+
+  /// Fixed point literal
+  static const int CXCursor_FixedPointLiteral = 149;
+  static const int CXCursor_LastExpr = 149;
+  static const int CXCursor_FirstStmt = 200;
+
+  /// A statement whose specific kind is not exposed via this
+  /// interface.
+  ///
+  /// Unexposed statements have the same operations as any other kind of
+  /// statement; one can extract their location information, spelling,
+  /// children, etc. However, the specific kind of the statement is not
+  /// reported.
+  static const int CXCursor_UnexposedStmt = 200;
+
+  /// A labelled statement in a function.
+  ///
+  /// This cursor kind is used to describe the "start_over:" label statement in
+  /// the following example:
+  ///
+  /// \code
+  /// start_over:
+  /// ++counter;
+  /// \endcode
+  static const int CXCursor_LabelStmt = 201;
+
+  /// A group of statements like { stmt stmt }.
+  ///
+  /// This cursor kind is used to describe compound statements, e.g. function
+  /// bodies.
+  static const int CXCursor_CompoundStmt = 202;
+
+  /// A case statement.
+  static const int CXCursor_CaseStmt = 203;
+
+  /// A default statement.
+  static const int CXCursor_DefaultStmt = 204;
+
+  /// An if statement
+  static const int CXCursor_IfStmt = 205;
+
+  /// A switch statement.
+  static const int CXCursor_SwitchStmt = 206;
+
+  /// A while statement.
+  static const int CXCursor_WhileStmt = 207;
+
+  /// A do statement.
+  static const int CXCursor_DoStmt = 208;
+
+  /// A for statement.
+  static const int CXCursor_ForStmt = 209;
+
+  /// A goto statement.
+  static const int CXCursor_GotoStmt = 210;
+
+  /// An indirect goto statement.
+  static const int CXCursor_IndirectGotoStmt = 211;
+
+  /// A continue statement.
+  static const int CXCursor_ContinueStmt = 212;
+
+  /// A break statement.
+  static const int CXCursor_BreakStmt = 213;
+
+  /// A return statement.
+  static const int CXCursor_ReturnStmt = 214;
+
+  /// A GCC inline assembly statement extension.
+  static const int CXCursor_GCCAsmStmt = 215;
+  static const int CXCursor_AsmStmt = 215;
+
+  /// Objective-C's overall \@try-\@catch-\@finally statement.
+  static const int CXCursor_ObjCAtTryStmt = 216;
+
+  /// Objective-C's \@catch statement.
+  static const int CXCursor_ObjCAtCatchStmt = 217;
+
+  /// Objective-C's \@finally statement.
+  static const int CXCursor_ObjCAtFinallyStmt = 218;
+
+  /// Objective-C's \@throw statement.
+  static const int CXCursor_ObjCAtThrowStmt = 219;
+
+  /// Objective-C's \@synchronized statement.
+  static const int CXCursor_ObjCAtSynchronizedStmt = 220;
+
+  /// Objective-C's autorelease pool statement.
+  static const int CXCursor_ObjCAutoreleasePoolStmt = 221;
+
+  /// Objective-C's collection statement.
+  static const int CXCursor_ObjCForCollectionStmt = 222;
+
+  /// C++'s catch statement.
+  static const int CXCursor_CXXCatchStmt = 223;
+
+  /// C++'s try statement.
+  static const int CXCursor_CXXTryStmt = 224;
+
+  /// C++'s for (* : *) statement.
+  static const int CXCursor_CXXForRangeStmt = 225;
+
+  /// Windows Structured Exception Handling's try statement.
+  static const int CXCursor_SEHTryStmt = 226;
+
+  /// Windows Structured Exception Handling's except statement.
+  static const int CXCursor_SEHExceptStmt = 227;
+
+  /// Windows Structured Exception Handling's finally statement.
+  static const int CXCursor_SEHFinallyStmt = 228;
+
+  /// A MS inline assembly statement extension.
+  static const int CXCursor_MSAsmStmt = 229;
+
+  /// The null statement ";": C99 6.8.3p3.
+  ///
+  /// This cursor kind is used to describe the null statement.
+  static const int CXCursor_NullStmt = 230;
+
+  /// Adaptor class for mixing declarations with statements and
+  /// expressions.
+  static const int CXCursor_DeclStmt = 231;
+
+  /// OpenMP parallel directive.
+  static const int CXCursor_OMPParallelDirective = 232;
+
+  /// OpenMP SIMD directive.
+  static const int CXCursor_OMPSimdDirective = 233;
+
+  /// OpenMP for directive.
+  static const int CXCursor_OMPForDirective = 234;
+
+  /// OpenMP sections directive.
+  static const int CXCursor_OMPSectionsDirective = 235;
+
+  /// OpenMP section directive.
+  static const int CXCursor_OMPSectionDirective = 236;
+
+  /// OpenMP single directive.
+  static const int CXCursor_OMPSingleDirective = 237;
+
+  /// OpenMP parallel for directive.
+  static const int CXCursor_OMPParallelForDirective = 238;
+
+  /// OpenMP parallel sections directive.
+  static const int CXCursor_OMPParallelSectionsDirective = 239;
+
+  /// OpenMP task directive.
+  static const int CXCursor_OMPTaskDirective = 240;
+
+  /// OpenMP master directive.
+  static const int CXCursor_OMPMasterDirective = 241;
+
+  /// OpenMP critical directive.
+  static const int CXCursor_OMPCriticalDirective = 242;
+
+  /// OpenMP taskyield directive.
+  static const int CXCursor_OMPTaskyieldDirective = 243;
+
+  /// OpenMP barrier directive.
+  static const int CXCursor_OMPBarrierDirective = 244;
+
+  /// OpenMP taskwait directive.
+  static const int CXCursor_OMPTaskwaitDirective = 245;
+
+  /// OpenMP flush directive.
+  static const int CXCursor_OMPFlushDirective = 246;
+
+  /// Windows Structured Exception Handling's leave statement.
+  static const int CXCursor_SEHLeaveStmt = 247;
+
+  /// OpenMP ordered directive.
+  static const int CXCursor_OMPOrderedDirective = 248;
+
+  /// OpenMP atomic directive.
+  static const int CXCursor_OMPAtomicDirective = 249;
+
+  /// OpenMP for SIMD directive.
+  static const int CXCursor_OMPForSimdDirective = 250;
+
+  /// OpenMP parallel for SIMD directive.
+  static const int CXCursor_OMPParallelForSimdDirective = 251;
+
+  /// OpenMP target directive.
+  static const int CXCursor_OMPTargetDirective = 252;
+
+  /// OpenMP teams directive.
+  static const int CXCursor_OMPTeamsDirective = 253;
+
+  /// OpenMP taskgroup directive.
+  static const int CXCursor_OMPTaskgroupDirective = 254;
+
+  /// OpenMP cancellation point directive.
+  static const int CXCursor_OMPCancellationPointDirective = 255;
+
+  /// OpenMP cancel directive.
+  static const int CXCursor_OMPCancelDirective = 256;
+
+  /// OpenMP target data directive.
+  static const int CXCursor_OMPTargetDataDirective = 257;
+
+  /// OpenMP taskloop directive.
+  static const int CXCursor_OMPTaskLoopDirective = 258;
+
+  /// OpenMP taskloop simd directive.
+  static const int CXCursor_OMPTaskLoopSimdDirective = 259;
+
+  /// OpenMP distribute directive.
+  static const int CXCursor_OMPDistributeDirective = 260;
+
+  /// OpenMP target enter data directive.
+  static const int CXCursor_OMPTargetEnterDataDirective = 261;
+
+  /// OpenMP target exit data directive.
+  static const int CXCursor_OMPTargetExitDataDirective = 262;
+
+  /// OpenMP target parallel directive.
+  static const int CXCursor_OMPTargetParallelDirective = 263;
+
+  /// OpenMP target parallel for directive.
+  static const int CXCursor_OMPTargetParallelForDirective = 264;
+
+  /// OpenMP target update directive.
+  static const int CXCursor_OMPTargetUpdateDirective = 265;
+
+  /// OpenMP distribute parallel for directive.
+  static const int CXCursor_OMPDistributeParallelForDirective = 266;
+
+  /// OpenMP distribute parallel for simd directive.
+  static const int CXCursor_OMPDistributeParallelForSimdDirective = 267;
+
+  /// OpenMP distribute simd directive.
+  static const int CXCursor_OMPDistributeSimdDirective = 268;
+
+  /// OpenMP target parallel for simd directive.
+  static const int CXCursor_OMPTargetParallelForSimdDirective = 269;
+
+  /// OpenMP target simd directive.
+  static const int CXCursor_OMPTargetSimdDirective = 270;
+
+  /// OpenMP teams distribute directive.
+  static const int CXCursor_OMPTeamsDistributeDirective = 271;
+
+  /// OpenMP teams distribute simd directive.
+  static const int CXCursor_OMPTeamsDistributeSimdDirective = 272;
+
+  /// OpenMP teams distribute parallel for simd directive.
+  static const int CXCursor_OMPTeamsDistributeParallelForSimdDirective = 273;
+
+  /// OpenMP teams distribute parallel for directive.
+  static const int CXCursor_OMPTeamsDistributeParallelForDirective = 274;
+
+  /// OpenMP target teams directive.
+  static const int CXCursor_OMPTargetTeamsDirective = 275;
+
+  /// OpenMP target teams distribute directive.
+  static const int CXCursor_OMPTargetTeamsDistributeDirective = 276;
+
+  /// OpenMP target teams distribute parallel for directive.
+  static const int CXCursor_OMPTargetTeamsDistributeParallelForDirective = 277;
+
+  /// OpenMP target teams distribute parallel for simd directive.
+  static const int CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective =
+      278;
+
+  /// OpenMP target teams distribute simd directive.
+  static const int CXCursor_OMPTargetTeamsDistributeSimdDirective = 279;
+
+  /// C++2a std::bit_cast expression.
+  static const int CXCursor_BuiltinBitCastExpr = 280;
+
+  /// OpenMP master taskloop directive.
+  static const int CXCursor_OMPMasterTaskLoopDirective = 281;
+
+  /// OpenMP parallel master taskloop directive.
+  static const int CXCursor_OMPParallelMasterTaskLoopDirective = 282;
+
+  /// OpenMP master taskloop simd directive.
+  static const int CXCursor_OMPMasterTaskLoopSimdDirective = 283;
+
+  /// OpenMP parallel master taskloop simd directive.
+  static const int CXCursor_OMPParallelMasterTaskLoopSimdDirective = 284;
+
+  /// OpenMP parallel master directive.
+  static const int CXCursor_OMPParallelMasterDirective = 285;
+  static const int CXCursor_LastStmt = 285;
+
+  /// Cursor that represents the translation unit itself.
+  ///
+  /// The translation unit cursor exists primarily to act as the root
+  /// cursor for traversing the contents of a translation unit.
+  static const int CXCursor_TranslationUnit = 300;
+  static const int CXCursor_FirstAttr = 400;
+
+  /// An attribute whose specific kind is not exposed via this
+  /// interface.
+  static const int CXCursor_UnexposedAttr = 400;
+  static const int CXCursor_IBActionAttr = 401;
+  static const int CXCursor_IBOutletAttr = 402;
+  static const int CXCursor_IBOutletCollectionAttr = 403;
+  static const int CXCursor_CXXFinalAttr = 404;
+  static const int CXCursor_CXXOverrideAttr = 405;
+  static const int CXCursor_AnnotateAttr = 406;
+  static const int CXCursor_AsmLabelAttr = 407;
+  static const int CXCursor_PackedAttr = 408;
+  static const int CXCursor_PureAttr = 409;
+  static const int CXCursor_ConstAttr = 410;
+  static const int CXCursor_NoDuplicateAttr = 411;
+  static const int CXCursor_CUDAConstantAttr = 412;
+  static const int CXCursor_CUDADeviceAttr = 413;
+  static const int CXCursor_CUDAGlobalAttr = 414;
+  static const int CXCursor_CUDAHostAttr = 415;
+  static const int CXCursor_CUDASharedAttr = 416;
+  static const int CXCursor_VisibilityAttr = 417;
+  static const int CXCursor_DLLExport = 418;
+  static const int CXCursor_DLLImport = 419;
+  static const int CXCursor_NSReturnsRetained = 420;
+  static const int CXCursor_NSReturnsNotRetained = 421;
+  static const int CXCursor_NSReturnsAutoreleased = 422;
+  static const int CXCursor_NSConsumesSelf = 423;
+  static const int CXCursor_NSConsumed = 424;
+  static const int CXCursor_ObjCException = 425;
+  static const int CXCursor_ObjCNSObject = 426;
+  static const int CXCursor_ObjCIndependentClass = 427;
+  static const int CXCursor_ObjCPreciseLifetime = 428;
+  static const int CXCursor_ObjCReturnsInnerPointer = 429;
+  static const int CXCursor_ObjCRequiresSuper = 430;
+  static const int CXCursor_ObjCRootClass = 431;
+  static const int CXCursor_ObjCSubclassingRestricted = 432;
+  static const int CXCursor_ObjCExplicitProtocolImpl = 433;
+  static const int CXCursor_ObjCDesignatedInitializer = 434;
+  static const int CXCursor_ObjCRuntimeVisible = 435;
+  static const int CXCursor_ObjCBoxable = 436;
+  static const int CXCursor_FlagEnum = 437;
+  static const int CXCursor_ConvergentAttr = 438;
+  static const int CXCursor_WarnUnusedAttr = 439;
+  static const int CXCursor_WarnUnusedResultAttr = 440;
+  static const int CXCursor_AlignedAttr = 441;
+  static const int CXCursor_LastAttr = 441;
+  static const int CXCursor_PreprocessingDirective = 500;
+  static const int CXCursor_MacroDefinition = 501;
+  static const int CXCursor_MacroExpansion = 502;
+  static const int CXCursor_MacroInstantiation = 502;
+  static const int CXCursor_InclusionDirective = 503;
+  static const int CXCursor_FirstPreprocessing = 500;
+  static const int CXCursor_LastPreprocessing = 503;
+
+  /// A module import declaration.
+  static const int CXCursor_ModuleImportDecl = 600;
+  static const int CXCursor_TypeAliasTemplateDecl = 601;
+
+  /// A static_assert or _Static_assert node
+  static const int CXCursor_StaticAssert = 602;
+
+  /// a friend declaration.
+  static const int CXCursor_FriendDecl = 603;
+  static const int CXCursor_FirstExtraDecl = 600;
+  static const int CXCursor_LastExtraDecl = 603;
+
+  /// A code completion overload candidate.
+  static const int CXCursor_OverloadCandidate = 700;
+}
+
+/// A cursor representing some element in the abstract syntax tree for
+/// a translation unit.
+///
+/// The cursor abstraction unifies the different kinds of entities in a
+/// program--declaration, statements, expressions, references to declarations,
+/// etc.--under a single "cursor" abstraction with a common set of operations.
+/// Common operation for a cursor include: getting the physical location in
+/// a source file where the cursor points, getting the name associated with a
+/// cursor, and retrieving cursors for any child nodes of a particular cursor.
+///
+/// Cursors can be produced in two specific ways.
+/// clang_getTranslationUnitCursor() produces a cursor for a translation unit,
+/// from which one can use clang_visitChildren() to explore the rest of the
+/// translation unit. clang_getCursor() maps from a physical source location
+/// to the entity that resides at that location, allowing one to map from the
+/// source code into the AST.
+final class CXCursor extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  @ffi.Int()
+  external int xdata;
+
+  @ffi.Array.multi([3])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
+}
+
+/// Describes the kind of type
+abstract class CXTypeKind {
+  /// Represents an invalid type (e.g., where no type is available).
+  static const int CXType_Invalid = 0;
+
+  /// A type whose specific kind is not exposed via this
+  /// interface.
+  static const int CXType_Unexposed = 1;
+  static const int CXType_Void = 2;
+  static const int CXType_Bool = 3;
+  static const int CXType_Char_U = 4;
+  static const int CXType_UChar = 5;
+  static const int CXType_Char16 = 6;
+  static const int CXType_Char32 = 7;
+  static const int CXType_UShort = 8;
+  static const int CXType_UInt = 9;
+  static const int CXType_ULong = 10;
+  static const int CXType_ULongLong = 11;
+  static const int CXType_UInt128 = 12;
+  static const int CXType_Char_S = 13;
+  static const int CXType_SChar = 14;
+  static const int CXType_WChar = 15;
+  static const int CXType_Short = 16;
+  static const int CXType_Int = 17;
+  static const int CXType_Long = 18;
+  static const int CXType_LongLong = 19;
+  static const int CXType_Int128 = 20;
+  static const int CXType_Float = 21;
+  static const int CXType_Double = 22;
+  static const int CXType_LongDouble = 23;
+  static const int CXType_NullPtr = 24;
+  static const int CXType_Overload = 25;
+  static const int CXType_Dependent = 26;
+  static const int CXType_ObjCId = 27;
+  static const int CXType_ObjCClass = 28;
+  static const int CXType_ObjCSel = 29;
+  static const int CXType_Float128 = 30;
+  static const int CXType_Half = 31;
+  static const int CXType_Float16 = 32;
+  static const int CXType_ShortAccum = 33;
+  static const int CXType_Accum = 34;
+  static const int CXType_LongAccum = 35;
+  static const int CXType_UShortAccum = 36;
+  static const int CXType_UAccum = 37;
+  static const int CXType_ULongAccum = 38;
+  static const int CXType_FirstBuiltin = 2;
+  static const int CXType_LastBuiltin = 38;
+  static const int CXType_Complex = 100;
+  static const int CXType_Pointer = 101;
+  static const int CXType_BlockPointer = 102;
+  static const int CXType_LValueReference = 103;
+  static const int CXType_RValueReference = 104;
+  static const int CXType_Record = 105;
+  static const int CXType_Enum = 106;
+  static const int CXType_Typedef = 107;
+  static const int CXType_ObjCInterface = 108;
+  static const int CXType_ObjCObjectPointer = 109;
+  static const int CXType_FunctionNoProto = 110;
+  static const int CXType_FunctionProto = 111;
+  static const int CXType_ConstantArray = 112;
+  static const int CXType_Vector = 113;
+  static const int CXType_IncompleteArray = 114;
+  static const int CXType_VariableArray = 115;
+  static const int CXType_DependentSizedArray = 116;
+  static const int CXType_MemberPointer = 117;
+  static const int CXType_Auto = 118;
+
+  /// Represents a type that was referred to using an elaborated type keyword.
+  ///
+  /// E.g., struct S, or via a qualified name, e.g., N::M::type, or both.
+  static const int CXType_Elaborated = 119;
+  static const int CXType_Pipe = 120;
+  static const int CXType_OCLImage1dRO = 121;
+  static const int CXType_OCLImage1dArrayRO = 122;
+  static const int CXType_OCLImage1dBufferRO = 123;
+  static const int CXType_OCLImage2dRO = 124;
+  static const int CXType_OCLImage2dArrayRO = 125;
+  static const int CXType_OCLImage2dDepthRO = 126;
+  static const int CXType_OCLImage2dArrayDepthRO = 127;
+  static const int CXType_OCLImage2dMSAARO = 128;
+  static const int CXType_OCLImage2dArrayMSAARO = 129;
+  static const int CXType_OCLImage2dMSAADepthRO = 130;
+  static const int CXType_OCLImage2dArrayMSAADepthRO = 131;
+  static const int CXType_OCLImage3dRO = 132;
+  static const int CXType_OCLImage1dWO = 133;
+  static const int CXType_OCLImage1dArrayWO = 134;
+  static const int CXType_OCLImage1dBufferWO = 135;
+  static const int CXType_OCLImage2dWO = 136;
+  static const int CXType_OCLImage2dArrayWO = 137;
+  static const int CXType_OCLImage2dDepthWO = 138;
+  static const int CXType_OCLImage2dArrayDepthWO = 139;
+  static const int CXType_OCLImage2dMSAAWO = 140;
+  static const int CXType_OCLImage2dArrayMSAAWO = 141;
+  static const int CXType_OCLImage2dMSAADepthWO = 142;
+  static const int CXType_OCLImage2dArrayMSAADepthWO = 143;
+  static const int CXType_OCLImage3dWO = 144;
+  static const int CXType_OCLImage1dRW = 145;
+  static const int CXType_OCLImage1dArrayRW = 146;
+  static const int CXType_OCLImage1dBufferRW = 147;
+  static const int CXType_OCLImage2dRW = 148;
+  static const int CXType_OCLImage2dArrayRW = 149;
+  static const int CXType_OCLImage2dDepthRW = 150;
+  static const int CXType_OCLImage2dArrayDepthRW = 151;
+  static const int CXType_OCLImage2dMSAARW = 152;
+  static const int CXType_OCLImage2dArrayMSAARW = 153;
+  static const int CXType_OCLImage2dMSAADepthRW = 154;
+  static const int CXType_OCLImage2dArrayMSAADepthRW = 155;
+  static const int CXType_OCLImage3dRW = 156;
+  static const int CXType_OCLSampler = 157;
+  static const int CXType_OCLEvent = 158;
+  static const int CXType_OCLQueue = 159;
+  static const int CXType_OCLReserveID = 160;
+  static const int CXType_ObjCObject = 161;
+  static const int CXType_ObjCTypeParam = 162;
+  static const int CXType_Attributed = 163;
+  static const int CXType_OCLIntelSubgroupAVCMcePayload = 164;
+  static const int CXType_OCLIntelSubgroupAVCImePayload = 165;
+  static const int CXType_OCLIntelSubgroupAVCRefPayload = 166;
+  static const int CXType_OCLIntelSubgroupAVCSicPayload = 167;
+  static const int CXType_OCLIntelSubgroupAVCMceResult = 168;
+  static const int CXType_OCLIntelSubgroupAVCImeResult = 169;
+  static const int CXType_OCLIntelSubgroupAVCRefResult = 170;
+  static const int CXType_OCLIntelSubgroupAVCSicResult = 171;
+  static const int CXType_OCLIntelSubgroupAVCImeResultSingleRefStreamout = 172;
+  static const int CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout = 173;
+  static const int CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174;
+  static const int CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175;
+  static const int CXType_ExtVector = 176;
+}
+
+/// The type of an element in the abstract syntax tree.
+final class CXType extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
+}
+
+abstract class CXTypeNullabilityKind {
+  /// Values of this type can never be null.
+  static const int CXTypeNullability_NonNull = 0;
+
+  /// Values of this type can be null.
+  static const int CXTypeNullability_Nullable = 1;
+
+  /// Whether values of this type can be null is (explicitly)
+  /// unspecified. This captures a (fairly rare) case where we
+  /// can't conclude anything about the nullability of the type even
+  /// though it has been considered.
+  static const int CXTypeNullability_Unspecified = 2;
+
+  /// Nullability is not applicable to this type.
+  static const int CXTypeNullability_Invalid = 3;
+}
+
+/// List the possible error codes for \c clang_Type_getSizeOf,
+/// \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
+/// \c clang_Cursor_getOffsetOf.
+///
+/// A value of this enumeration type can be returned if the target type is not
+/// a valid argument to sizeof, alignof or offsetof.
+abstract class CXTypeLayoutError {
+  /// Type is of kind CXType_Invalid.
+  static const int CXTypeLayoutError_Invalid = -1;
+
+  /// The type is an incomplete Type.
+  static const int CXTypeLayoutError_Incomplete = -2;
+
+  /// The type is a dependent Type.
+  static const int CXTypeLayoutError_Dependent = -3;
+
+  /// The type is not a constant size type.
+  static const int CXTypeLayoutError_NotConstantSize = -4;
+
+  /// The Field name is not valid for this record.
+  static const int CXTypeLayoutError_InvalidFieldName = -5;
+
+  /// The type is undeduced.
+  static const int CXTypeLayoutError_Undeduced = -6;
+}
+
+/// Represents the storage classes as declared in the source. CX_SC_Invalid
+/// was added for the case that the passed cursor in not a declaration.
+abstract class CX_StorageClass {
+  static const int CX_SC_Invalid = 0;
+  static const int CX_SC_None = 1;
+  static const int CX_SC_Extern = 2;
+  static const int CX_SC_Static = 3;
+  static const int CX_SC_PrivateExtern = 4;
+  static const int CX_SC_OpenCLWorkGroupLocal = 5;
+  static const int CX_SC_Auto = 6;
+  static const int CX_SC_Register = 7;
+}
+
+/// Describes how the traversal of the children of a particular
+/// cursor should proceed after visiting a particular child cursor.
+///
+/// A value of this enumeration type should be returned by each
+/// \c CXCursorVisitor to indicate how clang_visitChildren() proceed.
+abstract class CXChildVisitResult {
+  /// Terminates the cursor traversal.
+  static const int CXChildVisit_Break = 0;
+
+  /// Continues the cursor traversal with the next sibling of
+  /// the cursor just visited, without visiting its children.
+  static const int CXChildVisit_Continue = 1;
+
+  /// Recursively traverse the children of this cursor, using
+  /// the same visitor and client data.
+  static const int CXChildVisit_Recurse = 2;
+}
+
+/// Visitor invoked for each cursor found by a traversal.
+///
+/// This visitor function will be invoked for each cursor found by
+/// clang_visitCursorChildren(). Its first argument is the cursor being
+/// visited, its second argument is the parent visitor for that cursor,
+/// and its third argument is the client data provided to
+/// clang_visitCursorChildren().
+///
+/// The visitor should return one of the \c CXChildVisitResult values
+/// to direct clang_visitCursorChildren().
+typedef CXCursorVisitor
+    = ffi.Pointer<ffi.NativeFunction<CXCursorVisitor_function>>;
+typedef CXCursorVisitor_function = ffi.Int32 Function(
+    CXCursor cursor, CXCursor parent, CXClientData client_data);
+
+/// Opaque pointer representing client data that will be passed through
+/// to various callbacks and visitors.
+typedef CXClientData = ffi.Pointer<ffi.Void>;
+
+/// Property attributes for a \c CXCursor_ObjCPropertyDecl.
+abstract class CXObjCPropertyAttrKind {
+  static const int CXObjCPropertyAttr_noattr = 0;
+  static const int CXObjCPropertyAttr_readonly = 1;
+  static const int CXObjCPropertyAttr_getter = 2;
+  static const int CXObjCPropertyAttr_assign = 4;
+  static const int CXObjCPropertyAttr_readwrite = 8;
+  static const int CXObjCPropertyAttr_retain = 16;
+  static const int CXObjCPropertyAttr_copy = 32;
+  static const int CXObjCPropertyAttr_nonatomic = 64;
+  static const int CXObjCPropertyAttr_setter = 128;
+  static const int CXObjCPropertyAttr_atomic = 256;
+  static const int CXObjCPropertyAttr_weak = 512;
+  static const int CXObjCPropertyAttr_strong = 1024;
+  static const int CXObjCPropertyAttr_unsafe_unretained = 2048;
+  static const int CXObjCPropertyAttr_class = 4096;
+}
+
+abstract class CXEvalResultKind {
+  static const int CXEval_Int = 1;
+  static const int CXEval_Float = 2;
+  static const int CXEval_ObjCStrLiteral = 3;
+  static const int CXEval_StrLiteral = 4;
+  static const int CXEval_CFStr = 5;
+  static const int CXEval_Other = 6;
+  static const int CXEval_UnExposed = 0;
+}
+
+/// Evaluation result of a cursor
+typedef CXEvalResult = ffi.Pointer<ffi.Void>;
+
+const int CINDEX_VERSION_MAJOR = 0;
+
+const int CINDEX_VERSION_MINOR = 59;
+
+const int CINDEX_VERSION = 59;
+
+const String CINDEX_VERSION_STRING = '0.59';
diff --git a/pkgs/ffigen/lib/src/header_parser/data.dart b/pkgs/ffigen/lib/src/header_parser/data.dart
new file mode 100644
index 0000000..5bd4e90
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/data.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+
+import 'package:ffigen/src/code_generator.dart'
+    show Constant, ObjCBuiltInFunctions;
+import 'package:ffigen/src/config_provider.dart' show Config;
+import 'clang_bindings/clang_bindings.dart' show Clang;
+
+import 'utils.dart';
+
+/// Holds all Global shared variables.
+
+/// Holds configurations.
+Config get config => _config;
+late Config _config;
+
+/// Holds clang functions.
+Clang get clang => _clang;
+late Clang _clang;
+
+// Cursor index.
+CursorIndex get cursorIndex => _cursorIndex;
+CursorIndex _cursorIndex = CursorIndex();
+
+// Tracks seen status for bindings
+BindingsIndex get bindingsIndex => _bindingsIndex;
+BindingsIndex _bindingsIndex = BindingsIndex();
+
+/// Used for naming typedefs.
+IncrementalNamer get incrementalNamer => _incrementalNamer;
+IncrementalNamer _incrementalNamer = IncrementalNamer();
+
+/// Saved macros, Key: prefixedName, Value originalName.
+Map<String, Macro> get savedMacros => _savedMacros;
+Map<String, Macro> _savedMacros = {};
+
+/// Saved unnamed EnumConstants.
+List<Constant> get unnamedEnumConstants => _unnamedEnumConstants;
+List<Constant> _unnamedEnumConstants = [];
+
+/// Built in functions used by the Objective C bindings.
+ObjCBuiltInFunctions get objCBuiltInFunctions => _objCBuiltInFunctions;
+late ObjCBuiltInFunctions _objCBuiltInFunctions;
+
+void initializeGlobals({required Config config}) {
+  _config = config;
+  _clang = Clang(DynamicLibrary.open(config.libclangDylib));
+  _incrementalNamer = IncrementalNamer();
+  _savedMacros = {};
+  _unnamedEnumConstants = [];
+  _cursorIndex = CursorIndex();
+  _bindingsIndex = BindingsIndex();
+  _objCBuiltInFunctions = ObjCBuiltInFunctions();
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/includer.dart b/pkgs/ffigen/lib/src/header_parser/includer.dart
new file mode 100644
index 0000000..5e55aa2
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/includer.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Utility functions to check whether a binding should be parsed or not
+/// based on filters.
+
+import '../config_provider/config_types.dart';
+import '../strings.dart' as strings;
+import 'data.dart';
+
+bool _shouldIncludeDecl(
+    String usr,
+    String name,
+    bool Function(String) isSeenDecl,
+    bool Function(String, bool) configIncludes) {
+  if (isSeenDecl(usr) || name == '') {
+    return false;
+  } else if (config.usrTypeMappings.containsKey(usr)) {
+    return false;
+  } else if (configIncludes(name, config.excludeAllByDefault)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool shouldIncludeStruct(String usr, String name) {
+  return _shouldIncludeDecl(
+      usr, name, bindingsIndex.isSeenType, config.structDecl.shouldInclude);
+}
+
+bool shouldIncludeUnion(String usr, String name) {
+  return _shouldIncludeDecl(
+      usr, name, bindingsIndex.isSeenType, config.unionDecl.shouldInclude);
+}
+
+bool shouldIncludeFunc(String usr, String name) {
+  return _shouldIncludeDecl(
+      usr, name, bindingsIndex.isSeenFunc, config.functionDecl.shouldInclude);
+}
+
+bool shouldIncludeEnumClass(String usr, String name) {
+  return _shouldIncludeDecl(
+      usr, name, bindingsIndex.isSeenType, config.enumClassDecl.shouldInclude);
+}
+
+bool shouldIncludeUnnamedEnumConstant(String usr, String name) {
+  return _shouldIncludeDecl(usr, name, bindingsIndex.isSeenUnnamedEnumConstant,
+      config.unnamedEnumConstants.shouldInclude);
+}
+
+bool shouldIncludeGlobalVar(String usr, String name) {
+  return _shouldIncludeDecl(
+      usr, name, bindingsIndex.isSeenGlobalVar, config.globals.shouldInclude);
+}
+
+bool shouldIncludeMacro(String usr, String name) {
+  return _shouldIncludeDecl(
+      usr, name, bindingsIndex.isSeenMacro, config.macroDecl.shouldInclude);
+}
+
+bool shouldIncludeTypealias(String usr, String name) {
+  // Objective C has some core typedefs that are important to keep.
+  if (config.language == Language.objc && name == strings.objcInstanceType) {
+    return true;
+  }
+  return _shouldIncludeDecl(
+      usr, name, bindingsIndex.isSeenType, config.typedefs.shouldInclude);
+}
+
+bool shouldIncludeObjCInterface(String usr, String name) {
+  return _shouldIncludeDecl(
+      usr, name, bindingsIndex.isSeenType, config.objcInterfaces.shouldInclude);
+}
+
+/// True if a cursor should be included based on headers config, used on root
+/// declarations.
+bool shouldIncludeRootCursor(String sourceFile) {
+  // Handle empty string in case of system headers or macros.
+  if (sourceFile.isEmpty) {
+    return false;
+  }
+
+  // Add header to seen if it's not.
+  if (!bindingsIndex.isSeenHeader(sourceFile)) {
+    bindingsIndex.addHeaderToSeen(
+        sourceFile, config.headers.includeFilter.shouldInclude(sourceFile));
+  }
+
+  return bindingsIndex.getSeenHeaderStatus(sourceFile)!;
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/parser.dart b/pkgs/ffigen/lib/src/header_parser/parser.dart
new file mode 100644
index 0000000..5be826f
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/parser.dart
@@ -0,0 +1,155 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:ffi/ffi.dart';
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/config_provider.dart';
+import 'package:ffigen/src/config_provider/config_types.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/macro_parser.dart';
+import 'package:ffigen/src/header_parser/translation_unit_parser.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+
+import 'clang_bindings/clang_bindings.dart' as clang_types;
+import 'data.dart';
+import 'utils.dart';
+
+/// Main entrypoint for header_parser.
+Library parse(Config c) {
+  initParser(c);
+
+  final bindings = parseToBindings();
+
+  final library = Library(
+    bindings: bindings,
+    name: config.wrapperName,
+    description: config.wrapperDocComment,
+    header: config.preamble,
+    sort: config.sort,
+    packingOverride: config.structPackingOverride,
+    libraryImports: c.libraryImports.values.toSet(),
+  );
+
+  return library;
+}
+
+// ===================================================================================
+//           BELOW FUNCTIONS ARE MEANT FOR INTERNAL USE AND TESTING
+// ===================================================================================
+
+final _logger = Logger('ffigen.header_parser.parser');
+
+/// Initializes parser, clears any previous values.
+void initParser(Config c) {
+  // Initialize global variables.
+  initializeGlobals(
+    config: c,
+  );
+}
+
+/// Parses source files and adds generated bindings to [bindings].
+List<Binding> parseToBindings() {
+  final index = clang.clang_createIndex(0, 0);
+
+  Pointer<Pointer<Utf8>> clangCmdArgs = nullptr;
+  final compilerOpts = <String>[
+    // Add compiler opt for comment parsing for clang based on config.
+    if (config.commentType.length != CommentLength.none &&
+        config.commentType.style == CommentStyle.any)
+      strings.fparseAllComments,
+
+    // If the config targets Objective C, add a compiler opt for it.
+    if (config.language == Language.objc) ...[
+      ...strings.clangLangObjC,
+      ..._findObjectiveCSysroot(),
+    ],
+
+    // Add the user options last so they can override any other options.
+    ...config.compilerOpts
+  ];
+
+  _logger.fine('CompilerOpts used: $compilerOpts');
+  clangCmdArgs = createDynamicStringArray(compilerOpts);
+  final cmdLen = compilerOpts.length;
+
+  // Contains all bindings. A set ensures we never have duplicates.
+  final bindings = <Binding>{};
+
+  // Log all headers for user.
+  _logger.info('Input Headers: ${config.headers.entryPoints}');
+
+  final tuList = <Pointer<clang_types.CXTranslationUnitImpl>>[];
+
+  // Parse all translation units from entry points.
+  for (final headerLocation in config.headers.entryPoints) {
+    _logger.fine('Creating TranslationUnit for header: $headerLocation');
+
+    final tu = clang.clang_parseTranslationUnit(
+      index,
+      headerLocation.toNativeUtf8().cast(),
+      clangCmdArgs.cast(),
+      cmdLen,
+      nullptr,
+      0,
+      clang_types.CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies |
+          clang_types.CXTranslationUnit_Flags
+              .CXTranslationUnit_DetailedPreprocessingRecord |
+          clang_types
+              .CXTranslationUnit_Flags.CXTranslationUnit_IncludeAttributedTypes,
+    );
+
+    if (tu == nullptr) {
+      _logger.severe(
+          "Skipped header/file: $headerLocation, couldn't parse source.");
+      // Skip parsing this header.
+      continue;
+    }
+
+    logTuDiagnostics(tu, _logger, headerLocation);
+    tuList.add(tu);
+  }
+
+  final tuCursors =
+      tuList.map((tu) => clang.clang_getTranslationUnitCursor(tu));
+
+  // Build usr to CXCusror map from translation units.
+  for (final rootCursor in tuCursors) {
+    buildUsrCursorDefinitionMap(rootCursor);
+  }
+
+  // Parse definitions from translation units.
+  for (final rootCursor in tuCursors) {
+    bindings.addAll(parseTranslationUnit(rootCursor));
+  }
+
+  // Dispose translation units.
+  for (final tu in tuList) {
+    clang.clang_disposeTranslationUnit(tu);
+  }
+
+  // Add all saved unnamed enums.
+  bindings.addAll(unnamedEnumConstants);
+
+  // Parse all saved macros.
+  bindings.addAll(parseSavedMacros()!);
+
+  clangCmdArgs.dispose(cmdLen);
+  clang.clang_disposeIndex(index);
+  return bindings.toList();
+}
+
+List<String> _findObjectiveCSysroot() {
+  final result = Process.runSync('xcrun', ['--show-sdk-path']);
+  if (result.exitCode == 0) {
+    for (final line in (result.stdout as String).split('\n')) {
+      if (line.isNotEmpty) {
+        return ['-isysroot', line];
+      }
+    }
+  }
+  return [];
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/compounddecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/compounddecl_parser.dart
new file mode 100644
index 0000000..8b162a3
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/compounddecl_parser.dart
@@ -0,0 +1,340 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/config_provider/config_types.dart';
+import 'package:logging/logging.dart';
+
+import '../../strings.dart' as strings;
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../data.dart';
+import '../includer.dart';
+import '../utils.dart';
+
+final _logger = Logger('ffigen.header_parser.compounddecl_parser');
+
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _compoundMembersVisitorPtr;
+
+/// Holds temporary information regarding [compound] while parsing.
+class _ParsedCompound {
+  Compound compound;
+  bool unimplementedMemberType = false;
+  bool flexibleArrayMember = false;
+  bool bitFieldMember = false;
+  bool dartHandleMember = false;
+  bool incompleteCompoundMember = false;
+
+  _ParsedCompound(this.compound);
+
+  bool get isIncomplete =>
+      unimplementedMemberType ||
+      flexibleArrayMember ||
+      bitFieldMember ||
+      (dartHandleMember && config.useDartHandle) ||
+      incompleteCompoundMember ||
+      alignment == clang_types.CXTypeLayoutError.CXTypeLayoutError_Incomplete;
+
+  // A struct without any attribute is definitely not packed. #pragma pack(...)
+  // also adds an attribute, but it's unexposed and cannot be travesed.
+  bool hasAttr = false;
+
+  // A struct which as a __packed__ attribute is definitely packed.
+  bool hasPackedAttr = false;
+
+  // Stores the maximum alignment from all the children.
+  int maxChildAlignment = 0;
+
+  // Alignment of this struct.
+  int alignment = 0;
+
+  bool get _isPacked {
+    if (!hasAttr || isIncomplete) return false;
+    if (hasPackedAttr) return true;
+
+    return maxChildAlignment > alignment;
+  }
+
+  /// Returns pack value of a struct depending on config, returns null for no
+  /// packing.
+  int? get packValue {
+    if (compound.isStruct && _isPacked && !isIncomplete) {
+      if (strings.packingValuesMap.containsKey(alignment)) {
+        return alignment;
+      } else {
+        _logger.warning(
+            'Unsupported pack value "$alignment" for Struct "${compound.name}".');
+        return null;
+      }
+    } else {
+      return null;
+    }
+  }
+}
+
+final _stack = Stack<_ParsedCompound>();
+
+/// Parses a compound declaration.
+Compound? parseCompoundDeclaration(
+  clang_types.CXCursor cursor,
+  CompoundType compoundType, {
+  /// Option to ignore declaration filter (Useful in case of extracting
+  /// declarations when they are passed/returned by an included function.)
+  bool ignoreFilter = false,
+
+  /// To track if the declaration was used by reference(i.e T*). (Used to only
+  /// generate these as opaque if `dependency-only` was set to opaque).
+  bool pointerReference = false,
+}) {
+  // Set includer functions according to compoundType.
+  final bool Function(String, String) shouldIncludeDecl;
+  final Declaration configDecl;
+  final String className = _compoundTypeDebugName(compoundType);
+  switch (compoundType) {
+    case CompoundType.struct:
+      shouldIncludeDecl = shouldIncludeStruct;
+      configDecl = config.structDecl;
+      break;
+    case CompoundType.union:
+      shouldIncludeDecl = shouldIncludeUnion;
+      configDecl = config.unionDecl;
+      break;
+  }
+
+  // Parse the cursor definition instead, if this is a forward declaration.
+  cursor = cursorIndex.getDefinition(cursor);
+  final declUsr = cursor.usr();
+  final String declName;
+
+  // Only set name using USR if the type is not Anonymous (A struct is anonymous
+  // if it has no name, is not inside any typedef and declared inline inside
+  // another declaration).
+  if (clang.clang_Cursor_isAnonymous(cursor) == 0) {
+    // This gives the significant name, i.e name of the struct if defined or
+    // name of the first typedef declaration that refers to it.
+    declName = declUsr.split('@').last;
+  } else {
+    // Empty names are treated as inline declarations.
+    declName = '';
+  }
+
+  if (declName.isEmpty) {
+    if (ignoreFilter) {
+      // This declaration is defined inside some other declaration and hence
+      // must be generated.
+      return Compound.fromType(
+        type: compoundType,
+        name: incrementalNamer.name('Unnamed$className'),
+        usr: declUsr,
+        dartDoc: getCursorDocComment(cursor),
+      );
+    } else {
+      _logger.finest('unnamed $className declaration');
+    }
+  } else if (ignoreFilter || shouldIncludeDecl(declUsr, declName)) {
+    _logger.fine(
+        '++++ Adding $className: Name: $declName, ${cursor.completeStringRepr()}');
+    return Compound.fromType(
+      type: compoundType,
+      usr: declUsr,
+      originalName: declName,
+      name: configDecl.renameUsingConfig(declName),
+      dartDoc: getCursorDocComment(cursor),
+    );
+  }
+  return null;
+}
+
+void fillCompoundMembersIfNeeded(
+  Compound compound,
+  clang_types.CXCursor cursor, {
+  /// Option to ignore declaration filter (Useful in case of extracting
+  /// declarations when they are passed/returned by an included function.)
+  bool ignoreFilter = false,
+
+  /// To track if the declaration was used by reference(i.e T*). (Used to only
+  /// generate these as opaque if `dependency-only` was set to opaque).
+  bool pointerReference = false,
+}) {
+  cursor = cursorIndex.getDefinition(cursor);
+  final compoundType = compound.compoundType;
+
+  // Skip dependencies if already seen OR user has specified `dependency-only`
+  // as opaque AND this is a pointer reference AND the declaration was not
+  // included according to config (ignoreFilter).
+  final skipDependencies = compound.parsedDependencies ||
+      (pointerReference &&
+          ignoreFilter &&
+          ((compoundType == CompoundType.struct &&
+                  config.structDependencies == CompoundDependencies.opaque) ||
+              (compoundType == CompoundType.union &&
+                  config.unionDependencies == CompoundDependencies.opaque)));
+  if (skipDependencies) return;
+
+  final parsed = _ParsedCompound(compound);
+  final String className = _compoundTypeDebugName(compoundType);
+  parsed.hasAttr = clang.clang_Cursor_hasAttrs(cursor) != 0;
+  parsed.alignment = cursor.type().alignment();
+  compound.parsedDependencies = true; // Break cycles.
+
+  _stack.push(parsed);
+  final resultCode = clang.clang_visitChildren(
+    cursor,
+    _compoundMembersVisitorPtr ??= Pointer.fromFunction(
+        _compoundMembersVisitor, exceptional_visitor_return),
+    nullptr,
+  );
+  _stack.pop();
+
+  _logger.finest(
+      'Opaque: ${parsed.isIncomplete}, HasAttr: ${parsed.hasAttr}, AlignValue: ${parsed.alignment}, MaxChildAlignValue: ${parsed.maxChildAlignment}, PackValue: ${parsed.packValue}.');
+  compound.pack = parsed.packValue;
+
+  visitChildrenResultChecker(resultCode);
+
+  if (parsed.unimplementedMemberType) {
+    _logger.fine(
+        '---- Removed $className members, reason: member with unimplementedtype ${cursor.completeStringRepr()}');
+    _logger.warning(
+        'Removed All $className Members from ${compound.name}(${compound.originalName}), struct member has an unsupported type.');
+  } else if (parsed.flexibleArrayMember) {
+    _logger.fine(
+        '---- Removed $className members, reason: incomplete array member ${cursor.completeStringRepr()}');
+    _logger.warning(
+        'Removed All $className Members from ${compound.name}(${compound.originalName}), Flexible array members not supported.');
+  } else if (parsed.bitFieldMember) {
+    _logger.fine(
+        '---- Removed $className members, reason: bitfield members ${cursor.completeStringRepr()}');
+    _logger.warning(
+        'Removed All $className Members from ${compound.name}(${compound.originalName}), Bit Field members not supported.');
+  } else if (parsed.dartHandleMember && config.useDartHandle) {
+    _logger.fine(
+        '---- Removed $className members, reason: Dart_Handle member. ${cursor.completeStringRepr()}');
+    _logger.warning(
+        'Removed All $className Members from ${compound.name}(${compound.originalName}), Dart_Handle member not supported.');
+  } else if (parsed.incompleteCompoundMember) {
+    _logger.fine(
+        '---- Removed $className members, reason: Incomplete Nested Struct member. ${cursor.completeStringRepr()}');
+    _logger.warning(
+        'Removed All $className Members from ${compound.name}(${compound.originalName}), Incomplete Nested Struct member not supported.');
+  }
+
+  // Clear all members if declaration is incomplete.
+  if (parsed.isIncomplete) {
+    compound.members.clear();
+  }
+
+  // C allows empty structs/union, but it's undefined behaviour at runtine.
+  // So we need to mark a declaration incomplete if it has no members.
+  compound.isIncomplete = parsed.isIncomplete || compound.members.isEmpty;
+}
+
+/// Visitor for the struct/union cursor [CXCursorKind.CXCursor_StructDecl]/
+/// [CXCursorKind.CXCursor_UnionDecl].
+///
+/// Child visitor invoked on struct/union cursor.
+int _compoundMembersVisitor(clang_types.CXCursor cursor,
+    clang_types.CXCursor parent, Pointer<Void> clientData) {
+  final parsed = _stack.top;
+  try {
+    switch (cursor.kind) {
+      case clang_types.CXCursorKind.CXCursor_FieldDecl:
+        _logger.finer('===== member: ${cursor.completeStringRepr()}');
+
+        // Set maxChildAlignValue.
+        final align = cursor.type().alignment();
+        if (align > parsed.maxChildAlignment) {
+          parsed.maxChildAlignment = align;
+        }
+
+        final mt = cursor.toCodeGenType();
+        if (mt is IncompleteArray) {
+          // TODO(https://github.com/dart-lang/ffigen/issues/68): Structs with
+          // flexible Array Members are not supported.
+          parsed.flexibleArrayMember = true;
+        }
+        if (clang.clang_getFieldDeclBitWidth(cursor) != -1) {
+          // TODO(https://github.com/dart-lang/ffigen/issues/84): Struct with
+          // bitfields are not suppoorted.
+          parsed.bitFieldMember = true;
+        }
+        if (mt is HandleType) {
+          parsed.dartHandleMember = true;
+        }
+        if (mt.isIncompleteCompound) {
+          parsed.incompleteCompoundMember = true;
+        }
+        if (mt.baseType is UnimplementedType) {
+          parsed.unimplementedMemberType = true;
+        }
+        parsed.compound.members.add(
+          Member(
+            dartDoc: getCursorDocComment(
+              cursor,
+              nesting.length + commentPrefix.length,
+            ),
+            originalName: cursor.spelling(),
+            name: config.structDecl.renameMemberUsingConfig(
+              parsed.compound.originalName,
+              cursor.spelling(),
+            ),
+            type: mt,
+          ),
+        );
+
+        break;
+
+      case clang_types.CXCursorKind.CXCursor_PackedAttr:
+        parsed.hasPackedAttr = true;
+
+        break;
+      case clang_types.CXCursorKind.CXCursor_UnionDecl:
+      case clang_types.CXCursorKind.CXCursor_StructDecl:
+        // If the union/struct are anonymous, then we need to add them now,
+        // otherwise they will be added in the next iteration.
+        if (!cursor.isAnonymousRecordDecl()) break;
+
+        final mt = cursor.toCodeGenType();
+        if (mt.isIncompleteCompound) {
+          parsed.incompleteCompoundMember = true;
+        }
+
+        // Anonymous members are always unnamed. To avoid environment-
+        // dependent naming issues with the generated code, we explicitly
+        // use the empty string as spelling.
+        final spelling = '';
+
+        parsed.compound.members.add(
+          Member(
+            dartDoc: getCursorDocComment(
+              cursor,
+              nesting.length + commentPrefix.length,
+            ),
+            originalName: spelling,
+            name: config.structDecl.renameMemberUsingConfig(
+              parsed.compound.originalName,
+              spelling,
+            ),
+            type: mt,
+          ),
+        );
+
+        break;
+    }
+  } catch (e, s) {
+    _logger.severe(e);
+    _logger.severe(s);
+    rethrow;
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
+
+String _compoundTypeDebugName(CompoundType compoundType) {
+  return compoundType == CompoundType.struct ? "Struct" : "Union";
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/enumdecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/enumdecl_parser.dart
new file mode 100644
index 0000000..e66781c
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/enumdecl_parser.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/data.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart';
+import 'package:logging/logging.dart';
+
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../includer.dart';
+import '../utils.dart';
+
+final _logger = Logger('ffigen.header_parser.enumdecl_parser');
+
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _enumCursorVisitorPtr;
+
+/// Holds temporary information regarding [EnumClass] while parsing.
+class _ParsedEnum {
+  EnumClass? enumClass;
+  _ParsedEnum();
+}
+
+final _stack = Stack<_ParsedEnum>();
+
+/// Parses an enum declaration.
+EnumClass? parseEnumDeclaration(
+  clang_types.CXCursor cursor, {
+  /// Option to ignore declaration filter (Useful in case of extracting
+  /// declarations when they are passed/returned by an included function.)
+  bool ignoreFilter = false,
+}) {
+  _stack.push(_ParsedEnum());
+
+  // Parse the cursor definition instead, if this is a forward declaration.
+  cursor = cursorIndex.getDefinition(cursor);
+
+  final enumUsr = cursor.usr();
+  final String enumName;
+  // Only set name using USR if the type is not Anonymous (i.e not inside
+  // any typedef and declared inplace inside another type).
+  if (clang.clang_Cursor_isAnonymous(cursor) == 0) {
+    // This gives the significant name, i.e name of the enum if defined or
+    // name of the first typedef declaration that refers to it.
+    enumName = enumUsr.split('@').last;
+  } else {
+    enumName = '';
+  }
+
+  if (enumName.isEmpty) {
+    _logger.fine('Saving anonymous enum.');
+    saveUnNamedEnum(cursor);
+  } else if (ignoreFilter || shouldIncludeEnumClass(enumUsr, enumName)) {
+    _logger.fine('++++ Adding Enum: ${cursor.completeStringRepr()}');
+    _stack.top.enumClass = EnumClass(
+      usr: enumUsr,
+      dartDoc: getCursorDocComment(cursor),
+      originalName: enumName,
+      name: config.enumClassDecl.renameUsingConfig(enumName),
+    );
+    _addEnumConstant(cursor);
+  }
+
+  return _stack.pop().enumClass;
+}
+
+void _addEnumConstant(clang_types.CXCursor cursor) {
+  final resultCode = clang.clang_visitChildren(
+    cursor,
+    _enumCursorVisitorPtr ??=
+        Pointer.fromFunction(_enumCursorVisitor, exceptional_visitor_return),
+    nullptr,
+  );
+
+  visitChildrenResultChecker(resultCode);
+}
+
+/// Visitor for a enum cursor [clang.CXCursorKind.CXCursor_EnumDecl].
+///
+/// Invoked on every enum directly under rootCursor.
+/// Used for for extracting enum values.
+int _enumCursorVisitor(clang_types.CXCursor cursor, clang_types.CXCursor parent,
+    Pointer<Void> clientData) {
+  try {
+    _logger.finest('  enumCursorVisitor: ${cursor.completeStringRepr()}');
+    switch (clang.clang_getCursorKind(cursor)) {
+      case clang_types.CXCursorKind.CXCursor_EnumConstantDecl:
+        _addEnumConstantToEnumClass(cursor);
+        break;
+      case clang_types.CXCursorKind.CXCursor_UnexposedAttr:
+        // Ignore.
+        break;
+      default:
+        _logger.fine('invalid enum constant');
+    }
+  } catch (e, s) {
+    _logger.severe(e);
+    _logger.severe(s);
+    rethrow;
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
+
+/// Adds the parameter to func in [functiondecl_parser.dart].
+void _addEnumConstantToEnumClass(clang_types.CXCursor cursor) {
+  _stack.top.enumClass!.enumConstants.add(
+    EnumConstant(
+        dartDoc: getCursorDocComment(
+          cursor,
+          nesting.length + commentPrefix.length,
+        ),
+        originalName: cursor.spelling(),
+        name: config.enumClassDecl.renameMemberUsingConfig(
+          _stack.top.enumClass!.originalName,
+          cursor.spelling(),
+        ),
+        value: clang.clang_getEnumConstantDeclValue(cursor)),
+  );
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/function_type_param_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/function_type_param_parser.dart
new file mode 100644
index 0000000..739b3b1
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/function_type_param_parser.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+
+import '../clang_bindings/clang_bindings.dart';
+import '../data.dart';
+import '../utils.dart';
+
+/// This type holds the list of `ParmDecl` nodes of a function type declaration.
+class FunctionTypeParams {
+  final List<String> paramNames;
+  final Map<String, CXCursor> params;
+  FunctionTypeParams()
+      : paramNames = [],
+        params = {};
+}
+
+FunctionTypeParams? _params;
+
+int _functionPointerFieldVisitor(
+    CXCursor cursor, CXCursor parent, Pointer<Void> clientData) {
+  if (cursor.kind == CXCursorKind.CXCursor_ParmDecl) {
+    final spelling = cursor.spelling();
+    if (spelling.isNotEmpty) {
+      _params!.paramNames.add(spelling);
+      _params!.params[spelling] = cursor;
+      return CXChildVisitResult.CXChildVisit_Continue;
+    } else {
+      // A parameter's spelling is empty, do not continue further traversal.
+      _params!.paramNames.clear();
+      _params!.params.clear();
+      return CXChildVisitResult.CXChildVisit_Break;
+    }
+  }
+  // The cursor itself may be a pointer etc..
+  return CXChildVisitResult.CXChildVisit_Recurse;
+}
+
+/// Returns `ParmDecl` nodes of function pointer declaration
+/// directly or indirectly pointed to by [cursor].
+FunctionTypeParams parseFunctionPointerParamNames(CXCursor cursor) {
+  _params = FunctionTypeParams();
+  clang.clang_visitChildren(
+    cursor,
+    Pointer.fromFunction(
+        _functionPointerFieldVisitor, exceptional_visitor_return),
+    nullptr,
+  );
+  final result = _params;
+  _params = null;
+  return result!;
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/functiondecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/functiondecl_parser.dart
new file mode 100644
index 0000000..c2291b4
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/functiondecl_parser.dart
@@ -0,0 +1,176 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/config_provider/config_types.dart';
+import 'package:ffigen/src/header_parser/data.dart';
+import 'package:logging/logging.dart';
+
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../includer.dart';
+import '../utils.dart';
+
+final _logger = Logger('ffigen.header_parser.functiondecl_parser');
+
+/// Holds temporary information regarding [Func] while parsing.
+class _ParserFunc {
+  /// Multiple values are since there may be more than one instance of the
+  /// same base C function with different variadic arguments.
+  List<Func> funcs = [];
+  bool incompleteStructParameter = false;
+  bool unimplementedParameterType = false;
+  bool objCReturnsRetained = false;
+  _ParserFunc();
+}
+
+final _stack = Stack<_ParserFunc>();
+
+/// Parses a function declaration.
+List<Func>? parseFunctionDeclaration(clang_types.CXCursor cursor) {
+  _stack.push(_ParserFunc());
+
+  final funcUsr = cursor.usr();
+  final funcName = cursor.spelling();
+  if (shouldIncludeFunc(funcUsr, funcName)) {
+    _logger.fine('++++ Adding Function: ${cursor.completeStringRepr()}');
+
+    final rt = _getFunctionReturnType(cursor);
+    final parameters = _getParameters(cursor, funcName);
+    if (clang.clang_Cursor_isFunctionInlined(cursor) != 0 &&
+        clang.clang_Cursor_getStorageClass(cursor) !=
+            clang_types.CX_StorageClass.CX_SC_Extern) {
+      _logger.fine('---- Removed Function, reason: inline function: '
+          '${cursor.completeStringRepr()}');
+      _logger.warning(
+          "Skipped Function '$funcName', inline functions are not supported.");
+      // Returning empty so that [addToBindings] function excludes this.
+      return _stack.pop().funcs;
+    }
+
+    if (rt.isIncompleteCompound || _stack.top.incompleteStructParameter) {
+      _logger.fine(
+          '---- Removed Function, reason: Incomplete struct pass/return by '
+          'value: ${cursor.completeStringRepr()}');
+      _logger.warning(
+          "Skipped Function '$funcName', Incomplete struct pass/return by "
+          'value not supported.');
+      // Returning null so that [addToBindings] function excludes this.
+      return _stack.pop().funcs;
+    }
+
+    if (rt.baseType is UnimplementedType ||
+        _stack.top.unimplementedParameterType) {
+      _logger.fine('---- Removed Function, reason: unsupported return type or '
+          'parameter type: ${cursor.completeStringRepr()}');
+      _logger.warning(
+          "Skipped Function '$funcName', function has unsupported return type "
+          'or parameter type.');
+      // Returning null so that [addToBindings] function excludes this.
+      return _stack.pop().funcs;
+    }
+
+    // Look for any annotations on the function.
+    clang.clang_visitChildren(
+        cursor,
+        _parseAnnotationVisitorPtr ??= Pointer.fromFunction(
+            _parseAnnotationVisitor, exceptional_visitor_return),
+        nullptr);
+
+    // Initialized with a single value with no prefix and empty var args.
+    var varArgFunctions = [VarArgFunction('', [])];
+    if (config.varArgFunctions.containsKey(funcName)) {
+      if (clang.clang_isFunctionTypeVariadic(cursor.type()) == 1) {
+        varArgFunctions = config.varArgFunctions[funcName]!;
+      } else {
+        _logger.warning(
+            "Skipping variadic-argument config for function $funcName since its not variadic.");
+      }
+    }
+    for (final vaFunc in varArgFunctions) {
+      _stack.top.funcs.add(Func(
+        dartDoc: getCursorDocComment(
+          cursor,
+          nesting.length + commentPrefix.length,
+        ),
+        usr: funcUsr + vaFunc.postfix,
+        name: config.functionDecl.renameUsingConfig(funcName) + vaFunc.postfix,
+        originalName: funcName,
+        returnType: rt,
+        parameters: parameters,
+        varArgParameters:
+            vaFunc.types.map((ta) => Parameter(type: ta, name: 'va')).toList(),
+        exposeSymbolAddress:
+            config.functionDecl.shouldIncludeSymbolAddress(funcName),
+        exposeFunctionTypedefs:
+            config.exposeFunctionTypedefs.shouldInclude(funcName),
+        isLeaf: config.leafFunctions.shouldInclude(funcName),
+        objCReturnsRetained: _stack.top.objCReturnsRetained,
+        ffiNativeConfig: config.ffiNativeConfig,
+      ));
+    }
+    bindingsIndex.addFuncToSeen(funcUsr, _stack.top.funcs.last);
+  } else if (bindingsIndex.isSeenFunc(funcUsr)) {
+    _stack.top.funcs.add(bindingsIndex.getSeenFunc(funcUsr)!);
+  }
+
+  return _stack.pop().funcs;
+}
+
+Type _getFunctionReturnType(clang_types.CXCursor cursor) {
+  return cursor.returnType().toCodeGenType();
+}
+
+List<Parameter> _getParameters(clang_types.CXCursor cursor, String funcName) {
+  final parameters = <Parameter>[];
+
+  final totalArgs = clang.clang_Cursor_getNumArguments(cursor);
+  for (var i = 0; i < totalArgs; i++) {
+    final paramCursor = clang.clang_Cursor_getArgument(cursor, i);
+
+    _logger.finer('===== parameter: ${paramCursor.completeStringRepr()}');
+
+    final pt = _getParameterType(paramCursor);
+    if (pt.isIncompleteCompound) {
+      _stack.top.incompleteStructParameter = true;
+    } else if (pt.baseType is UnimplementedType) {
+      _logger.finer('Unimplemented type: ${pt.baseType}');
+      _stack.top.unimplementedParameterType = true;
+    }
+
+    final pn = paramCursor.spelling();
+
+    /// If [pn] is null or empty, its set to `arg$i` by code_generator.
+    parameters.add(
+      Parameter(
+        originalName: pn,
+        name: config.functionDecl.renameMemberUsingConfig(funcName, pn),
+        type: pt,
+      ),
+    );
+  }
+
+  return parameters;
+}
+
+Type _getParameterType(clang_types.CXCursor cursor) {
+  return cursor.toCodeGenType();
+}
+
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _parseAnnotationVisitorPtr;
+int _parseAnnotationVisitor(clang_types.CXCursor cursor,
+    clang_types.CXCursor parent, Pointer<Void> clientData) {
+  switch (cursor.kind) {
+    case clang_types.CXCursorKind.CXCursor_NSReturnsRetained:
+      _stack.top.objCReturnsRetained = true;
+      break;
+    default:
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/macro_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/macro_parser.dart
new file mode 100644
index 0000000..535e46d
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/macro_parser.dart
@@ -0,0 +1,343 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:ffi/ffi.dart';
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/data.dart';
+import 'package:ffigen/src/header_parser/includer.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:path/path.dart' as p;
+
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../utils.dart';
+
+final _logger = Logger('ffigen.header_parser.macro_parser');
+
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _macroVariablevisitorPtr;
+
+/// Adds a macro definition to be parsed later.
+void saveMacroDefinition(clang_types.CXCursor cursor) {
+  final macroUsr = cursor.usr();
+  final originalMacroName = cursor.spelling();
+  if (clang.clang_Cursor_isMacroBuiltin(cursor) == 0 &&
+      clang.clang_Cursor_isMacroFunctionLike(cursor) == 0 &&
+      shouldIncludeMacro(macroUsr, originalMacroName)) {
+    // Parse macro only if it's not builtin or function-like.
+    _logger.fine(
+        "++++ Saved Macro '$originalMacroName' for later : ${cursor.completeStringRepr()}");
+    final prefixedName = config.macroDecl.renameUsingConfig(originalMacroName);
+    bindingsIndex.addMacroToSeen(macroUsr, prefixedName);
+    _saveMacro(prefixedName, macroUsr, originalMacroName);
+  }
+}
+
+/// Saves a macro to be parsed later.
+///
+/// Macros are parsed later in [parseSavedMacros()].
+void _saveMacro(String name, String usr, String originalName) {
+  savedMacros[name] = Macro(usr, originalName);
+}
+
+List<Constant>? _bindings;
+
+/// Macros cannot be parsed directly, so we create a new `.hpp` file in which
+/// they are assigned to a variable after which their value can be determined
+/// by evaluating the value of the variable.
+List<Constant>? parseSavedMacros() {
+  _bindings = [];
+
+  if (savedMacros.keys.isEmpty) {
+    return _bindings;
+  }
+
+  // Create a file for parsing macros;
+  final file = createFileForMacros();
+
+  final index = clang.clang_createIndex(0, 0);
+  Pointer<Pointer<Utf8>> clangCmdArgs = nullptr;
+  var cmdLen = 0;
+
+  final compilerOpts = config.compilerOpts;
+  clangCmdArgs = createDynamicStringArray(compilerOpts);
+
+  cmdLen = config.compilerOpts.length;
+  final tu = clang.clang_parseTranslationUnit(
+    index,
+    file.path.toNativeUtf8().cast(),
+    clangCmdArgs.cast(),
+    cmdLen,
+    nullptr,
+    0,
+    clang_types.CXTranslationUnit_Flags.CXTranslationUnit_KeepGoing,
+  );
+
+  if (tu == nullptr) {
+    _logger.severe('Unable to parse Macros.');
+  } else {
+    logTuDiagnostics(tu, _logger, file.path, logLevel: Level.FINEST);
+    final rootCursor = clang.clang_getTranslationUnitCursor(tu);
+
+    final resultCode = clang.clang_visitChildren(
+      rootCursor,
+      _macroVariablevisitorPtr ??= Pointer.fromFunction(
+          _macroVariablevisitor, exceptional_visitor_return),
+      nullptr,
+    );
+
+    visitChildrenResultChecker(resultCode);
+  }
+
+  clang.clang_disposeTranslationUnit(tu);
+  clang.clang_disposeIndex(index);
+  // Delete the temp file created for macros.
+  file.deleteSync();
+
+  return _bindings;
+}
+
+/// Child visitor invoked on translationUnitCursor for parsing macroVariables.
+int _macroVariablevisitor(clang_types.CXCursor cursor,
+    clang_types.CXCursor parent, Pointer<Void> clientData) {
+  Constant? constant;
+  try {
+    if (isFromGeneratedFile(cursor) &&
+        _macroVarNames.contains(cursor.spelling()) &&
+        cursor.kind == clang_types.CXCursorKind.CXCursor_VarDecl) {
+      final e = clang.clang_Cursor_Evaluate(cursor);
+      final k = clang.clang_EvalResult_getKind(e);
+      _logger.fine('macroVariablevisitor: ${cursor.completeStringRepr()}');
+
+      /// Get macro name, the variable name starts with '<macro-name>_'.
+      final macroName = MacroVariableString.decode(cursor.spelling());
+      switch (k) {
+        case clang_types.CXEvalResultKind.CXEval_Int:
+          constant = Constant(
+            usr: savedMacros[macroName]!.usr,
+            originalName: savedMacros[macroName]!.originalName,
+            name: macroName,
+            rawType: 'int',
+            rawValue: clang.clang_EvalResult_getAsLongLong(e).toString(),
+          );
+          break;
+        case clang_types.CXEvalResultKind.CXEval_Float:
+          constant = Constant(
+            usr: savedMacros[macroName]!.usr,
+            originalName: savedMacros[macroName]!.originalName,
+            name: macroName,
+            rawType: 'double',
+            rawValue:
+                _writeDoubleAsString(clang.clang_EvalResult_getAsDouble(e)),
+          );
+          break;
+        case clang_types.CXEvalResultKind.CXEval_StrLiteral:
+          final rawValue = _getWrittenRepresentation(
+            macroName,
+            clang.clang_EvalResult_getAsStr(e),
+          );
+          constant = Constant(
+            usr: savedMacros[macroName]!.usr,
+            originalName: savedMacros[macroName]!.originalName,
+            name: macroName,
+            rawType: 'String',
+            rawValue: "'$rawValue'",
+          );
+          break;
+      }
+      clang.clang_EvalResult_dispose(e);
+
+      if (constant != null) {
+        _bindings!.add(constant);
+      }
+    }
+  } catch (e, s) {
+    _logger.severe(e);
+    _logger.severe(s);
+    rethrow;
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
+
+/// Returns true if cursor is from generated file.
+bool isFromGeneratedFile(clang_types.CXCursor cursor) {
+  final s = cursor.sourceFileName();
+  return p.basename(s) == _generatedFileBaseName;
+}
+
+/// Base name of generated file.
+String? _generatedFileBaseName;
+
+/// Generated macro variable names.
+///
+/// Used to determine if macro should be included in bindings or not.
+late Set<String> _macroVarNames;
+
+/// Creates a temporary file for parsing macros in current directory.
+File createFileForMacros() {
+  final fileNameBase = p.join(strings.tmpDir, 'temp_for_macros');
+  final fileExt = 'hpp';
+
+  // Find a filename which doesn't already exist.
+  var file = File('$fileNameBase.$fileExt');
+  var i = 0;
+  while (file.existsSync()) {
+    i++;
+    file = File('${fileNameBase}_$i.$fileExt');
+  }
+
+  // Create file.
+  file.createSync();
+
+  // Save generated name.
+  _generatedFileBaseName = p.basename(file.path);
+
+  // Write file contents.
+  final sb = StringBuffer();
+  for (final h in config.headers.entryPoints) {
+    final fullHeaderPath = File(h).absolute.path;
+    sb.writeln('#include "$fullHeaderPath"');
+  }
+
+  _macroVarNames = {};
+  for (final prefixedMacroName in savedMacros.keys) {
+    // Write macro.
+    final macroVarName = MacroVariableString.encode(prefixedMacroName);
+    sb.writeln(
+        'auto $macroVarName = ${savedMacros[prefixedMacroName]!.originalName};');
+    // Add to _macroVarNames.
+    _macroVarNames.add(macroVarName);
+  }
+  final macroFileContent = sb.toString();
+  // Log this generated file for debugging purpose.
+  // We use the finest log because this file may be very big.
+  _logger.finest('=====FILE FOR MACROS====');
+  _logger.finest(macroFileContent);
+  _logger.finest('========================');
+
+  file.writeAsStringSync(macroFileContent);
+  return file;
+}
+
+/// Deals with encoding/decoding name of the variable generated for a Macro.
+class MacroVariableString {
+  static String encode(String s) {
+    return '_${s.length}_${s}_generated_macro_variable';
+  }
+
+  static String decode(String s) {
+    // Remove underscore.
+    s = s.substring(1);
+    final intReg = RegExp('[0-9]+');
+    final lengthEnd = intReg.matchAsPrefix(s)!.end;
+    final len = int.parse(s.substring(0, lengthEnd));
+
+    // Name starts after an unerscore.
+    final nameStart = lengthEnd + 1;
+    return s.substring(nameStart, nameStart + len);
+  }
+}
+
+/// Gets a written representation string of a C string.
+///
+/// E.g- For a string "Hello\nWorld", The new line character is converted to \n.
+/// Note: The string is considered to be Utf8, but is treated as Extended ASCII,
+/// if the conversion fails.
+String _getWrittenRepresentation(String macroName, Pointer<Char> strPtr) {
+  final sb = StringBuffer();
+  try {
+    // Consider string to be Utf8 encoded by default.
+    sb.clear();
+    // This throws a Format Exception if string isn't Utf8 so that we handle it
+    // in the catch block.
+    final result = strPtr.cast<Utf8>().toDartString();
+    for (final s in result.runes) {
+      sb.write(_getWritableChar(s));
+    }
+  } catch (e) {
+    // Handle string if it isn't Utf8. String is considered to be
+    // Extended ASCII in this case.
+    _logger.warning(
+        "Couldn't decode Macro string '$macroName' as Utf8, using ASCII instead.");
+    sb.clear();
+    final length = strPtr.cast<Utf8>().length;
+    final charList = Uint8List.view(
+        strPtr.cast<Uint8>().asTypedList(length).buffer, 0, length);
+
+    for (final char in charList) {
+      sb.write(_getWritableChar(char, utf8: false));
+    }
+  }
+
+  return sb.toString();
+}
+
+/// Creates a writable char from [char] code.
+///
+/// E.g- `\` is converted to `\\`.
+String _getWritableChar(int char, {bool utf8 = true}) {
+  /// Handle control characters.
+  if (char >= 0 && char < 32 || char == 127) {
+    /// Handle these - `\b \t \n \v \f \r` as special cases.
+    switch (char) {
+      case 8: // \b
+        return r'\b';
+      case 9: // \t
+        return r'\t';
+      case 10: // \n
+        return r'\n';
+      case 11: // \v
+        return r'\v';
+      case 12: // \f
+        return r'\f';
+      case 13: // \r
+        return r'\r';
+      default:
+        final h = char.toRadixString(16).toUpperCase().padLeft(2, '0');
+        return '\\x$h';
+    }
+  }
+
+  /// Handle characters - `$ ' \` these need to be escaped when writing to file.
+  switch (char) {
+    case 36: // $
+      return r'\$';
+    case 39: // '
+      return r"\'";
+    case 92: // \
+      return r'\\';
+  }
+
+  /// In case encoding is not Utf8, we know all characters will fall in [0..255]
+  /// Print range [128..255] as `\xHH`.
+  if (!utf8) {
+    final h = char.toRadixString(16).toUpperCase().padLeft(2, '0');
+    return '\\x$h';
+  }
+
+  /// In all other cases, simply convert to string.
+  return String.fromCharCode(char);
+}
+
+/// Converts a double to a string, handling cases like Infinity and NaN.
+String _writeDoubleAsString(double d) {
+  if (d.isFinite) {
+    return d.toString();
+  } else {
+    // The only Non-Finite numbers are Infinity, NegativeInfinity and NaN.
+    if (d.isInfinite) {
+      return d.isNegative
+          ? strings.doubleNegativeInfinity
+          : strings.doubleInfinity;
+    }
+    return strings.doubleNaN;
+  }
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objc_block_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objc_block_parser.dart
new file mode 100644
index 0000000..313de4e
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objc_block_parser.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/data.dart';
+import 'package:logging/logging.dart';
+
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../utils.dart';
+
+final _logger = Logger('ffigen.header_parser.objc_block_parser');
+
+ObjCBlock parseObjCBlock(clang_types.CXType cxtype) {
+  final blk = clang.clang_getPointeeType(cxtype);
+  final returnType = clang.clang_getResultType(blk).toCodeGenType();
+  final argTypes = <Type>[];
+  final int numArgs = clang.clang_getNumArgTypes(blk);
+  for (int i = 0; i < numArgs; ++i) {
+    argTypes.add(clang.clang_getArgType(blk, i).toCodeGenType());
+  }
+
+  // Create a fake USR code for the block. This code is used to dedupe blocks
+  // with the same signature.
+  var usr = 'objcBlock: ${returnType.cacheKey()}';
+  for (final type in argTypes) {
+    usr += ' ${type.cacheKey()}';
+  }
+
+  _logger.fine('++++ Adding ObjC block: '
+      '${cxtype.completeStringRepr()}, syntheticUsr: $usr');
+
+  return ObjCBlock(
+    usr: usr.toString(),
+    returnType: returnType,
+    argTypes: argTypes,
+    builtInFunctions: objCBuiltInFunctions,
+  );
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
new file mode 100644
index 0000000..4fa57c3
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
@@ -0,0 +1,336 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/data.dart';
+import 'package:logging/logging.dart';
+
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../includer.dart';
+import '../utils.dart';
+
+final _logger = Logger('ffigen.header_parser.objcinterfacedecl_parser');
+
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _parseInterfaceVisitorPtr;
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _isClassDeclarationVisitorPtr;
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _parseMethodVisitorPtr;
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _findCategoryInterfaceVisitorPtr;
+
+class _ParsedObjCInterface {
+  ObjCInterface interface;
+  _ParsedObjCInterface(this.interface);
+}
+
+class _ParsedObjCMethod {
+  ObjCMethod method;
+  bool hasError = false;
+  _ParsedObjCMethod(this.method);
+}
+
+final _interfaceStack = Stack<_ParsedObjCInterface>();
+final _methodStack = Stack<_ParsedObjCMethod>();
+
+Type? parseObjCInterfaceDeclaration(
+  clang_types.CXCursor cursor, {
+  /// Option to ignore declaration filter (Useful in case of extracting
+  /// declarations when they are passed/returned by an included function.)
+  bool ignoreFilter = false,
+}) {
+  final itfUsr = cursor.usr();
+  final itfName = cursor.spelling();
+  if (!ignoreFilter && !shouldIncludeObjCInterface(itfUsr, itfName)) {
+    return null;
+  }
+
+  final t = cursor.type();
+  final name = t.spelling();
+
+  _logger.fine('++++ Adding ObjC interface: '
+      'Name: $name, ${cursor.completeStringRepr()}');
+
+  return ObjCInterface(
+    usr: itfUsr,
+    originalName: name,
+    name: config.objcInterfaces.renameUsingConfig(name),
+    lookupName: config.objcModulePrefixer.applyPrefix(name),
+    dartDoc: getCursorDocComment(cursor),
+    builtInFunctions: objCBuiltInFunctions,
+  );
+}
+
+void fillObjCInterfaceMethodsIfNeeded(
+    ObjCInterface itf, clang_types.CXCursor cursor) {
+  if (_isClassDeclaration(cursor)) {
+    // @class declarations are ObjC's way of forward declaring classes. In that
+    // case there's nothing to fill yet.
+    return;
+  }
+
+  if (itf.filled) return;
+  itf.filled = true; // Break cycles.
+
+  _logger.fine('++++ Filling ObjC interface: '
+      'Name: ${itf.originalName}, ${cursor.completeStringRepr()}');
+
+  _interfaceStack.push(_ParsedObjCInterface(itf));
+  clang.clang_visitChildren(
+      cursor,
+      _parseInterfaceVisitorPtr ??= Pointer.fromFunction(
+          _parseInterfaceVisitor, exceptional_visitor_return),
+      nullptr);
+  _interfaceStack.pop();
+
+  _logger.fine('++++ Finished ObjC interface: '
+      'Name: ${itf.originalName}, ${cursor.completeStringRepr()}');
+}
+
+bool _isClassDeclarationResult = false;
+bool _isClassDeclaration(clang_types.CXCursor cursor) {
+  // It's a class declaration if it has no children other than ObjCClassRef.
+  _isClassDeclarationResult = true;
+  clang.clang_visitChildren(
+      cursor,
+      _isClassDeclarationVisitorPtr ??= Pointer.fromFunction(
+          _isClassDeclarationVisitor, exceptional_visitor_return),
+      nullptr);
+  return _isClassDeclarationResult;
+}
+
+int _isClassDeclarationVisitor(clang_types.CXCursor cursor,
+    clang_types.CXCursor parent, Pointer<Void> clientData) {
+  if (cursor.kind == clang_types.CXCursorKind.CXCursor_ObjCClassRef) {
+    return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+  }
+  _isClassDeclarationResult = false;
+  return clang_types.CXChildVisitResult.CXChildVisit_Break;
+}
+
+int _parseInterfaceVisitor(clang_types.CXCursor cursor,
+    clang_types.CXCursor parent, Pointer<Void> clientData) {
+  switch (cursor.kind) {
+    case clang_types.CXCursorKind.CXCursor_ObjCSuperClassRef:
+      _parseSuperType(cursor);
+      break;
+    case clang_types.CXCursorKind.CXCursor_ObjCPropertyDecl:
+      _parseProperty(cursor);
+      break;
+    case clang_types.CXCursorKind.CXCursor_ObjCInstanceMethodDecl:
+    case clang_types.CXCursorKind.CXCursor_ObjCClassMethodDecl:
+      _parseMethod(cursor);
+      break;
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
+
+void _parseSuperType(clang_types.CXCursor cursor) {
+  final superType = cursor.type().toCodeGenType();
+  _logger.fine('       > Super type: '
+      '$superType ${cursor.completeStringRepr()}');
+  final itf = _interfaceStack.top.interface;
+  if (superType is ObjCInterface) {
+    itf.superType = superType;
+  } else {
+    _logger.severe(
+        'Super type of $itf is $superType, which is not a valid interface.');
+  }
+}
+
+void _parseProperty(clang_types.CXCursor cursor) {
+  final itf = _interfaceStack.top.interface;
+  final fieldName = cursor.spelling();
+  final fieldType = cursor.type().toCodeGenType();
+
+  if (fieldType.isIncompleteCompound) {
+    _logger.warning('Property "$fieldName" in instance "${itf.originalName}" '
+        'has incomplete type: $fieldType.');
+    return;
+  }
+
+  final dartDoc = getCursorDocComment(cursor);
+
+  final propertyAttributes =
+      clang.clang_Cursor_getObjCPropertyAttributes(cursor, 0);
+  final isClass = propertyAttributes &
+          clang_types.CXObjCPropertyAttrKind.CXObjCPropertyAttr_class >
+      0;
+  final isReadOnly = propertyAttributes &
+          clang_types.CXObjCPropertyAttrKind.CXObjCPropertyAttr_readonly >
+      0;
+
+  final property = ObjCProperty(fieldName);
+
+  _logger.fine('       > Property: '
+      '$fieldType $fieldName ${cursor.completeStringRepr()}');
+
+  final getterName =
+      clang.clang_Cursor_getObjCPropertyGetterName(cursor).toStringAndDispose();
+  final getter = ObjCMethod(
+    originalName: getterName,
+    property: property,
+    dartDoc: dartDoc,
+    kind: ObjCMethodKind.propertyGetter,
+    isClass: isClass,
+    returnType: fieldType,
+  );
+  itf.addMethod(getter);
+
+  if (!isReadOnly) {
+    final setterName = clang
+        .clang_Cursor_getObjCPropertySetterName(cursor)
+        .toStringAndDispose();
+    final setter = ObjCMethod(
+        originalName: setterName,
+        property: property,
+        dartDoc: dartDoc,
+        kind: ObjCMethodKind.propertySetter,
+        isClass: isClass,
+        returnType: NativeType(SupportedNativeType.Void));
+    setter.params.add(ObjCMethodParam(fieldType, 'value'));
+    itf.addMethod(setter);
+  }
+}
+
+void _parseMethod(clang_types.CXCursor cursor) {
+  final methodName = cursor.spelling();
+  final isClassMethod =
+      cursor.kind == clang_types.CXCursorKind.CXCursor_ObjCClassMethodDecl;
+  final returnType = clang.clang_getCursorResultType(cursor).toCodeGenType();
+  if (returnType.isIncompleteCompound) {
+    _logger.warning('Method "$methodName" in instance '
+        '"${_interfaceStack.top.interface.originalName}" has incomplete '
+        'return type: $returnType.');
+    return;
+  }
+  final method = ObjCMethod(
+    originalName: methodName,
+    dartDoc: getCursorDocComment(cursor),
+    kind: ObjCMethodKind.method,
+    isClass: isClassMethod,
+    returnType: returnType,
+  );
+  final parsed = _ParsedObjCMethod(method);
+  _logger.fine('       > ${isClassMethod ? 'Class' : 'Instance'} method: '
+      '${method.originalName} ${cursor.completeStringRepr()}');
+  _methodStack.push(parsed);
+  clang.clang_visitChildren(
+      cursor,
+      _parseMethodVisitorPtr ??=
+          Pointer.fromFunction(_parseMethodVisitor, exceptional_visitor_return),
+      nullptr);
+  _methodStack.pop();
+  if (parsed.hasError) {
+    // Discard it.
+    return;
+  }
+  _interfaceStack.top.interface.addMethod(method);
+}
+
+int _parseMethodVisitor(clang_types.CXCursor cursor,
+    clang_types.CXCursor parent, Pointer<Void> clientData) {
+  switch (cursor.kind) {
+    case clang_types.CXCursorKind.CXCursor_ParmDecl:
+      _parseMethodParam(cursor);
+      break;
+    case clang_types.CXCursorKind.CXCursor_NSReturnsRetained:
+      _markMethodReturnsRetained(cursor);
+      break;
+    default:
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
+
+void _parseMethodParam(clang_types.CXCursor cursor) {
+  final parsed = _methodStack.top;
+  final name = cursor.spelling();
+  final type = cursor.type().toCodeGenType();
+  if (type.isIncompleteCompound) {
+    parsed.hasError = true;
+    _logger.warning('Method "${parsed.method.originalName}" in instance '
+        '"${_interfaceStack.top.interface.originalName}" has incomplete '
+        'parameter type: $type.');
+    return;
+  }
+  _logger.fine(
+      '           >> Parameter: $type $name ${cursor.completeStringRepr()}');
+  parsed.method.params.add(ObjCMethodParam(type, name));
+}
+
+void _markMethodReturnsRetained(clang_types.CXCursor cursor) {
+  _methodStack.top.method.returnsRetained = true;
+}
+
+BindingType? parseObjCCategoryDeclaration(clang_types.CXCursor cursor) {
+  // Categories add methods to an existing interface, so first we run a visitor
+  // to find the interface, then we fully parse that interface, then we run the
+  // _parseInterfaceVisitor over the category to add its methods etc. Reusing
+  // the interface visitor relies on the fact that the structure of the category
+  // AST looks exactly the same as the interface AST, and that the category's
+  // interface is a different kind of node to the interface's super type (so is
+  // ignored by _parseInterfaceVisitor).
+  final name = cursor.spelling();
+  _logger.fine('++++ Adding ObjC category: '
+      'Name: $name, ${cursor.completeStringRepr()}');
+
+  _findCategoryInterfaceVisitorResult = null;
+  clang.clang_visitChildren(
+      cursor,
+      _findCategoryInterfaceVisitorPtr ??= Pointer.fromFunction(
+          _findCategoryInterfaceVisitor, exceptional_visitor_return),
+      nullptr);
+  final itfCursor = _findCategoryInterfaceVisitorResult;
+  if (itfCursor == null) {
+    _logger.severe('Category $name has no interface.');
+    return null;
+  }
+
+  // TODO(https://github.com/dart-lang/ffigen/issues/347): Currently any
+  // interface with a category bypasses the filters.
+  final itf = itfCursor.type().toCodeGenType();
+  if (itf is! ObjCInterface) {
+    _logger.severe(
+        'Interface of category $name is $itf, which is not a valid interface.');
+    return null;
+  }
+
+  _interfaceStack.push(_ParsedObjCInterface(itf));
+  clang.clang_visitChildren(
+      cursor,
+      _parseInterfaceVisitorPtr ??= Pointer.fromFunction(
+          _parseInterfaceVisitor, exceptional_visitor_return),
+      nullptr);
+  _interfaceStack.pop();
+
+  _logger.fine('++++ Finished ObjC category: '
+      'Name: $name, ${cursor.completeStringRepr()}');
+
+  return itf;
+}
+
+clang_types.CXCursor? _findCategoryInterfaceVisitorResult;
+int _findCategoryInterfaceVisitor(clang_types.CXCursor cursor,
+    clang_types.CXCursor parent, Pointer<Void> clientData) {
+  if (cursor.kind == clang_types.CXCursorKind.CXCursor_ObjCClassRef) {
+    _findCategoryInterfaceVisitorResult = cursor;
+    return clang_types.CXChildVisitResult.CXChildVisit_Break;
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart
new file mode 100644
index 0000000..85df348
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/includer.dart';
+import 'package:ffigen/src/header_parser/type_extractor/extractor.dart';
+import 'package:logging/logging.dart';
+
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../data.dart';
+import '../utils.dart';
+
+final _logger = Logger('ffigen.header_parser.typedefdecl_parser');
+
+/// Parses a typedef declaration.
+///
+/// Notes:
+/// - Pointer to Typedefs structs are skipped if the struct is seen.
+/// - If there are multiple typedefs for a declaration (struct/enum), the last
+/// seen name is used.
+/// - Typerefs are completely ignored.
+///
+/// Libclang marks them as following -
+/// ```C
+/// typedef struct A{
+///   int a
+/// } B, *pB; // Typedef(s).
+///
+/// typedef A D; // Typeref.
+/// ```
+///
+/// Returns `null` if the typedef could not be generated or has been excluded
+/// by the config.
+Typealias? parseTypedefDeclaration(
+  clang_types.CXCursor cursor, {
+  bool pointerReference = false,
+}) {
+  final typedefName = cursor.spelling();
+  final typedefUsr = cursor.usr();
+  if (shouldIncludeTypealias(typedefUsr, typedefName)) {
+    final ct = clang.clang_getTypedefDeclUnderlyingType(cursor);
+    final s = getCodeGenType(ct,
+        pointerReference: pointerReference, originalCursor: cursor);
+
+    if (bindingsIndex.isSeenUnsupportedTypealias(typedefUsr)) {
+      // Do not process unsupported typealiases again.
+    } else if (s is UnimplementedType) {
+      _logger.fine("Skipped Typedef '$typedefName': "
+          'Unimplemented type referred.');
+      bindingsIndex.addUnsupportedTypealiasToSeen(typedefUsr);
+    } else if (s is Compound && s.originalName == typedefName) {
+      // Ignore typedef if it refers to a compound with the same original name.
+      bindingsIndex.addUnsupportedTypealiasToSeen(typedefUsr);
+      _logger.fine("Skipped Typedef '$typedefName': "
+          'Name matches with referred struct/union.');
+    } else if (s is EnumClass) {
+      // Ignore typedefs to Enum.
+      bindingsIndex.addUnsupportedTypealiasToSeen(typedefUsr);
+      _logger.fine("Skipped Typedef '$typedefName': typedef to enum.");
+    } else if (s is HandleType) {
+      // Ignore typedefs to Handle.
+      _logger.fine("Skipped Typedef '$typedefName': typedef to Dart Handle.");
+      bindingsIndex.addUnsupportedTypealiasToSeen(typedefUsr);
+    } else if (s is ConstantArray || s is IncompleteArray) {
+      // Ignore typedefs to Constant Array.
+      _logger.fine("Skipped Typedef '$typedefName': typedef to array.");
+      bindingsIndex.addUnsupportedTypealiasToSeen(typedefUsr);
+    } else if (s is BooleanType) {
+      // Ignore typedefs to Boolean.
+      _logger.fine("Skipped Typedef '$typedefName': typedef to bool.");
+      bindingsIndex.addUnsupportedTypealiasToSeen(typedefUsr);
+    } else {
+      // Create typealias.
+      return Typealias(
+        usr: typedefUsr,
+        originalName: typedefName,
+        name: config.typedefs.renameUsingConfig(typedefName),
+        type: s,
+        dartDoc: getCursorDocComment(cursor),
+      );
+    }
+  }
+  return null;
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart
new file mode 100644
index 0000000..320e084
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/data.dart';
+import 'package:ffigen/src/header_parser/includer.dart';
+import 'package:logging/logging.dart';
+
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../utils.dart';
+
+final _logger = Logger('ffigen.header_parser.unnamed_enumdecl_parser');
+
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _unnamedenumCursorVisitorPtr;
+
+/// Saves unnamed enums.
+void saveUnNamedEnum(clang_types.CXCursor cursor) {
+  final resultCode = clang.clang_visitChildren(
+    cursor,
+    _unnamedenumCursorVisitorPtr ??= Pointer.fromFunction(
+        _unnamedenumCursorVisitor, exceptional_visitor_return),
+    nullptr,
+  );
+
+  visitChildrenResultChecker(resultCode);
+}
+
+/// Visitor for a enum cursor [clang.CXCursorKind.CXCursor_EnumDecl].
+///
+/// Invoked on every enum directly under rootCursor.
+/// Used for for extracting enum values.
+int _unnamedenumCursorVisitor(clang_types.CXCursor cursor,
+    clang_types.CXCursor parent, Pointer<Void> clientData) {
+  try {
+    _logger
+        .finest('  unnamedenumCursorVisitor: ${cursor.completeStringRepr()}');
+    switch (clang.clang_getCursorKind(cursor)) {
+      case clang_types.CXCursorKind.CXCursor_EnumConstantDecl:
+        if (shouldIncludeUnnamedEnumConstant(cursor.usr(), cursor.spelling())) {
+          _addUnNamedEnumConstant(cursor);
+        }
+        break;
+      case clang_types.CXCursorKind.CXCursor_UnexposedAttr:
+        // Ignore.
+        break;
+      default:
+        _logger.severe('Invalid enum constant.');
+    }
+  } catch (e, s) {
+    _logger.severe(e);
+    _logger.severe(s);
+    rethrow;
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
+
+/// Adds the parameter to func in [functiondecl_parser.dart].
+void _addUnNamedEnumConstant(clang_types.CXCursor cursor) {
+  _logger.fine(
+      '++++ Adding Constant from unnamed enum: ${cursor.completeStringRepr()}');
+  final constant = Constant(
+    usr: cursor.usr(),
+    originalName: cursor.spelling(),
+    name: config.unnamedEnumConstants.renameUsingConfig(
+      cursor.spelling(),
+    ),
+    rawType: 'int',
+    rawValue: clang.clang_getEnumConstantDeclValue(cursor).toString(),
+  );
+  bindingsIndex.addUnnamedEnumConstantToSeen(cursor.usr(), constant);
+  unnamedEnumConstants.add(constant);
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/var_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/var_parser.dart
new file mode 100644
index 0000000..90b3853
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/var_parser.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/data.dart';
+import 'package:ffigen/src/header_parser/includer.dart';
+import 'package:logging/logging.dart';
+
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../utils.dart';
+
+final _logger = Logger('ffigen.header_parser.var_parser');
+
+/// Parses a global variable
+Global? parseVarDeclaration(clang_types.CXCursor cursor) {
+  final name = cursor.spelling();
+  final usr = cursor.usr();
+  if (bindingsIndex.isSeenGlobalVar(usr)) {
+    return bindingsIndex.getSeenGlobalVar(usr);
+  }
+  if (!shouldIncludeGlobalVar(usr, name)) {
+    return null;
+  }
+
+  _logger.fine('++++ Adding Global: ${cursor.completeStringRepr()}');
+
+  final type = cursor.type().toCodeGenType();
+  if (type.baseType is UnimplementedType) {
+    _logger.fine('---- Removed Global, reason: unsupported type: '
+        '${cursor.completeStringRepr()}');
+    _logger.warning("Skipped global variable '$name', type not supported.");
+    return null;
+  }
+
+  if (config.ffiNativeConfig.enabled) {
+    _logger
+        .warning("Skipped global variable '$name', not supported in Natives.");
+    return null;
+  }
+
+  final global = Global(
+    originalName: name,
+    name: config.globals.renameUsingConfig(name),
+    usr: usr,
+    type: type,
+    dartDoc: getCursorDocComment(cursor),
+    exposeSymbolAddress: config.functionDecl.shouldIncludeSymbolAddress(name),
+  );
+  bindingsIndex.addGlobalVarToSeen(usr, global);
+  return global;
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart b/pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart
new file mode 100644
index 0000000..31f50b8
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/macro_parser.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/var_parser.dart';
+import 'package:logging/logging.dart';
+
+import 'clang_bindings/clang_bindings.dart' as clang_types;
+import 'data.dart';
+import 'includer.dart';
+import 'sub_parsers/functiondecl_parser.dart';
+import 'type_extractor/extractor.dart';
+import 'utils.dart';
+
+final _logger = Logger('ffigen.header_parser.translation_unit_parser');
+
+late Set<Binding> _bindings;
+
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _rootCursorVisitorPtr;
+
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _cursorDefinitionVisitorPtr;
+
+/// Parses the translation unit and returns the generated bindings.
+Set<Binding> parseTranslationUnit(clang_types.CXCursor translationUnitCursor) {
+  _bindings = {};
+  final resultCode = clang.clang_visitChildren(
+    translationUnitCursor,
+    _rootCursorVisitorPtr ??=
+        Pointer.fromFunction(_rootCursorVisitor, exceptional_visitor_return),
+    nullptr,
+  );
+
+  visitChildrenResultChecker(resultCode);
+
+  return _bindings;
+}
+
+/// Child visitor invoked on translationUnitCursor [CXCursorKind.CXCursor_TranslationUnit].
+int _rootCursorVisitor(clang_types.CXCursor cursor, clang_types.CXCursor parent,
+    Pointer<Void> clientData) {
+  try {
+    if (shouldIncludeRootCursor(cursor.sourceFileName())) {
+      _logger.finest('rootCursorVisitor: ${cursor.completeStringRepr()}');
+      switch (clang.clang_getCursorKind(cursor)) {
+        case clang_types.CXCursorKind.CXCursor_FunctionDecl:
+          addAllToBindings(parseFunctionDeclaration(cursor) as List<Binding>);
+          break;
+        case clang_types.CXCursorKind.CXCursor_StructDecl:
+        case clang_types.CXCursorKind.CXCursor_UnionDecl:
+        case clang_types.CXCursorKind.CXCursor_EnumDecl:
+        case clang_types.CXCursorKind.CXCursor_ObjCInterfaceDecl:
+          addToBindings(_getCodeGenTypeFromCursor(cursor));
+          break;
+        case clang_types.CXCursorKind.CXCursor_ObjCCategoryDecl:
+          addToBindings(parseObjCCategoryDeclaration(cursor));
+          break;
+        case clang_types.CXCursorKind.CXCursor_MacroDefinition:
+          saveMacroDefinition(cursor);
+          break;
+        case clang_types.CXCursorKind.CXCursor_VarDecl:
+          addToBindings(parseVarDeclaration(cursor));
+          break;
+        default:
+          _logger.finer('rootCursorVisitor: CursorKind not implemented');
+      }
+    } else {
+      _logger.finest(
+          'rootCursorVisitor:(not included) ${cursor.completeStringRepr()}');
+    }
+  } catch (e, s) {
+    _logger.severe(e);
+    _logger.severe(s);
+    rethrow;
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
+
+/// Adds to binding if unseen and not null.
+void addToBindings(Binding? b) {
+  if (b != null) {
+    // This is a set, and hence will not have duplicates.
+    _bindings.add(b);
+  }
+}
+
+/// Adds all binding if not empty.
+void addAllToBindings(List<Binding> b) {
+  if (b.isNotEmpty) {
+    // This is a set, and hence will not have duplicates.
+    _bindings.addAll(b);
+  }
+}
+
+BindingType? _getCodeGenTypeFromCursor(clang_types.CXCursor cursor) {
+  final t = getCodeGenType(cursor.type(), ignoreFilter: false);
+  return t is BindingType ? t : null;
+}
+
+/// Visits all cursors and builds a map of usr and [CXCursor].
+void buildUsrCursorDefinitionMap(clang_types.CXCursor translationUnitCursor) {
+  _bindings = {};
+  final resultCode = clang.clang_visitChildren(
+    translationUnitCursor,
+    _cursorDefinitionVisitorPtr ??= Pointer.fromFunction(
+        _definitionCursorVisitor, exceptional_visitor_return),
+    nullptr,
+  );
+
+  visitChildrenResultChecker(resultCode);
+}
+
+/// Child visitor invoked on translationUnitCursor [CXCursorKind.CXCursor_TranslationUnit].
+int _definitionCursorVisitor(clang_types.CXCursor cursor,
+    clang_types.CXCursor parent, Pointer<Void> clientData) {
+  try {
+    cursorIndex.saveDefinition(cursor);
+  } catch (e, s) {
+    _logger.severe(e);
+    _logger.severe(s);
+    rethrow;
+  }
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/type_extractor/cxtypekindmap.dart b/pkgs/ffigen/lib/src/header_parser/type_extractor/cxtypekindmap.dart
new file mode 100644
index 0000000..2d25d9f
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/type_extractor/cxtypekindmap.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart' show SupportedNativeType;
+import 'package:ffigen/src/code_generator/imports.dart';
+
+var cxTypeKindToImportedTypes = <String, ImportedType>{
+  'void': voidType,
+  'unsigned char': unsignedCharType,
+  'signed char': signedCharType,
+  'char': charType,
+  'unsigned short': unsignedShortType,
+  'short': shortType,
+  'unsigned int': unsignedIntType,
+  'int': intType,
+  'unsigned long': unsignedLongType,
+  'long': longType,
+  'unsigned long long': unsignedLongLongType,
+  'long long': longLongType,
+  'float': floatType,
+  'double': doubleType,
+};
+
+var suportedTypedefToSuportedNativeType = <String, SupportedNativeType>{
+  'uint8_t': SupportedNativeType.Uint8,
+  'uint16_t': SupportedNativeType.Uint16,
+  'uint32_t': SupportedNativeType.Uint32,
+  'uint64_t': SupportedNativeType.Uint64,
+  'int8_t': SupportedNativeType.Int8,
+  'int16_t': SupportedNativeType.Int16,
+  'int32_t': SupportedNativeType.Int32,
+  'int64_t': SupportedNativeType.Int64,
+  'intptr_t': SupportedNativeType.IntPtr,
+  'uintptr_t': SupportedNativeType.UintPtr,
+};
+
+var supportedTypedefToImportedType = <String, ImportedType>{
+  'size_t': sizeType,
+  'wchar_t': wCharType,
+};
diff --git a/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart b/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart
new file mode 100644
index 0000000..311c1e8
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart
@@ -0,0 +1,383 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Extracts code_gen Type from type.
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/function_type_param_parser.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/typedefdecl_parser.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+
+import '../../config_provider/config_types.dart';
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../data.dart';
+import '../sub_parsers/compounddecl_parser.dart';
+import '../sub_parsers/enumdecl_parser.dart';
+import '../sub_parsers/objc_block_parser.dart';
+import '../sub_parsers/objcinterfacedecl_parser.dart';
+import '../type_extractor/cxtypekindmap.dart';
+import '../utils.dart';
+
+final _logger = Logger('ffigen.header_parser.extractor');
+const _padding = '  ';
+
+const maxRecursionDepth = 5;
+
+/// Converts cxtype to a typestring code_generator can accept.
+Type getCodeGenType(
+  clang_types.CXType cxtype, {
+  /// Option to ignore declaration filter (Useful in case of extracting
+  /// declarations when they are passed/returned by an included function.)
+  bool ignoreFilter = true,
+
+  /// Passed on if a value was marked as a pointer before this one.
+  bool pointerReference = false,
+
+  /// Cursor of the declaration, currently this is useful only to extract
+  /// parameter names in function types.
+  clang_types.CXCursor? originalCursor,
+}) {
+  _logger.fine('${_padding}getCodeGenType ${cxtype.completeStringRepr()}');
+
+  // Special case: Elaborated types just refer to another type.
+  if (cxtype.kind == clang_types.CXTypeKind.CXType_Elaborated) {
+    return getCodeGenType(clang.clang_Type_getNamedType(cxtype),
+        ignoreFilter: ignoreFilter, pointerReference: pointerReference);
+  }
+
+  // These basic Objective C types skip the cache, and are conditional on the
+  // language flag.
+  if (config.language == Language.objc) {
+    switch (cxtype.kind) {
+      case clang_types.CXTypeKind.CXType_ObjCObjectPointer:
+        final pt = clang.clang_getPointeeType(cxtype);
+        final s = getCodeGenType(pt,
+            ignoreFilter: ignoreFilter, pointerReference: true);
+        if (s is ObjCInterface) {
+          return s;
+        }
+        return PointerType(objCObjectType);
+      case clang_types.CXTypeKind.CXType_ObjCId:
+      case clang_types.CXTypeKind.CXType_ObjCTypeParam:
+      case clang_types.CXTypeKind.CXType_ObjCClass:
+        return PointerType(objCObjectType);
+      case clang_types.CXTypeKind.CXType_ObjCSel:
+        return PointerType(objCSelType);
+      case clang_types.CXTypeKind.CXType_BlockPointer:
+        return _getOrCreateBlockType(cxtype);
+    }
+  }
+
+  // If the type has a declaration cursor, then use the BindingsIndex to break
+  // any potential cycles, and dedupe the Type.
+  final cursor = clang.clang_getTypeDeclaration(cxtype);
+  if (cursor.kind != clang_types.CXCursorKind.CXCursor_NoDeclFound) {
+    final usr = cursor.usr();
+    var type = bindingsIndex.getSeenType(usr);
+    if (type == null) {
+      final result =
+          _createTypeFromCursor(cxtype, cursor, ignoreFilter, pointerReference);
+      type = result.type;
+      if (type == null) {
+        return UnimplementedType('${cxtype.kindSpelling()} not implemented');
+      }
+      if (result.addToCache) {
+        bindingsIndex.addTypeToSeen(usr, type);
+      }
+    }
+    _fillFromCursorIfNeeded(type, cursor, ignoreFilter, pointerReference);
+    return type;
+  }
+
+  // If the type doesn't have a declaration cursor, then it's a basic type such
+  // as int, or a simple derived type like a pointer, so doesn't need to be
+  // cached.
+  switch (cxtype.kind) {
+    case clang_types.CXTypeKind.CXType_Pointer:
+      final pt = clang.clang_getPointeeType(cxtype);
+      final s = getCodeGenType(
+        pt,
+        pointerReference: true,
+        originalCursor: originalCursor,
+      );
+
+      // Replace Pointer<_Dart_Handle> with Handle.
+      if (config.useDartHandle &&
+          s is Compound &&
+          s.compoundType == CompoundType.struct &&
+          s.usr == strings.dartHandleUsr) {
+        return HandleType();
+      }
+      return PointerType(s);
+    case clang_types.CXTypeKind.CXType_FunctionProto:
+      // Primarily used for function pointers.
+      return _extractFromFunctionProto(cxtype, cursor: originalCursor);
+    case clang_types.CXTypeKind.CXType_FunctionNoProto:
+      // Primarily used for function types with zero arguments.
+      return _extractFromFunctionProto(cxtype, cursor: originalCursor);
+    case clang_types.CXTypeKind.CXType_ConstantArray:
+      // Primarily used for constant array in struct members.
+      final numElements = clang.clang_getNumElements(cxtype);
+      final elementType =
+          clang.clang_getArrayElementType(cxtype).toCodeGenType();
+      // Handle numElements being 0 as an incomplete array.
+      return numElements == 0
+          ? IncompleteArray(elementType)
+          : ConstantArray(numElements, elementType);
+    case clang_types.CXTypeKind.CXType_IncompleteArray:
+      // Primarily used for incomplete array in function parameters.
+      return IncompleteArray(
+        clang.clang_getArrayElementType(cxtype).toCodeGenType(),
+      );
+    case clang_types.CXTypeKind.CXType_Bool:
+      return BooleanType();
+    case clang_types.CXTypeKind.CXType_Attributed:
+    case clang_types.CXTypeKind.CXType_Unexposed:
+      final innerType = getCodeGenType(
+        clang.clang_Type_getModifiedType(cxtype),
+        ignoreFilter: ignoreFilter,
+        originalCursor: originalCursor,
+      );
+      final isNullable = clang.clang_Type_getNullability(cxtype) ==
+          clang_types.CXTypeNullabilityKind.CXTypeNullability_Nullable;
+      return isNullable && ObjCNullable.isSupported(innerType)
+          ? ObjCNullable(innerType)
+          : innerType;
+    default:
+      var typeSpellKey =
+          clang.clang_getTypeSpelling(cxtype).toStringAndDispose();
+      if (typeSpellKey.startsWith('const ')) {
+        typeSpellKey = typeSpellKey.replaceFirst('const ', '');
+      }
+      if (config.nativeTypeMappings.containsKey(typeSpellKey)) {
+        _logger.fine('  Type $typeSpellKey mapped from type-map.');
+        return config.nativeTypeMappings[typeSpellKey]!;
+      } else if (cxTypeKindToImportedTypes.containsKey(typeSpellKey)) {
+        return cxTypeKindToImportedTypes[typeSpellKey]!;
+      } else {
+        _logger.fine('typedeclarationCursorVisitor: getCodeGenType: Type Not '
+            'Implemented, ${cxtype.completeStringRepr()}');
+        return UnimplementedType('${cxtype.kindSpelling()} not implemented');
+      }
+  }
+}
+
+Type _getOrCreateBlockType(clang_types.CXType cxtype) {
+  final block = parseObjCBlock(cxtype);
+  final key = block.usr;
+  final oldBlock = bindingsIndex.getSeenObjCBlock(key);
+  if (oldBlock != null) {
+    return oldBlock;
+  }
+  bindingsIndex.addObjCBlockToSeen(key, block);
+  return block;
+}
+
+class _CreateTypeFromCursorResult {
+  final Type? type;
+
+  // Flag that controls whether the type is added to the cache. It should not
+  // be added to the cache if it's just a fallback implementation, such as the
+  // int that is returned when an enum is excluded by the config. Later we might
+  // need to build the full enum type (eg if it's part of an included struct),
+  // and if we put the fallback int in the cache then the full enum will never
+  // be created.
+  final bool addToCache;
+
+  _CreateTypeFromCursorResult(this.type, {this.addToCache = true});
+}
+
+_CreateTypeFromCursorResult _createTypeFromCursor(clang_types.CXType cxtype,
+    clang_types.CXCursor cursor, bool ignoreFilter, bool pointerReference) {
+  switch (cxtype.kind) {
+    case clang_types.CXTypeKind.CXType_Typedef:
+      final spelling = clang.clang_getTypedefName(cxtype).toStringAndDispose();
+      if (config.language == Language.objc && spelling == strings.objcBOOL) {
+        // Objective C's BOOL type can be either bool or signed char, depending
+        // on the platform. We want to present a consistent API to the user, and
+        // those two types are ABI compatible, so just return bool regardless.
+        return _CreateTypeFromCursorResult(BooleanType());
+      }
+      final usr = cursor.usr();
+      if (config.typedefTypeMappings.containsKey(spelling)) {
+        _logger.fine('  Type $spelling mapped from type-map');
+        return _CreateTypeFromCursorResult(
+            config.typedefTypeMappings[spelling]!);
+      }
+      if (config.usrTypeMappings.containsKey(usr)) {
+        _logger.fine('  Type $spelling mapped from usr');
+        return _CreateTypeFromCursorResult(config.usrTypeMappings[usr]!);
+      }
+      // Get name from supported typedef name if config allows.
+      if (config.useSupportedTypedefs) {
+        if (suportedTypedefToSuportedNativeType.containsKey(spelling)) {
+          _logger.fine('  Type Mapped from supported typedef');
+          return _CreateTypeFromCursorResult(
+              NativeType(suportedTypedefToSuportedNativeType[spelling]!));
+        } else if (supportedTypedefToImportedType.containsKey(spelling)) {
+          _logger.fine('  Type Mapped from supported typedef');
+          return _CreateTypeFromCursorResult(
+              supportedTypedefToImportedType[spelling]!);
+        }
+      }
+
+      final typealias =
+          parseTypedefDeclaration(cursor, pointerReference: pointerReference);
+
+      if (typealias != null) {
+        return _CreateTypeFromCursorResult(typealias);
+      } else {
+        // Use underlying type if typealias couldn't be created or if the user
+        // excluded this typedef.
+        final ct = clang.clang_getTypedefDeclUnderlyingType(cursor);
+        return _CreateTypeFromCursorResult(
+            getCodeGenType(ct, pointerReference: pointerReference),
+            addToCache: false);
+      }
+    case clang_types.CXTypeKind.CXType_Record:
+      return _CreateTypeFromCursorResult(
+          _extractfromRecord(cxtype, cursor, ignoreFilter, pointerReference));
+    case clang_types.CXTypeKind.CXType_Enum:
+      final enumClass = parseEnumDeclaration(
+        cursor,
+        ignoreFilter: ignoreFilter,
+      );
+      if (enumClass == null) {
+        // Handle anonymous enum declarations within another declaration.
+        return _CreateTypeFromCursorResult(EnumClass.nativeType,
+            addToCache: false);
+      } else {
+        return _CreateTypeFromCursorResult(enumClass);
+      }
+    case clang_types.CXTypeKind.CXType_ObjCInterface:
+      return _CreateTypeFromCursorResult(
+          parseObjCInterfaceDeclaration(cursor, ignoreFilter: ignoreFilter));
+    default:
+      return _CreateTypeFromCursorResult(
+          UnimplementedType('Unknown type: ${cxtype.completeStringRepr()}'),
+          addToCache: false);
+  }
+}
+
+void _fillFromCursorIfNeeded(Type? type, clang_types.CXCursor cursor,
+    bool ignoreFilter, bool pointerReference) {
+  if (type == null) return;
+  if (type is Compound) {
+    fillCompoundMembersIfNeeded(type, cursor,
+        ignoreFilter: ignoreFilter, pointerReference: pointerReference);
+  } else if (type is ObjCInterface) {
+    fillObjCInterfaceMethodsIfNeeded(type, cursor);
+  }
+}
+
+Type? _extractfromRecord(clang_types.CXType cxtype, clang_types.CXCursor cursor,
+    bool ignoreFilter, bool pointerReference) {
+  _logger.fine('${_padding}_extractfromRecord: ${cursor.completeStringRepr()}');
+
+  final cursorKind = clang.clang_getCursorKind(cursor);
+  if (cursorKind == clang_types.CXCursorKind.CXCursor_StructDecl ||
+      cursorKind == clang_types.CXCursorKind.CXCursor_UnionDecl) {
+    final declSpelling = cursor.spelling();
+    final declUsr = cursor.usr();
+
+    // Set includer functions according to compoundType.
+    final CompoundType compoundType;
+    final Map<String, ImportedType> compoundTypeMappings;
+
+    switch (cursorKind) {
+      case clang_types.CXCursorKind.CXCursor_StructDecl:
+        compoundType = CompoundType.struct;
+        compoundTypeMappings = config.structTypeMappings;
+        break;
+      case clang_types.CXCursorKind.CXCursor_UnionDecl:
+        compoundType = CompoundType.union;
+        compoundTypeMappings = config.unionTypeMappings;
+        break;
+      default:
+        throw Exception('Unhandled compound type cursorkind.');
+    }
+
+    // Also add a struct binding, if its unseen.
+    if (compoundTypeMappings.containsKey(declSpelling)) {
+      _logger.fine('  Type Mapped from type-map');
+      return compoundTypeMappings[declSpelling]!;
+    } else if (config.usrTypeMappings.containsKey(declUsr)) {
+      _logger.fine('  Type Mapped from usr');
+      return config.usrTypeMappings[declUsr]!;
+    } else {
+      final struct = parseCompoundDeclaration(
+        cursor,
+        compoundType,
+        ignoreFilter: ignoreFilter,
+        pointerReference: pointerReference,
+      );
+      return struct;
+    }
+  }
+  _logger.fine('typedeclarationCursorVisitor: _extractfromRecord: '
+      'Not Implemented, ${cursor.completeStringRepr()}');
+  return UnimplementedType('${cxtype.kindSpelling()} not implemented');
+}
+
+// Used for function pointer arguments.
+Type _extractFromFunctionProto(clang_types.CXType cxtype,
+    {clang_types.CXCursor? cursor}) {
+  final parameters = <Parameter>[];
+  final totalArgs = clang.clang_getNumArgTypes(cxtype);
+  for (var i = 0; i < totalArgs; i++) {
+    final t = clang.clang_getArgType(cxtype, i);
+    final pt = t.toCodeGenType();
+
+    if (pt.isIncompleteCompound) {
+      return UnimplementedType(
+          'Incomplete Struct by value in function parameter.');
+    } else if (pt.baseType is UnimplementedType) {
+      return UnimplementedType('Function parameter has an unsupported type.');
+    }
+
+    parameters.add(
+      Parameter(name: '', type: pt),
+    );
+  }
+
+  final functionType = FunctionType(
+    parameters: parameters,
+    returnType: clang.clang_getResultType(cxtype).toCodeGenType(),
+  );
+  _parseAndMergeParamNames(functionType, cursor, maxRecursionDepth);
+  return NativeFunc(functionType);
+}
+
+void _parseAndMergeParamNames(
+  FunctionType functionType,
+  clang_types.CXCursor? cursor,
+  int recursionDepth,
+) {
+  if (cursor == null) {
+    return;
+  }
+  if (recursionDepth == 0) {
+    final cursorRepr = cursor.completeStringRepr();
+    _logger.warning('Recursion depth exceeded when merging function parameters.'
+        ' Last cursor encountered was $cursorRepr');
+    return;
+  }
+
+  final paramsInfo = parseFunctionPointerParamNames(cursor);
+  functionType.addParameterNames(paramsInfo.paramNames);
+
+  for (final param in functionType.parameters) {
+    final paramRealType = param.type.typealiasType;
+    final paramBaseType = paramRealType.baseType.typealiasType;
+    if (paramBaseType is NativeFunc && param.name.isNotEmpty) {
+      final paramFunctionType = paramBaseType.type;
+      final paramCursor = paramsInfo.params[param.name];
+      _parseAndMergeParamNames(
+        paramFunctionType,
+        paramCursor,
+        recursionDepth - 1,
+      );
+    }
+  }
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/utils.dart b/pkgs/ffigen/lib/src/header_parser/utils.dart
new file mode 100644
index 0000000..f03df3f
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/utils.dart
@@ -0,0 +1,461 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+
+import 'package:ffi/ffi.dart';
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/config_provider/config_types.dart';
+import 'package:logging/logging.dart';
+
+import 'clang_bindings/clang_bindings.dart' as clang_types;
+import 'data.dart';
+import 'type_extractor/extractor.dart';
+
+final _logger = Logger('ffigen.header_parser.utils');
+
+const exceptional_visitor_return =
+    clang_types.CXChildVisitResult.CXChildVisit_Break;
+
+/// Check [resultCode] of [clang.clang_visitChildren_wrap].
+///
+/// Throws exception if resultCode is not [exceptional_visitor_return].
+void visitChildrenResultChecker(int resultCode) {
+  if (resultCode != exceptional_visitor_return) {
+    throw Exception(
+        'Exception thrown in a dart function called via C, use --verbose to see more details');
+  }
+}
+
+/// Logs the warnings/errors returned by clang for a translation unit.
+void logTuDiagnostics(
+    Pointer<clang_types.CXTranslationUnitImpl> tu, Logger logger, String header,
+    {Level logLevel = Level.SEVERE}) {
+  final total = clang.clang_getNumDiagnostics(tu);
+  if (total == 0) {
+    return;
+  }
+  logger.log(logLevel, 'Header $header: Total errors/warnings: $total.');
+  for (var i = 0; i < total; i++) {
+    final diag = clang.clang_getDiagnostic(tu, i);
+    final cxstring = clang.clang_formatDiagnostic(
+      diag,
+      clang_types
+              .CXDiagnosticDisplayOptions.CXDiagnostic_DisplaySourceLocation |
+          clang_types.CXDiagnosticDisplayOptions.CXDiagnostic_DisplayColumn |
+          clang_types
+              .CXDiagnosticDisplayOptions.CXDiagnostic_DisplayCategoryName,
+    );
+    logger.log(logLevel, '    ${cxstring.toStringAndDispose()}');
+    clang.clang_disposeDiagnostic(diag);
+  }
+}
+
+extension CXSourceRangeExt on Pointer<clang_types.CXSourceRange> {
+  void dispose() {
+    calloc.free(this);
+  }
+}
+
+extension CXCursorExt on clang_types.CXCursor {
+  String usr() {
+    var res = clang.clang_getCursorUSR(this).toStringAndDispose();
+    if (isAnonymousRecordDecl()) {
+      res += "@offset:${sourceFileOffset()}";
+    }
+    return res;
+  }
+
+  /// Returns the kind int from [clang_types.CXCursorKind].
+  int kind() {
+    return clang.clang_getCursorKind(this);
+  }
+
+  /// Name of the cursor (E.g function name, Struct name, Parameter name).
+  String spelling() {
+    return clang.clang_getCursorSpelling(this).toStringAndDispose();
+  }
+
+  /// Spelling for a [clang_types.CXCursorKind], useful for debug purposes.
+  String kindSpelling() {
+    return clang
+        .clang_getCursorKindSpelling(clang.clang_getCursorKind(this))
+        .toStringAndDispose();
+  }
+
+  /// Get code_gen [Type] representation of [clang_types.CXType].
+  Type toCodeGenType() {
+    return getCodeGenType(type(), originalCursor: this);
+  }
+
+  /// for debug: returns [spelling] [kind] [kindSpelling] [type] [typeSpelling].
+  String completeStringRepr() {
+    final cxtype = type();
+    final s =
+        '(Cursor) spelling: ${spelling()}, kind: ${kind()}, kindSpelling: ${kindSpelling()}, type: ${cxtype.kind}, typeSpelling: ${cxtype.spelling()}, usr: ${usr()}';
+    return s;
+  }
+
+  /// Type associated with the pointer if any. Type will have kind
+  /// [clang.CXTypeKind.CXType_Invalid] otherwise.
+  clang_types.CXType type() {
+    return clang.clang_getCursorType(this);
+  }
+
+  /// Determine whether the given cursor
+  /// represents an anonymous record declaration.
+  bool isAnonymousRecordDecl() {
+    return clang.clang_Cursor_isAnonymousRecordDecl(this) == 1;
+  }
+
+  /// Only valid for [clang.CXCursorKind.CXCursor_FunctionDecl]. Type will have
+  /// kind [clang.CXTypeKind.CXType_Invalid] otherwise.
+  clang_types.CXType returnType() {
+    return clang.clang_getResultType(type());
+  }
+
+  /// Returns the file name of the file that the cursor is inside.
+  String sourceFileName() {
+    final cxsource = clang.clang_getCursorLocation(this);
+    final cxfilePtr = calloc<Pointer<Void>>();
+
+    // Puts the values in these pointers.
+    clang.clang_getFileLocation(cxsource, cxfilePtr, nullptr, nullptr, nullptr);
+    final s = clang.clang_getFileName(cxfilePtr.value).toStringAndDispose();
+
+    calloc.free(cxfilePtr);
+    return s;
+  }
+
+  int sourceFileOffset() {
+    final cxsource = clang.clang_getCursorLocation(this);
+    final cxOffset = calloc<UnsignedInt>();
+
+    // Puts the values in these pointers.
+    clang.clang_getFileLocation(cxsource, nullptr, nullptr, nullptr, cxOffset);
+    final offset = cxOffset.value;
+    calloc.free(cxOffset);
+    return offset;
+  }
+
+  /// Returns whether the file that the cursor is inside is a system header.
+  bool isInSystemHeader() {
+    final location = clang.clang_getCursorLocation(this);
+    return clang.clang_Location_isInSystemHeader(location) != 0;
+  }
+
+  /// Recursively print the AST, for debugging.
+  void printAst([int maxDepth = 3]) {
+    _printAstVisitorMaxDepth = maxDepth;
+    _printAstVisitor(this, this, Pointer<Void>.fromAddress(0));
+  }
+}
+
+Pointer<
+        NativeFunction<
+            Int32 Function(
+                clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>?
+    _printAstVisitorPtr;
+int _printAstVisitorMaxDepth = 0;
+int _printAstVisitor(clang_types.CXCursor cursor, clang_types.CXCursor parent,
+    Pointer<Void> clientData) {
+  final depth = clientData.address;
+  if (depth > _printAstVisitorMaxDepth) {
+    return clang_types.CXChildVisitResult.CXChildVisit_Break;
+  }
+  print(('  ' * depth) + cursor.completeStringRepr());
+  clang.clang_visitChildren(
+      cursor,
+      _printAstVisitorPtr ??=
+          Pointer.fromFunction(_printAstVisitor, exceptional_visitor_return),
+      Pointer<Void>.fromAddress(depth + 1));
+  return clang_types.CXChildVisitResult.CXChildVisit_Continue;
+}
+
+const commentPrefix = '/// ';
+const nesting = '  ';
+
+/// Stores the [clang_types.CXSourceRange] of the last comment.
+clang_types.CXSourceRange? lastCommentRange;
+
+/// Returns a cursor's associated comment.
+///
+/// The given string is wrapped at line width = 80 - [indent]. The [indent] is
+/// [commentPrefix.dimensions] by default because a comment starts with
+/// [commentPrefix].
+String? getCursorDocComment(clang_types.CXCursor cursor,
+    [int indent = commentPrefix.length]) {
+  String? formattedDocComment;
+  final currentCommentRange = clang.clang_Cursor_getCommentRange(cursor);
+
+  // See if this comment and the last comment both point to the same source
+  // range.
+  if (lastCommentRange != null &&
+      clang.clang_equalRanges(lastCommentRange!, currentCommentRange) != 0) {
+    formattedDocComment = null;
+  } else {
+    switch (config.commentType.length) {
+      case CommentLength.full:
+        formattedDocComment = removeRawCommentMarkups(
+            clang.clang_Cursor_getRawCommentText(cursor).toStringAndDispose());
+        break;
+      case CommentLength.brief:
+        formattedDocComment = _wrapNoNewLineString(
+            clang.clang_Cursor_getBriefCommentText(cursor).toStringAndDispose(),
+            80 - indent);
+        break;
+      default:
+        formattedDocComment = null;
+    }
+  }
+  lastCommentRange = currentCommentRange;
+  return formattedDocComment;
+}
+
+/// Wraps [string] according to given [lineWidth].
+///
+/// Wrapping will work properly only when String has no new lines
+/// characters(\n).
+String? _wrapNoNewLineString(String? string, int lineWidth) {
+  if (string == null || string.isEmpty) {
+    return null;
+  }
+  final sb = StringBuffer();
+
+  final words = string.split(' ');
+
+  sb.write(words[0]);
+  var trackLineWidth = words[0].length;
+  for (var i = 1; i < words.length; i++) {
+    final word = words[i];
+    if (trackLineWidth + word.length < lineWidth) {
+      sb.write(' ');
+      sb.write(word);
+      trackLineWidth += word.length + 1;
+    } else {
+      sb.write('\n');
+      sb.write(word);
+      trackLineWidth = word.length;
+    }
+  }
+  return sb.toString();
+}
+
+/// Removes /*, */ and any *'s in the beginning of a line.
+String? removeRawCommentMarkups(String? string) {
+  if (string == null || string.isEmpty) {
+    return null;
+  }
+  final sb = StringBuffer();
+
+  // Remove comment identifiers (`/** * */`, `///`, `//`) from lines.
+  if (string.contains(RegExp(r'^\s*\/\*+'))) {
+    string = string.replaceFirst(RegExp(r'^\s*\/\*+\s*'), '');
+    string = string.replaceFirst(RegExp(r'\s*\*+\/$'), '');
+    string.split('\n').forEach((element) {
+      element = element.replaceFirst(RegExp(r'^\s*\**\s*'), '');
+      sb.writeln(element);
+    });
+  } else if (string.contains(RegExp(r'^\s*\/\/\/?\s*'))) {
+    string.split('\n').forEach((element) {
+      element = element.replaceFirst(RegExp(r'^\s*\/\/\/?\s*'), '');
+      sb.writeln(element);
+    });
+  }
+
+  return sb.toString().trim();
+}
+
+extension CXTypeExt on clang_types.CXType {
+  /// Get code_gen [Type] representation of [clang_types.CXType].
+  Type toCodeGenType() {
+    return getCodeGenType(this);
+  }
+
+  /// Spelling for a [clang_types.CXTypeKind], useful for debug purposes.
+  String spelling() {
+    return clang.clang_getTypeSpelling(this).toStringAndDispose();
+  }
+
+  /// Returns the typeKind int from [clang_types.CXTypeKind].
+  int kind() {
+    return this.kind;
+  }
+
+  String kindSpelling() {
+    return clang.clang_getTypeKindSpelling(kind()).toStringAndDispose();
+  }
+
+  int alignment() {
+    return clang.clang_Type_getAlignOf(this);
+  }
+
+  /// For debugging: returns [spelling] [kind] [kindSpelling].
+  String completeStringRepr() {
+    final s =
+        '(Type) spelling: ${spelling()}, kind: ${kind()}, kindSpelling: ${kindSpelling()}';
+    return s;
+  }
+}
+
+extension CXStringExt on clang_types.CXString {
+  /// Convert CXString to a Dart string
+  ///
+  /// Make sure to dispose CXstring using dispose method, or use the
+  /// [toStringAndDispose] method.
+  String string() {
+    final cstring = clang.clang_getCString(this);
+    if (cstring != nullptr) {
+      return cstring.cast<Utf8>().toDartString();
+    } else {
+      return '';
+    }
+  }
+
+  /// Converts CXString to dart string and disposes CXString.
+  String toStringAndDispose() {
+    // Note: clang_getCString_wrap returns a const char *, calling free will result in error.
+    final s = string();
+    clang.clang_disposeString(this);
+    return s;
+  }
+
+  void dispose() {
+    clang.clang_disposeString(this);
+  }
+}
+
+/// Converts a [List<String>] to [Pointer<Pointer<Utf8>>].
+Pointer<Pointer<Utf8>> createDynamicStringArray(List<String> list) {
+  final nativeCmdArgs = calloc<Pointer<Utf8>>(list.length);
+
+  for (var i = 0; i < list.length; i++) {
+    nativeCmdArgs[i] = list[i].toNativeUtf8();
+  }
+
+  return nativeCmdArgs;
+}
+
+extension DynamicCStringArray on Pointer<Pointer<Utf8>> {
+  // Properly disposes a Pointer<Pointer<Utf8>, ensure that sure length is correct.
+  void dispose(int length) {
+    for (var i = 0; i < length; i++) {
+      calloc.free(this[i]);
+    }
+    calloc.free(this);
+  }
+}
+
+class Stack<T> {
+  final _stack = <T>[];
+
+  T get top => _stack.last;
+  T pop() => _stack.removeLast();
+  void push(T item) => _stack.add(item);
+}
+
+class IncrementalNamer {
+  final _incrementedStringCounters = <String, int>{};
+
+  /// Appends `<int>` to base. <int> is incremented on every call.
+  String name(String base) {
+    var i = _incrementedStringCounters[base] ?? 0;
+    i++;
+    _incrementedStringCounters[base] = i;
+    return '$base$i';
+  }
+}
+
+class Macro {
+  final String usr;
+  final String? originalName;
+
+  Macro(this.usr, this.originalName);
+}
+
+/// Tracks if a binding is 'seen' or not.
+class BindingsIndex {
+  // Tracks if bindings are already seen, Map key is USR obtained from libclang.
+  final Map<String, Type> _declaredTypes = {};
+  final Map<String, Func> _functions = {};
+  final Map<String, Constant> _unnamedEnumConstants = {};
+  final Map<String, String> _macros = {};
+  final Map<String, Global> _globals = {};
+  final Map<String, ObjCBlock> _objcBlocks = {};
+
+  /// Contains usr for typedefs which cannot be generated.
+  final Set<String> _unsupportedTypealiases = {};
+
+  /// Index for headers.
+  final Map<String, bool> _headerCache = {};
+
+  bool isSeenType(String usr) => _declaredTypes.containsKey(usr);
+  void addTypeToSeen(String usr, Type type) => _declaredTypes[usr] = type;
+  Type? getSeenType(String usr) => _declaredTypes[usr];
+  bool isSeenFunc(String usr) => _functions.containsKey(usr);
+  void addFuncToSeen(String usr, Func func) => _functions[usr] = func;
+  Func? getSeenFunc(String usr) => _functions[usr];
+  bool isSeenUnnamedEnumConstant(String usr) =>
+      _unnamedEnumConstants.containsKey(usr);
+  void addUnnamedEnumConstantToSeen(String usr, Constant enumConstant) =>
+      _unnamedEnumConstants[usr] = enumConstant;
+  Constant? getSeenUnnamedEnumConstant(String usr) =>
+      _unnamedEnumConstants[usr];
+  bool isSeenGlobalVar(String usr) => _globals.containsKey(usr);
+  void addGlobalVarToSeen(String usr, Global global) => _globals[usr] = global;
+  Global? getSeenGlobalVar(String usr) => _globals[usr];
+  bool isSeenMacro(String usr) => _macros.containsKey(usr);
+  void addMacroToSeen(String usr, String macro) => _macros[usr] = macro;
+  String? getSeenMacro(String usr) => _macros[usr];
+  bool isSeenUnsupportedTypealias(String usr) =>
+      _unsupportedTypealiases.contains(usr);
+  void addUnsupportedTypealiasToSeen(String usr) =>
+      _unsupportedTypealiases.add(usr);
+  bool isSeenHeader(String source) => _headerCache.containsKey(source);
+  void addHeaderToSeen(String source, bool includeStatus) =>
+      _headerCache[source] = includeStatus;
+  bool? getSeenHeaderStatus(String source) => _headerCache[source];
+  void addObjCBlockToSeen(String key, ObjCBlock t) => _objcBlocks[key] = t;
+  ObjCBlock? getSeenObjCBlock(String key) => _objcBlocks[key];
+}
+
+class CursorIndex {
+  final _usrCursorDefinition = <String, clang_types.CXCursor>{};
+
+  /// Returns the Cursor definition (if found) or itself.
+  clang_types.CXCursor getDefinition(clang_types.CXCursor cursor) {
+    final cursorDefinition = clang.clang_getCursorDefinition(cursor);
+    if (clang.clang_Cursor_isNull(cursorDefinition) == 0) {
+      return cursorDefinition;
+    } else {
+      final usr = cursor.usr();
+      if (_usrCursorDefinition.containsKey(usr)) {
+        return _usrCursorDefinition[cursor.usr()]!;
+      } else {
+        _logger.warning(
+            "No definition found for declaration - ${cursor.completeStringRepr()}");
+        return cursor;
+      }
+    }
+  }
+
+  /// Saves cursor definition based on its kind.
+  void saveDefinition(clang_types.CXCursor cursor) {
+    switch (cursor.kind) {
+      case clang_types.CXCursorKind.CXCursor_StructDecl:
+      case clang_types.CXCursorKind.CXCursor_UnionDecl:
+      case clang_types.CXCursorKind.CXCursor_EnumDecl:
+        final usr = cursor.usr();
+        if (!_usrCursorDefinition.containsKey(usr)) {
+          final cursorDefinition = clang.clang_getCursorDefinition(cursor);
+          if (clang.clang_Cursor_isNull(cursorDefinition) == 0) {
+            _usrCursorDefinition[usr] = cursorDefinition;
+          } else {
+            _logger.finest(
+                "Missing cursor definition in current translation unit: ${cursor.completeStringRepr()}");
+          }
+        }
+    }
+  }
+}
diff --git a/pkgs/ffigen/lib/src/strings.dart b/pkgs/ffigen/lib/src/strings.dart
new file mode 100644
index 0000000..0918f48
--- /dev/null
+++ b/pkgs/ffigen/lib/src/strings.dart
@@ -0,0 +1,283 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'dart:io';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/clang_bindings/clang_bindings.dart'
+    as clang;
+
+/// Name of the dynamic library file according to current platform.
+String get dylibFileName {
+  String name;
+  if (Platform.isLinux) {
+    name = libclang_dylib_linux;
+  } else if (Platform.isMacOS) {
+    name = libclang_dylib_macos;
+  } else if (Platform.isWindows) {
+    name = libclang_dylib_windows;
+  } else {
+    throw Exception('Unsupported Platform.');
+  }
+  return name;
+}
+
+const llvmPath = 'llvm-path';
+
+/// Name of the parent folder of dynamic library `lib` or `bin` (on windows).
+String get dynamicLibParentName => Platform.isWindows ? 'bin' : 'lib';
+
+const output = 'output';
+
+// Sub-keys of output.
+const bindings = "bindings";
+const symbolFile = 'symbol-file';
+
+const language = 'language';
+
+// String mappings for the Language enum.
+const langC = 'c';
+const langObjC = 'objc';
+
+// Clang command line args for Objective C.
+const clangLangObjC = ['-x', 'objective-c'];
+const clangObjCBoolDefine = '__OBJC_BOOL_IS_BOOL';
+const clangInclude = '-include';
+
+// Special objective C types.
+const objcBOOL = 'BOOL';
+const objcInstanceType = 'instancetype';
+
+const headers = 'headers';
+
+// Sub-fields of headers
+const entryPoints = 'entry-points';
+const includeDirectives = 'include-directives';
+
+const compilerOpts = 'compiler-opts';
+
+const compilerOptsAuto = 'compiler-opts-automatic';
+// Sub-fields of compilerOptsAuto.
+const macos = 'macos';
+// Sub-fields of macos.
+const includeCStdLib = 'include-c-standard-library';
+
+// Declarations.
+const functions = 'functions';
+const structs = 'structs';
+const unions = 'unions';
+const enums = 'enums';
+const unnamedEnums = 'unnamed-enums';
+const globals = 'globals';
+const macros = 'macros';
+const typedefs = 'typedefs';
+const objcInterfaces = 'objc-interfaces';
+
+const excludeAllByDefault = 'exclude-all-by-default';
+
+// Sub-fields of Declarations.
+const include = 'include';
+const exclude = 'exclude';
+const rename = 'rename';
+const memberRename = 'member-rename';
+const symbolAddress = 'symbol-address';
+
+// Nested under `functions`
+const exposeFunctionTypedefs = 'expose-typedefs';
+const leafFunctions = 'leaf';
+const varArgFunctions = 'variadic-arguments';
+
+// Nested under varArg entries
+const postfix = "postfix";
+const types = "types";
+
+// Sub-fields of ObjC interfaces.
+const objcModule = 'module';
+
+const dependencyOnly = 'dependency-only';
+// Values for `compoundDependencies`.
+const fullCompoundDependencies = 'full';
+const opaqueCompoundDependencies = 'opaque';
+
+const structPack = 'pack';
+const Map<Object, int?> packingValuesMap = {
+  'none': null,
+  1: 1,
+  2: 2,
+  4: 4,
+  8: 8,
+  16: 16,
+};
+
+// Sizemap values.
+const SChar = 'char';
+const UChar = 'unsigned char';
+const Short = 'short';
+const UShort = 'unsigned short';
+const Int = 'int';
+const UInt = 'unsigned int';
+const Long = 'long';
+const ULong = 'unsigned long';
+const LongLong = 'long long';
+const ULongLong = 'unsigned long long';
+const Enum = 'enum';
+
+// Used for validation and extraction of sizemap.
+const sizemap_native_mapping = <String, int>{
+  SChar: clang.CXTypeKind.CXType_SChar,
+  UChar: clang.CXTypeKind.CXType_UChar,
+  Short: clang.CXTypeKind.CXType_Short,
+  UShort: clang.CXTypeKind.CXType_UShort,
+  Int: clang.CXTypeKind.CXType_Int,
+  UInt: clang.CXTypeKind.CXType_UInt,
+  Long: clang.CXTypeKind.CXType_Long,
+  ULong: clang.CXTypeKind.CXType_ULong,
+  LongLong: clang.CXTypeKind.CXType_LongLong,
+  ULongLong: clang.CXTypeKind.CXType_ULongLong,
+  Enum: clang.CXTypeKind.CXType_Enum
+};
+
+// Library imports.
+const libraryImports = 'library-imports';
+
+// Sub Keys of symbol file.
+const symbols = 'symbols';
+
+// Symbol file yaml.
+const formatVersion = "format_version";
+
+/// Current symbol file format version.
+///
+/// This is generated when generating any symbol file. When importing any other
+/// symbol file, this version is compared according to `semantic` versioning
+/// to determine compatibility.
+const symbolFileFormatVersion = "1.0.0";
+const files = "files";
+const usedConfig = "used-config";
+
+const import = 'import';
+const defaultSymbolFileImportPrefix = 'imp';
+
+// Sub keys of import.
+const symbolFilesImport = 'symbol-files';
+// Sub-Sub keys of symbolFilesImport.
+const importPath = 'import-path';
+
+final predefinedLibraryImports = {
+  ffiImport.name: ffiImport,
+  ffiPkgImport.name: ffiPkgImport
+};
+
+const typeMap = 'type-map';
+
+// Sub-fields for type-map.
+const typeMapTypedefs = 'typedefs';
+const typeMapStructs = 'structs';
+const typeMapUnions = 'unions';
+const typeMapNativeTypes = 'native-types';
+
+// Sub-sub-keys for fields under typeMap.
+const lib = 'lib';
+const cType = 'c-type';
+const dartType = 'dart-type';
+
+const supportedNativeType_mappings = <String, SupportedNativeType>{
+  'Void': SupportedNativeType.Void,
+  'Uint8': SupportedNativeType.Uint8,
+  'Uint16': SupportedNativeType.Uint16,
+  'Uint32': SupportedNativeType.Uint32,
+  'Uint64': SupportedNativeType.Uint64,
+  'Int8': SupportedNativeType.Int8,
+  'Int16': SupportedNativeType.Int16,
+  'Int32': SupportedNativeType.Int32,
+  'Int64': SupportedNativeType.Int64,
+  'IntPtr': SupportedNativeType.IntPtr,
+  'Float': SupportedNativeType.Float,
+  'Double': SupportedNativeType.Double,
+};
+
+// Boolean flags.
+const sort = 'sort';
+const useSupportedTypedefs = 'use-supported-typedefs';
+const useDartHandle = 'use-dart-handle';
+
+const comments = 'comments';
+// Sub-fields of comments.
+const style = 'style';
+const length = 'length';
+
+// Sub-fields of style.
+const doxygen = 'doxygen';
+const any = 'any';
+// Sub-fields of length.
+const brief = 'brief';
+const full = 'full';
+// Cmd line comment option.
+const fparseAllComments = '-fparse-all-comments';
+
+// Library input.
+const name = 'name';
+const description = 'description';
+const preamble = 'preamble';
+
+// Dynamic library names.
+const libclang_dylib_linux = 'libclang.so';
+const libclang_dylib_macos = 'libclang.dylib';
+const libclang_dylib_windows = 'libclang.dll';
+
+// Dynamic library default locations.
+const linuxDylibLocations = {
+  '/usr/lib/llvm-9/lib/',
+  '/usr/lib/llvm-10/lib/',
+  '/usr/lib/llvm-11/lib/',
+  '/usr/lib/llvm-12/lib/',
+  '/usr/lib/llvm-13/lib/',
+  '/usr/lib/llvm-14/lib/',
+  '/usr/lib/llvm-15/lib/',
+  '/usr/lib/',
+  '/usr/lib64/',
+};
+const windowsDylibLocations = {
+  r'C:\Program Files\LLVM\bin\',
+};
+const macOsDylibLocations = {
+  // Default Xcode commandline tools installation.
+  '/Library/Developer/CommandLineTools/usr/',
+  // Default path for LLVM installed with apt-get.
+  '/usr/local/opt/llvm/lib/',
+  // Default path for LLVM installed with brew.
+  '/opt/homebrew/opt/llvm/lib/',
+  // Default Xcode installation.
+  // Last because it does not include ObjectiveC headers by default.
+  // See https://github.com/dart-lang/ffigen/pull/402#issuecomment-1154348670.
+  '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/',
+};
+const xcodeDylibLocation = 'Toolchains/XcodeDefault.xctoolchain/usr/lib/';
+
+// Writen doubles.
+const doubleInfinity = 'double.infinity';
+const doubleNegativeInfinity = 'double.negativeInfinity';
+const doubleNaN = 'double.nan';
+
+/// USR for struct `_Dart_Handle`.
+const dartHandleUsr = 'c:@S@_Dart_Handle';
+
+const ffiNative = 'ffi-native';
+const ffiNativeAsset = 'assetId';
+
+Directory? _tmpDir;
+
+/// A path to a unique temporary directory that should be used for files meant
+/// to be discarded after the current execution is finished.
+String get tmpDir {
+  if (Platform.environment.containsKey('TEST_TMPDIR')) {
+    return Platform.environment['TEST_TMPDIR']!;
+  }
+
+  _tmpDir ??= Directory.systemTemp.createTempSync();
+  return _tmpDir!.path;
+}
+
+const ffigenJsonSchemaIndent = '  ';
+const ffigenJsonSchemaId = "https://json.schemastore.org/ffigen";
+const ffigenJsonSchemaFileName = "ffigen.schema.json";
diff --git a/pkgs/ffigen/pubspec.yaml b/pkgs/ffigen/pubspec.yaml
new file mode 100644
index 0000000..5504c2a
--- /dev/null
+++ b/pkgs/ffigen/pubspec.yaml
@@ -0,0 +1,35 @@
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+name: ffigen
+version: 10.0.0
+description: >
+  Generator for FFI bindings, using LibClang to parse C, Objective-C, and Swift
+  files.
+repository: https://github.com/dart-lang/native/tree/main/pkgs/ffigen
+topics:
+  - interop
+  - ffi
+  - codegen
+
+environment:
+  sdk: '>=3.2.0 <4.0.0'
+
+dependencies:
+  ffi: ^2.0.1
+  yaml: ^3.0.0
+  path: ^1.8.0
+  quiver: ^3.0.0
+  args: ^2.0.0
+  logging: ^1.0.0
+  cli_util: ^0.4.0
+  glob: ^2.0.0
+  file: ^7.0.0
+  package_config: ^2.1.0
+  yaml_edit: ^2.0.3
+
+dev_dependencies:
+  lints: ^2.0.1
+  test: ^1.16.2
+  json_schema: ^5.1.1
diff --git a/pkgs/ffigen/test/README.md b/pkgs/ffigen/test/README.md
new file mode 100644
index 0000000..0f4c50c
--- /dev/null
+++ b/pkgs/ffigen/test/README.md
@@ -0,0 +1,61 @@
+# ffigen testing
+
+## Running Tests
+
+1.  Some tests require that dynamic libraries be built before running the tests.
+    You can do so with:
+
+    ```shell
+    dart run test/setup.dart
+    ```
+
+2.  Run the tests with:
+
+    ```shell
+    dart test
+    ```
+
+## Development
+
+Some tests verify that the generated Dart FFI bindings match a golden file.
+
+For example, the test
+[`test/native_test/native_test.dart`](https://github.com/dart-lang/native/tree/main/pkgs/ffigen/test/native_test/native_test.dart)
+works by:
+
+1.  Loading the dynamic library for
+    [`test/native_test/native_test.c`](https://github.com/dart-lang/native/tree/main/pkgs/ffigen/test/native_test/native_test.c)
+    (which was generated by `dart run test/setup.dart`).
+
+2.  Generating binding files for that dynamic library in the
+    `test/debug_generated` directory.
+
+3.  Comparing the golden file (i.e.
+    [`test/native_test/_expected_native_test_bindings.dart`](https://github.com/dart-lang/native/tree/main/pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart))
+    to the generated file and generating a test failure if they do not match.
+
+4.  Using the *golden* bindings to excercise the dynamic library.
+
+If you modify any source for a dynamic library (e.g. any `.c`, `.h` or `.m`
+files), then you should run:
+
+```shell
+   dart run test/setup.dart  # Rebuild the dynamic libraries.
+   dart run test/regen.dart  # Rebuild the golden FFI bindings.
+```
+
+If you modify any code that changes how FFI bindings are generated, then you
+should run:
+
+  ```shell
+  dart run test/regen.dart  # Rebuild the golden FFI bindings.
+  ```
+
+A conservative way to run tests is with:
+
+  ```shell
+  dart run test/setup.dart && dart run test/regen.dart && dart test
+  ```
+
+> Note: you should verify that the changes to the golden bindings are
+> reasonable with `git diff`.
diff --git a/pkgs/ffigen/test/code_generator_tests/code_generator_test.dart b/pkgs/ffigen/test/code_generator_tests/code_generator_test.dart
new file mode 100644
index 0000000..e16d3d9
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/code_generator_test.dart
@@ -0,0 +1,491 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:test/test.dart';
+import '../test_utils.dart';
+
+void main() {
+  group('code_generator: ', () {
+    test('Function Binding (primitives, pointers)', () {
+      final library = Library(
+        name: 'Bindings',
+        bindings: [
+          Func(
+            name: 'noParam',
+            dartDoc: 'Just a test function\nheres another line',
+            returnType: NativeType(
+              SupportedNativeType.Int32,
+            ),
+          ),
+          Func(
+            name: 'withPrimitiveParam',
+            parameters: [
+              Parameter(
+                name: 'a',
+                type: NativeType(
+                  SupportedNativeType.Int32,
+                ),
+              ),
+              Parameter(
+                name: 'b',
+                type: NativeType(
+                  SupportedNativeType.Uint8,
+                ),
+              ),
+            ],
+            returnType: NativeType(
+              SupportedNativeType.Char,
+            ),
+          ),
+          Func(
+            name: 'withPointerParam',
+            parameters: [
+              Parameter(
+                name: 'a',
+                type: PointerType(
+                  NativeType(
+                    SupportedNativeType.Int32,
+                  ),
+                ),
+              ),
+              Parameter(
+                name: 'b',
+                type: PointerType(
+                  PointerType(
+                    NativeType(
+                      SupportedNativeType.Uint8,
+                    ),
+                  ),
+                ),
+              ),
+            ],
+            returnType: PointerType(
+              NativeType(
+                SupportedNativeType.Double,
+              ),
+            ),
+          ),
+          Func(
+            isLeaf: true,
+            name: 'leafFunc',
+            dartDoc: 'A function with isLeaf: true',
+            parameters: [
+              Parameter(
+                name: 'a',
+                type: NativeType(
+                  SupportedNativeType.Int32,
+                ),
+              ),
+            ],
+            returnType: NativeType(
+              SupportedNativeType.Int32,
+            ),
+          ),
+        ],
+      );
+
+      _matchLib(library, 'function');
+    });
+
+    test('Struct Binding (primitives, pointers)', () {
+      final library = Library(
+        name: 'Bindings',
+        bindings: [
+          Struct(
+            name: 'NoMember',
+            dartDoc: 'Just a test struct\nheres another line',
+          ),
+          Struct(
+            name: 'WithPrimitiveMember',
+            members: [
+              Member(
+                name: 'a',
+                type: NativeType(
+                  SupportedNativeType.Int32,
+                ),
+              ),
+              Member(
+                name: 'b',
+                type: NativeType(
+                  SupportedNativeType.Double,
+                ),
+              ),
+              Member(
+                name: 'c',
+                type: NativeType(
+                  SupportedNativeType.Char,
+                ),
+              ),
+            ],
+          ),
+          Struct(
+            name: 'WithPointerMember',
+            members: [
+              Member(
+                name: 'a',
+                type: PointerType(
+                  NativeType(
+                    SupportedNativeType.Int32,
+                  ),
+                ),
+              ),
+              Member(
+                name: 'b',
+                type: PointerType(
+                  PointerType(
+                    NativeType(
+                      SupportedNativeType.Double,
+                    ),
+                  ),
+                ),
+              ),
+              Member(
+                name: 'c',
+                type: NativeType(
+                  SupportedNativeType.Char,
+                ),
+              ),
+            ],
+          ),
+          Struct(
+            name: 'WithIntPtrUintPtr',
+            members: [
+              Member(
+                name: 'a',
+                type: PointerType(
+                  NativeType(
+                    SupportedNativeType.UintPtr,
+                  ),
+                ),
+              ),
+              Member(
+                name: 'b',
+                type: PointerType(
+                  PointerType(
+                    NativeType(
+                      SupportedNativeType.IntPtr,
+                    ),
+                  ),
+                ),
+              ),
+            ],
+          ),
+        ],
+      );
+
+      _matchLib(library, 'struct');
+    });
+
+    test('Function and Struct Binding (pointer to Struct)', () {
+      final structSome = Struct(
+        name: 'SomeStruct',
+        members: [
+          Member(
+            name: 'a',
+            type: NativeType(
+              SupportedNativeType.Int32,
+            ),
+          ),
+          Member(
+            name: 'b',
+            type: NativeType(
+              SupportedNativeType.Double,
+            ),
+          ),
+          Member(
+            name: 'c',
+            type: NativeType(
+              SupportedNativeType.Char,
+            ),
+          ),
+        ],
+      );
+      final library = Library(
+        name: 'Bindings',
+        bindings: [
+          structSome,
+          Func(
+            name: 'someFunc',
+            parameters: [
+              Parameter(
+                name: 'some',
+                type: PointerType(
+                  PointerType(
+                    structSome,
+                  ),
+                ),
+              ),
+            ],
+            returnType: PointerType(
+              structSome,
+            ),
+          ),
+        ],
+      );
+
+      _matchLib(library, 'function_n_struct');
+    });
+
+    test('global (primitives, pointers, pointer to struct)', () {
+      final structSome = Struct(
+        name: 'Some',
+      );
+      final emptyGlobalStruct = Struct(name: 'EmptyStruct');
+
+      final library = Library(
+        name: 'Bindings',
+        bindings: [
+          Global(
+            name: 'test1',
+            type: NativeType(
+              SupportedNativeType.Int32,
+            ),
+          ),
+          Global(
+            name: 'test2',
+            type: PointerType(
+              NativeType(
+                SupportedNativeType.Float,
+              ),
+            ),
+          ),
+          structSome,
+          Global(
+            name: 'test5',
+            type: PointerType(
+              structSome,
+            ),
+          ),
+          emptyGlobalStruct,
+          Global(name: 'globalStruct', type: emptyGlobalStruct),
+        ],
+      );
+      _matchLib(library, 'global');
+    });
+
+    test('constant', () {
+      final library = Library(
+        name: 'Bindings',
+        header: '// ignore_for_file: unused_import\n',
+        bindings: [
+          Constant(
+            name: 'test1',
+            rawType: 'int',
+            rawValue: '20',
+          ),
+          Constant(
+            name: 'test2',
+            rawType: 'double',
+            rawValue: '20.0',
+          ),
+        ],
+      );
+      _matchLib(library, 'constant');
+    });
+
+    test('enum_class', () {
+      final library = Library(
+        name: 'Bindings',
+        header: '// ignore_for_file: unused_import\n',
+        bindings: [
+          EnumClass(
+            name: 'Constants',
+            dartDoc: 'test line 1\ntest line 2',
+            enumConstants: [
+              EnumConstant(
+                name: 'a',
+                value: 10,
+              ),
+              EnumConstant(name: 'b', value: -1, dartDoc: 'negative'),
+            ],
+          ),
+        ],
+      );
+      _matchLib(library, 'enumclass');
+    });
+    test('Internal conflict resolution', () {
+      final library = Library(
+        name: 'init_dylib',
+        header:
+            '// ignore_for_file: unused_element, camel_case_types, non_constant_identifier_names\n',
+        bindings: [
+          Func(
+            name: 'test',
+            returnType: NativeType(SupportedNativeType.Void),
+          ),
+          Func(
+            name: '_test',
+            returnType: NativeType(SupportedNativeType.Void),
+          ),
+          Func(
+            name: '_c_test',
+            returnType: NativeType(SupportedNativeType.Void),
+          ),
+          Func(
+            name: '_dart_test',
+            returnType: NativeType(SupportedNativeType.Void),
+          ),
+          Struct(
+            name: '_Test',
+            members: [
+              Member(
+                name: 'array',
+                type: ConstantArray(
+                  2,
+                  NativeType(
+                    SupportedNativeType.Int8,
+                  ),
+                ),
+              ),
+            ],
+          ),
+          Struct(name: 'ArrayHelperPrefixCollisionTest'),
+          Func(
+            name: 'Test',
+            returnType: NativeType(SupportedNativeType.Void),
+          ),
+          EnumClass(name: '_c_Test'),
+          EnumClass(name: 'init_dylib'),
+        ],
+      );
+      _matchLib(library, 'internal_conflict_resolution');
+    });
+  });
+  test('boolean_dartBool', () {
+    final library = Library(
+      name: 'Bindings',
+      bindings: [
+        Func(
+          name: 'test1',
+          returnType: BooleanType(),
+          parameters: [
+            Parameter(name: 'a', type: BooleanType()),
+            Parameter(name: 'b', type: PointerType(BooleanType())),
+          ],
+        ),
+        Struct(
+          name: 'Test2',
+          members: [
+            Member(name: 'a', type: BooleanType()),
+          ],
+        ),
+      ],
+    );
+    _matchLib(library, 'boolean_dartbool');
+  });
+  test('sort bindings', () {
+    final library = Library(
+      name: 'Bindings',
+      sort: true,
+      bindings: [
+        Func(name: 'b', returnType: NativeType(SupportedNativeType.Void)),
+        Func(name: 'a', returnType: NativeType(SupportedNativeType.Void)),
+        Struct(name: 'D'),
+        Struct(name: 'C'),
+      ],
+    );
+    _matchLib(library, 'sort_bindings');
+  });
+  test('Pack Structs', () {
+    final library = Library(
+      name: 'Bindings',
+      bindings: [
+        Struct(name: 'NoPacking', pack: null, members: [
+          Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
+        ]),
+        Struct(name: 'Pack1', pack: 1, members: [
+          Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
+        ]),
+        Struct(name: 'Pack2', pack: 2, members: [
+          Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
+        ]),
+        Struct(name: 'Pack2', pack: 4, members: [
+          Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
+        ]),
+        Struct(name: 'Pack2', pack: 8, members: [
+          Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
+        ]),
+        Struct(name: 'Pack16', pack: 16, members: [
+          Member(name: 'a', type: NativeType(SupportedNativeType.Char)),
+        ]),
+      ],
+    );
+    _matchLib(library, 'packed_structs');
+  });
+  test('Union Bindings', () {
+    final struct1 =
+        Struct(name: 'Struct1', members: [Member(name: 'a', type: charType)]);
+    final union1 =
+        Union(name: 'Union1', members: [Member(name: 'a', type: charType)]);
+    final library = Library(
+      name: 'Bindings',
+      bindings: [
+        struct1,
+        union1,
+        Union(name: 'EmptyUnion'),
+        Union(name: 'Primitives', members: [
+          Member(name: 'a', type: charType),
+          Member(name: 'b', type: intType),
+          Member(name: 'c', type: floatType),
+          Member(name: 'd', type: doubleType),
+        ]),
+        Union(name: 'PrimitivesWithPointers', members: [
+          Member(name: 'a', type: charType),
+          Member(name: 'b', type: floatType),
+          Member(name: 'c', type: PointerType(doubleType)),
+          Member(name: 'd', type: PointerType(union1)),
+          Member(name: 'd', type: PointerType(struct1)),
+        ]),
+        Union(name: 'WithArray', members: [
+          Member(name: 'a', type: ConstantArray(10, charType)),
+          Member(name: 'b', type: ConstantArray(10, union1)),
+          Member(name: 'b', type: ConstantArray(10, struct1)),
+          Member(name: 'c', type: ConstantArray(10, PointerType(union1))),
+        ]),
+      ],
+    );
+    _matchLib(library, 'unions');
+  });
+  test('Typealias Bindings', () {
+    final library = Library(
+      name: 'Bindings',
+      header: '// ignore_for_file: non_constant_identifier_names\n',
+      bindings: [
+        Typealias(name: 'RawUnused', type: Struct(name: 'Struct1')),
+        Struct(name: 'WithTypealiasStruct', members: [
+          Member(
+              name: 't',
+              type: Typealias(
+                  name: 'Struct2Typealias',
+                  type: Struct(
+                      name: 'Struct2',
+                      members: [Member(name: 'a', type: doubleType)])))
+        ]),
+        Func(
+            name: 'WithTypealiasStruct',
+            returnType: PointerType(NativeFunc(FunctionType(
+                returnType: NativeType(SupportedNativeType.Void),
+                parameters: []))),
+            parameters: [
+              Parameter(
+                  name: 't',
+                  type: Typealias(
+                      name: 'Struct3Typealias', type: Struct(name: 'Struct3')))
+            ]),
+      ],
+    );
+    _matchLib(library, 'typealias');
+  });
+}
+
+/// Utility to match expected bindings to the generated bindings.
+void _matchLib(Library lib, String testName) {
+  matchLibraryWithExpected(lib, 'code_generator_test_${testName}_output.dart', [
+    'test',
+    'code_generator_tests',
+    'expected_bindings',
+    '_expected_${testName}_bindings.dart'
+  ]);
+}
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_boolean_dartbool_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_boolean_dartbool_bindings.dart
new file mode 100644
index 0000000..015821e
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_boolean_dartbool_bindings.dart
@@ -0,0 +1,41 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+class Bindings {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  Bindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  Bindings.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  bool test1(
+    bool a,
+    ffi.Pointer<ffi.Bool> b,
+  ) {
+    return _test1(
+      a,
+      b,
+    );
+  }
+
+  late final _test1Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Bool Function(ffi.Bool, ffi.Pointer<ffi.Bool>)>>('test1');
+  late final _test1 =
+      _test1Ptr.asFunction<bool Function(bool, ffi.Pointer<ffi.Bool>)>();
+}
+
+final class Test2 extends ffi.Struct {
+  @ffi.Bool()
+  external bool a;
+}
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_constant_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_constant_bindings.dart
new file mode 100644
index 0000000..a425c42
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_constant_bindings.dart
@@ -0,0 +1,10 @@
+// ignore_for_file: unused_import
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+
+const int test1 = 20;
+
+const double test2 = 20.0;
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_enumclass_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_enumclass_bindings.dart
new file mode 100644
index 0000000..1f759d5
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_enumclass_bindings.dart
@@ -0,0 +1,14 @@
+// ignore_for_file: unused_import
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+/// test line 1
+/// test line 2
+abstract class Constants {
+  static const int a = 10;
+
+  /// negative
+  static const int b = -1;
+}
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_function_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_function_bindings.dart
new file mode 100644
index 0000000..ae9fc13
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_function_bindings.dart
@@ -0,0 +1,78 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+class Bindings {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  Bindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  Bindings.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  /// Just a test function
+  /// heres another line
+  int noParam() {
+    return _noParam();
+  }
+
+  late final _noParamPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function()>>('noParam');
+  late final _noParam = _noParamPtr.asFunction<int Function()>();
+
+  int withPrimitiveParam(
+    int a,
+    int b,
+  ) {
+    return _withPrimitiveParam(
+      a,
+      b,
+    );
+  }
+
+  late final _withPrimitiveParamPtr =
+      _lookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Int32, ffi.Uint8)>>(
+          'withPrimitiveParam');
+  late final _withPrimitiveParam =
+      _withPrimitiveParamPtr.asFunction<int Function(int, int)>();
+
+  ffi.Pointer<ffi.Double> withPointerParam(
+    ffi.Pointer<ffi.Int32> a,
+    ffi.Pointer<ffi.Pointer<ffi.Uint8>> b,
+  ) {
+    return _withPointerParam(
+      a,
+      b,
+    );
+  }
+
+  late final _withPointerParamPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Double> Function(ffi.Pointer<ffi.Int32>,
+              ffi.Pointer<ffi.Pointer<ffi.Uint8>>)>>('withPointerParam');
+  late final _withPointerParam = _withPointerParamPtr.asFunction<
+      ffi.Pointer<ffi.Double> Function(
+          ffi.Pointer<ffi.Int32>, ffi.Pointer<ffi.Pointer<ffi.Uint8>>)>();
+
+  /// A function with isLeaf: true
+  int leafFunc(
+    int a,
+  ) {
+    return _leafFunc(
+      a,
+    );
+  }
+
+  late final _leafFuncPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Int32)>>('leafFunc');
+  late final _leafFunc =
+      _leafFuncPtr.asFunction<int Function(int)>(isLeaf: true);
+}
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_function_n_struct_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_function_n_struct_bindings.dart
new file mode 100644
index 0000000..cf255b2
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_function_n_struct_bindings.dart
@@ -0,0 +1,46 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+class Bindings {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  Bindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  Bindings.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  ffi.Pointer<SomeStruct> someFunc(
+    ffi.Pointer<ffi.Pointer<SomeStruct>> some,
+  ) {
+    return _someFunc(
+      some,
+    );
+  }
+
+  late final _someFuncPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<SomeStruct> Function(
+              ffi.Pointer<ffi.Pointer<SomeStruct>>)>>('someFunc');
+  late final _someFunc = _someFuncPtr.asFunction<
+      ffi.Pointer<SomeStruct> Function(ffi.Pointer<ffi.Pointer<SomeStruct>>)>();
+}
+
+final class SomeStruct extends ffi.Struct {
+  @ffi.Int32()
+  external int a;
+
+  @ffi.Double()
+  external double b;
+
+  @ffi.Uint8()
+  external int c;
+}
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_global_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_global_bindings.dart
new file mode 100644
index 0000000..37081b8
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_global_bindings.dart
@@ -0,0 +1,49 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+class Bindings {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  Bindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  Bindings.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  late final ffi.Pointer<ffi.Int32> _test1 = _lookup<ffi.Int32>('test1');
+
+  int get test1 => _test1.value;
+
+  set test1(int value) => _test1.value = value;
+
+  late final ffi.Pointer<ffi.Pointer<ffi.Float>> _test2 =
+      _lookup<ffi.Pointer<ffi.Float>>('test2');
+
+  ffi.Pointer<ffi.Float> get test2 => _test2.value;
+
+  set test2(ffi.Pointer<ffi.Float> value) => _test2.value = value;
+
+  late final ffi.Pointer<ffi.Pointer<Some>> _test5 =
+      _lookup<ffi.Pointer<Some>>('test5');
+
+  ffi.Pointer<Some> get test5 => _test5.value;
+
+  set test5(ffi.Pointer<Some> value) => _test5.value = value;
+
+  late final ffi.Pointer<EmptyStruct> _globalStruct =
+      _lookup<EmptyStruct>('globalStruct');
+
+  ffi.Pointer<EmptyStruct> get globalStruct => _globalStruct;
+}
+
+final class Some extends ffi.Opaque {}
+
+final class EmptyStruct extends ffi.Opaque {}
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_internal_conflict_resolution_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_internal_conflict_resolution_bindings.dart
new file mode 100644
index 0000000..1a71e3b
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_internal_conflict_resolution_bindings.dart
@@ -0,0 +1,74 @@
+// ignore_for_file: unused_element, camel_case_types, non_constant_identifier_names
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+class init_dylib1 {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  init_dylib1(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  init_dylib1.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void test() {
+    return _test1();
+  }
+
+  late final _testPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('test');
+  late final _test1 = _testPtr.asFunction<void Function()>();
+
+  void _test() {
+    return __test();
+  }
+
+  late final __testPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('_test');
+  late final __test = __testPtr.asFunction<void Function()>();
+
+  void _c_test() {
+    return __c_test();
+  }
+
+  late final __c_testPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('_c_test');
+  late final __c_test = __c_testPtr.asFunction<void Function()>();
+
+  void _dart_test() {
+    return __dart_test();
+  }
+
+  late final __dart_testPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('_dart_test');
+  late final __dart_test = __dart_testPtr.asFunction<void Function()>();
+
+  void Test() {
+    return _Test();
+  }
+
+  late final _TestPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('Test');
+  late final _Test = _TestPtr.asFunction<void Function()>();
+}
+
+final class _Test extends ffi.Struct {
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Int8> array;
+}
+
+final class ArrayHelperPrefixCollisionTest extends ffi.Opaque {}
+
+abstract class _c_Test {}
+
+abstract class init_dylib {}
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_packed_structs_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_packed_structs_bindings.dart
new file mode 100644
index 0000000..f882e7e
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_packed_structs_bindings.dart
@@ -0,0 +1,40 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+final class NoPacking extends ffi.Struct {
+  @ffi.Uint8()
+  external int a;
+}
+
+@ffi.Packed(1)
+final class Pack1 extends ffi.Struct {
+  @ffi.Uint8()
+  external int a;
+}
+
+@ffi.Packed(2)
+final class Pack2 extends ffi.Struct {
+  @ffi.Uint8()
+  external int a;
+}
+
+@ffi.Packed(4)
+final class Pack21 extends ffi.Struct {
+  @ffi.Uint8()
+  external int a;
+}
+
+@ffi.Packed(8)
+final class Pack22 extends ffi.Struct {
+  @ffi.Uint8()
+  external int a;
+}
+
+@ffi.Packed(16)
+final class Pack16 extends ffi.Struct {
+  @ffi.Uint8()
+  external int a;
+}
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_sort_bindings_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_sort_bindings_bindings.dart
new file mode 100644
index 0000000..eddeeb7
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_sort_bindings_bindings.dart
@@ -0,0 +1,38 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+class Bindings {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  Bindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  Bindings.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void a() {
+    return _a();
+  }
+
+  late final _aPtr = _lookup<ffi.NativeFunction<ffi.Void Function()>>('a');
+  late final _a = _aPtr.asFunction<void Function()>();
+
+  void b() {
+    return _b();
+  }
+
+  late final _bPtr = _lookup<ffi.NativeFunction<ffi.Void Function()>>('b');
+  late final _b = _bPtr.asFunction<void Function()>();
+}
+
+final class C extends ffi.Opaque {}
+
+final class D extends ffi.Opaque {}
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_struct_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_struct_bindings.dart
new file mode 100644
index 0000000..b7a4e9d
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_struct_bindings.dart
@@ -0,0 +1,35 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Just a test struct
+/// heres another line
+final class NoMember extends ffi.Opaque {}
+
+final class WithPrimitiveMember extends ffi.Struct {
+  @ffi.Int32()
+  external int a;
+
+  @ffi.Double()
+  external double b;
+
+  @ffi.Uint8()
+  external int c;
+}
+
+final class WithPointerMember extends ffi.Struct {
+  external ffi.Pointer<ffi.Int32> a;
+
+  external ffi.Pointer<ffi.Pointer<ffi.Double>> b;
+
+  @ffi.Uint8()
+  external int c;
+}
+
+final class WithIntPtrUintPtr extends ffi.Struct {
+  external ffi.Pointer<ffi.UintPtr> a;
+
+  external ffi.Pointer<ffi.Pointer<ffi.IntPtr>> b;
+}
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_typealias_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_typealias_bindings.dart
new file mode 100644
index 0000000..4383756
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_typealias_bindings.dart
@@ -0,0 +1,57 @@
+// ignore_for_file: non_constant_identifier_names
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+class Bindings {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  Bindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  Bindings.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> WithTypealiasStruct1(
+    Struct3Typealias t,
+  ) {
+    return _WithTypealiasStruct1(
+      t,
+    );
+  }
+
+  late final _WithTypealiasStruct1Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> Function(
+              Struct3Typealias)>>('WithTypealiasStruct');
+  late final _WithTypealiasStruct1 = _WithTypealiasStruct1Ptr.asFunction<
+      ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> Function(
+          Struct3Typealias)>();
+}
+
+typedef RawUnused = Struct1;
+
+final class Struct1 extends ffi.Opaque {}
+
+final class WithTypealiasStruct extends ffi.Struct {
+  external Struct2Typealias t;
+}
+
+typedef Struct2Typealias = Struct2;
+
+final class Struct2 extends ffi.Struct {
+  @ffi.Double()
+  external double a;
+}
+
+typedef Struct3Typealias = Struct3;
+
+final class Struct3 extends ffi.Opaque {}
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_unions_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_unions_bindings.dart
new file mode 100644
index 0000000..692f0d6
--- /dev/null
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_unions_bindings.dart
@@ -0,0 +1,59 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+final class Struct1 extends ffi.Struct {
+  @ffi.Char()
+  external int a;
+}
+
+final class Union1 extends ffi.Union {
+  @ffi.Char()
+  external int a;
+}
+
+final class EmptyUnion extends ffi.Opaque {}
+
+final class Primitives extends ffi.Union {
+  @ffi.Char()
+  external int a;
+
+  @ffi.Int()
+  external int b;
+
+  @ffi.Float()
+  external double c;
+
+  @ffi.Double()
+  external double d;
+}
+
+final class PrimitivesWithPointers extends ffi.Union {
+  @ffi.Char()
+  external int a;
+
+  @ffi.Float()
+  external double b;
+
+  external ffi.Pointer<ffi.Double> c;
+
+  external ffi.Pointer<Union1> d;
+
+  external ffi.Pointer<Struct1> d1;
+}
+
+final class WithArray extends ffi.Union {
+  @ffi.Array.multi([10])
+  external ffi.Array<ffi.Char> a;
+
+  @ffi.Array.multi([10])
+  external ffi.Array<Union1> b;
+
+  @ffi.Array.multi([10])
+  external ffi.Array<Struct1> b1;
+
+  @ffi.Array.multi([10])
+  external ffi.Array<ffi.Pointer<Union1>> c;
+}
diff --git a/pkgs/ffigen/test/collision_tests/decl_decl_collision_test.dart b/pkgs/ffigen/test/collision_tests/decl_decl_collision_test.dart
new file mode 100644
index 0000000..1edcaeb
--- /dev/null
+++ b/pkgs/ffigen/test/collision_tests/decl_decl_collision_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+import '../test_utils.dart';
+
+void main() {
+  group('decl_decl_collision_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+    });
+    test('declaration conflict', () {
+      final library = Library(name: 'Bindings', bindings: [
+        Struct(name: 'TestStruct'),
+        Struct(name: 'TestStruct'),
+        EnumClass(name: 'TestEnum'),
+        EnumClass(name: 'TestEnum'),
+        Func(
+            name: 'testFunc', returnType: NativeType(SupportedNativeType.Void)),
+        Func(
+            name: 'testFunc', returnType: NativeType(SupportedNativeType.Void)),
+        Constant(
+          originalName: 'Test_Macro',
+          name: 'Test_Macro',
+          rawType: 'int',
+          rawValue: '0',
+        ),
+        Constant(
+          originalName: 'Test_Macro',
+          name: 'Test_Macro',
+          rawType: 'int',
+          rawValue: '0',
+        ),
+        Typealias(
+            name: 'testAlias', type: NativeType(SupportedNativeType.Void)),
+        Typealias(
+            name: 'testAlias', type: NativeType(SupportedNativeType.Void)),
+
+        /// Conflicts across declarations.
+        Struct(name: 'testCrossDecl'),
+        Func(
+            name: 'testCrossDecl',
+            returnType: NativeType(SupportedNativeType.Void)),
+        Constant(name: 'testCrossDecl', rawValue: '0', rawType: 'int'),
+        EnumClass(name: 'testCrossDecl'),
+        Typealias(
+            name: 'testCrossDecl', type: NativeType(SupportedNativeType.Void)),
+
+        /// Conflicts with ffi library prefix, name of prefix is changed.
+        Struct(name: 'ffi'),
+        Func(name: 'ffi1', returnType: NativeType(SupportedNativeType.Void)),
+      ]);
+      matchLibraryWithExpected(
+          library, 'decl_decl_collision_test_output.dart', [
+        'test',
+        'collision_tests',
+        'expected_bindings',
+        '_expected_decl_decl_collision_bindings.dart',
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/collision_tests/decl_symbol_address_collision_test.dart b/pkgs/ffigen/test/collision_tests/decl_symbol_address_collision_test.dart
new file mode 100644
index 0000000..0280732
--- /dev/null
+++ b/pkgs/ffigen/test/collision_tests/decl_symbol_address_collision_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+import '../test_utils.dart';
+
+late Library actual;
+void main() {
+  group('decl_symbol_address_collision_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      actual = Library(
+        name: 'Bindings',
+        header:
+            '// ignore_for_file: unused_element, camel_case_types, non_constant_identifier_names\n',
+        bindings: [
+          Struct(name: 'addresses'),
+          Struct(name: '_SymbolAddresses'),
+          EnumClass(name: 'Bindings'),
+          Func(
+            name: '_library',
+            returnType: NativeType(SupportedNativeType.Void),
+            exposeSymbolAddress: true,
+            exposeFunctionTypedefs: true,
+          ),
+          Func(
+            name: '_SymbolAddresses_1',
+            returnType: NativeType(SupportedNativeType.Void),
+            exposeSymbolAddress: true,
+          ),
+        ],
+      );
+    });
+    test('declaration and symbol address conflict', () {
+      matchLibraryWithExpected(
+          actual, 'collision_test_decl_symbol_address_collision_output.dart', [
+        'test',
+        'collision_tests',
+        'expected_bindings',
+        '_expected_decl_symbol_address_collision_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/collision_tests/decl_type_name_collision.h b/pkgs/ffigen/test/collision_tests/decl_type_name_collision.h
new file mode 100644
index 0000000..9d25f38
--- /dev/null
+++ b/pkgs/ffigen/test/collision_tests/decl_type_name_collision.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+struct A {
+  int a;
+};
+
+struct B {
+  int B;
+  int A;
+};
+
+struct C {
+  struct A A;
+  struct B B;
+};
+
+struct D {
+  struct B A;
+  struct A B;
+};
diff --git a/pkgs/ffigen/test/collision_tests/decl_type_name_collision_test.dart b/pkgs/ffigen/test/collision_tests/decl_type_name_collision_test.dart
new file mode 100644
index 0000000..19e9497
--- /dev/null
+++ b/pkgs/ffigen/test/collision_tests/decl_type_name_collision_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual;
+void main() {
+  group('decl_type_name_collision test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Decl type name collision test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/collision_tests/decl_type_name_collision.h'
+${strings.preamble}: |
+    // ignore_for_file: non_constant_identifier_names, 
+        '''),
+      );
+    });
+
+    test('Expected bindings', () {
+      matchLibraryWithExpected(
+          actual, 'decl_type_name_collision_test_output.dart', [
+        'test',
+        'collision_tests',
+        'expected_bindings',
+        '_expected_decl_type_name_collision_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_decl_collision_bindings.dart b/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_decl_collision_bindings.dart
new file mode 100644
index 0000000..32388b6
--- /dev/null
+++ b/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_decl_collision_bindings.dart
@@ -0,0 +1,80 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+class Bindings {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  Bindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  Bindings.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void testFunc() {
+    return _testFunc();
+  }
+
+  late final _testFuncPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('testFunc');
+  late final _testFunc = _testFuncPtr.asFunction<void Function()>();
+
+  void testFunc1() {
+    return _testFunc1();
+  }
+
+  late final _testFunc1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('testFunc');
+  late final _testFunc1 = _testFunc1Ptr.asFunction<void Function()>();
+
+  void testCrossDecl1() {
+    return _testCrossDecl1();
+  }
+
+  late final _testCrossDecl1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('testCrossDecl');
+  late final _testCrossDecl1 = _testCrossDecl1Ptr.asFunction<void Function()>();
+
+  void ffi1() {
+    return _ffi1();
+  }
+
+  late final _ffi1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('ffi1');
+  late final _ffi1 = _ffi1Ptr.asFunction<void Function()>();
+}
+
+final class TestStruct extends ffi.Opaque {}
+
+final class TestStruct1 extends ffi.Opaque {}
+
+abstract class TestEnum {}
+
+abstract class TestEnum1 {}
+
+const int Test_Macro = 0;
+
+const int Test_Macro1 = 0;
+
+typedef testAlias = ffi.Void;
+typedef DarttestAlias = void;
+typedef testAlias1 = ffi.Void;
+typedef DarttestAlias1 = void;
+
+final class testCrossDecl extends ffi.Opaque {}
+
+const int testCrossDecl2 = 0;
+
+abstract class testCrossDecl3 {}
+
+typedef testCrossDecl4 = ffi.Void;
+typedef DarttestCrossDecl = void;
+
+final class ffi extends ffi.Opaque {}
diff --git a/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_symbol_address_collision_bindings.dart b/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_symbol_address_collision_bindings.dart
new file mode 100644
index 0000000..0d5473f
--- /dev/null
+++ b/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_symbol_address_collision_bindings.dart
@@ -0,0 +1,60 @@
+// ignore_for_file: unused_element, camel_case_types, non_constant_identifier_names
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+class Bindings1 {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  Bindings1(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  Bindings1.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void _library() {
+    return __library();
+  }
+
+  late final __libraryPtr =
+      _lookup<ffi.NativeFunction<Native_library>>('_library');
+  late final __library = __libraryPtr.asFunction<Dart_library>();
+
+  void _SymbolAddresses_1() {
+    return __SymbolAddresses_1();
+  }
+
+  late final __SymbolAddresses_1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('_SymbolAddresses_1');
+  late final __SymbolAddresses_1 =
+      __SymbolAddresses_1Ptr.asFunction<void Function()>();
+
+  late final addresses = _SymbolAddresses1(this);
+}
+
+class _SymbolAddresses1 {
+  final Bindings1 _library1;
+  _SymbolAddresses1(this._library1);
+  ffi.Pointer<ffi.NativeFunction<Native_library>> get _library =>
+      _library1.__libraryPtr;
+  ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> get _SymbolAddresses_1 =>
+      _library1.__SymbolAddresses_1Ptr;
+}
+
+final class addresses extends ffi.Opaque {}
+
+final class _SymbolAddresses extends ffi.Opaque {}
+
+abstract class Bindings {}
+
+typedef Native_library = ffi.Void Function();
+typedef Dart_library = void Function();
diff --git a/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_type_name_collision_bindings.dart b/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_type_name_collision_bindings.dart
new file mode 100644
index 0000000..625c69a
--- /dev/null
+++ b/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_type_name_collision_bindings.dart
@@ -0,0 +1,32 @@
+// ignore_for_file: non_constant_identifier_names,
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+final class A extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+final class B extends ffi.Struct {
+  @ffi.Int()
+  external int B1;
+
+  @ffi.Int()
+  external int A;
+}
+
+final class C extends ffi.Struct {
+  external A A1;
+
+  external B B1;
+}
+
+final class D extends ffi.Struct {
+  external B A1;
+
+  external A B1;
+}
diff --git a/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_reserved_keyword_collision_bindings.dart b/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_reserved_keyword_collision_bindings.dart
new file mode 100644
index 0000000..c788b49
--- /dev/null
+++ b/pkgs/ffigen/test/collision_tests/expected_bindings/_expected_reserved_keyword_collision_bindings.dart
@@ -0,0 +1,61 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+class Bindings {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  Bindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  Bindings.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void show1() {
+    return _show1();
+  }
+
+  late final _show1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('show');
+  late final _show1 = _show1Ptr.asFunction<void Function()>();
+
+  void implements1(
+    int if1,
+    int abstract1,
+    int in1,
+  ) {
+    return _implements1(
+      if1,
+      abstract1,
+      in1,
+    );
+  }
+
+  late final _implements1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int, ffi.Int, ffi.Int)>>(
+          'implements');
+  late final _implements1 =
+      _implements1Ptr.asFunction<void Function(int, int, int)>();
+}
+
+final class abstract1 extends ffi.Opaque {}
+
+final class abstract2 extends ffi.Opaque {}
+
+final class if1 extends ffi.Opaque {}
+
+abstract class return1 {}
+
+abstract class export1 {}
+
+const int else1 = 0;
+
+typedef var1 = ffi.Void;
+typedef Dartvar = void;
diff --git a/pkgs/ffigen/test/collision_tests/reserved_keyword_collision_test.dart b/pkgs/ffigen/test/collision_tests/reserved_keyword_collision_test.dart
new file mode 100644
index 0000000..88f353a
--- /dev/null
+++ b/pkgs/ffigen/test/collision_tests/reserved_keyword_collision_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void main() {
+  group('reserved_keyword_collision_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+    });
+    test('reserved keyword collision', () {
+      final library = Library(name: 'Bindings', bindings: [
+        Struct(name: 'abstract'),
+        Struct(name: 'abstract'),
+        Struct(name: 'if'),
+        EnumClass(name: 'return'),
+        EnumClass(name: 'export'),
+        Func(name: 'show', returnType: NativeType(SupportedNativeType.Void)),
+        Func(
+            name: 'implements',
+            parameters: [
+              Parameter(
+                type: intType,
+                name: 'if',
+              ),
+              Parameter(
+                type: intType,
+                name: 'abstract',
+              ),
+              Parameter(
+                type: intType,
+                name: 'in',
+              ),
+            ],
+            returnType: NativeType(SupportedNativeType.Void)),
+        Constant(
+          name: 'else',
+          rawType: 'int',
+          rawValue: '0',
+        ),
+        Typealias(name: 'var', type: NativeType(SupportedNativeType.Void)),
+      ]);
+      matchLibraryWithExpected(
+          library, 'reserved_keyword_collision_test_output.dart', [
+        'test',
+        'collision_tests',
+        'expected_bindings',
+        '_expected_reserved_keyword_collision_bindings.dart',
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/config_tests/compiler_opts_test.dart b/pkgs/ffigen/test/config_tests/compiler_opts_test.dart
new file mode 100644
index 0000000..0b711ac
--- /dev/null
+++ b/pkgs/ffigen/test/config_tests/compiler_opts_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/ffigen.dart';
+import 'package:ffigen/src/config_provider/spec_utils.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('compiler_opts_test', () {
+    test('Compiler Opts', () {
+      final opts =
+          '''--option value "in double quotes" 'in single quotes'  -tab=separated''';
+      final list = compilerOptsToList(opts);
+      expect(
+        list,
+        <String>[
+          '--option',
+          'value',
+          'in double quotes',
+          'in single quotes',
+          '-tab=separated',
+        ],
+      );
+    });
+    test('Compiler Opts Automatic', () {
+      final config = testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Compiler Opts Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/comment_markup.h'
+${strings.compilerOptsAuto}:
+  ${strings.macos}:
+    ${strings.includeCStdLib}: false
+        ''');
+      expect(config.compilerOpts.isEmpty, true);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/config_tests/exclude_all_by_default.h b/pkgs/ffigen/test/config_tests/exclude_all_by_default.h
new file mode 100644
index 0000000..e45634a
--- /dev/null
+++ b/pkgs/ffigen/test/config_tests/exclude_all_by_default.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void func();
+
+struct Struct {
+  int a;
+};
+
+union Union {
+  int a;
+};
+
+int global;
+
+#define MACRO 123
+
+enum Enum {
+  zero = 0,
+};
+
+enum {
+  unnamedEnum = 123,
+};
diff --git a/pkgs/ffigen/test/config_tests/exclude_all_by_default_test.dart b/pkgs/ffigen/test/config_tests/exclude_all_by_default_test.dart
new file mode 100644
index 0000000..361e4b2
--- /dev/null
+++ b/pkgs/ffigen/test/config_tests/exclude_all_by_default_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/ffigen.dart';
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void main() {
+  group('exclude_all_by_default', () {
+    test('exclude_all_by_default test flag false', () {
+      final config = testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'exclude_all_by_default test'
+${strings.output}: 'unused'
+${strings.excludeAllByDefault}: false
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/config_tests/exclude_all_by_default.h'
+''');
+
+      final library = parse(config);
+      expect(library.getBinding('func'), isA<Func>());
+      expect(library.getBinding('Struct'), isA<Struct>());
+      expect(library.getBinding('Union'), isA<Union>());
+      expect(library.getBinding('global'), isA<Global>());
+      expect(library.getBinding('MACRO'), isA<Constant>());
+      expect(library.getBinding('Enum'), isA<EnumClass>());
+      expect(library.getBinding('unnamedEnum'), isA<Constant>());
+    });
+
+    test('exclude_all_by_default test flag true', () {
+      final config = testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'exclude_all_by_default test'
+${strings.output}: 'unused'
+${strings.excludeAllByDefault}: true
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/config_tests/exclude_all_by_default.h'
+''');
+
+      final library = parse(config);
+      expect(() => library.getBinding('func'), throwsException);
+      expect(() => library.getBinding('Struct'), throwsException);
+      expect(() => library.getBinding('Union'), throwsException);
+      expect(() => library.getBinding('global'), throwsException);
+      expect(() => library.getBinding('MACRO'), throwsException);
+      expect(() => library.getBinding('Enum'), throwsException);
+      expect(() => library.getBinding('unnamedEnum'), throwsException);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/config_tests/include_exclude.h b/pkgs/ffigen/test/config_tests/include_exclude.h
new file mode 100644
index 0000000..b62e8f3
--- /dev/null
+++ b/pkgs/ffigen/test/config_tests/include_exclude.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+typedef int Typedef;
+
+void func(Typedef s);
+
+struct Struct {
+  int a;
+};
+
+union Union {
+  int a;
+};
+
+int global;
+
+#define MACRO 123
+
+enum Enum {
+  zero = 0,
+};
+
+enum {
+  unnamedEnum = 123,
+};
+
diff --git a/pkgs/ffigen/test/config_tests/include_exclude_test.dart b/pkgs/ffigen/test/config_tests/include_exclude_test.dart
new file mode 100644
index 0000000..1f27885
--- /dev/null
+++ b/pkgs/ffigen/test/config_tests/include_exclude_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/ffigen.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void main() {
+  group('include_exclude', () {
+    const fieldsAndNameMap = {
+      strings.functions: 'func',
+      strings.structs: 'Struct',
+      strings.unions: 'Union',
+      strings.enums: 'Enum',
+      strings.unnamedEnums: 'unnamedEnum',
+      strings.macros: 'MACRO',
+      strings.globals: 'global',
+      strings.typedefs: 'Typedef',
+    };
+    for (final f in fieldsAndNameMap.keys) {
+      test('include $f', () {
+        final config = _makeFieldIncludeExcludeConfig(
+            field: f, include: fieldsAndNameMap[f]);
+        final library = parse(config);
+        expect(library.getBinding(fieldsAndNameMap[f]!), isNotNull);
+      });
+      test('exclude $f', () {
+        final config = _makeFieldIncludeExcludeConfig(
+            field: f, exclude: fieldsAndNameMap[f]);
+        final library = parse(config);
+        expect(() => library.getBinding(fieldsAndNameMap[f]!), throwsException);
+      });
+    }
+  });
+}
+
+Config _makeFieldIncludeExcludeConfig({
+  required String field,
+  String? include,
+  String? exclude,
+}) {
+  var templateString = '''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'include_exclude test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/config_tests/include_exclude.h'
+''';
+  if (include != null || exclude != null) {
+    templateString += '''
+$field:
+''';
+    if (include != null) {
+      templateString += '''
+  ${strings.include}:
+    - $include
+''';
+    }
+    if (exclude != null) {
+      templateString += '''
+  ${strings.exclude}:
+    - $exclude
+''';
+    }
+  }
+
+  final config = testConfig(templateString);
+  return config;
+}
diff --git a/pkgs/ffigen/test/config_tests/json_schema_test.dart b/pkgs/ffigen/test/config_tests/json_schema_test.dart
new file mode 100644
index 0000000..44ea1e7
--- /dev/null
+++ b/pkgs/ffigen/test/config_tests/json_schema_test.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:ffigen/ffigen.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:file/local.dart';
+import 'package:glob/glob.dart';
+import 'package:json_schema/json_schema.dart';
+import 'package:test/test.dart';
+import 'package:yaml/yaml.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('json_schema_test', () {
+    final schema = Config.getsRootConfigSpec()
+        .generateJsonSchema(strings.ffigenJsonSchemaId);
+
+    test('Schema Changes', () {
+      final actualJsonSchema =
+          JsonEncoder.withIndent(strings.ffigenJsonSchemaIndent).convert(
+        Config.getsRootConfigSpec()
+            .generateJsonSchema(strings.ffigenJsonSchemaId),
+      );
+      final expectedJsonSchema = File(strings.ffigenJsonSchemaFileName)
+          .readAsStringSync()
+          .replaceAll('\r\n', '\n');
+      expect(actualJsonSchema, expectedJsonSchema);
+    });
+
+    final jsonSchema = JsonSchema.create(schema);
+    test('Valid json schema', () {
+      expect(jsonSchema, isNot(null));
+    });
+
+    // Find all ffigen config files in the repo.
+    final configYamlGlob = Glob("**config.yaml");
+    final configYamlFiles =
+        configYamlGlob.listFileSystemSync(const LocalFileSystem());
+    test('$configYamlGlob files not empty', () {
+      expect(configYamlFiles.isNotEmpty, true);
+    });
+
+    final sharedBindingsConfigYamlGlob =
+        Glob("example/shared_bindings/ffigen_configs/**.yaml");
+    final sharedBindingsConfigYamlFiles = sharedBindingsConfigYamlGlob
+        .listFileSystemSync(const LocalFileSystem());
+    test('$sharedBindingsConfigYamlGlob files not emty', () {
+      expect(sharedBindingsConfigYamlFiles.isNotEmpty, true);
+    });
+
+    final allConfigFiles = configYamlFiles + sharedBindingsConfigYamlFiles;
+
+    for (final fe in allConfigFiles) {
+      test('validate config file: ${fe.path}', () {
+        final yamlDoc = loadYaml(File(fe.absolute.path).readAsStringSync());
+        final validationResult = jsonSchema.validate(yamlDoc);
+        expect(validationResult.errors.isEmpty, true,
+            reason: "Schema Errors: ${validationResult.errors}");
+        expect(validationResult.warnings.isEmpty, true,
+            reason: "Schema Warnings: ${validationResult.errors}");
+      });
+    }
+
+    test('Bare minimal input', () {
+      expect(
+          jsonSchema
+              .validate({
+                "output": "abcd.dart",
+                "headers": {
+                  "entry-points": ["a.h"]
+                }
+              })
+              .errors
+              .isEmpty,
+          true);
+    });
+    test('Fail input', () {
+      expect(jsonSchema.validate(null).errors.isNotEmpty, true);
+      expect(jsonSchema.validate({"a": 1}).errors.isNotEmpty, true);
+      expect(
+          jsonSchema.validate({"output": "abcd.dart"}).errors.isNotEmpty, true);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/config_tests/packed_struct_override_test.dart b/pkgs/ffigen/test/config_tests/packed_struct_override_test.dart
new file mode 100644
index 0000000..68f8954
--- /dev/null
+++ b/pkgs/ffigen/test/config_tests/packed_struct_override_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/ffigen.dart';
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('packed_struct_override_test', () {
+    test('Invalid Packed Config values', () {
+      const baseYaml = '''${strings.name}: 'NativeLibrary'
+${strings.description}: 'Packed Struct Override Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/packed_structs.h'
+${strings.structs}:
+  ${strings.structPack}:
+    ''';
+      expect(() => testConfig("$baseYaml'.*': null"),
+          throwsA(TypeMatcher<FormatException>()));
+      expect(() => testConfig("$baseYaml'.*': 3"),
+          throwsA(TypeMatcher<FormatException>()));
+      expect(() => testConfig("$baseYaml'.*': 32"),
+          throwsA(TypeMatcher<FormatException>()));
+    });
+    test('Override values', () {
+      final config = testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Packed Struct Override Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/packed_structs.h'
+${strings.structs}:
+  ${strings.structPack}:
+    'Normal.*': 1
+    'StructWithAttr': 2
+    'PackedAttr': none
+        ''');
+
+      final library = parse(config);
+
+      expect((library.getBinding('NormalStruct1') as Struct).pack, 1);
+      expect((library.getBinding('StructWithAttr') as Struct).pack, 2);
+      expect((library.getBinding('PackedAttr') as Struct).pack, null);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/config_tests/unknown_keys_warn_test.dart b/pkgs/ffigen/test/config_tests/unknown_keys_warn_test.dart
new file mode 100644
index 0000000..6f80757
--- /dev/null
+++ b/pkgs/ffigen/test/config_tests/unknown_keys_warn_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/ffigen.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  var logString = '';
+  group('unknown_keys_warn_test', () {
+    setUpAll(() {
+      final logArr = <String>[];
+      logWarningsToArray(logArr, Level.WARNING);
+      testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Warn for unknown keys.'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/packed_structs.h'
+'warn-1': 'warn'
+${strings.typeMap}:
+  'warn-2': 'warn'
+  'warn-3': 'warn'
+        ''');
+      logString = logArr.join("\n");
+    });
+    test('Warn for unknown keys.', () {
+      expect(logString.contains('warn-1'), true);
+      expect(logString.contains('warn-2'), true);
+      expect(logString.contains('warn-3'), true);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/example_tests/cjson_example_test.dart b/pkgs/ffigen/test/example_tests/cjson_example_test.dart
new file mode 100644
index 0000000..714cb70
--- /dev/null
+++ b/pkgs/ffigen/test/example_tests/cjson_example_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/header_parser.dart';
+import 'package:logging/logging.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void main() {
+  group('cjson_example_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+    });
+    test('c_json', () {
+      final config =
+          testConfigFromPath(path.join('example', 'c_json', 'config.yaml'));
+      final library = parse(config);
+
+      matchLibraryWithExpected(
+        library,
+        'example_c_json.dart',
+        [config.output],
+      );
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/example_tests/ffinative_example_test.dart b/pkgs/ffigen/test/example_tests/ffinative_example_test.dart
new file mode 100644
index 0000000..28588b1
--- /dev/null
+++ b/pkgs/ffigen/test/example_tests/ffinative_example_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/header_parser.dart';
+import 'package:logging/logging.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void main() {
+  group('ffinative_example_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+    });
+
+    test('ffinative', () {
+      final config =
+          testConfigFromPath(path.join('example', 'ffinative', 'config.yaml'));
+      final library = parse(config);
+
+      matchLibraryWithExpected(
+        library,
+        'example_ffinative.dart',
+        [config.output],
+      );
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/example_tests/libclang_example_test.dart b/pkgs/ffigen/test/example_tests/libclang_example_test.dart
new file mode 100644
index 0000000..8414e49
--- /dev/null
+++ b/pkgs/ffigen/test/example_tests/libclang_example_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:ffigen/src/code_generator/library.dart';
+import 'package:ffigen/src/config_provider/config.dart';
+import 'package:ffigen/src/header_parser.dart';
+import 'package:logging/logging.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void main() {
+  group('example_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+    });
+    test('libclang-example', () {
+      final configYaml =
+          File(path.join('example', 'libclang-example', 'config.yaml'))
+              .absolute;
+      late Config config;
+      late Library library;
+      withChDir(configYaml.path, () {
+        config = testConfigFromPath(configYaml.path);
+        library = parse(config);
+      });
+
+      matchLibraryWithExpected(
+        library,
+        'example_libclang.dart',
+        [config.output],
+      );
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/example_tests/objective_c_example_test.dart b/pkgs/ffigen/test/example_tests/objective_c_example_test.dart
new file mode 100644
index 0000000..eba22e6
--- /dev/null
+++ b/pkgs/ffigen/test/example_tests/objective_c_example_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'package:ffigen/src/header_parser.dart';
+import 'package:logging/logging.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void main() {
+  group('objective_c_example_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+    });
+
+    test('objective_c', () {
+      final config = testConfigFromPath(
+          path.join('example', 'objective_c', 'config.yaml'));
+      final output = parse(config).generate();
+
+      // Verify that the output contains all the methods and classes that the
+      // example app uses.
+      expect(output, contains('class AVFAudio{'));
+      expect(output, contains('class NSString extends NSObject {'));
+      expect(output, contains('class NSURL extends NSObject {'));
+      expect(
+          output,
+          contains(
+              'static NSURL fileURLWithPath_(AVFAudio _lib, NSString path) {'));
+      expect(output, contains('class AVAudioPlayer extends NSObject {'));
+      expect(
+          output,
+          contains('AVAudioPlayer? initWithContentsOfURL_error_('
+              'NSURL url, ffi.Pointer<ffi.Pointer<ObjCObject>> outError) {'));
+      expect(output, contains('double get duration {'));
+      expect(output, contains('bool play() {'));
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/example_tests/shared_bindings_example_test.dart b/pkgs/ffigen/test/example_tests/shared_bindings_example_test.dart
new file mode 100644
index 0000000..0d4e39b
--- /dev/null
+++ b/pkgs/ffigen/test/example_tests/shared_bindings_example_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/header_parser.dart';
+import 'package:logging/logging.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void main() {
+  group('shared_bindings_example', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+    });
+
+    test('a_shared_base bindings', () {
+      final config = testConfigFromPath(path.join(
+        'example',
+        'shared_bindings',
+        'ffigen_configs',
+        'a_shared_base.yaml',
+      ));
+      final library = parse(config);
+
+      matchLibraryWithExpected(
+        library,
+        'example_shared_bindings.dart',
+        [config.output],
+      );
+    });
+
+    test('base symbol file output', () {
+      final config = testConfigFromPath(path.join(
+        'example',
+        'shared_bindings',
+        'ffigen_configs',
+        'base.yaml',
+      ));
+      final library = parse(config);
+      matchLibrarySymbolFileWithExpected(
+        library,
+        'example_shared_bindings.yaml',
+        [config.symbolFile!.output],
+        config.symbolFile!.importPath,
+      );
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/example_tests/simple_example_test.dart b/pkgs/ffigen/test/example_tests/simple_example_test.dart
new file mode 100644
index 0000000..343bf1c
--- /dev/null
+++ b/pkgs/ffigen/test/example_tests/simple_example_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/header_parser.dart';
+import 'package:logging/logging.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void main() {
+  group('simple_example_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+    });
+
+    test('simple', () {
+      final config = testConfigFromPath(path.join(
+        'example',
+        'simple',
+        'config.yaml',
+      ));
+      final library = parse(config);
+
+      matchLibraryWithExpected(
+        library,
+        'example_simple.dart',
+        [config.output],
+      );
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/example_tests/swift_example_test.dart b/pkgs/ffigen/test/example_tests/swift_example_test.dart
new file mode 100644
index 0000000..a4ac61e
--- /dev/null
+++ b/pkgs/ffigen/test/example_tests/swift_example_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Swift support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:ffigen/src/header_parser.dart';
+import 'package:logging/logging.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void main() {
+  group('swift_example_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+    });
+
+    test('swift', () async {
+      // Run the swiftc command from the example README, to generate the header.
+      final process = await Process.start(
+          'swiftc',
+          [
+            '-c',
+            'swift_api.swift',
+            '-module-name',
+            'swift_module',
+            '-emit-objc-header-path',
+            'third_party/swift_api.h',
+            '-emit-library',
+            '-o',
+            'libswiftapi.dylib',
+          ],
+          workingDirectory: path.join(Directory.current.path, 'example/swift'));
+      unawaited(stdout.addStream(process.stdout));
+      unawaited(stderr.addStream(process.stderr));
+      final result = await process.exitCode;
+      expect(result, 0);
+
+      final config = testConfigFromPath(path.join(
+        'example',
+        'swift',
+        'config.yaml',
+      ));
+      final output = parse(config).generate();
+
+      // Verify that the output contains all the methods and classes that the
+      // example app uses.
+      expect(output, contains('class SwiftLibrary{'));
+      expect(output, contains('class NSString extends NSObject {'));
+      expect(output, contains('class SwiftClass extends NSObject {'));
+      expect(output, contains('static SwiftClass new1(SwiftLibrary _lib) {'));
+      expect(output, contains('NSString sayHello() {'));
+      expect(output, contains('int get someField {'));
+      expect(output, contains('set someField(int value) {'));
+
+      // Verify that SwiftClass is loaded using the swift_module prefix.
+      expect(
+          output,
+          contains(RegExp(r'late final _class_SwiftClass.* = '
+              r'_getClass.*\("swift_module\.SwiftClass"\)')));
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/comment_markup.h b/pkgs/ffigen/test/header_parser_tests/comment_markup.h
new file mode 100644
index 0000000..635c2c3
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/comment_markup.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This is a single line test comment.
+void com1();
+
+/// This is a multi-line
+/// test comment.
+void com2();
+
+/** This is a multi-line
+ * doxygen style
+ * test comment.
+ */
+void com3();
+
+// Test comment for struct.
+struct Com4{
+    /// Muli-line test comment for struct field
+    // With multiple line and both // and ///.
+    int a;
+
+    /* Single line field comment. */
+    float b;
+
+    /* Comment on array member. */
+    int c[3];
+};
diff --git a/pkgs/ffigen/test/header_parser_tests/comment_markup_test.dart b/pkgs/ffigen/test/header_parser_tests/comment_markup_test.dart
new file mode 100644
index 0000000..e31098a
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/comment_markup_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual;
+void main() {
+  group('comment_markup_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Comment Markup Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/comment_markup.h'
+${strings.comments}:
+  ${strings.style}: ${strings.any}
+  ${strings.length}: ${strings.full}
+        '''),
+      );
+    });
+
+    test('Expected bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_comment_markup_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_comment_markup_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/dart_handle.h b/pkgs/ffigen/test/header_parser_tests/dart_handle.h
new file mode 100644
index 0000000..26d73fa
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/dart_handle.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <dart_api.h>
+
+void func1(Dart_Handle);
+Dart_Handle func2();
+Dart_Handle **func3(Dart_Handle *);
+
+typedef void (*Typedef1)(Dart_Handle);
+void func4(Typedef1);
+
+// Dart_Handle isn't supported directly, so all members are removed.
+struct Struct1
+{
+    Dart_Handle h;
+    int a;
+};
+
+// Pointer<Handle> works.
+struct Struct2
+{
+    Dart_Handle *h;
+};
diff --git a/pkgs/ffigen/test/header_parser_tests/dart_handle_test.dart b/pkgs/ffigen/test/header_parser_tests/dart_handle_test.dart
new file mode 100644
index 0000000..484d8b0
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/dart_handle_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:cli_util/cli_util.dart';
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('dart_handle_test', () {
+    setUpAll(() {
+      logWarnings();
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Dart_Handle Test'
+${strings.output}: 'unused'
+${strings.compilerOpts}: '-I${path.join(getSdkPath(), "include")}'
+
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/dart_handle.h'
+  ${strings.includeDirectives}:
+    - '**dart_handle.h'
+        '''),
+      );
+    });
+    test('Expected Bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_dart_handle_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_dart_handle_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_comment_markup_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_comment_markup_bindings.dart
new file mode 100644
index 0000000..91d9908
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_comment_markup_bindings.dart
@@ -0,0 +1,68 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Comment Markup Test
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  /// This is a single line test comment.
+  void com1() {
+    return _com1();
+  }
+
+  late final _com1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('com1');
+  late final _com1 = _com1Ptr.asFunction<void Function()>();
+
+  /// This is a multi-line
+  /// test comment.
+  void com2() {
+    return _com2();
+  }
+
+  late final _com2Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('com2');
+  late final _com2 = _com2Ptr.asFunction<void Function()>();
+
+  /// This is a multi-line
+  /// doxygen style
+  /// test comment.
+  void com3() {
+    return _com3();
+  }
+
+  late final _com3Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('com3');
+  late final _com3 = _com3Ptr.asFunction<void Function()>();
+}
+
+/// Test comment for struct.
+final class Com4 extends ffi.Struct {
+  /// Muli-line test comment for struct field
+  /// With multiple line and both // and ///.
+  @ffi.Int()
+  external int a;
+
+  /// Single line field comment.
+  @ffi.Float()
+  external double b;
+
+  /// Comment on array member.
+  @ffi.Array.multi([3])
+  external ffi.Array<ffi.Int> c;
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_dart_handle_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_dart_handle_bindings.dart
new file mode 100644
index 0000000..6106985
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_dart_handle_bindings.dart
@@ -0,0 +1,79 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Dart_Handle Test
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void func1(
+    Object arg0,
+  ) {
+    return _func1(
+      arg0,
+    );
+  }
+
+  late final _func1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Handle)>>('func1');
+  late final _func1 = _func1Ptr.asFunction<void Function(Object)>();
+
+  Object func2() {
+    return _func2();
+  }
+
+  late final _func2Ptr =
+      _lookup<ffi.NativeFunction<ffi.Handle Function()>>('func2');
+  late final _func2 = _func2Ptr.asFunction<Object Function()>();
+
+  ffi.Pointer<ffi.Pointer<ffi.Handle>> func3(
+    ffi.Pointer<ffi.Handle> arg0,
+  ) {
+    return _func3(
+      arg0,
+    );
+  }
+
+  late final _func3Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Pointer<ffi.Handle>> Function(
+              ffi.Pointer<ffi.Handle>)>>('func3');
+  late final _func3 = _func3Ptr.asFunction<
+      ffi.Pointer<ffi.Pointer<ffi.Handle>> Function(ffi.Pointer<ffi.Handle>)>();
+
+  void func4(
+    Typedef1 arg0,
+  ) {
+    return _func4(
+      arg0,
+    );
+  }
+
+  late final _func4Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(Typedef1)>>('func4');
+  late final _func4 = _func4Ptr.asFunction<void Function(Typedef1)>();
+}
+
+typedef Typedef1 = ffi.Pointer<ffi.NativeFunction<Typedef1Function>>;
+typedef Typedef1Function = ffi.Void Function(ffi.Handle);
+typedef DartTypedef1Function = void Function(Object);
+
+final class Struct1 extends ffi.Opaque {}
+
+final class Struct2 extends ffi.Struct {
+  external ffi.Pointer<ffi.Handle> h;
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_forward_decl_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_forward_decl_bindings.dart
new file mode 100644
index 0000000..f1175cc
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_forward_decl_bindings.dart
@@ -0,0 +1,50 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Forward Declaration Test
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void func(
+    ffi.Pointer<A> a,
+    int b,
+  ) {
+    return _func(
+      a,
+      b,
+    );
+  }
+
+  late final _funcPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<A>, ffi.Int32)>>(
+          'func');
+  late final _func = _funcPtr.asFunction<void Function(ffi.Pointer<A>, int)>();
+}
+
+final class A extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+
+  @ffi.Int()
+  external int b;
+}
+
+abstract class B {
+  static const int a = 0;
+  static const int b = 1;
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart
new file mode 100644
index 0000000..7475b09
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart
@@ -0,0 +1,155 @@
+// ignore_for_file: camel_case_types
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Functions Test
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void func1() {
+    return _func1();
+  }
+
+  late final _func1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>('func1');
+  late final _func1 = _func1Ptr.asFunction<void Function()>(isLeaf: true);
+
+  int func2(
+    int arg0,
+  ) {
+    return _func2(
+      arg0,
+    );
+  }
+
+  late final _func2Ptr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Int16)>>('func2');
+  late final _func2 = _func2Ptr.asFunction<int Function(int)>();
+
+  double func3(
+    double arg0,
+    int a,
+    int arg2,
+    int b,
+  ) {
+    return _func3(
+      arg0,
+      a,
+      arg2,
+      b,
+    );
+  }
+
+  late final _func3Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Double Function(
+              ffi.Float, ffi.Int8, ffi.Int64, ffi.Int32)>>('func3');
+  late final _func3 =
+      _func3Ptr.asFunction<double Function(double, int, int, int)>();
+
+  ffi.Pointer<ffi.Void> func4(
+    ffi.Pointer<ffi.Pointer<ffi.Int8>> arg0,
+    double arg1,
+    ffi.Pointer<ffi.Pointer<ffi.Pointer<ffi.Int32>>> arg2,
+  ) {
+    return _func4(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _func4Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Pointer<ffi.Int8>>,
+              ffi.Double,
+              ffi.Pointer<ffi.Pointer<ffi.Pointer<ffi.Int32>>>)>>('func4');
+  late final _func4 = _func4Ptr.asFunction<
+      ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Pointer<ffi.Int8>>, double,
+          ffi.Pointer<ffi.Pointer<ffi.Pointer<ffi.Int32>>>)>();
+
+  void func5(
+    ffi.Pointer<shortHand> a,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> b,
+  ) {
+    return _func5(
+      a,
+      b,
+    );
+  }
+
+  late final _func5Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<shortHand>,
+              ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>>('func5');
+  late final _func5 = _func5Ptr.asFunction<
+      void Function(ffi.Pointer<shortHand>,
+          ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>();
+
+  void externInlineFunc(
+    int a,
+  ) {
+    return _externInlineFunc(
+      a,
+    );
+  }
+
+  late final _externInlineFuncPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int)>>(
+          'externInlineFunc');
+  late final _externInlineFunc =
+      _externInlineFuncPtr.asFunction<void Function(int)>();
+
+  int diffChars(
+    int a,
+    int b,
+  ) {
+    return _diffChars(
+      a,
+      b,
+    );
+  }
+
+  late final _diffCharsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Char Function(ffi.UnsignedChar, ffi.SignedChar)>>('diffChars');
+  late final _diffChars = _diffCharsPtr.asFunction<int Function(int, int)>();
+
+  late final addresses = _SymbolAddresses(this);
+}
+
+class _SymbolAddresses {
+  final NativeLibrary _library;
+  _SymbolAddresses(this._library);
+  ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Double Function(ffi.Float, ffi.Int8, ffi.Int64, ffi.Int32)>>
+      get func3 => _library._func3Ptr;
+  ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Pointer<ffi.Int8>>,
+              ffi.Double,
+              ffi.Pointer<ffi.Pointer<ffi.Pointer<ffi.Int32>>>)>> get func4 =>
+      _library._func4Ptr;
+}
+
+typedef shortHand = ffi.NativeFunction<
+    ffi.Void Function(ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> b)>;
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_imported_types_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_imported_types_bindings.dart
new file mode 100644
index 0000000..ab0fc5a
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_imported_types_bindings.dart
@@ -0,0 +1,82 @@
+// ignore_for_file: camel_case_types
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Imported types test
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void default_imported_types(
+    int arg0,
+    int arg1,
+    int arg2,
+    int arg3,
+    int arg4,
+    int arg5,
+    int arg6,
+    int arg7,
+    int arg8,
+    int arg9,
+    int arg10,
+    double arg11,
+    double arg12,
+    int arg13,
+    int arg14,
+  ) {
+    return _default_imported_types(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+      arg4,
+      arg5,
+      arg6,
+      arg7,
+      arg8,
+      arg9,
+      arg10,
+      arg11,
+      arg12,
+      arg13,
+      arg14,
+    );
+  }
+
+  late final _default_imported_typesPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.UnsignedChar,
+              ffi.SignedChar,
+              ffi.Char,
+              ffi.UnsignedShort,
+              ffi.Short,
+              ffi.UnsignedInt,
+              ffi.Int,
+              ffi.UnsignedLong,
+              ffi.Long,
+              ffi.UnsignedLongLong,
+              ffi.LongLong,
+              ffi.Float,
+              ffi.Double,
+              ffi.Size,
+              ffi.WChar)>>('default_imported_types');
+  late final _default_imported_types = _default_imported_typesPtr.asFunction<
+      void Function(int, int, int, int, int, int, int, int, int, int, int,
+          double, double, int, int)>();
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_native_func_typedef_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_native_func_typedef_bindings.dart
new file mode 100644
index 0000000..b3063c4
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_native_func_typedef_bindings.dart
@@ -0,0 +1,90 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Native Func Typedef Test.
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void func(
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(
+                    ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>
+                        unnamed2)>>
+        unnamed1,
+  ) {
+    return _func(
+      unnamed1,
+    );
+  }
+
+  late final _funcPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>
+                              unnamed2)>>)>>('func');
+  late final _func = _funcPtr.asFunction<
+      void Function(
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>
+                          unnamed2)>>)>();
+
+  void funcWithNativeFunc(
+    WithTypedefReturnType named,
+  ) {
+    return _funcWithNativeFunc(
+      named,
+    );
+  }
+
+  late final _funcWithNativeFuncPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(WithTypedefReturnType)>>(
+          'funcWithNativeFunc');
+  late final _funcWithNativeFunc =
+      _funcWithNativeFuncPtr.asFunction<void Function(WithTypedefReturnType)>();
+}
+
+final class Struct extends ffi.Struct {
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>
+                  unnamed2)>> unnamed1;
+}
+
+typedef WithTypedefReturnType
+    = ffi.Pointer<ffi.NativeFunction<WithTypedefReturnTypeFunction>>;
+typedef WithTypedefReturnTypeFunction = InsideReturnType Function();
+typedef InsideReturnType
+    = ffi.Pointer<ffi.NativeFunction<InsideReturnTypeFunction>>;
+typedef InsideReturnTypeFunction = ffi.Void Function();
+typedef DartInsideReturnTypeFunction = void Function();
+
+final class Struct2 extends ffi.Struct {
+  external VoidFuncPointer constFuncPointer;
+}
+
+typedef VoidFuncPointer
+    = ffi.Pointer<ffi.NativeFunction<VoidFuncPointerFunction>>;
+typedef VoidFuncPointerFunction = ffi.Void Function();
+typedef DartVoidFuncPointerFunction = void Function();
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_opaque_dependencies_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_opaque_dependencies_bindings.dart
new file mode 100644
index 0000000..6481420
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_opaque_dependencies_bindings.dart
@@ -0,0 +1,86 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Opaque Dependencies Test
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  ffi.Pointer<BAlias> func(
+    ffi.Pointer<A> a,
+  ) {
+    return _func(
+      a,
+    );
+  }
+
+  late final _funcPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<BAlias> Function(ffi.Pointer<A>)>>(
+          'func');
+  late final _func =
+      _funcPtr.asFunction<ffi.Pointer<BAlias> Function(ffi.Pointer<A>)>();
+
+  ffi.Pointer<UB> func2(
+    ffi.Pointer<UA> a,
+  ) {
+    return _func2(
+      a,
+    );
+  }
+
+  late final _func2Ptr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<UB> Function(ffi.Pointer<UA>)>>(
+          'func2');
+  late final _func2 =
+      _func2Ptr.asFunction<ffi.Pointer<UB> Function(ffi.Pointer<UA>)>();
+}
+
+typedef BAlias = B;
+
+final class B extends ffi.Opaque {}
+
+final class A extends ffi.Opaque {}
+
+final class E extends ffi.Struct {
+  external ffi.Pointer<C> c;
+
+  external D d;
+}
+
+final class C extends ffi.Opaque {}
+
+final class D extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+final class UB extends ffi.Opaque {}
+
+final class UA extends ffi.Opaque {}
+
+final class UE extends ffi.Union {
+  external ffi.Pointer<UC> c;
+
+  external UD d;
+}
+
+final class UC extends ffi.Opaque {}
+
+final class UD extends ffi.Union {
+  @ffi.Int()
+  external int a;
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_packed_structs_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_packed_structs_bindings.dart
new file mode 100644
index 0000000..dc2ea75
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_packed_structs_bindings.dart
@@ -0,0 +1,50 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+final class NormalStruct1 extends ffi.Struct {
+  @ffi.Char()
+  external int a;
+}
+
+/// Should not be packed.
+final class StructWithAttr extends ffi.Struct {
+  external ffi.Pointer<ffi.Int> a;
+
+  external ffi.Pointer<ffi.Int> b;
+}
+
+/// Should be packed with 1.
+@ffi.Packed(1)
+final class PackedAttr extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+/// Should be packed with 8.
+@ffi.Packed(8)
+final class PackedAttrAlign8 extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+/// Should be packed with 2.
+@ffi.Packed(2)
+final class Pack2WithPragma extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+/// Should be packed with 4.
+@ffi.Packed(4)
+final class Pack4WithPragma extends ffi.Struct {
+  @ffi.LongLong()
+  external int a;
+}
+
+final class NormalStruct2 extends ffi.Struct {
+  @ffi.Char()
+  external int a;
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_regress_384_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_regress_384_bindings.dart
new file mode 100644
index 0000000..ab9ec8f
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_regress_384_bindings.dart
@@ -0,0 +1,29 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Regression test for #384
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void foo() {
+    return _foo();
+  }
+
+  late final _fooPtr = _lookup<ffi.NativeFunction<ffi.Void Function()>>('foo');
+  late final _foo = _fooPtr.asFunction<void Function()>();
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_struct_fptr_fields_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_struct_fptr_fields_bindings.dart
new file mode 100644
index 0000000..f5af81f
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_struct_fptr_fields_bindings.dart
@@ -0,0 +1,74 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+final class S extends ffi.Struct {
+  external ffi.Pointer<ffi.NativeFunction<ffi.Int Function()>> func1;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Int a, ffi.Int b)>>
+      comparator;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Double a, ffi.Float b, ffi.Pointer<ffi.Char> c,
+              ffi.Int d, ffi.LongLong e)>> veryManyArguments;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Int, ffi.Int, ffi.Int, ffi.Float, ffi.Pointer<ffi.Char>)>>
+      argsDontHaveNames;
+
+  external ArithmeticOperation operation;
+
+  external ffi.Pointer<
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Void Function(ffi.Pointer<ffi.Int> array, ffi.Int len)>>>
+      sortPtr;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<ffi.Int> array,
+              ffi.Int len,
+              ffi.Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Int x)>>
+                  evaluator)>> sortBy;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Void Function(ffi.Int, ffi.Int, ffi.Char)>>
+      improperlyDeclaredParams;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<ffi.Int> array,
+              ffi.Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Int x)>>
+                  primaryEvaluator,
+              ffi.Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Int x)>>
+                  fallbackEvaluator)>> sortByWithFallback;
+
+  @ffi.Array.multi([2])
+  external ffi.Array<
+          ffi
+          .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Char, ffi.Char)>>>
+      manyFunctions;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Int, ffi.Int)>>
+              Function(ffi.Int, ffi.Int)>> functionReturningFunction;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Int, ffi.Int)>>
+              Function(ffi.Int, ffi.Int)>> functionReturningFunctionImproper;
+}
+
+typedef ArithmeticOperation
+    = ffi.Pointer<ffi.NativeFunction<ArithmeticOperationFunction>>;
+typedef ArithmeticOperationFunction = ffi.Int Function(ffi.Int a, ffi.Int b);
+typedef DartArithmeticOperationFunction = int Function(int a, int b);
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_typedef_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_typedef_bindings.dart
new file mode 100644
index 0000000..a33e9c8
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_typedef_bindings.dart
@@ -0,0 +1,124 @@
+// ignore_for_file: unused_element, unused_field
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Typedef Test
+class Bindings {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  Bindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  Bindings.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  NamedFunctionProto func1(
+    NamedFunctionProto named,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Int)>> unnamed,
+  ) {
+    return _func1(
+      named,
+      unnamed,
+    );
+  }
+
+  late final _func1Ptr = _lookup<
+      ffi.NativeFunction<
+          NamedFunctionProto Function(
+              NamedFunctionProto,
+              ffi.Pointer<
+                  ffi.NativeFunction<ffi.Void Function(ffi.Int)>>)>>('func1');
+  late final _func1 = _func1Ptr.asFunction<
+      NamedFunctionProto Function(NamedFunctionProto,
+          ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Int)>>)>();
+
+  void func2(
+    ffi.Pointer<NTyperef1> arg0,
+  ) {
+    return _func2(
+      arg0,
+    );
+  }
+
+  late final _func2Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<NTyperef1>)>>(
+          'func2');
+  late final _func2 =
+      _func2Ptr.asFunction<void Function(ffi.Pointer<NTyperef1>)>();
+
+  void func3(
+    int arg0,
+    int b,
+  ) {
+    return _func3(
+      arg0,
+      b,
+    );
+  }
+
+  late final _func3Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.IntPtr, NestingASpecifiedType)>>('func3');
+  late final _func3 = _func3Ptr.asFunction<void Function(int, int)>();
+
+  bool func4(
+    ffi.Pointer<ffi.Bool> a,
+  ) {
+    return _func4(
+      a,
+    );
+  }
+
+  late final _func4Ptr =
+      _lookup<ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<ffi.Bool>)>>(
+          'func4');
+  late final _func4 =
+      _func4Ptr.asFunction<bool Function(ffi.Pointer<ffi.Bool>)>();
+}
+
+final class Struct1 extends ffi.Struct {
+  external NamedFunctionProto named;
+
+  external ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> unnamed;
+}
+
+typedef NamedFunctionProto
+    = ffi.Pointer<ffi.NativeFunction<NamedFunctionProtoFunction>>;
+typedef NamedFunctionProtoFunction = ffi.Void Function();
+typedef DartNamedFunctionProtoFunction = void Function();
+
+final class AnonymousStructInTypedef extends ffi.Opaque {}
+
+final class _NamedStructInTypedef extends ffi.Opaque {}
+
+typedef NTyperef1 = ExcludedStruct;
+typedef ExcludedStruct = _ExcludedStruct;
+
+final class _ExcludedStruct extends ffi.Opaque {}
+
+abstract class AnonymousEnumInTypedef {
+  static const int a = 0;
+}
+
+abstract class _NamedEnumInTypedef {
+  static const int b = 0;
+}
+
+typedef NestingASpecifiedType = ffi.IntPtr;
+typedef DartNestingASpecifiedType = int;
+
+final class Struct2 extends ffi.Opaque {}
+
+final class WithBoolAlias extends ffi.Struct {
+  @ffi.Bool()
+  external bool b;
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_unions_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_unions_bindings.dart
new file mode 100644
index 0000000..9ef50eb
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_unions_bindings.dart
@@ -0,0 +1,83 @@
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Unions Test
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  void func1(
+    ffi.Pointer<Union2> s,
+  ) {
+    return _func1(
+      s,
+    );
+  }
+
+  late final _func1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<Union2>)>>(
+          'func1');
+  late final _func1 =
+      _func1Ptr.asFunction<void Function(ffi.Pointer<Union2>)>();
+
+  void func2(
+    ffi.Pointer<Union3> s,
+  ) {
+    return _func2(
+      s,
+    );
+  }
+
+  late final _func2Ptr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<Union3>)>>(
+          'func2');
+  late final _func2 =
+      _func2Ptr.asFunction<void Function(ffi.Pointer<Union3>)>();
+}
+
+final class Union1 extends ffi.Union {
+  @ffi.Int()
+  external int a;
+}
+
+final class Union2 extends ffi.Union {
+  external Union1 a;
+}
+
+final class Union3 extends ffi.Opaque {}
+
+final class Union4 extends ffi.Opaque {}
+
+final class Union5 extends ffi.Opaque {}
+
+final class Union6 extends ffi.Union {
+  external UnnamedUnion1 unnamed;
+
+  external UnnamedUnion2 unnamed1;
+}
+
+final class UnnamedUnion1 extends ffi.Union {
+  @ffi.Float()
+  external double a;
+}
+
+final class UnnamedUnion2 extends ffi.Union {
+  @ffi.Float()
+  external double b;
+}
+
+final class Union7 extends ffi.Opaque {}
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_varargs_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_varargs_bindings.dart
new file mode 100644
index 0000000..5b51bcd
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_varargs_bindings.dart
@@ -0,0 +1,196 @@
+// ignore_for_file: camel_case_types
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// VarArgs Test
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  int myfunc(
+    int a,
+    int va,
+    ffi.Pointer<ffi.Char> va1,
+    SA va2,
+  ) {
+    return _myfunc(
+      a,
+      va,
+      va1,
+      va2,
+    );
+  }
+
+  late final _myfuncPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Int,
+              ffi.VarArgs<
+                  (
+                    ffi.Int,
+                    ffi.Pointer<ffi.Char>,
+                    SA,
+                  )>)>>('myfunc');
+  late final _myfunc = _myfuncPtr
+      .asFunction<int Function(int, int, ffi.Pointer<ffi.Char>, SA)>();
+
+  void myfunc2CharPtrLongPtrPtr(
+    int a,
+    int b,
+    ffi.Pointer<ffi.Char> va,
+    ffi.Pointer<ffi.Pointer<ffi.Long>> va1,
+  ) {
+    return _myfunc2CharPtrLongPtrPtr(
+      a,
+      b,
+      va,
+      va1,
+    );
+  }
+
+  late final _myfunc2CharPtrLongPtrPtrPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Char,
+              ffi.Char,
+              ffi.VarArgs<
+                  (
+                    ffi.Pointer<ffi.Char>,
+                    ffi.Pointer<ffi.Pointer<ffi.Long>>,
+                  )>)>>('myfunc2');
+  late final _myfunc2CharPtrLongPtrPtr =
+      _myfunc2CharPtrLongPtrPtrPtr.asFunction<
+          void Function(int, int, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Long>>)>();
+
+  void myfunc2SAIntPtrUnsignedcharPtrPtr(
+    int a,
+    int b,
+    SA va,
+    ffi.Pointer<ffi.Int> va1,
+    ffi.Pointer<ffi.Pointer<ffi.UnsignedChar>> va2,
+  ) {
+    return _myfunc2SAIntPtrUnsignedcharPtrPtr(
+      a,
+      b,
+      va,
+      va1,
+      va2,
+    );
+  }
+
+  late final _myfunc2SAIntPtrUnsignedcharPtrPtrPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Char,
+              ffi.Char,
+              ffi.VarArgs<
+                  (
+                    SA,
+                    ffi.Pointer<ffi.Int>,
+                    ffi.Pointer<ffi.Pointer<ffi.UnsignedChar>>,
+                  )>)>>('myfunc2');
+  late final _myfunc2SAIntPtrUnsignedcharPtrPtr =
+      _myfunc2SAIntPtrUnsignedcharPtrPtrPtr.asFunction<
+          void Function(int, int, SA, ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Pointer<ffi.UnsignedChar>>)>();
+
+  void myfunc2_custompostfix(
+    int a,
+    int b,
+    SA va,
+    ffi.Pointer<ffi.Int> va1,
+    ffi.Pointer<ffi.Pointer<ffi.UnsignedChar>> va2,
+  ) {
+    return _myfunc2_custompostfix(
+      a,
+      b,
+      va,
+      va1,
+      va2,
+    );
+  }
+
+  late final _myfunc2_custompostfixPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Char,
+              ffi.Char,
+              ffi.VarArgs<
+                  (
+                    SA,
+                    ffi.Pointer<ffi.Int>,
+                    ffi.Pointer<ffi.Pointer<ffi.UnsignedChar>>,
+                  )>)>>('myfunc2');
+  late final _myfunc2_custompostfix = _myfunc2_custompostfixPtr.asFunction<
+      void Function(int, int, SA, ffi.Pointer<ffi.Int>,
+          ffi.Pointer<ffi.Pointer<ffi.UnsignedChar>>)>();
+
+  void myfunc3Struct_WithLong_Name_testPtrFloatPtr(
+    int a,
+    ffi.Pointer<Struct_WithLong_Name_test> va,
+    ffi.Pointer<ffi.Float> va1,
+  ) {
+    return _myfunc3Struct_WithLong_Name_testPtrFloatPtr(
+      a,
+      va,
+      va1,
+    );
+  }
+
+  late final _myfunc3Struct_WithLong_Name_testPtrFloatPtrPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Long,
+              ffi.VarArgs<
+                  (
+                    ffi.Pointer<Struct_WithLong_Name_test>,
+                    ffi.Pointer<ffi.Float>,
+                  )>)>>('myfunc3');
+  late final _myfunc3Struct_WithLong_Name_testPtrFloatPtr =
+      _myfunc3Struct_WithLong_Name_testPtrFloatPtrPtr.asFunction<
+          void Function(int, ffi.Pointer<Struct_WithLong_Name_test>,
+              ffi.Pointer<ffi.Float>)>();
+
+  void myfunc3_custompostfix2(
+    int a,
+    Struct_WithLong_Name_test va,
+  ) {
+    return _myfunc3_custompostfix2(
+      a,
+      va,
+    );
+  }
+
+  late final _myfunc3_custompostfix2Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Long, ffi.VarArgs<(Struct_WithLong_Name_test,)>)>>('myfunc3');
+  late final _myfunc3_custompostfix2 = _myfunc3_custompostfix2Ptr
+      .asFunction<void Function(int, Struct_WithLong_Name_test)>();
+}
+
+final class SA extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
+
+final class Struct_WithLong_Name_test extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/forward_decl.h b/pkgs/ffigen/test/header_parser_tests/forward_decl.h
new file mode 100644
index 0000000..9e669aa
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/forward_decl.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+struct A;
+enum B;
+
+void func(struct A *a, enum B b);
+
+struct A
+{
+    int a;
+    int b;
+};
+
+enum B
+{
+    a,
+    b
+};
diff --git a/pkgs/ffigen/test/header_parser_tests/forward_decl_test.dart b/pkgs/ffigen/test/header_parser_tests/forward_decl_test.dart
new file mode 100644
index 0000000..73b9f32
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/forward_decl_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual;
+void main() {
+  group('forward_decl_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Forward Declaration Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/forward_decl.h'
+        '''),
+      );
+    });
+
+    test('Expected bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_forward_decl_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_forward_decl_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/function_n_struct.h b/pkgs/ffigen/test/header_parser_tests/function_n_struct.h
new file mode 100644
index 0000000..b3c43a7
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/function_n_struct.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+struct Struct1
+{
+    int a;
+};
+
+struct Struct2
+{
+    struct Struct1 a;
+};
+
+// All members should be removed, Flexible array members are not supported.
+struct Struct3
+{
+    int a;
+    int b[]; // Flexible array member.
+};
+
+// All members should be removed, Bit fields are not supported.
+struct Struct4
+{
+    int a : 3;
+    int : 2; // Unnamed bit field.
+};
+
+// All members should be removed, Incomplete struct members are not supported.
+struct Struct5
+{
+    int a;
+    struct Struct3 s; // Incomplete nested struct.
+};
+
+typedef int arr10[10];
+
+struct Struct6
+{
+    arr10 a[2];
+};
+
+// All members should be removed, Zero-length arrays are equivalent to
+// flexible arrays members (by an extension) are not supported.
+struct Struct7
+{
+    int a;
+    int b[0]; // Flexible array member.
+};
+
+void func1(struct Struct2 *s);
+
+// Incomplete array parameter will be treated as a pointer.
+void func2(struct Struct3 s[]);
+
+void func3(arr10 a);
diff --git a/pkgs/ffigen/test/header_parser_tests/function_n_struct_test.dart b/pkgs/ffigen/test/header_parser_tests/function_n_struct_test.dart
new file mode 100644
index 0000000..5ddd58a
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/function_n_struct_test.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('function_n_struct_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      expected = expectedLibrary();
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Function And Struct Test'
+${strings.output}: 'unused'
+
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/function_n_struct.h'
+        '''),
+      );
+    });
+
+    test('Total bindings count', () {
+      expect(actual.bindings.length, expected.bindings.length);
+    });
+    test('func1 struct pointer parameter', () {
+      expect(actual.getBindingAsString('func1'),
+          expected.getBindingAsString('func1'));
+    });
+    test('func2 incomplete array parameter', () {
+      expect(actual.getBindingAsString('func2'),
+          expected.getBindingAsString('func2'));
+    });
+    test('Struct2 nested struct member', () {
+      expect(actual.getBindingAsString('Struct2'),
+          expected.getBindingAsString('Struct2'));
+    });
+    test('Struct3 flexible array member', () {
+      expect((actual.getBinding('Struct3') as Struct).members.isEmpty, true);
+    });
+    test('Struct4 bit field member', () {
+      expect((actual.getBinding('Struct4') as Struct).members.isEmpty, true);
+    });
+    test('Struct5 incompleted struct member', () {
+      expect((actual.getBinding('Struct5') as Struct).members.isEmpty, true);
+    });
+    test('Struct6 typedef constant array', () {
+      expect(actual.getBindingAsString('Struct6'),
+          expected.getBindingAsString('Struct6'));
+    });
+    test('Struct7 zero length array (extension on flexible array member)', () {
+      expect((actual.getBinding('Struct7') as Struct).members.isEmpty, true);
+    });
+    test('func3 constant typedef array parameter', () {
+      expect(actual.getBindingAsString('func3'),
+          expected.getBindingAsString('func3'));
+    });
+  });
+}
+
+Library expectedLibrary() {
+  final struct1 = Struct(name: 'Struct1', members: [
+    Member(
+      name: 'a',
+      type: intType,
+    ),
+  ]);
+  final struct2 = Struct(name: 'Struct2', members: [
+    Member(
+      name: 'a',
+      type: struct1,
+    ),
+  ]);
+  final struct3 = Struct(name: 'Struct3');
+  return Library(
+    name: 'Bindings',
+    bindings: [
+      struct1,
+      struct2,
+      struct3,
+      Func(
+        name: 'func1',
+        parameters: [
+          Parameter(name: 's', type: PointerType(struct2)),
+        ],
+        returnType: NativeType(
+          SupportedNativeType.Void,
+        ),
+      ),
+      Func(
+        name: 'func2',
+        parameters: [
+          Parameter(name: 's', type: PointerType(struct3)),
+        ],
+        returnType: NativeType(
+          SupportedNativeType.Void,
+        ),
+      ),
+      Func(
+        name: 'func3',
+        parameters: [
+          Parameter(name: 'a', type: PointerType(intType)),
+        ],
+        returnType: NativeType(
+          SupportedNativeType.Void,
+        ),
+      ),
+      Struct(name: 'Struct4'),
+      Struct(name: 'Struct5'),
+      Struct(name: 'Struct6', members: [
+        Member(name: 'a', type: ConstantArray(2, ConstantArray(10, intType)))
+      ]),
+      Struct(name: 'Struct7'),
+    ],
+  );
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/functions.h b/pkgs/ffigen/test/header_parser_tests/functions.h
new file mode 100644
index 0000000..9cf6a3b
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/functions.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdint.h>
+
+// Simple tests with primitives.
+void func1();
+int32_t func2(int16_t);
+double func3(float, int8_t a, int64_t, int32_t b);
+
+// Tests with pointers to primitives.
+void *func4(int8_t **, double, int32_t ***);
+
+// Would be treated as `typedef void shortHand(void (*b)())`.
+typedef void shortHand(void(b)());
+// Would be treated as `void func5(shortHand *a, void (*b)())`.
+void func5(shortHand a, void(b)());
+
+// Should be skipped as inline functions are not supported.
+static inline void inlineFunc();
+
+// Not skipped since it is extern.
+extern inline void externInlineFunc(int a);
+
+char diffChars(unsigned char a, signed char b);
diff --git a/pkgs/ffigen/test/header_parser_tests/functions_test.dart b/pkgs/ffigen/test/header_parser_tests/functions_test.dart
new file mode 100644
index 0000000..97685b0
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/functions_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('functions_test', () {
+    setUpAll(() {
+      logWarnings();
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Functions Test'
+${strings.output}: 'unused'
+
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/functions.h'
+  ${strings.includeDirectives}:
+    - '**functions.h'
+
+${strings.functions}:
+  ${strings.symbolAddress}:
+    ${strings.include}:
+      - func3
+      - func4
+  ${strings.leafFunctions}:
+    ${strings.include}:
+      - func1
+
+${strings.preamble}: |
+  // ignore_for_file: camel_case_types
+        '''),
+      );
+    });
+    test('Expected Bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_functions_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_functions_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/globals.h b/pkgs/ffigen/test/header_parser_tests/globals.h
new file mode 100644
index 0000000..5ce3fc5
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/globals.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdint.h>
+#include <stdbool.h>
+
+bool coolGlobal;
+int32_t myInt;
+int32_t *aGlobalPointer;
+long double longDouble;
+long double *pointerToLongDouble;
+
+// This should be ignored
+int GlobalIgnore;
+
+struct EmptyStruct
+{
+};
+
+struct EmptyStruct globalStruct;
+
+typedef struct EmptyStruct EmptyStruct_Alias;
+EmptyStruct_Alias globalStruct_from_alias;
diff --git a/pkgs/ffigen/test/header_parser_tests/globals_test.dart b/pkgs/ffigen/test/header_parser_tests/globals_test.dart
new file mode 100644
index 0000000..55184a8
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/globals_test.dart
@@ -0,0 +1,98 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('globals_test', () {
+    setUpAll(() {
+      logWarnings();
+      expected = expectedLibrary();
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Globals Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/globals.h'
+  ${strings.includeDirectives}:
+    - '**globals.h'
+${strings.globals}:
+  ${strings.exclude}:
+    - GlobalIgnore
+  ${strings.symbolAddress}:
+    ${strings.include}:
+      - myInt
+      - pointerToLongDouble
+      - globalStruct
+${strings.compilerOpts}: '-Wno-nullability-completeness'
+        '''),
+      );
+    });
+
+    test('Total bindings count', () {
+      expect(actual.bindings.length, expected.bindings.length);
+    });
+
+    test('Parse global Values', () {
+      expect(actual.getBindingAsString('coolGlobal'),
+          expected.getBindingAsString('coolGlobal'));
+      expect(actual.getBindingAsString('myInt'),
+          expected.getBindingAsString('myInt'));
+      expect(actual.getBindingAsString('aGlobalPointer'),
+          expected.getBindingAsString('aGlobalPointer'));
+    });
+
+    test('Ignore global values', () {
+      expect(() => actual.getBindingAsString('GlobalIgnore'),
+          throwsA(TypeMatcher<NotFoundException>()));
+      expect(() => actual.getBindingAsString('longDouble'),
+          throwsA(TypeMatcher<NotFoundException>()));
+      expect(() => actual.getBindingAsString('pointerToLongDouble'),
+          throwsA(TypeMatcher<NotFoundException>()));
+    });
+  });
+}
+
+Library expectedLibrary() {
+  final globalStruct = Struct(name: 'EmptyStruct');
+  return Library(
+    name: 'Bindings',
+    bindings: [
+      Global(type: BooleanType(), name: 'coolGlobal'),
+      Global(
+        type: NativeType(SupportedNativeType.Int32),
+        name: 'myInt',
+        exposeSymbolAddress: true,
+      ),
+      Global(
+        type: PointerType(NativeType(SupportedNativeType.Int32)),
+        name: 'aGlobalPointer',
+        exposeSymbolAddress: true,
+      ),
+      globalStruct,
+      Global(
+        name: 'globalStruct',
+        type: globalStruct,
+        exposeSymbolAddress: true,
+      ),
+      Global(
+        name: 'globalStruct_from_alias',
+        type: Typealias(
+          name: 'EmptyStruct_Alias',
+          type: globalStruct,
+        ),
+        exposeSymbolAddress: true,
+      )
+    ],
+  );
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/imported_types.h b/pkgs/ffigen/test/header_parser_tests/imported_types.h
new file mode 100644
index 0000000..685e47c
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/imported_types.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stddef.h>
+
+void default_imported_types(
+  unsigned char,
+  signed char,
+  char,
+  unsigned short,
+  short,
+  unsigned int,
+  int,
+  unsigned long,
+  long,
+  unsigned long long,
+  long long,
+  float,
+  double,
+  size_t,
+  wchar_t
+);
diff --git a/pkgs/ffigen/test/header_parser_tests/imported_types_test.dart b/pkgs/ffigen/test/header_parser_tests/imported_types_test.dart
new file mode 100644
index 0000000..fc02cff
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/imported_types_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('imported_types_test', () {
+    setUpAll(() {
+      logWarnings();
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Imported types test'
+${strings.output}: 'unused'
+
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/imported_types.h'
+  ${strings.includeDirectives}:
+    - '**imported_types.h'
+
+${strings.preamble}: |
+  // ignore_for_file: camel_case_types
+        '''),
+      );
+    });
+    test('Expected Bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_imported_types_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_imported_types_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/macros.h b/pkgs/ffigen/test/header_parser_tests/macros.h
new file mode 100644
index 0000000..5cae837
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/macros.h
@@ -0,0 +1,45 @@
+#include<math.h>
+
+#define TEST1 1.1
+#define TEST2 10
+#define TEST3 (TEST1 + TEST2)
+#define TEST4 "test"
+
+// The comma operator should actually return the last value (3),
+// when returned by a function. This value, however, when assigned to a variable
+// will not compile and so libclang tries to fix it and assigns the first
+// value (4) to the generated macro variable.
+#define TEST5 4, \
+              2, \
+              3
+#define TEST6 (1 == 1);
+#define TEST7(x, y) x *y
+
+#define TEST8 5,2,3
+
+// These test that special characters are escaped properly.
+#define TEST9 "$dollar"
+#define TEST10 "test's"
+
+// These test that extended ASCII and control characters are handled properly.
+#define TEST11 "\x80"
+#define TEST12 "hello\n\t\r\v\b"
+#define TEST13 "test\\"
+
+// Infinity, NaN and Negative Infinity.
+#define TEST14 INFINITY
+#define TEST15 -INFINITY
+#define TEST16 NAN
+
+
+// Inside include guard.
+#ifndef __TEST_INCLUDE_GUARD_1__
+#define __TEST_INCLUDE_GUARD_1__
+
+#define TEST17 TEST_FUNCTION_MACRO(0)
+#define TEST18 TEST_FUNCTION_MACRO(1)
+#define TEST19 TEST_FUNCTION_MACRO(2)
+
+#define TEST_FUNCTION_MACRO(x) ((unsigned long)((x) << (2)))
+
+#endif /* __TEST_INCLUDE_GUARD_1__ */
diff --git a/pkgs/ffigen/test/header_parser_tests/macros_test.dart b/pkgs/ffigen/test/header_parser_tests/macros_test.dart
new file mode 100644
index 0000000..70439ef
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/macros_test.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('macros_test', () {
+    setUpAll(() {
+      logWarnings(Level.WARNING);
+      expected = expectedLibrary();
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Macros Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/macros.h'
+  ${strings.includeDirectives}:
+    - '**macros.h'
+        '''),
+      );
+    });
+    test('Total bindings count', () {
+      expect(actual.bindings.length, expected.bindings.length);
+    });
+
+    test('TEST1', () {
+      expect(actual.getBindingAsString('TEST1'),
+          expected.getBindingAsString('TEST1'));
+    });
+    test('TEST2', () {
+      expect(actual.getBindingAsString('TEST2'),
+          expected.getBindingAsString('TEST2'));
+    });
+    test('TEST3', () {
+      expect(actual.getBindingAsString('TEST3'),
+          expected.getBindingAsString('TEST3'));
+    });
+
+    test('TEST4', () {
+      expect(actual.getBindingAsString('TEST4'),
+          expected.getBindingAsString('TEST4'));
+    });
+
+    test('TEST5', () {
+      expect(actual.getBindingAsString('TEST5'),
+          expected.getBindingAsString('TEST5'));
+    });
+    test('TEST6', () {
+      expect(actual.getBindingAsString('TEST6'),
+          expected.getBindingAsString('TEST6'));
+    });
+    test('TEST8', () {
+      expect(actual.getBindingAsString('TEST8'),
+          expected.getBindingAsString('TEST8'));
+    });
+    test('TEST9', () {
+      expect(actual.getBindingAsString('TEST9'),
+          expected.getBindingAsString('TEST9'));
+    });
+    test('TEST10', () {
+      expect(actual.getBindingAsString('TEST10'),
+          expected.getBindingAsString('TEST10'));
+    });
+    test('TEST11', () {
+      expect(actual.getBindingAsString('TEST11'),
+          expected.getBindingAsString('TEST11'));
+    });
+    test('TEST12', () {
+      expect(actual.getBindingAsString('TEST12'),
+          expected.getBindingAsString('TEST12'));
+    });
+    test('TEST13', () {
+      expect(actual.getBindingAsString('TEST13'),
+          expected.getBindingAsString('TEST13'));
+    });
+    test('TEST14', () {
+      expect(actual.getBindingAsString('TEST14'),
+          expected.getBindingAsString('TEST14'));
+    });
+    test('TEST15', () {
+      expect(actual.getBindingAsString('TEST15'),
+          expected.getBindingAsString('TEST15'));
+    });
+    test('TEST16', () {
+      expect(actual.getBindingAsString('TEST16'),
+          expected.getBindingAsString('TEST16'));
+    });
+    test('TEST17', () {
+      expect(actual.getBindingAsString('TEST17'),
+          expected.getBindingAsString('TEST17'));
+    });
+    test('TEST18', () {
+      expect(actual.getBindingAsString('TEST18'),
+          expected.getBindingAsString('TEST18'));
+    });
+    test('TEST19', () {
+      expect(actual.getBindingAsString('TEST19'),
+          expected.getBindingAsString('TEST19'));
+    });
+  });
+}
+
+Library expectedLibrary() {
+  return Library(
+    name: 'NativeLibrary',
+    bindings: [
+      Constant(name: 'TEST1', rawType: 'double', rawValue: '1.1'),
+      Constant(name: 'TEST2', rawType: 'int', rawValue: '10'),
+      Constant(name: 'TEST3', rawType: 'double', rawValue: '11.1'),
+      Constant(name: 'TEST4', rawType: 'String', rawValue: "'test'"),
+      Constant(name: 'TEST5', rawType: 'int', rawValue: '4'),
+      Constant(name: 'TEST6', rawType: 'int', rawValue: '1'),
+      Constant(name: 'TEST8', rawType: 'int', rawValue: '5'),
+      Constant(name: 'TEST9', rawType: 'String', rawValue: r"'\$dollar'"),
+      Constant(name: 'TEST10', rawType: 'String', rawValue: r"'test\'s'"),
+      Constant(name: 'TEST11', rawType: 'String', rawValue: r"'\x80'"),
+      Constant(
+          name: 'TEST12', rawType: 'String', rawValue: r"'hello\n\t\r\v\b'"),
+      Constant(name: 'TEST13', rawType: 'String', rawValue: r"'test\\'"),
+      Constant(
+          name: 'TEST14', rawType: 'double', rawValue: strings.doubleInfinity),
+      Constant(
+          name: 'TEST15',
+          rawType: 'double',
+          rawValue: strings.doubleNegativeInfinity),
+      Constant(name: 'TEST16', rawType: 'double', rawValue: strings.doubleNaN),
+      Constant(name: 'TEST17', rawType: 'int', rawValue: "0"),
+      Constant(name: 'TEST18', rawType: 'int', rawValue: "4"),
+      Constant(name: 'TEST19', rawType: 'int', rawValue: "8"),
+    ],
+  );
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/native_func_typedef.h b/pkgs/ffigen/test/header_parser_tests/native_func_typedef.h
new file mode 100644
index 0000000..0c6f7a0
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/native_func_typedef.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+struct Struct
+{
+    void (*unnamed1)(void (*unnamed2)());
+};
+
+void func(void (*unnamed1)(void (*unnamed2)()));
+
+// This will be removed because 'long double' is unsupported.
+void funcNestedUnimplemented(void (*unnamed1)(void (*unnamed2)(long double)));
+
+typedef void (*InsideReturnType)();
+typedef InsideReturnType (*WithTypedefReturnType)();
+void funcWithNativeFunc(WithTypedefReturnType named);
+
+typedef void (*VoidFuncPointer)();
+struct Struct2{
+    const VoidFuncPointer constFuncPointer;
+};
diff --git a/pkgs/ffigen/test/header_parser_tests/native_func_typedef_test.dart b/pkgs/ffigen/test/header_parser_tests/native_func_typedef_test.dart
new file mode 100644
index 0000000..180ff4d
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/native_func_typedef_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual;
+void main() {
+  group('native_func_typedef_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Native Func Typedef Test.'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/native_func_typedef.h'
+        '''),
+      );
+    });
+
+    test('Remove deeply nested unsupported types', () {
+      expect(() => actual.getBindingAsString('funcNestedUnimplemented'),
+          throwsA(TypeMatcher<NotFoundException>()));
+    });
+
+    test('Expected bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_native_func_typedef_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_native_func_typedef_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/nested_parsing.h b/pkgs/ffigen/test/header_parser_tests/nested_parsing.h
new file mode 100644
index 0000000..8557b64
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/nested_parsing.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+struct Struct2
+{
+    int e;
+    int f;
+};
+
+struct Struct1
+{
+    int a;
+    int b;
+    struct Struct2 *struct2;
+};
+
+struct Struct3
+{
+    int a;
+    // An unnamed struct.
+    struct
+    {
+        int a;
+        int b;
+    } b;
+};
+
+struct EmptyStruct{
+};
+
+struct Struct4{
+    int a;
+    // Incomplete struct inside a struct.
+    struct EmptyStruct b;
+};
+
+struct Struct5{
+    int a;
+    // Incomplete struct array.
+    struct EmptyStruct b[3];
+};
+
+struct Struct6
+{
+    // An anonymous, unnamed union.
+    union
+    {
+        float a;
+    };
+
+    // An unnamed union.
+    union
+    {
+        float b;
+    } c;
+
+    union
+    {
+        float d;
+    } e;
+};
diff --git a/pkgs/ffigen/test/header_parser_tests/nested_parsing_test.dart b/pkgs/ffigen/test/header_parser_tests/nested_parsing_test.dart
new file mode 100644
index 0000000..75803a0
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/nested_parsing_test.dart
@@ -0,0 +1,158 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('nested_parsing_test', () {
+    setUpAll(() {
+      logWarnings();
+      expected = expectedLibrary();
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Nested Parsing Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/nested_parsing.h'
+${strings.structs}:
+  ${strings.exclude}:
+    - Struct2
+        '''),
+      );
+    });
+
+    test('Total bindings count', () {
+      expect(actual.bindings.length, expected.bindings.length);
+    });
+
+    test('Struct1', () {
+      expect(actual.getBindingAsString('Struct1'),
+          expected.getBindingAsString('Struct1'));
+    });
+    test('Struct2', () {
+      expect(actual.getBindingAsString('Struct2'),
+          expected.getBindingAsString('Struct2'));
+    });
+    test('Struct3', () {
+      expect(actual.getBindingAsString('Struct3'),
+          expected.getBindingAsString('Struct3'));
+    });
+    test('Struct4', () {
+      expect(actual.getBindingAsString('Struct4'),
+          expected.getBindingAsString('Struct4'));
+    });
+    test('Struct5', () {
+      expect(actual.getBindingAsString('Struct5'),
+          expected.getBindingAsString('Struct5'));
+    });
+    test('Struct6', () {
+      expect(actual.getBindingAsString('Struct6'),
+          expected.getBindingAsString('Struct6'));
+    });
+  });
+}
+
+Library expectedLibrary() {
+  final struct2 = Struct(name: 'Struct2', members: [
+    Member(
+      name: 'e',
+      type: intType,
+    ),
+    Member(
+      name: 'f',
+      type: intType,
+    ),
+  ]);
+  final unnamedInternalStruct = Struct(name: 'UnnamedStruct1', members: [
+    Member(
+      name: 'a',
+      type: intType,
+    ),
+    Member(
+      name: 'b',
+      type: intType,
+    ),
+  ]);
+  return Library(
+    name: 'Bindings',
+    bindings: [
+      unnamedInternalStruct,
+      struct2,
+      Struct(name: 'Struct1', members: [
+        Member(
+          name: 'a',
+          type: intType,
+        ),
+        Member(
+          name: 'b',
+          type: intType,
+        ),
+        Member(name: 'struct2', type: PointerType(struct2)),
+      ]),
+      Struct(name: 'Struct3', members: [
+        Member(
+          name: 'a',
+          type: intType,
+        ),
+        Member(
+          name: 'b',
+          type: unnamedInternalStruct,
+        ),
+      ]),
+      Struct(name: 'EmptyStruct'),
+      Struct(name: 'Struct4'),
+      Struct(name: 'Struct5'),
+      Struct(
+        name: 'Struct6',
+        members: [
+          Member(
+            name: '',
+            type: Union(
+              name: 'UnnamedUnion1',
+              members: [
+                Member(
+                  name: 'a',
+                  type: floatType,
+                ),
+              ],
+            ),
+          ),
+          Member(
+            name: 'c',
+            type: Union(
+              name: 'UnnamedUnion2',
+              members: [
+                Member(
+                  name: 'b',
+                  type: floatType,
+                ),
+              ],
+            ),
+          ),
+          Member(
+            name: 'e',
+            type: Union(
+              name: 'UnnamedUnion3',
+              members: [
+                Member(
+                  name: 'd',
+                  type: floatType,
+                ),
+              ],
+            ),
+          ),
+        ],
+      ),
+    ],
+  );
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/opaque_dependencies.h b/pkgs/ffigen/test/header_parser_tests/opaque_dependencies.h
new file mode 100644
index 0000000..c1607d4
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/opaque_dependencies.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Opaque.
+struct A
+{
+    int a;
+};
+
+// Opaque.
+typedef struct B
+{
+    int a;
+} BAlias;
+
+BAlias *func(struct A *a);
+
+// Opaque.
+struct C
+{
+    int a;
+};
+
+// Full (excluded, but used by value).
+struct D
+{
+    int a;
+};
+
+// Full (included)
+struct E
+{
+    struct C *c;
+    struct D d;
+};
+
+// Opaque.
+union UA
+{
+    int a;
+};
+
+// Opaque.
+union UB
+{
+    int a;
+};
+
+union UB *func2(union UA *a);
+
+// Opaque.
+union UC
+{
+    int a;
+};
+
+// Full (excluded, but used by value).
+union UD
+{
+    int a;
+};
+
+// Full (included)
+union UE
+{
+    union UC *c;
+    union UD d;
+};
diff --git a/pkgs/ffigen/test/header_parser_tests/opaque_dependencies_test.dart b/pkgs/ffigen/test/header_parser_tests/opaque_dependencies_test.dart
new file mode 100644
index 0000000..fc73cfe
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/opaque_dependencies_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual;
+void main() {
+  group('opaque_dependencies_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Opaque Dependencies Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/opaque_dependencies.h'
+${strings.structs}:
+  ${strings.include}:
+    - 'E'
+  ${strings.dependencyOnly}: ${strings.opaqueCompoundDependencies}
+${strings.unions}:
+  ${strings.include}:
+    - 'UE'
+  ${strings.dependencyOnly}: ${strings.opaqueCompoundDependencies}
+        '''),
+      );
+    });
+    test('Expected bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_opaque_dependencies_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_opaque_dependencies_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/packed_structs.h b/pkgs/ffigen/test/header_parser_tests/packed_structs.h
new file mode 100644
index 0000000..2edec80
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/packed_structs.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+struct NormalStruct1
+{
+    char a;
+};
+
+/// Should not be packed.
+struct StructWithAttr
+{
+    int *a;
+    int *b;
+} __attribute__((annotate("Attr is not __packed__")));
+
+/// Should be packed with 1.
+struct PackedAttr{
+    int a;
+} __attribute__((__packed__));
+
+/// Should be packed with 8.
+struct PackedAttrAlign8{
+    int a;
+} __attribute__((__packed__, aligned(8)));
+
+#pragma pack(push, 2)
+/// Should be packed with 2.
+struct Pack2WithPragma{
+    int a;
+};
+#pragma pack(4)
+/// Should be packed with 4.
+struct Pack4WithPragma{
+    long long a;
+};
+#pragma pack(pop)
+struct NormalStruct2
+{
+    char a;
+};
diff --git a/pkgs/ffigen/test/header_parser_tests/packed_structs_test.dart b/pkgs/ffigen/test/header_parser_tests/packed_structs_test.dart
new file mode 100644
index 0000000..62b7075
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/packed_structs_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual;
+void main() {
+  group('packed_structs_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Packed Structs Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/packed_structs.h'
+        '''),
+      );
+    });
+
+    test('Expected bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_packed_structs_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_packed_structs_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/regress_384_header_1.h b/pkgs/ffigen/test/header_parser_tests/regress_384_header_1.h
new file mode 100644
index 0000000..3129b2d
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/regress_384_header_1.h
@@ -0,0 +1,5 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "regress_384_shared.h"
diff --git a/pkgs/ffigen/test/header_parser_tests/regress_384_header_2.h b/pkgs/ffigen/test/header_parser_tests/regress_384_header_2.h
new file mode 100644
index 0000000..3129b2d
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/regress_384_header_2.h
@@ -0,0 +1,5 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "regress_384_shared.h"
diff --git a/pkgs/ffigen/test/header_parser_tests/regress_384_shared.h b/pkgs/ffigen/test/header_parser_tests/regress_384_shared.h
new file mode 100644
index 0000000..265a786
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/regress_384_shared.h
@@ -0,0 +1,10 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef __REGRESS_384_SHARED__
+#define __REGRESS_384_SHARED__
+
+void foo();
+
+#endif
diff --git a/pkgs/ffigen/test/header_parser_tests/regress_384_test.dart b/pkgs/ffigen/test/header_parser_tests/regress_384_test.dart
new file mode 100644
index 0000000..b5751d1
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/regress_384_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual;
+void main() {
+  group('regress_384_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Regression test for #384'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/regress_384_header_1.h'
+    - 'test/header_parser_tests/regress_384_header_2.h'
+        '''),
+      );
+    });
+
+    test('Expected bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_regress_384_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_regress_384_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/separate_definition.h b/pkgs/ffigen/test/header_parser_tests/separate_definition.h
new file mode 100644
index 0000000..4c8584b
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/separate_definition.h
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Forward declaration to SeparatelyDefinedStruct, with definition in
+// separate_definition_base.h
+struct SeparatelyDefinedStruct;
+
+void func(struct SeparatelyDefinedStruct s);
+
+void func2(struct SeparatelyDefinedStruct *s);
diff --git a/pkgs/ffigen/test/header_parser_tests/separate_definition_base.h b/pkgs/ffigen/test/header_parser_tests/separate_definition_base.h
new file mode 100644
index 0000000..2342bdf
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/separate_definition_base.h
@@ -0,0 +1,8 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+struct SeparatelyDefinedStruct{
+    int a;
+    int b;
+};
diff --git a/pkgs/ffigen/test/header_parser_tests/separate_definition_test.dart b/pkgs/ffigen/test/header_parser_tests/separate_definition_test.dart
new file mode 100644
index 0000000..663bebf
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/separate_definition_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/config_provider.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('separate_definition', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+    });
+    test('different header order', () {
+      final entryPoints = [
+        "test/header_parser_tests/separate_definition_base.h",
+        "test/header_parser_tests/separate_definition.h"
+      ];
+      final library1String = parser.parse(_makeConfig(entryPoints)).generate();
+      final library2String =
+          parser.parse(_makeConfig(entryPoints.reversed.toList())).generate();
+
+      expect(library1String, library2String);
+    });
+  });
+}
+
+Config _makeConfig(List<String> entryPoints) {
+  final entryPointBuilder = StringBuffer();
+  for (final ep in entryPoints) {
+    entryPointBuilder.writeln("    - $ep");
+  }
+  final config = testConfig('''
+${strings.name}: 'Bindings'
+${strings.output}: 'unused'
+
+${strings.headers}:
+  ${strings.entryPoints}:
+${entryPointBuilder.toString()}
+''');
+  return config;
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/struct_fptr_fields.h b/pkgs/ffigen/test/header_parser_tests/struct_fptr_fields.h
new file mode 100644
index 0000000..f760d8a
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/struct_fptr_fields.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+typedef int (*ArithmeticOperation)(int a, int b);
+
+struct S {
+  // Function pointer field, but no parameters.
+  int (*func1)(void);
+  // Function pointer field with parameters.
+  int (*comparator)(int a, int b);
+  // Function pointer field with lot of parameters
+  int (*veryManyArguments)(double a, float b, char *c, int d, long long e);
+  // Function pointer field with parameters, but no names
+  int (*argsDontHaveNames)(int, int, int, float, char *);
+  // Function pointer through typedef
+  ArithmeticOperation operation;
+  // Pointer to function pointer
+  void (**sortPtr)(int *array, int len);
+  // Function pointer with a function pointer parameter
+  void (*sortBy)(int *array, int len, int (*evaluator)(int x));
+  // Function where few parameters are named. This should not
+  // produce parameters in output.
+  void (*improperlyDeclaredParams)(int a, int, char);
+  // Function pointer with 2 function pointer parameters
+  void (*sortByWithFallback)(int *array, int (*primaryEvaluator)(int x),
+                             int (*fallbackEvaluator)(int x));
+
+  // TODO(https://github.com/dart-lang/ffigen/issues/545): Handle remaining
+  // cases of parsing param names.
+  // ---
+  // Array of function pointers. Does not produce proper output right now.
+  void (*manyFunctions[2])(char a, char b);
+  // Function pointer returning function pointer. Does not produce valid output.
+  int (*(*functionReturningFunction)(int a, int b))(int c, int d);
+  // Function pointer returning function pointer. The return type has param
+  // names, but the function itself doesn't. This also shouldn't produce
+  // any parameters in output.
+  int (*(*functionReturningFunctionImproper)(int a, int b))(int, int);
+};
diff --git a/pkgs/ffigen/test/header_parser_tests/struct_fptr_fields_test.dart b/pkgs/ffigen/test/header_parser_tests/struct_fptr_fields_test.dart
new file mode 100644
index 0000000..765b8b0
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/struct_fptr_fields_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/config_provider.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+import 'package:yaml/yaml.dart' as yaml;
+
+import '../test_utils.dart';
+
+late Library actual;
+void main() {
+  group('Function pointer parameters parsing test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      actual = parser.parse(
+        Config.fromYaml(yaml.loadYaml('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Function pointer fields in structs Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/struct_fptr_fields.h'
+        ''') as yaml.YamlMap),
+      );
+    });
+
+    test('Expected bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_struct_fptr_fields_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_struct_fptr_fields_bindings.dart',
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/typedef.h b/pkgs/ffigen/test/header_parser_tests/typedef.h
new file mode 100644
index 0000000..5e4f7fb
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/typedef.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include<stdbool.h>
+
+typedef void (*NamedFunctionProto)();
+
+struct Struct1
+{
+    NamedFunctionProto named;
+    void (*unnamed)();
+};
+
+extern NamedFunctionProto func1(NamedFunctionProto named, void (*unnamed)(int));
+
+typedef struct
+{
+
+} AnonymousStructInTypedef;
+// These typerefs do not affect the name of AnonymousStructInTypedef.
+typedef AnonymousStructInTypedef Typeref1;
+typedef AnonymousStructInTypedef Typeref2;
+
+// Name from global namespace is used.
+typedef struct _NamedStructInTypedef
+{
+
+} NamedStructInTypedef;
+
+// Both these names must be exlucded or this struct will be generated.
+typedef struct _ExcludedStruct
+{
+
+} ExcludedStruct;
+typedef ExcludedStruct NTyperef1;
+
+// Because `struct _ExcludedStruct` is excluded, the type name used
+// in this function (the first function) will be used.
+// Therefore, _ExcludedStruct will be generated as NTyperef1.
+void func2(NTyperef1 *);
+
+typedef enum
+{
+    a = 0
+} AnonymousEnumInTypedef;
+
+// Name from global namespace is used.
+typedef enum _NamedEnumInTypedef
+{
+    b = 0
+} NamedEnumInTypedef;
+
+// Should be treated as IntPtr when used.
+typedef char SpecifiedTypeAsIntPtr;
+typedef SpecifiedTypeAsIntPtr NestingASpecifiedType;
+
+void func3(SpecifiedTypeAsIntPtr, NestingASpecifiedType b);
+
+// Struct3 is used. `pStruct2` and `pStruct3` are ignored.
+typedef struct
+{
+} Struct2, Struct3, *pStruct2, *pStruct3;
+
+typedef bool BoolAlias;
+
+BoolAlias func4(BoolAlias *a);
+
+struct WithBoolAlias{
+    BoolAlias b;
+};
diff --git a/pkgs/ffigen/test/header_parser_tests/typedef_test.dart b/pkgs/ffigen/test/header_parser_tests/typedef_test.dart
new file mode 100644
index 0000000..5c373f5
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/typedef_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('typedef_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'Bindings'
+${strings.description}: 'Typedef Test'
+${strings.output}: 'unused'
+
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/typedef.h'
+  ${strings.includeDirectives}:
+    - '**typedef.h'
+${strings.structs}:
+  ${strings.exclude}:
+    - ExcludedStruct
+    - _ExcludedStruct
+${strings.typeMap}:
+  ${strings.typeMapTypedefs}:
+    'SpecifiedTypeAsIntPtr':
+        lib: 'ffi'
+        c-type: 'IntPtr'
+        dart-type: 'int'
+${strings.preamble}: |
+  // ignore_for_file: unused_element, unused_field
+        '''),
+      );
+    });
+
+    test('Expected Bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_typedef_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_typedef_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/unions.h b/pkgs/ffigen/test/header_parser_tests/unions.h
new file mode 100644
index 0000000..7f03834
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/unions.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+union Union1
+{
+    int a;
+};
+
+union Union2
+{
+    union Union1 a;
+};
+
+// Should be marked incomplete, long double not supported.
+union Union3
+{
+    long double a;
+};
+
+// All members should be removed, Bit fields are not supported.
+union Union4
+{
+    int a : 3;
+    int : 2; // Unnamed bit field.
+};
+
+// All members should be removed, Incomplete union members are not supported.
+union Union5
+{
+    int a;
+    union Union3 s; // Incomplete nested union.
+};
+
+// Multiple anonymous declarations
+union Union6
+{
+    union
+    {
+        float a;
+    };
+
+    union
+    {
+        float b;
+    };
+};
+
+// Multiple anonymous declarations with incomplete members
+union Union7
+{
+    union
+    {
+        float a;
+    };
+
+    union
+    {
+        float b;
+        int c[];
+    };
+};
+
+void func1(union Union2 *s);
+
+// Incomplete array parameter will be treated as a pointer.
+void func2(union Union3 s[]);
diff --git a/pkgs/ffigen/test/header_parser_tests/unions_test.dart b/pkgs/ffigen/test/header_parser_tests/unions_test.dart
new file mode 100644
index 0000000..e248dfb
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/unions_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual;
+void main() {
+  group('unions_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Unions Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/unions.h'
+        '''),
+      );
+    });
+
+    test('Expected bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_unions_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_unions_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/unnamed_enums.h b/pkgs/ffigen/test/header_parser_tests/unnamed_enums.h
new file mode 100644
index 0000000..8b64555
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/unnamed_enums.h
@@ -0,0 +1,13 @@
+// Only this should be parsed.
+enum{
+    A=1,
+    B=2, // This will be excluded by config.
+    C=3
+};
+
+// Shouldn't be parsed.
+typedef enum{
+    E,
+    F,
+    G
+} Named;
diff --git a/pkgs/ffigen/test/header_parser_tests/unnamed_enums_test.dart b/pkgs/ffigen/test/header_parser_tests/unnamed_enums_test.dart
new file mode 100644
index 0000000..eae9cf3
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/unnamed_enums_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('unnamed_enums_test', () {
+    setUpAll(() {
+      logWarnings();
+      expected = expectedLibrary();
+      actual = parser.parse(
+        testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Unnamed Enums Test'
+${strings.output}: 'unused'
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/unnamed_enums.h'
+${strings.enums}:
+  ${strings.exclude}:
+    - Named
+${strings.unnamedEnums}:
+  ${strings.exclude}:
+    - B
+        '''),
+      );
+    });
+
+    test('Total bindings count', () {
+      expect(actual.bindings.length, expected.bindings.length);
+    });
+
+    test('Parse unnamed enum Values', () {
+      expect(actual.getBindingAsString('A'), expected.getBindingAsString('A'));
+      expect(actual.getBindingAsString('C'), expected.getBindingAsString('C'));
+    });
+
+    test('Ignore unnamed enums inside typedefs', () {
+      expect(() => actual.getBindingAsString('E'),
+          throwsA(TypeMatcher<NotFoundException>()));
+      expect(() => actual.getBindingAsString('F'),
+          throwsA(TypeMatcher<NotFoundException>()));
+      expect(() => actual.getBindingAsString('G'),
+          throwsA(TypeMatcher<NotFoundException>()));
+    });
+  });
+}
+
+Library expectedLibrary() {
+  return Library(
+    name: 'Bindings',
+    bindings: [
+      Constant(
+        name: 'A',
+        rawType: 'int',
+        rawValue: '1',
+      ),
+      Constant(
+        name: 'C',
+        rawType: 'int',
+        rawValue: '3',
+      ),
+    ],
+  );
+}
diff --git a/pkgs/ffigen/test/header_parser_tests/varargs.h b/pkgs/ffigen/test/header_parser_tests/varargs.h
new file mode 100644
index 0000000..e316b90
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/varargs.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+int myfunc(int a, ...);
+void myfunc2(char a, char b, ...);
+void myfunc3(long a, ...);
+
+struct SA {
+    int a;
+};
+
+struct Struct_WithLong_Name_test {
+    int a;
+};
diff --git a/pkgs/ffigen/test/header_parser_tests/varargs_test.dart b/pkgs/ffigen/test/header_parser_tests/varargs_test.dart
new file mode 100644
index 0000000..deaa5af
--- /dev/null
+++ b/pkgs/ffigen/test/header_parser_tests/varargs_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/config_provider.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:test/test.dart';
+import 'package:yaml/yaml.dart' as yaml;
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+
+void main() {
+  group('varargs_test', () {
+    setUpAll(() {
+      logWarnings();
+      actual = parser.parse(
+        Config.fromYaml(yaml.loadYaml('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'VarArgs Test'
+${strings.output}: 'unused'
+
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/header_parser_tests/varargs.h'
+
+${strings.functions}:
+  ${strings.varArgFunctions}:
+    myfunc:
+      - [int, char*, SA]
+    myfunc2:
+      - [char*, long**]
+      - [SA, int*, unsigned char**]
+      - types: [SA, int*, unsigned char**]
+        postfix: _custompostfix
+    myfunc3:
+      - [Struct_WithLong_Name_test*, float*]
+      - types: [Struct_WithLong_Name_test]
+        postfix: _custompostfix2
+
+${strings.preamble}: |
+  // ignore_for_file: camel_case_types
+        ''') as yaml.YamlMap),
+      );
+    });
+    test('Expected Bindings', () {
+      matchLibraryWithExpected(
+          actual, 'header_parser_varargs_test_output.dart', [
+        'test',
+        'header_parser_tests',
+        'expected_bindings',
+        '_expected_varargs_bindings.dart'
+      ]);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/large_integration_tests/_expected_cjson_bindings.dart b/pkgs/ffigen/test/large_integration_tests/_expected_cjson_bindings.dart
new file mode 100644
index 0000000..9c5a3e1
--- /dev/null
+++ b/pkgs/ffigen/test/large_integration_tests/_expected_cjson_bindings.dart
@@ -0,0 +1,1282 @@
+// ignore_for_file: camel_case_types, non_constant_identifier_names
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Bindings to Cjson.
+class CJson {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  CJson(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  CJson.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  ffi.Pointer<ffi.Char> cJSON_Version() {
+    return _cJSON_Version();
+  }
+
+  late final _cJSON_VersionPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
+          'cJSON_Version');
+  late final _cJSON_Version =
+      _cJSON_VersionPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();
+
+  void cJSON_InitHooks(
+    ffi.Pointer<cJSON_Hooks> hooks,
+  ) {
+    return _cJSON_InitHooks(
+      hooks,
+    );
+  }
+
+  late final _cJSON_InitHooksPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<cJSON_Hooks>)>>(
+          'cJSON_InitHooks');
+  late final _cJSON_InitHooks =
+      _cJSON_InitHooksPtr.asFunction<void Function(ffi.Pointer<cJSON_Hooks>)>();
+
+  ffi.Pointer<cJSON> cJSON_Parse(
+    ffi.Pointer<ffi.Char> value,
+  ) {
+    return _cJSON_Parse(
+      value,
+    );
+  }
+
+  late final _cJSON_ParsePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>('cJSON_Parse');
+  late final _cJSON_Parse = _cJSON_ParsePtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_ParseWithOpts(
+    ffi.Pointer<ffi.Char> value,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> return_parse_end,
+    int require_null_terminated,
+  ) {
+    return _cJSON_ParseWithOpts(
+      value,
+      return_parse_end,
+      require_null_terminated,
+    );
+  }
+
+  late final _cJSON_ParseWithOptsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              cJSON_bool)>>('cJSON_ParseWithOpts');
+  late final _cJSON_ParseWithOpts = _cJSON_ParseWithOptsPtr.asFunction<
+      ffi.Pointer<cJSON> Function(
+          ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Pointer<ffi.Char>>, int)>();
+
+  ffi.Pointer<ffi.Char> cJSON_Print(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_Print(
+      item,
+    );
+  }
+
+  late final _cJSON_PrintPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>('cJSON_Print');
+  late final _cJSON_Print = _cJSON_PrintPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<ffi.Char> cJSON_PrintUnformatted(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_PrintUnformatted(
+      item,
+    );
+  }
+
+  late final _cJSON_PrintUnformattedPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_PrintUnformatted');
+  late final _cJSON_PrintUnformatted = _cJSON_PrintUnformattedPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<ffi.Char> cJSON_PrintBuffered(
+    ffi.Pointer<cJSON> item,
+    int prebuffer,
+    int fmt,
+  ) {
+    return _cJSON_PrintBuffered(
+      item,
+      prebuffer,
+      fmt,
+    );
+  }
+
+  late final _cJSON_PrintBufferedPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<cJSON>, ffi.Int, cJSON_bool)>>('cJSON_PrintBuffered');
+  late final _cJSON_PrintBuffered = _cJSON_PrintBufferedPtr.asFunction<
+      ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>, int, int)>();
+
+  int cJSON_PrintPreallocated(
+    ffi.Pointer<cJSON> item,
+    ffi.Pointer<ffi.Char> buffer,
+    int length,
+    int format,
+  ) {
+    return _cJSON_PrintPreallocated(
+      item,
+      buffer,
+      length,
+      format,
+    );
+  }
+
+  late final _cJSON_PrintPreallocatedPtr = _lookup<
+      ffi.NativeFunction<
+          cJSON_bool Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Int, cJSON_bool)>>('cJSON_PrintPreallocated');
+  late final _cJSON_PrintPreallocated = _cJSON_PrintPreallocatedPtr.asFunction<
+      int Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, int, int)>();
+
+  void cJSON_Delete(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_Delete(
+      item,
+    );
+  }
+
+  late final _cJSON_DeletePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_Delete');
+  late final _cJSON_Delete =
+      _cJSON_DeletePtr.asFunction<void Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_GetArraySize(
+    ffi.Pointer<cJSON> array,
+  ) {
+    return _cJSON_GetArraySize(
+      array,
+    );
+  }
+
+  late final _cJSON_GetArraySizePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_GetArraySize');
+  late final _cJSON_GetArraySize =
+      _cJSON_GetArraySizePtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_GetArrayItem(
+    ffi.Pointer<cJSON> array,
+    int index,
+  ) {
+    return _cJSON_GetArrayItem(
+      array,
+      index,
+    );
+  }
+
+  late final _cJSON_GetArrayItemPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Int)>>('cJSON_GetArrayItem');
+  late final _cJSON_GetArrayItem = _cJSON_GetArrayItemPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_GetObjectItem(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_GetObjectItem(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_GetObjectItemPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_GetObjectItem');
+  late final _cJSON_GetObjectItem = _cJSON_GetObjectItemPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_GetObjectItemCaseSensitive(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_GetObjectItemCaseSensitive(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_GetObjectItemCaseSensitivePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_GetObjectItemCaseSensitive');
+  late final _cJSON_GetObjectItemCaseSensitive =
+      _cJSON_GetObjectItemCaseSensitivePtr.asFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  int cJSON_HasObjectItem(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_HasObjectItem(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_HasObjectItemPtr = _lookup<
+      ffi.NativeFunction<
+          cJSON_bool Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_HasObjectItem');
+  late final _cJSON_HasObjectItem = _cJSON_HasObjectItemPtr
+      .asFunction<int Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<ffi.Char> cJSON_GetErrorPtr() {
+    return _cJSON_GetErrorPtr();
+  }
+
+  late final _cJSON_GetErrorPtrPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
+          'cJSON_GetErrorPtr');
+  late final _cJSON_GetErrorPtr =
+      _cJSON_GetErrorPtrPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();
+
+  ffi.Pointer<ffi.Char> cJSON_GetStringValue(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_GetStringValue(
+      item,
+    );
+  }
+
+  late final _cJSON_GetStringValuePtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_GetStringValue');
+  late final _cJSON_GetStringValue = _cJSON_GetStringValuePtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsInvalid(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsInvalid(
+      item,
+    );
+  }
+
+  late final _cJSON_IsInvalidPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsInvalid');
+  late final _cJSON_IsInvalid =
+      _cJSON_IsInvalidPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsFalse(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsFalse(
+      item,
+    );
+  }
+
+  late final _cJSON_IsFalsePtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsFalse');
+  late final _cJSON_IsFalse =
+      _cJSON_IsFalsePtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsTrue(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsTrue(
+      item,
+    );
+  }
+
+  late final _cJSON_IsTruePtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsTrue');
+  late final _cJSON_IsTrue =
+      _cJSON_IsTruePtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsBool(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsBool(
+      item,
+    );
+  }
+
+  late final _cJSON_IsBoolPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsBool');
+  late final _cJSON_IsBool =
+      _cJSON_IsBoolPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsNull(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsNull(
+      item,
+    );
+  }
+
+  late final _cJSON_IsNullPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsNull');
+  late final _cJSON_IsNull =
+      _cJSON_IsNullPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsNumber(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsNumber(
+      item,
+    );
+  }
+
+  late final _cJSON_IsNumberPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsNumber');
+  late final _cJSON_IsNumber =
+      _cJSON_IsNumberPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsString(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsString(
+      item,
+    );
+  }
+
+  late final _cJSON_IsStringPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsString');
+  late final _cJSON_IsString =
+      _cJSON_IsStringPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsArray(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsArray(
+      item,
+    );
+  }
+
+  late final _cJSON_IsArrayPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsArray');
+  late final _cJSON_IsArray =
+      _cJSON_IsArrayPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsObject(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsObject(
+      item,
+    );
+  }
+
+  late final _cJSON_IsObjectPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsObject');
+  late final _cJSON_IsObject =
+      _cJSON_IsObjectPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  int cJSON_IsRaw(
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_IsRaw(
+      item,
+    );
+  }
+
+  late final _cJSON_IsRawPtr =
+      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
+          'cJSON_IsRaw');
+  late final _cJSON_IsRaw =
+      _cJSON_IsRawPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateNull() {
+    return _cJSON_CreateNull();
+  }
+
+  late final _cJSON_CreateNullPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
+          'cJSON_CreateNull');
+  late final _cJSON_CreateNull =
+      _cJSON_CreateNullPtr.asFunction<ffi.Pointer<cJSON> Function()>();
+
+  ffi.Pointer<cJSON> cJSON_CreateTrue() {
+    return _cJSON_CreateTrue();
+  }
+
+  late final _cJSON_CreateTruePtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
+          'cJSON_CreateTrue');
+  late final _cJSON_CreateTrue =
+      _cJSON_CreateTruePtr.asFunction<ffi.Pointer<cJSON> Function()>();
+
+  ffi.Pointer<cJSON> cJSON_CreateFalse() {
+    return _cJSON_CreateFalse();
+  }
+
+  late final _cJSON_CreateFalsePtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
+          'cJSON_CreateFalse');
+  late final _cJSON_CreateFalse =
+      _cJSON_CreateFalsePtr.asFunction<ffi.Pointer<cJSON> Function()>();
+
+  ffi.Pointer<cJSON> cJSON_CreateBool(
+    int boolean,
+  ) {
+    return _cJSON_CreateBool(
+      boolean,
+    );
+  }
+
+  late final _cJSON_CreateBoolPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function(cJSON_bool)>>(
+          'cJSON_CreateBool');
+  late final _cJSON_CreateBool =
+      _cJSON_CreateBoolPtr.asFunction<ffi.Pointer<cJSON> Function(int)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateNumber(
+    double num,
+  ) {
+    return _cJSON_CreateNumber(
+      num,
+    );
+  }
+
+  late final _cJSON_CreateNumberPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function(ffi.Double)>>(
+          'cJSON_CreateNumber');
+  late final _cJSON_CreateNumber =
+      _cJSON_CreateNumberPtr.asFunction<ffi.Pointer<cJSON> Function(double)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateString(
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_CreateString(
+      string,
+    );
+  }
+
+  late final _cJSON_CreateStringPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateString');
+  late final _cJSON_CreateString = _cJSON_CreateStringPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateRaw(
+    ffi.Pointer<ffi.Char> raw,
+  ) {
+    return _cJSON_CreateRaw(
+      raw,
+    );
+  }
+
+  late final _cJSON_CreateRawPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateRaw');
+  late final _cJSON_CreateRaw = _cJSON_CreateRawPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateArray() {
+    return _cJSON_CreateArray();
+  }
+
+  late final _cJSON_CreateArrayPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
+          'cJSON_CreateArray');
+  late final _cJSON_CreateArray =
+      _cJSON_CreateArrayPtr.asFunction<ffi.Pointer<cJSON> Function()>();
+
+  ffi.Pointer<cJSON> cJSON_CreateObject() {
+    return _cJSON_CreateObject();
+  }
+
+  late final _cJSON_CreateObjectPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
+          'cJSON_CreateObject');
+  late final _cJSON_CreateObject =
+      _cJSON_CreateObjectPtr.asFunction<ffi.Pointer<cJSON> Function()>();
+
+  ffi.Pointer<cJSON> cJSON_CreateStringReference(
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_CreateStringReference(
+      string,
+    );
+  }
+
+  late final _cJSON_CreateStringReferencePtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateStringReference');
+  late final _cJSON_CreateStringReference = _cJSON_CreateStringReferencePtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateObjectReference(
+    ffi.Pointer<cJSON> child,
+  ) {
+    return _cJSON_CreateObjectReference(
+      child,
+    );
+  }
+
+  late final _cJSON_CreateObjectReferencePtr = _lookup<
+          ffi.NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_CreateObjectReference');
+  late final _cJSON_CreateObjectReference = _cJSON_CreateObjectReferencePtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateArrayReference(
+    ffi.Pointer<cJSON> child,
+  ) {
+    return _cJSON_CreateArrayReference(
+      child,
+    );
+  }
+
+  late final _cJSON_CreateArrayReferencePtr = _lookup<
+          ffi.NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_CreateArrayReference');
+  late final _cJSON_CreateArrayReference = _cJSON_CreateArrayReferencePtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateIntArray(
+    ffi.Pointer<ffi.Int> numbers,
+    int count,
+  ) {
+    return _cJSON_CreateIntArray(
+      numbers,
+      count,
+    );
+  }
+
+  late final _cJSON_CreateIntArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<ffi.Int>, ffi.Int)>>('cJSON_CreateIntArray');
+  late final _cJSON_CreateIntArray = _cJSON_CreateIntArrayPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Int>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateFloatArray(
+    ffi.Pointer<ffi.Float> numbers,
+    int count,
+  ) {
+    return _cJSON_CreateFloatArray(
+      numbers,
+      count,
+    );
+  }
+
+  late final _cJSON_CreateFloatArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<ffi.Float>, ffi.Int)>>('cJSON_CreateFloatArray');
+  late final _cJSON_CreateFloatArray = _cJSON_CreateFloatArrayPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Float>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateDoubleArray(
+    ffi.Pointer<ffi.Double> numbers,
+    int count,
+  ) {
+    return _cJSON_CreateDoubleArray(
+      numbers,
+      count,
+    );
+  }
+
+  late final _cJSON_CreateDoubleArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<ffi.Double>, ffi.Int)>>('cJSON_CreateDoubleArray');
+  late final _cJSON_CreateDoubleArray = _cJSON_CreateDoubleArrayPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Double>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_CreateStringArray(
+    ffi.Pointer<ffi.Pointer<ffi.Char>> strings,
+    int count,
+  ) {
+    return _cJSON_CreateStringArray(
+      strings,
+      count,
+    );
+  }
+
+  late final _cJSON_CreateStringArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Int)>>('cJSON_CreateStringArray');
+  late final _cJSON_CreateStringArray = _cJSON_CreateStringArrayPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Pointer<ffi.Char>>, int)>();
+
+  void cJSON_AddItemToArray(
+    ffi.Pointer<cJSON> array,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_AddItemToArray(
+      array,
+      item,
+    );
+  }
+
+  late final _cJSON_AddItemToArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>>('cJSON_AddItemToArray');
+  late final _cJSON_AddItemToArray = _cJSON_AddItemToArrayPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_AddItemToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_AddItemToObject(
+      object,
+      string,
+      item,
+    );
+  }
+
+  late final _cJSON_AddItemToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<cJSON>)>>('cJSON_AddItemToObject');
+  late final _cJSON_AddItemToObject = _cJSON_AddItemToObjectPtr.asFunction<
+      void Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_AddItemToObjectCS(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_AddItemToObjectCS(
+      object,
+      string,
+      item,
+    );
+  }
+
+  late final _cJSON_AddItemToObjectCSPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<cJSON>)>>('cJSON_AddItemToObjectCS');
+  late final _cJSON_AddItemToObjectCS = _cJSON_AddItemToObjectCSPtr.asFunction<
+      void Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_AddItemReferenceToArray(
+    ffi.Pointer<cJSON> array,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_AddItemReferenceToArray(
+      array,
+      item,
+    );
+  }
+
+  late final _cJSON_AddItemReferenceToArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<cJSON>)>>('cJSON_AddItemReferenceToArray');
+  late final _cJSON_AddItemReferenceToArray = _cJSON_AddItemReferenceToArrayPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_AddItemReferenceToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_AddItemReferenceToObject(
+      object,
+      string,
+      item,
+    );
+  }
+
+  late final _cJSON_AddItemReferenceToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<cJSON>)>>('cJSON_AddItemReferenceToObject');
+  late final _cJSON_AddItemReferenceToObject =
+      _cJSON_AddItemReferenceToObjectPtr.asFunction<
+          void Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_DetachItemViaPointer(
+    ffi.Pointer<cJSON> parent,
+    ffi.Pointer<cJSON> item,
+  ) {
+    return _cJSON_DetachItemViaPointer(
+      parent,
+      item,
+    );
+  }
+
+  late final _cJSON_DetachItemViaPointerPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<cJSON>)>>('cJSON_DetachItemViaPointer');
+  late final _cJSON_DetachItemViaPointer =
+      _cJSON_DetachItemViaPointerPtr.asFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_DetachItemFromArray(
+    ffi.Pointer<cJSON> array,
+    int which,
+  ) {
+    return _cJSON_DetachItemFromArray(
+      array,
+      which,
+    );
+  }
+
+  late final _cJSON_DetachItemFromArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Int)>>('cJSON_DetachItemFromArray');
+  late final _cJSON_DetachItemFromArray = _cJSON_DetachItemFromArrayPtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, int)>();
+
+  void cJSON_DeleteItemFromArray(
+    ffi.Pointer<cJSON> array,
+    int which,
+  ) {
+    return _cJSON_DeleteItemFromArray(
+      array,
+      which,
+    );
+  }
+
+  late final _cJSON_DeleteItemFromArrayPtr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<cJSON>, ffi.Int)>>(
+      'cJSON_DeleteItemFromArray');
+  late final _cJSON_DeleteItemFromArray = _cJSON_DeleteItemFromArrayPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_DetachItemFromObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_DetachItemFromObject(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_DetachItemFromObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_DetachItemFromObject');
+  late final _cJSON_DetachItemFromObject =
+      _cJSON_DetachItemFromObjectPtr.asFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_DetachItemFromObjectCaseSensitive(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_DetachItemFromObjectCaseSensitive(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_DetachItemFromObjectCaseSensitivePtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Pointer<cJSON> Function(
+                  ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>>(
+      'cJSON_DetachItemFromObjectCaseSensitive');
+  late final _cJSON_DetachItemFromObjectCaseSensitive =
+      _cJSON_DetachItemFromObjectCaseSensitivePtr.asFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  void cJSON_DeleteItemFromObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_DeleteItemFromObject(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_DeleteItemFromObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_DeleteItemFromObject');
+  late final _cJSON_DeleteItemFromObject = _cJSON_DeleteItemFromObjectPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  void cJSON_DeleteItemFromObjectCaseSensitive(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_DeleteItemFromObjectCaseSensitive(
+      object,
+      string,
+    );
+  }
+
+  late final _cJSON_DeleteItemFromObjectCaseSensitivePtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>>(
+      'cJSON_DeleteItemFromObjectCaseSensitive');
+  late final _cJSON_DeleteItemFromObjectCaseSensitive =
+      _cJSON_DeleteItemFromObjectCaseSensitivePtr.asFunction<
+          void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  void cJSON_InsertItemInArray(
+    ffi.Pointer<cJSON> array,
+    int which,
+    ffi.Pointer<cJSON> newitem,
+  ) {
+    return _cJSON_InsertItemInArray(
+      array,
+      which,
+      newitem,
+    );
+  }
+
+  late final _cJSON_InsertItemInArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Int,
+              ffi.Pointer<cJSON>)>>('cJSON_InsertItemInArray');
+  late final _cJSON_InsertItemInArray = _cJSON_InsertItemInArrayPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, int, ffi.Pointer<cJSON>)>();
+
+  int cJSON_ReplaceItemViaPointer(
+    ffi.Pointer<cJSON> parent,
+    ffi.Pointer<cJSON> item,
+    ffi.Pointer<cJSON> replacement,
+  ) {
+    return _cJSON_ReplaceItemViaPointer(
+      parent,
+      item,
+      replacement,
+    );
+  }
+
+  late final _cJSON_ReplaceItemViaPointerPtr = _lookup<
+      ffi.NativeFunction<
+          cJSON_bool Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>,
+              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemViaPointer');
+  late final _cJSON_ReplaceItemViaPointer =
+      _cJSON_ReplaceItemViaPointerPtr.asFunction<
+          int Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_ReplaceItemInArray(
+    ffi.Pointer<cJSON> array,
+    int which,
+    ffi.Pointer<cJSON> newitem,
+  ) {
+    return _cJSON_ReplaceItemInArray(
+      array,
+      which,
+      newitem,
+    );
+  }
+
+  late final _cJSON_ReplaceItemInArrayPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Int,
+              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemInArray');
+  late final _cJSON_ReplaceItemInArray = _cJSON_ReplaceItemInArrayPtr
+      .asFunction<void Function(ffi.Pointer<cJSON>, int, ffi.Pointer<cJSON>)>();
+
+  void cJSON_ReplaceItemInObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+    ffi.Pointer<cJSON> newitem,
+  ) {
+    return _cJSON_ReplaceItemInObject(
+      object,
+      string,
+      newitem,
+    );
+  }
+
+  late final _cJSON_ReplaceItemInObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemInObject');
+  late final _cJSON_ReplaceItemInObject =
+      _cJSON_ReplaceItemInObjectPtr.asFunction<
+          void Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();
+
+  void cJSON_ReplaceItemInObjectCaseSensitive(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> string,
+    ffi.Pointer<cJSON> newitem,
+  ) {
+    return _cJSON_ReplaceItemInObjectCaseSensitive(
+      object,
+      string,
+      newitem,
+    );
+  }
+
+  late final _cJSON_ReplaceItemInObjectCaseSensitivePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemInObjectCaseSensitive');
+  late final _cJSON_ReplaceItemInObjectCaseSensitive =
+      _cJSON_ReplaceItemInObjectCaseSensitivePtr.asFunction<
+          void Function(
+              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();
+
+  ffi.Pointer<cJSON> cJSON_Duplicate(
+    ffi.Pointer<cJSON> item,
+    int recurse,
+  ) {
+    return _cJSON_Duplicate(
+      item,
+      recurse,
+    );
+  }
+
+  late final _cJSON_DuplicatePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(
+              ffi.Pointer<cJSON>, cJSON_bool)>>('cJSON_Duplicate');
+  late final _cJSON_Duplicate = _cJSON_DuplicatePtr
+      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, int)>();
+
+  int cJSON_Compare(
+    ffi.Pointer<cJSON> a,
+    ffi.Pointer<cJSON> b,
+    int case_sensitive,
+  ) {
+    return _cJSON_Compare(
+      a,
+      b,
+      case_sensitive,
+    );
+  }
+
+  late final _cJSON_ComparePtr = _lookup<
+      ffi.NativeFunction<
+          cJSON_bool Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>,
+              cJSON_bool)>>('cJSON_Compare');
+  late final _cJSON_Compare = _cJSON_ComparePtr
+      .asFunction<int Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>, int)>();
+
+  void cJSON_Minify(
+    ffi.Pointer<ffi.Char> json,
+  ) {
+    return _cJSON_Minify(
+      json,
+    );
+  }
+
+  late final _cJSON_MinifyPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Char>)>>(
+          'cJSON_Minify');
+  late final _cJSON_Minify =
+      _cJSON_MinifyPtr.asFunction<void Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddNullToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _cJSON_AddNullToObject(
+      object,
+      name,
+    );
+  }
+
+  late final _cJSON_AddNullToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddNullToObject');
+  late final _cJSON_AddNullToObject = _cJSON_AddNullToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddTrueToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _cJSON_AddTrueToObject(
+      object,
+      name,
+    );
+  }
+
+  late final _cJSON_AddTrueToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddTrueToObject');
+  late final _cJSON_AddTrueToObject = _cJSON_AddTrueToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddFalseToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _cJSON_AddFalseToObject(
+      object,
+      name,
+    );
+  }
+
+  late final _cJSON_AddFalseToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddFalseToObject');
+  late final _cJSON_AddFalseToObject = _cJSON_AddFalseToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddBoolToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+    int boolean,
+  ) {
+    return _cJSON_AddBoolToObject(
+      object,
+      name,
+      boolean,
+    );
+  }
+
+  late final _cJSON_AddBoolToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              cJSON_bool)>>('cJSON_AddBoolToObject');
+  late final _cJSON_AddBoolToObject = _cJSON_AddBoolToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, int)>();
+
+  ffi.Pointer<cJSON> cJSON_AddNumberToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+    double number,
+  ) {
+    return _cJSON_AddNumberToObject(
+      object,
+      name,
+      number,
+    );
+  }
+
+  late final _cJSON_AddNumberToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Double)>>('cJSON_AddNumberToObject');
+  late final _cJSON_AddNumberToObject = _cJSON_AddNumberToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, double)>();
+
+  ffi.Pointer<cJSON> cJSON_AddStringToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+    ffi.Pointer<ffi.Char> string,
+  ) {
+    return _cJSON_AddStringToObject(
+      object,
+      name,
+      string,
+    );
+  }
+
+  late final _cJSON_AddStringToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddStringToObject');
+  late final _cJSON_AddStringToObject = _cJSON_AddStringToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddRawToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+    ffi.Pointer<ffi.Char> raw,
+  ) {
+    return _cJSON_AddRawToObject(
+      object,
+      name,
+      raw,
+    );
+  }
+
+  late final _cJSON_AddRawToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddRawToObject');
+  late final _cJSON_AddRawToObject = _cJSON_AddRawToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(
+          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddObjectToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _cJSON_AddObjectToObject(
+      object,
+      name,
+    );
+  }
+
+  late final _cJSON_AddObjectToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddObjectToObject');
+  late final _cJSON_AddObjectToObject = _cJSON_AddObjectToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<cJSON> cJSON_AddArrayToObject(
+    ffi.Pointer<cJSON> object,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _cJSON_AddArrayToObject(
+      object,
+      name,
+    );
+  }
+
+  late final _cJSON_AddArrayToObjectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
+              ffi.Pointer<ffi.Char>)>>('cJSON_AddArrayToObject');
+  late final _cJSON_AddArrayToObject = _cJSON_AddArrayToObjectPtr.asFunction<
+      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();
+
+  double cJSON_SetNumberHelper(
+    ffi.Pointer<cJSON> object,
+    double number,
+  ) {
+    return _cJSON_SetNumberHelper(
+      object,
+      number,
+    );
+  }
+
+  late final _cJSON_SetNumberHelperPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Double Function(ffi.Pointer<cJSON>, ffi.Double)>>(
+      'cJSON_SetNumberHelper');
+  late final _cJSON_SetNumberHelper = _cJSON_SetNumberHelperPtr
+      .asFunction<double Function(ffi.Pointer<cJSON>, double)>();
+
+  ffi.Pointer<ffi.Void> cJSON_malloc(
+    int size,
+  ) {
+    return _cJSON_malloc(
+      size,
+    );
+  }
+
+  late final _cJSON_mallocPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Size)>>(
+          'cJSON_malloc');
+  late final _cJSON_malloc =
+      _cJSON_mallocPtr.asFunction<ffi.Pointer<ffi.Void> Function(int)>();
+
+  void cJSON_free(
+    ffi.Pointer<ffi.Void> object,
+  ) {
+    return _cJSON_free(
+      object,
+    );
+  }
+
+  late final _cJSON_freePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
+          'cJSON_free');
+  late final _cJSON_free =
+      _cJSON_freePtr.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
+}
+
+final class cJSON extends ffi.Struct {
+  external ffi.Pointer<cJSON> next;
+
+  external ffi.Pointer<cJSON> prev;
+
+  external ffi.Pointer<cJSON> child;
+
+  @ffi.Int()
+  external int type;
+
+  external ffi.Pointer<ffi.Char> valuestring;
+
+  @ffi.Int()
+  external int valueint;
+
+  @ffi.Double()
+  external double valuedouble;
+
+  external ffi.Pointer<ffi.Char> string;
+}
+
+final class cJSON_Hooks extends ffi.Struct {
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Size sz)>>
+      malloc_fn;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void> ptr)>>
+      free_fn;
+}
+
+typedef cJSON_bool = ffi.Int;
+typedef DartcJSON_bool = int;
+
+const int CJSON_VERSION_MAJOR = 1;
+
+const int CJSON_VERSION_MINOR = 7;
+
+const int CJSON_VERSION_PATCH = 12;
+
+const int cJSON_Invalid = 0;
+
+const int cJSON_False = 1;
+
+const int cJSON_True = 2;
+
+const int cJSON_NULL = 4;
+
+const int cJSON_Number = 8;
+
+const int cJSON_String = 16;
+
+const int cJSON_Array = 32;
+
+const int cJSON_Object = 64;
+
+const int cJSON_Raw = 128;
+
+const int cJSON_IsReference = 256;
+
+const int cJSON_StringIsConst = 512;
+
+const int CJSON_NESTING_LIMIT = 1000;
+
+const double CJSON_DOUBLE_PRECISION = 1e-16;
diff --git a/pkgs/ffigen/test/large_integration_tests/_expected_libclang_bindings.dart b/pkgs/ffigen/test/large_integration_tests/_expected_libclang_bindings.dart
new file mode 100644
index 0000000..3d27499
--- /dev/null
+++ b/pkgs/ffigen/test/large_integration_tests/_expected_libclang_bindings.dart
@@ -0,0 +1,8247 @@
+// ignore_for_file: camel_case_types, non_constant_identifier_names
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Bindings to LibClang.
+class LibClang {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  LibClang(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  LibClang.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  /// Retrieve the character data associated with the given string.
+  ffi.Pointer<ffi.Char> clang_getCString(
+    CXString string,
+  ) {
+    return _clang_getCString(
+      string,
+    );
+  }
+
+  late final _clang_getCStringPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(CXString)>>(
+          'clang_getCString');
+  late final _clang_getCString = _clang_getCStringPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(CXString)>();
+
+  /// Free the given string.
+  void clang_disposeString(
+    CXString string,
+  ) {
+    return _clang_disposeString(
+      string,
+    );
+  }
+
+  late final _clang_disposeStringPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXString)>>(
+          'clang_disposeString');
+  late final _clang_disposeString =
+      _clang_disposeStringPtr.asFunction<void Function(CXString)>();
+
+  /// Free the given string set.
+  void clang_disposeStringSet(
+    ffi.Pointer<CXStringSet> set1,
+  ) {
+    return _clang_disposeStringSet(
+      set1,
+    );
+  }
+
+  late final _clang_disposeStringSetPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<CXStringSet>)>>(
+          'clang_disposeStringSet');
+  late final _clang_disposeStringSet = _clang_disposeStringSetPtr
+      .asFunction<void Function(ffi.Pointer<CXStringSet>)>();
+
+  /// Return the timestamp for use with Clang's -fbuild-session-timestamp=
+  /// option.
+  int clang_getBuildSessionTimestamp() {
+    return _clang_getBuildSessionTimestamp();
+  }
+
+  late final _clang_getBuildSessionTimestampPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedLongLong Function()>>(
+          'clang_getBuildSessionTimestamp');
+  late final _clang_getBuildSessionTimestamp =
+      _clang_getBuildSessionTimestampPtr.asFunction<int Function()>();
+
+  /// Create a CXVirtualFileOverlay object. Must be disposed with
+  /// clang_VirtualFileOverlay_dispose().
+  CXVirtualFileOverlay clang_VirtualFileOverlay_create(
+    int options,
+  ) {
+    return _clang_VirtualFileOverlay_create(
+      options,
+    );
+  }
+
+  late final _clang_VirtualFileOverlay_createPtr = _lookup<
+          ffi.NativeFunction<CXVirtualFileOverlay Function(ffi.UnsignedInt)>>(
+      'clang_VirtualFileOverlay_create');
+  late final _clang_VirtualFileOverlay_create =
+      _clang_VirtualFileOverlay_createPtr
+          .asFunction<CXVirtualFileOverlay Function(int)>();
+
+  /// Map an absolute virtual file path to an absolute real one. The virtual
+  /// path must be canonicalized (not contain "."/"..").
+  int clang_VirtualFileOverlay_addFileMapping(
+    CXVirtualFileOverlay arg0,
+    ffi.Pointer<ffi.Char> virtualPath,
+    ffi.Pointer<ffi.Char> realPath,
+  ) {
+    return _clang_VirtualFileOverlay_addFileMapping(
+      arg0,
+      virtualPath,
+      realPath,
+    );
+  }
+
+  late final _clang_VirtualFileOverlay_addFileMappingPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int32 Function(CXVirtualFileOverlay, ffi.Pointer<ffi.Char>,
+                  ffi.Pointer<ffi.Char>)>>(
+      'clang_VirtualFileOverlay_addFileMapping');
+  late final _clang_VirtualFileOverlay_addFileMapping =
+      _clang_VirtualFileOverlay_addFileMappingPtr.asFunction<
+          int Function(CXVirtualFileOverlay, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>)>();
+
+  /// Set the case sensitivity for the CXVirtualFileOverlay object. The
+  /// CXVirtualFileOverlay object is case-sensitive by default, this option can
+  /// be used to override the default.
+  int clang_VirtualFileOverlay_setCaseSensitivity(
+    CXVirtualFileOverlay arg0,
+    int caseSensitive,
+  ) {
+    return _clang_VirtualFileOverlay_setCaseSensitivity(
+      arg0,
+      caseSensitive,
+    );
+  }
+
+  late final _clang_VirtualFileOverlay_setCaseSensitivityPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Int32 Function(CXVirtualFileOverlay, ffi.Int)>>(
+      'clang_VirtualFileOverlay_setCaseSensitivity');
+  late final _clang_VirtualFileOverlay_setCaseSensitivity =
+      _clang_VirtualFileOverlay_setCaseSensitivityPtr
+          .asFunction<int Function(CXVirtualFileOverlay, int)>();
+
+  /// Write out the CXVirtualFileOverlay object to a char buffer.
+  int clang_VirtualFileOverlay_writeToBuffer(
+    CXVirtualFileOverlay arg0,
+    int options,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> out_buffer_ptr,
+    ffi.Pointer<ffi.UnsignedInt> out_buffer_size,
+  ) {
+    return _clang_VirtualFileOverlay_writeToBuffer(
+      arg0,
+      options,
+      out_buffer_ptr,
+      out_buffer_size,
+    );
+  }
+
+  late final _clang_VirtualFileOverlay_writeToBufferPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int32 Function(
+                  CXVirtualFileOverlay,
+                  ffi.UnsignedInt,
+                  ffi.Pointer<ffi.Pointer<ffi.Char>>,
+                  ffi.Pointer<ffi.UnsignedInt>)>>(
+      'clang_VirtualFileOverlay_writeToBuffer');
+  late final _clang_VirtualFileOverlay_writeToBuffer =
+      _clang_VirtualFileOverlay_writeToBufferPtr.asFunction<
+          int Function(
+              CXVirtualFileOverlay,
+              int,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// free memory allocated by libclang, such as the buffer returned by
+  /// CXVirtualFileOverlay() or clang_ModuleMapDescriptor_writeToBuffer().
+  void clang_free(
+    ffi.Pointer<ffi.Void> buffer,
+  ) {
+    return _clang_free(
+      buffer,
+    );
+  }
+
+  late final _clang_freePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
+          'clang_free');
+  late final _clang_free =
+      _clang_freePtr.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
+
+  /// Dispose a CXVirtualFileOverlay object.
+  void clang_VirtualFileOverlay_dispose(
+    CXVirtualFileOverlay arg0,
+  ) {
+    return _clang_VirtualFileOverlay_dispose(
+      arg0,
+    );
+  }
+
+  late final _clang_VirtualFileOverlay_disposePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXVirtualFileOverlay)>>(
+          'clang_VirtualFileOverlay_dispose');
+  late final _clang_VirtualFileOverlay_dispose =
+      _clang_VirtualFileOverlay_disposePtr
+          .asFunction<void Function(CXVirtualFileOverlay)>();
+
+  /// Create a CXModuleMapDescriptor object. Must be disposed with
+  /// clang_ModuleMapDescriptor_dispose().
+  CXModuleMapDescriptor clang_ModuleMapDescriptor_create(
+    int options,
+  ) {
+    return _clang_ModuleMapDescriptor_create(
+      options,
+    );
+  }
+
+  late final _clang_ModuleMapDescriptor_createPtr = _lookup<
+          ffi.NativeFunction<CXModuleMapDescriptor Function(ffi.UnsignedInt)>>(
+      'clang_ModuleMapDescriptor_create');
+  late final _clang_ModuleMapDescriptor_create =
+      _clang_ModuleMapDescriptor_createPtr
+          .asFunction<CXModuleMapDescriptor Function(int)>();
+
+  /// Sets the framework module name that the module.map describes.
+  int clang_ModuleMapDescriptor_setFrameworkModuleName(
+    CXModuleMapDescriptor arg0,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _clang_ModuleMapDescriptor_setFrameworkModuleName(
+      arg0,
+      name,
+    );
+  }
+
+  late final _clang_ModuleMapDescriptor_setFrameworkModuleNamePtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int32 Function(
+                  CXModuleMapDescriptor, ffi.Pointer<ffi.Char>)>>(
+      'clang_ModuleMapDescriptor_setFrameworkModuleName');
+  late final _clang_ModuleMapDescriptor_setFrameworkModuleName =
+      _clang_ModuleMapDescriptor_setFrameworkModuleNamePtr.asFunction<
+          int Function(CXModuleMapDescriptor, ffi.Pointer<ffi.Char>)>();
+
+  /// Sets the umbrealla header name that the module.map describes.
+  int clang_ModuleMapDescriptor_setUmbrellaHeader(
+    CXModuleMapDescriptor arg0,
+    ffi.Pointer<ffi.Char> name,
+  ) {
+    return _clang_ModuleMapDescriptor_setUmbrellaHeader(
+      arg0,
+      name,
+    );
+  }
+
+  late final _clang_ModuleMapDescriptor_setUmbrellaHeaderPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int32 Function(
+                  CXModuleMapDescriptor, ffi.Pointer<ffi.Char>)>>(
+      'clang_ModuleMapDescriptor_setUmbrellaHeader');
+  late final _clang_ModuleMapDescriptor_setUmbrellaHeader =
+      _clang_ModuleMapDescriptor_setUmbrellaHeaderPtr.asFunction<
+          int Function(CXModuleMapDescriptor, ffi.Pointer<ffi.Char>)>();
+
+  /// Write out the CXModuleMapDescriptor object to a char buffer.
+  int clang_ModuleMapDescriptor_writeToBuffer(
+    CXModuleMapDescriptor arg0,
+    int options,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> out_buffer_ptr,
+    ffi.Pointer<ffi.UnsignedInt> out_buffer_size,
+  ) {
+    return _clang_ModuleMapDescriptor_writeToBuffer(
+      arg0,
+      options,
+      out_buffer_ptr,
+      out_buffer_size,
+    );
+  }
+
+  late final _clang_ModuleMapDescriptor_writeToBufferPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int32 Function(
+                  CXModuleMapDescriptor,
+                  ffi.UnsignedInt,
+                  ffi.Pointer<ffi.Pointer<ffi.Char>>,
+                  ffi.Pointer<ffi.UnsignedInt>)>>(
+      'clang_ModuleMapDescriptor_writeToBuffer');
+  late final _clang_ModuleMapDescriptor_writeToBuffer =
+      _clang_ModuleMapDescriptor_writeToBufferPtr.asFunction<
+          int Function(
+              CXModuleMapDescriptor,
+              int,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Dispose a CXModuleMapDescriptor object.
+  void clang_ModuleMapDescriptor_dispose(
+    CXModuleMapDescriptor arg0,
+  ) {
+    return _clang_ModuleMapDescriptor_dispose(
+      arg0,
+    );
+  }
+
+  late final _clang_ModuleMapDescriptor_disposePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXModuleMapDescriptor)>>(
+          'clang_ModuleMapDescriptor_dispose');
+  late final _clang_ModuleMapDescriptor_dispose =
+      _clang_ModuleMapDescriptor_disposePtr
+          .asFunction<void Function(CXModuleMapDescriptor)>();
+
+  /// Provides a shared context for creating translation units.
+  CXIndex clang_createIndex(
+    int excludeDeclarationsFromPCH,
+    int displayDiagnostics,
+  ) {
+    return _clang_createIndex(
+      excludeDeclarationsFromPCH,
+      displayDiagnostics,
+    );
+  }
+
+  late final _clang_createIndexPtr =
+      _lookup<ffi.NativeFunction<CXIndex Function(ffi.Int, ffi.Int)>>(
+          'clang_createIndex');
+  late final _clang_createIndex =
+      _clang_createIndexPtr.asFunction<CXIndex Function(int, int)>();
+
+  /// Destroy the given index.
+  void clang_disposeIndex(
+    CXIndex index,
+  ) {
+    return _clang_disposeIndex(
+      index,
+    );
+  }
+
+  late final _clang_disposeIndexPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXIndex)>>(
+          'clang_disposeIndex');
+  late final _clang_disposeIndex =
+      _clang_disposeIndexPtr.asFunction<void Function(CXIndex)>();
+
+  /// Sets general options associated with a CXIndex.
+  void clang_CXIndex_setGlobalOptions(
+    CXIndex arg0,
+    int options,
+  ) {
+    return _clang_CXIndex_setGlobalOptions(
+      arg0,
+      options,
+    );
+  }
+
+  late final _clang_CXIndex_setGlobalOptionsPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXIndex, ffi.UnsignedInt)>>(
+          'clang_CXIndex_setGlobalOptions');
+  late final _clang_CXIndex_setGlobalOptions =
+      _clang_CXIndex_setGlobalOptionsPtr
+          .asFunction<void Function(CXIndex, int)>();
+
+  /// Gets the general options associated with a CXIndex.
+  int clang_CXIndex_getGlobalOptions(
+    CXIndex arg0,
+  ) {
+    return _clang_CXIndex_getGlobalOptions(
+      arg0,
+    );
+  }
+
+  late final _clang_CXIndex_getGlobalOptionsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXIndex)>>(
+          'clang_CXIndex_getGlobalOptions');
+  late final _clang_CXIndex_getGlobalOptions =
+      _clang_CXIndex_getGlobalOptionsPtr.asFunction<int Function(CXIndex)>();
+
+  /// Sets the invocation emission path option in a CXIndex.
+  void clang_CXIndex_setInvocationEmissionPathOption(
+    CXIndex arg0,
+    ffi.Pointer<ffi.Char> Path,
+  ) {
+    return _clang_CXIndex_setInvocationEmissionPathOption(
+      arg0,
+      Path,
+    );
+  }
+
+  late final _clang_CXIndex_setInvocationEmissionPathOptionPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Void Function(CXIndex, ffi.Pointer<ffi.Char>)>>(
+      'clang_CXIndex_setInvocationEmissionPathOption');
+  late final _clang_CXIndex_setInvocationEmissionPathOption =
+      _clang_CXIndex_setInvocationEmissionPathOptionPtr
+          .asFunction<void Function(CXIndex, ffi.Pointer<ffi.Char>)>();
+
+  /// Retrieve the complete file and path name of the given file.
+  CXString clang_getFileName(
+    CXFile SFile,
+  ) {
+    return _clang_getFileName(
+      SFile,
+    );
+  }
+
+  late final _clang_getFileNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXFile)>>(
+          'clang_getFileName');
+  late final _clang_getFileName =
+      _clang_getFileNamePtr.asFunction<CXString Function(CXFile)>();
+
+  /// Retrieve the last modification time of the given file.
+  int clang_getFileTime(
+    CXFile SFile,
+  ) {
+    return _clang_getFileTime(
+      SFile,
+    );
+  }
+
+  late final _clang_getFileTimePtr =
+      _lookup<ffi.NativeFunction<ffi.Int64 Function(CXFile)>>(
+          'clang_getFileTime');
+  late final _clang_getFileTime =
+      _clang_getFileTimePtr.asFunction<int Function(CXFile)>();
+
+  /// Retrieve the unique ID for the given file.
+  int clang_getFileUniqueID(
+    CXFile file,
+    ffi.Pointer<CXFileUniqueID> outID,
+  ) {
+    return _clang_getFileUniqueID(
+      file,
+      outID,
+    );
+  }
+
+  late final _clang_getFileUniqueIDPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              CXFile, ffi.Pointer<CXFileUniqueID>)>>('clang_getFileUniqueID');
+  late final _clang_getFileUniqueID = _clang_getFileUniqueIDPtr
+      .asFunction<int Function(CXFile, ffi.Pointer<CXFileUniqueID>)>();
+
+  /// Determine whether the given header is guarded against multiple inclusions,
+  /// either with the conventional #ifndef/#define/#endif macro guards or with
+  /// #pragma once.
+  int clang_isFileMultipleIncludeGuarded(
+    CXTranslationUnit tu,
+    CXFile file,
+  ) {
+    return _clang_isFileMultipleIncludeGuarded(
+      tu,
+      file,
+    );
+  }
+
+  late final _clang_isFileMultipleIncludeGuardedPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.UnsignedInt Function(CXTranslationUnit, CXFile)>>(
+      'clang_isFileMultipleIncludeGuarded');
+  late final _clang_isFileMultipleIncludeGuarded =
+      _clang_isFileMultipleIncludeGuardedPtr
+          .asFunction<int Function(CXTranslationUnit, CXFile)>();
+
+  /// Retrieve a file handle within the given translation unit.
+  CXFile clang_getFile(
+    CXTranslationUnit tu,
+    ffi.Pointer<ffi.Char> file_name,
+  ) {
+    return _clang_getFile(
+      tu,
+      file_name,
+    );
+  }
+
+  late final _clang_getFilePtr = _lookup<
+      ffi.NativeFunction<
+          CXFile Function(
+              CXTranslationUnit, ffi.Pointer<ffi.Char>)>>('clang_getFile');
+  late final _clang_getFile = _clang_getFilePtr
+      .asFunction<CXFile Function(CXTranslationUnit, ffi.Pointer<ffi.Char>)>();
+
+  /// Retrieve the buffer associated with the given file.
+  ffi.Pointer<ffi.Char> clang_getFileContents(
+    CXTranslationUnit tu,
+    CXFile file,
+    ffi.Pointer<ffi.Size> size,
+  ) {
+    return _clang_getFileContents(
+      tu,
+      file,
+      size,
+    );
+  }
+
+  late final _clang_getFileContentsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(CXTranslationUnit, CXFile,
+              ffi.Pointer<ffi.Size>)>>('clang_getFileContents');
+  late final _clang_getFileContents = _clang_getFileContentsPtr.asFunction<
+      ffi.Pointer<ffi.Char> Function(
+          CXTranslationUnit, CXFile, ffi.Pointer<ffi.Size>)>();
+
+  /// Returns non-zero if the file1 and file2 point to the same file, or they
+  /// are both NULL.
+  int clang_File_isEqual(
+    CXFile file1,
+    CXFile file2,
+  ) {
+    return _clang_File_isEqual(
+      file1,
+      file2,
+    );
+  }
+
+  late final _clang_File_isEqualPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXFile, CXFile)>>(
+          'clang_File_isEqual');
+  late final _clang_File_isEqual =
+      _clang_File_isEqualPtr.asFunction<int Function(CXFile, CXFile)>();
+
+  /// Returns the real path name of file.
+  CXString clang_File_tryGetRealPathName(
+    CXFile file,
+  ) {
+    return _clang_File_tryGetRealPathName(
+      file,
+    );
+  }
+
+  late final _clang_File_tryGetRealPathNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXFile)>>(
+          'clang_File_tryGetRealPathName');
+  late final _clang_File_tryGetRealPathName =
+      _clang_File_tryGetRealPathNamePtr.asFunction<CXString Function(CXFile)>();
+
+  /// Retrieve a NULL (invalid) source location.
+  CXSourceLocation clang_getNullLocation() {
+    return _clang_getNullLocation();
+  }
+
+  late final _clang_getNullLocationPtr =
+      _lookup<ffi.NativeFunction<CXSourceLocation Function()>>(
+          'clang_getNullLocation');
+  late final _clang_getNullLocation =
+      _clang_getNullLocationPtr.asFunction<CXSourceLocation Function()>();
+
+  /// Determine whether two source locations, which must refer into the same
+  /// translation unit, refer to exactly the same point in the source code.
+  int clang_equalLocations(
+    CXSourceLocation loc1,
+    CXSourceLocation loc2,
+  ) {
+    return _clang_equalLocations(
+      loc1,
+      loc2,
+    );
+  }
+
+  late final _clang_equalLocationsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.UnsignedInt Function(
+              CXSourceLocation, CXSourceLocation)>>('clang_equalLocations');
+  late final _clang_equalLocations = _clang_equalLocationsPtr
+      .asFunction<int Function(CXSourceLocation, CXSourceLocation)>();
+
+  /// Retrieves the source location associated with a given file/line/column in
+  /// a particular translation unit.
+  CXSourceLocation clang_getLocation(
+    CXTranslationUnit tu,
+    CXFile file,
+    int line,
+    int column,
+  ) {
+    return _clang_getLocation(
+      tu,
+      file,
+      line,
+      column,
+    );
+  }
+
+  late final _clang_getLocationPtr = _lookup<
+      ffi.NativeFunction<
+          CXSourceLocation Function(CXTranslationUnit, CXFile, ffi.UnsignedInt,
+              ffi.UnsignedInt)>>('clang_getLocation');
+  late final _clang_getLocation = _clang_getLocationPtr.asFunction<
+      CXSourceLocation Function(CXTranslationUnit, CXFile, int, int)>();
+
+  /// Retrieves the source location associated with a given character offset in
+  /// a particular translation unit.
+  CXSourceLocation clang_getLocationForOffset(
+    CXTranslationUnit tu,
+    CXFile file,
+    int offset,
+  ) {
+    return _clang_getLocationForOffset(
+      tu,
+      file,
+      offset,
+    );
+  }
+
+  late final _clang_getLocationForOffsetPtr = _lookup<
+      ffi.NativeFunction<
+          CXSourceLocation Function(CXTranslationUnit, CXFile,
+              ffi.UnsignedInt)>>('clang_getLocationForOffset');
+  late final _clang_getLocationForOffset = _clang_getLocationForOffsetPtr
+      .asFunction<CXSourceLocation Function(CXTranslationUnit, CXFile, int)>();
+
+  /// Returns non-zero if the given source location is in a system header.
+  int clang_Location_isInSystemHeader(
+    CXSourceLocation location,
+  ) {
+    return _clang_Location_isInSystemHeader(
+      location,
+    );
+  }
+
+  late final _clang_Location_isInSystemHeaderPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXSourceLocation)>>(
+          'clang_Location_isInSystemHeader');
+  late final _clang_Location_isInSystemHeader =
+      _clang_Location_isInSystemHeaderPtr
+          .asFunction<int Function(CXSourceLocation)>();
+
+  /// Returns non-zero if the given source location is in the main file of the
+  /// corresponding translation unit.
+  int clang_Location_isFromMainFile(
+    CXSourceLocation location,
+  ) {
+    return _clang_Location_isFromMainFile(
+      location,
+    );
+  }
+
+  late final _clang_Location_isFromMainFilePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXSourceLocation)>>(
+          'clang_Location_isFromMainFile');
+  late final _clang_Location_isFromMainFile = _clang_Location_isFromMainFilePtr
+      .asFunction<int Function(CXSourceLocation)>();
+
+  /// Retrieve a NULL (invalid) source range.
+  CXSourceRange clang_getNullRange() {
+    return _clang_getNullRange();
+  }
+
+  late final _clang_getNullRangePtr =
+      _lookup<ffi.NativeFunction<CXSourceRange Function()>>(
+          'clang_getNullRange');
+  late final _clang_getNullRange =
+      _clang_getNullRangePtr.asFunction<CXSourceRange Function()>();
+
+  /// Retrieve a source range given the beginning and ending source locations.
+  CXSourceRange clang_getRange(
+    CXSourceLocation begin,
+    CXSourceLocation end,
+  ) {
+    return _clang_getRange(
+      begin,
+      end,
+    );
+  }
+
+  late final _clang_getRangePtr = _lookup<
+      ffi.NativeFunction<
+          CXSourceRange Function(
+              CXSourceLocation, CXSourceLocation)>>('clang_getRange');
+  late final _clang_getRange = _clang_getRangePtr
+      .asFunction<CXSourceRange Function(CXSourceLocation, CXSourceLocation)>();
+
+  /// Determine whether two ranges are equivalent.
+  int clang_equalRanges(
+    CXSourceRange range1,
+    CXSourceRange range2,
+  ) {
+    return _clang_equalRanges(
+      range1,
+      range2,
+    );
+  }
+
+  late final _clang_equalRangesPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.UnsignedInt Function(
+              CXSourceRange, CXSourceRange)>>('clang_equalRanges');
+  late final _clang_equalRanges = _clang_equalRangesPtr
+      .asFunction<int Function(CXSourceRange, CXSourceRange)>();
+
+  /// Returns non-zero if range is null.
+  int clang_Range_isNull(
+    CXSourceRange range,
+  ) {
+    return _clang_Range_isNull(
+      range,
+    );
+  }
+
+  late final _clang_Range_isNullPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXSourceRange)>>(
+          'clang_Range_isNull');
+  late final _clang_Range_isNull =
+      _clang_Range_isNullPtr.asFunction<int Function(CXSourceRange)>();
+
+  /// Retrieve the file, line, column, and offset represented by the given
+  /// source location.
+  void clang_getExpansionLocation(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset,
+  ) {
+    return _clang_getExpansionLocation(
+      location,
+      file,
+      line,
+      column,
+      offset,
+    );
+  }
+
+  late final _clang_getExpansionLocationPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              CXSourceLocation,
+              ffi.Pointer<CXFile>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>>('clang_getExpansionLocation');
+  late final _clang_getExpansionLocation =
+      _clang_getExpansionLocationPtr.asFunction<
+          void Function(
+              CXSourceLocation,
+              ffi.Pointer<CXFile>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Retrieve the file, line and column represented by the given source
+  /// location, as specified in a # line directive.
+  void clang_getPresumedLocation(
+    CXSourceLocation location,
+    ffi.Pointer<CXString> filename,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+  ) {
+    return _clang_getPresumedLocation(
+      location,
+      filename,
+      line,
+      column,
+    );
+  }
+
+  late final _clang_getPresumedLocationPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              CXSourceLocation,
+              ffi.Pointer<CXString>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>>('clang_getPresumedLocation');
+  late final _clang_getPresumedLocation =
+      _clang_getPresumedLocationPtr.asFunction<
+          void Function(CXSourceLocation, ffi.Pointer<CXString>,
+              ffi.Pointer<ffi.UnsignedInt>, ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Legacy API to retrieve the file, line, column, and offset represented by
+  /// the given source location.
+  void clang_getInstantiationLocation(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset,
+  ) {
+    return _clang_getInstantiationLocation(
+      location,
+      file,
+      line,
+      column,
+      offset,
+    );
+  }
+
+  late final _clang_getInstantiationLocationPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              CXSourceLocation,
+              ffi.Pointer<CXFile>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>>('clang_getInstantiationLocation');
+  late final _clang_getInstantiationLocation =
+      _clang_getInstantiationLocationPtr.asFunction<
+          void Function(
+              CXSourceLocation,
+              ffi.Pointer<CXFile>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Retrieve the file, line, column, and offset represented by the given
+  /// source location.
+  void clang_getSpellingLocation(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset,
+  ) {
+    return _clang_getSpellingLocation(
+      location,
+      file,
+      line,
+      column,
+      offset,
+    );
+  }
+
+  late final _clang_getSpellingLocationPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              CXSourceLocation,
+              ffi.Pointer<CXFile>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>>('clang_getSpellingLocation');
+  late final _clang_getSpellingLocation =
+      _clang_getSpellingLocationPtr.asFunction<
+          void Function(
+              CXSourceLocation,
+              ffi.Pointer<CXFile>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Retrieve the file, line, column, and offset represented by the given
+  /// source location.
+  void clang_getFileLocation(
+    CXSourceLocation location,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset,
+  ) {
+    return _clang_getFileLocation(
+      location,
+      file,
+      line,
+      column,
+      offset,
+    );
+  }
+
+  late final _clang_getFileLocationPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              CXSourceLocation,
+              ffi.Pointer<CXFile>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>>('clang_getFileLocation');
+  late final _clang_getFileLocation = _clang_getFileLocationPtr.asFunction<
+      void Function(
+          CXSourceLocation,
+          ffi.Pointer<CXFile>,
+          ffi.Pointer<ffi.UnsignedInt>,
+          ffi.Pointer<ffi.UnsignedInt>,
+          ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Retrieve a source location representing the first character within a
+  /// source range.
+  CXSourceLocation clang_getRangeStart(
+    CXSourceRange range,
+  ) {
+    return _clang_getRangeStart(
+      range,
+    );
+  }
+
+  late final _clang_getRangeStartPtr =
+      _lookup<ffi.NativeFunction<CXSourceLocation Function(CXSourceRange)>>(
+          'clang_getRangeStart');
+  late final _clang_getRangeStart = _clang_getRangeStartPtr
+      .asFunction<CXSourceLocation Function(CXSourceRange)>();
+
+  /// Retrieve a source location representing the last character within a source
+  /// range.
+  CXSourceLocation clang_getRangeEnd(
+    CXSourceRange range,
+  ) {
+    return _clang_getRangeEnd(
+      range,
+    );
+  }
+
+  late final _clang_getRangeEndPtr =
+      _lookup<ffi.NativeFunction<CXSourceLocation Function(CXSourceRange)>>(
+          'clang_getRangeEnd');
+  late final _clang_getRangeEnd = _clang_getRangeEndPtr
+      .asFunction<CXSourceLocation Function(CXSourceRange)>();
+
+  /// Retrieve all ranges that were skipped by the preprocessor.
+  ffi.Pointer<CXSourceRangeList> clang_getSkippedRanges(
+    CXTranslationUnit tu,
+    CXFile file,
+  ) {
+    return _clang_getSkippedRanges(
+      tu,
+      file,
+    );
+  }
+
+  late final _clang_getSkippedRangesPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<CXSourceRangeList> Function(
+              CXTranslationUnit, CXFile)>>('clang_getSkippedRanges');
+  late final _clang_getSkippedRanges = _clang_getSkippedRangesPtr.asFunction<
+      ffi.Pointer<CXSourceRangeList> Function(CXTranslationUnit, CXFile)>();
+
+  /// Retrieve all ranges from all files that were skipped by the preprocessor.
+  ffi.Pointer<CXSourceRangeList> clang_getAllSkippedRanges(
+    CXTranslationUnit tu,
+  ) {
+    return _clang_getAllSkippedRanges(
+      tu,
+    );
+  }
+
+  late final _clang_getAllSkippedRangesPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<CXSourceRangeList> Function(
+              CXTranslationUnit)>>('clang_getAllSkippedRanges');
+  late final _clang_getAllSkippedRanges = _clang_getAllSkippedRangesPtr
+      .asFunction<ffi.Pointer<CXSourceRangeList> Function(CXTranslationUnit)>();
+
+  /// Destroy the given CXSourceRangeList.
+  void clang_disposeSourceRangeList(
+    ffi.Pointer<CXSourceRangeList> ranges,
+  ) {
+    return _clang_disposeSourceRangeList(
+      ranges,
+    );
+  }
+
+  late final _clang_disposeSourceRangeListPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Void Function(ffi.Pointer<CXSourceRangeList>)>>(
+      'clang_disposeSourceRangeList');
+  late final _clang_disposeSourceRangeList = _clang_disposeSourceRangeListPtr
+      .asFunction<void Function(ffi.Pointer<CXSourceRangeList>)>();
+
+  /// Determine the number of diagnostics in a CXDiagnosticSet.
+  int clang_getNumDiagnosticsInSet(
+    CXDiagnosticSet Diags,
+  ) {
+    return _clang_getNumDiagnosticsInSet(
+      Diags,
+    );
+  }
+
+  late final _clang_getNumDiagnosticsInSetPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXDiagnosticSet)>>(
+          'clang_getNumDiagnosticsInSet');
+  late final _clang_getNumDiagnosticsInSet = _clang_getNumDiagnosticsInSetPtr
+      .asFunction<int Function(CXDiagnosticSet)>();
+
+  /// Retrieve a diagnostic associated with the given CXDiagnosticSet.
+  CXDiagnostic clang_getDiagnosticInSet(
+    CXDiagnosticSet Diags,
+    int Index,
+  ) {
+    return _clang_getDiagnosticInSet(
+      Diags,
+      Index,
+    );
+  }
+
+  late final _clang_getDiagnosticInSetPtr = _lookup<
+      ffi.NativeFunction<
+          CXDiagnostic Function(
+              CXDiagnosticSet, ffi.UnsignedInt)>>('clang_getDiagnosticInSet');
+  late final _clang_getDiagnosticInSet = _clang_getDiagnosticInSetPtr
+      .asFunction<CXDiagnostic Function(CXDiagnosticSet, int)>();
+
+  /// Deserialize a set of diagnostics from a Clang diagnostics bitcode file.
+  CXDiagnosticSet clang_loadDiagnostics(
+    ffi.Pointer<ffi.Char> file,
+    ffi.Pointer<ffi.Int32> error,
+    ffi.Pointer<CXString> errorString,
+  ) {
+    return _clang_loadDiagnostics(
+      file,
+      error,
+      errorString,
+    );
+  }
+
+  late final _clang_loadDiagnosticsPtr = _lookup<
+      ffi.NativeFunction<
+          CXDiagnosticSet Function(
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Int32>,
+              ffi.Pointer<CXString>)>>('clang_loadDiagnostics');
+  late final _clang_loadDiagnostics = _clang_loadDiagnosticsPtr.asFunction<
+      CXDiagnosticSet Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Int32>,
+          ffi.Pointer<CXString>)>();
+
+  /// Release a CXDiagnosticSet and all of its contained diagnostics.
+  void clang_disposeDiagnosticSet(
+    CXDiagnosticSet Diags,
+  ) {
+    return _clang_disposeDiagnosticSet(
+      Diags,
+    );
+  }
+
+  late final _clang_disposeDiagnosticSetPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXDiagnosticSet)>>(
+          'clang_disposeDiagnosticSet');
+  late final _clang_disposeDiagnosticSet = _clang_disposeDiagnosticSetPtr
+      .asFunction<void Function(CXDiagnosticSet)>();
+
+  /// Retrieve the child diagnostics of a CXDiagnostic.
+  CXDiagnosticSet clang_getChildDiagnostics(
+    CXDiagnostic D,
+  ) {
+    return _clang_getChildDiagnostics(
+      D,
+    );
+  }
+
+  late final _clang_getChildDiagnosticsPtr =
+      _lookup<ffi.NativeFunction<CXDiagnosticSet Function(CXDiagnostic)>>(
+          'clang_getChildDiagnostics');
+  late final _clang_getChildDiagnostics = _clang_getChildDiagnosticsPtr
+      .asFunction<CXDiagnosticSet Function(CXDiagnostic)>();
+
+  /// Determine the number of diagnostics produced for the given translation
+  /// unit.
+  int clang_getNumDiagnostics(
+    CXTranslationUnit Unit,
+  ) {
+    return _clang_getNumDiagnostics(
+      Unit,
+    );
+  }
+
+  late final _clang_getNumDiagnosticsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXTranslationUnit)>>(
+          'clang_getNumDiagnostics');
+  late final _clang_getNumDiagnostics =
+      _clang_getNumDiagnosticsPtr.asFunction<int Function(CXTranslationUnit)>();
+
+  /// Retrieve a diagnostic associated with the given translation unit.
+  CXDiagnostic clang_getDiagnostic(
+    CXTranslationUnit Unit,
+    int Index,
+  ) {
+    return _clang_getDiagnostic(
+      Unit,
+      Index,
+    );
+  }
+
+  late final _clang_getDiagnosticPtr = _lookup<
+      ffi.NativeFunction<
+          CXDiagnostic Function(
+              CXTranslationUnit, ffi.UnsignedInt)>>('clang_getDiagnostic');
+  late final _clang_getDiagnostic = _clang_getDiagnosticPtr
+      .asFunction<CXDiagnostic Function(CXTranslationUnit, int)>();
+
+  /// Retrieve the complete set of diagnostics associated with a translation
+  /// unit.
+  CXDiagnosticSet clang_getDiagnosticSetFromTU(
+    CXTranslationUnit Unit,
+  ) {
+    return _clang_getDiagnosticSetFromTU(
+      Unit,
+    );
+  }
+
+  late final _clang_getDiagnosticSetFromTUPtr =
+      _lookup<ffi.NativeFunction<CXDiagnosticSet Function(CXTranslationUnit)>>(
+          'clang_getDiagnosticSetFromTU');
+  late final _clang_getDiagnosticSetFromTU = _clang_getDiagnosticSetFromTUPtr
+      .asFunction<CXDiagnosticSet Function(CXTranslationUnit)>();
+
+  /// Destroy a diagnostic.
+  void clang_disposeDiagnostic(
+    CXDiagnostic Diagnostic,
+  ) {
+    return _clang_disposeDiagnostic(
+      Diagnostic,
+    );
+  }
+
+  late final _clang_disposeDiagnosticPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXDiagnostic)>>(
+          'clang_disposeDiagnostic');
+  late final _clang_disposeDiagnostic =
+      _clang_disposeDiagnosticPtr.asFunction<void Function(CXDiagnostic)>();
+
+  /// Format the given diagnostic in a manner that is suitable for display.
+  CXString clang_formatDiagnostic(
+    CXDiagnostic Diagnostic,
+    int Options,
+  ) {
+    return _clang_formatDiagnostic(
+      Diagnostic,
+      Options,
+    );
+  }
+
+  late final _clang_formatDiagnosticPtr = _lookup<
+          ffi.NativeFunction<CXString Function(CXDiagnostic, ffi.UnsignedInt)>>(
+      'clang_formatDiagnostic');
+  late final _clang_formatDiagnostic = _clang_formatDiagnosticPtr
+      .asFunction<CXString Function(CXDiagnostic, int)>();
+
+  /// Retrieve the set of display options most similar to the default behavior
+  /// of the clang compiler.
+  int clang_defaultDiagnosticDisplayOptions() {
+    return _clang_defaultDiagnosticDisplayOptions();
+  }
+
+  late final _clang_defaultDiagnosticDisplayOptionsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function()>>(
+          'clang_defaultDiagnosticDisplayOptions');
+  late final _clang_defaultDiagnosticDisplayOptions =
+      _clang_defaultDiagnosticDisplayOptionsPtr.asFunction<int Function()>();
+
+  /// Determine the severity of the given diagnostic.
+  int clang_getDiagnosticSeverity(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticSeverity(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticSeverityPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXDiagnostic)>>(
+          'clang_getDiagnosticSeverity');
+  late final _clang_getDiagnosticSeverity =
+      _clang_getDiagnosticSeverityPtr.asFunction<int Function(CXDiagnostic)>();
+
+  /// Retrieve the source location of the given diagnostic.
+  CXSourceLocation clang_getDiagnosticLocation(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticLocation(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticLocationPtr =
+      _lookup<ffi.NativeFunction<CXSourceLocation Function(CXDiagnostic)>>(
+          'clang_getDiagnosticLocation');
+  late final _clang_getDiagnosticLocation = _clang_getDiagnosticLocationPtr
+      .asFunction<CXSourceLocation Function(CXDiagnostic)>();
+
+  /// Retrieve the text of the given diagnostic.
+  CXString clang_getDiagnosticSpelling(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticSpelling(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticSpellingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXDiagnostic)>>(
+          'clang_getDiagnosticSpelling');
+  late final _clang_getDiagnosticSpelling = _clang_getDiagnosticSpellingPtr
+      .asFunction<CXString Function(CXDiagnostic)>();
+
+  /// Retrieve the name of the command-line option that enabled this diagnostic.
+  CXString clang_getDiagnosticOption(
+    CXDiagnostic Diag,
+    ffi.Pointer<CXString> Disable,
+  ) {
+    return _clang_getDiagnosticOption(
+      Diag,
+      Disable,
+    );
+  }
+
+  late final _clang_getDiagnosticOptionPtr = _lookup<
+      ffi.NativeFunction<
+          CXString Function(CXDiagnostic,
+              ffi.Pointer<CXString>)>>('clang_getDiagnosticOption');
+  late final _clang_getDiagnosticOption = _clang_getDiagnosticOptionPtr
+      .asFunction<CXString Function(CXDiagnostic, ffi.Pointer<CXString>)>();
+
+  /// Retrieve the category number for this diagnostic.
+  int clang_getDiagnosticCategory(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticCategory(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticCategoryPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXDiagnostic)>>(
+          'clang_getDiagnosticCategory');
+  late final _clang_getDiagnosticCategory =
+      _clang_getDiagnosticCategoryPtr.asFunction<int Function(CXDiagnostic)>();
+
+  /// Retrieve the name of a particular diagnostic category. This is now
+  /// deprecated. Use clang_getDiagnosticCategoryText() instead.
+  CXString clang_getDiagnosticCategoryName(
+    int Category,
+  ) {
+    return _clang_getDiagnosticCategoryName(
+      Category,
+    );
+  }
+
+  late final _clang_getDiagnosticCategoryNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(ffi.UnsignedInt)>>(
+          'clang_getDiagnosticCategoryName');
+  late final _clang_getDiagnosticCategoryName =
+      _clang_getDiagnosticCategoryNamePtr.asFunction<CXString Function(int)>();
+
+  /// Retrieve the diagnostic category text for a given diagnostic.
+  CXString clang_getDiagnosticCategoryText(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticCategoryText(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticCategoryTextPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXDiagnostic)>>(
+          'clang_getDiagnosticCategoryText');
+  late final _clang_getDiagnosticCategoryText =
+      _clang_getDiagnosticCategoryTextPtr
+          .asFunction<CXString Function(CXDiagnostic)>();
+
+  /// Determine the number of source ranges associated with the given
+  /// diagnostic.
+  int clang_getDiagnosticNumRanges(
+    CXDiagnostic arg0,
+  ) {
+    return _clang_getDiagnosticNumRanges(
+      arg0,
+    );
+  }
+
+  late final _clang_getDiagnosticNumRangesPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXDiagnostic)>>(
+          'clang_getDiagnosticNumRanges');
+  late final _clang_getDiagnosticNumRanges =
+      _clang_getDiagnosticNumRangesPtr.asFunction<int Function(CXDiagnostic)>();
+
+  /// Retrieve a source range associated with the diagnostic.
+  CXSourceRange clang_getDiagnosticRange(
+    CXDiagnostic Diagnostic,
+    int Range,
+  ) {
+    return _clang_getDiagnosticRange(
+      Diagnostic,
+      Range,
+    );
+  }
+
+  late final _clang_getDiagnosticRangePtr = _lookup<
+      ffi.NativeFunction<
+          CXSourceRange Function(
+              CXDiagnostic, ffi.UnsignedInt)>>('clang_getDiagnosticRange');
+  late final _clang_getDiagnosticRange = _clang_getDiagnosticRangePtr
+      .asFunction<CXSourceRange Function(CXDiagnostic, int)>();
+
+  /// Determine the number of fix-it hints associated with the given diagnostic.
+  int clang_getDiagnosticNumFixIts(
+    CXDiagnostic Diagnostic,
+  ) {
+    return _clang_getDiagnosticNumFixIts(
+      Diagnostic,
+    );
+  }
+
+  late final _clang_getDiagnosticNumFixItsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXDiagnostic)>>(
+          'clang_getDiagnosticNumFixIts');
+  late final _clang_getDiagnosticNumFixIts =
+      _clang_getDiagnosticNumFixItsPtr.asFunction<int Function(CXDiagnostic)>();
+
+  /// Retrieve the replacement information for a given fix-it.
+  CXString clang_getDiagnosticFixIt(
+    CXDiagnostic Diagnostic,
+    int FixIt,
+    ffi.Pointer<CXSourceRange> ReplacementRange,
+  ) {
+    return _clang_getDiagnosticFixIt(
+      Diagnostic,
+      FixIt,
+      ReplacementRange,
+    );
+  }
+
+  late final _clang_getDiagnosticFixItPtr = _lookup<
+      ffi.NativeFunction<
+          CXString Function(CXDiagnostic, ffi.UnsignedInt,
+              ffi.Pointer<CXSourceRange>)>>('clang_getDiagnosticFixIt');
+  late final _clang_getDiagnosticFixIt =
+      _clang_getDiagnosticFixItPtr.asFunction<
+          CXString Function(CXDiagnostic, int, ffi.Pointer<CXSourceRange>)>();
+
+  /// Get the original translation unit source file name.
+  CXString clang_getTranslationUnitSpelling(
+    CXTranslationUnit CTUnit,
+  ) {
+    return _clang_getTranslationUnitSpelling(
+      CTUnit,
+    );
+  }
+
+  late final _clang_getTranslationUnitSpellingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXTranslationUnit)>>(
+          'clang_getTranslationUnitSpelling');
+  late final _clang_getTranslationUnitSpelling =
+      _clang_getTranslationUnitSpellingPtr
+          .asFunction<CXString Function(CXTranslationUnit)>();
+
+  /// Return the CXTranslationUnit for a given source file and the provided
+  /// command line arguments one would pass to the compiler.
+  CXTranslationUnit clang_createTranslationUnitFromSourceFile(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    int num_clang_command_line_args,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> clang_command_line_args,
+    int num_unsaved_files,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+  ) {
+    return _clang_createTranslationUnitFromSourceFile(
+      CIdx,
+      source_filename,
+      num_clang_command_line_args,
+      clang_command_line_args,
+      num_unsaved_files,
+      unsaved_files,
+    );
+  }
+
+  late final _clang_createTranslationUnitFromSourceFilePtr = _lookup<
+          ffi.NativeFunction<
+              CXTranslationUnit Function(
+                  CXIndex,
+                  ffi.Pointer<ffi.Char>,
+                  ffi.Int,
+                  ffi.Pointer<ffi.Pointer<ffi.Char>>,
+                  ffi.UnsignedInt,
+                  ffi.Pointer<CXUnsavedFile>)>>(
+      'clang_createTranslationUnitFromSourceFile');
+  late final _clang_createTranslationUnitFromSourceFile =
+      _clang_createTranslationUnitFromSourceFilePtr.asFunction<
+          CXTranslationUnit Function(
+              CXIndex,
+              ffi.Pointer<ffi.Char>,
+              int,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              int,
+              ffi.Pointer<CXUnsavedFile>)>();
+
+  /// Same as clang_createTranslationUnit2, but returns the CXTranslationUnit
+  /// instead of an error code. In case of an error this routine returns a NULL
+  /// CXTranslationUnit, without further detailed error codes.
+  CXTranslationUnit clang_createTranslationUnit(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> ast_filename,
+  ) {
+    return _clang_createTranslationUnit(
+      CIdx,
+      ast_filename,
+    );
+  }
+
+  late final _clang_createTranslationUnitPtr = _lookup<
+      ffi.NativeFunction<
+          CXTranslationUnit Function(
+              CXIndex, ffi.Pointer<ffi.Char>)>>('clang_createTranslationUnit');
+  late final _clang_createTranslationUnit = _clang_createTranslationUnitPtr
+      .asFunction<CXTranslationUnit Function(CXIndex, ffi.Pointer<ffi.Char>)>();
+
+  /// Create a translation unit from an AST file ( -emit-ast).
+  int clang_createTranslationUnit2(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> ast_filename,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+  ) {
+    return _clang_createTranslationUnit2(
+      CIdx,
+      ast_filename,
+      out_TU,
+    );
+  }
+
+  late final _clang_createTranslationUnit2Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int32 Function(CXIndex, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<CXTranslationUnit>)>>('clang_createTranslationUnit2');
+  late final _clang_createTranslationUnit2 =
+      _clang_createTranslationUnit2Ptr.asFunction<
+          int Function(CXIndex, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<CXTranslationUnit>)>();
+
+  /// Returns the set of flags that is suitable for parsing a translation unit
+  /// that is being edited.
+  int clang_defaultEditingTranslationUnitOptions() {
+    return _clang_defaultEditingTranslationUnitOptions();
+  }
+
+  late final _clang_defaultEditingTranslationUnitOptionsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function()>>(
+          'clang_defaultEditingTranslationUnitOptions');
+  late final _clang_defaultEditingTranslationUnitOptions =
+      _clang_defaultEditingTranslationUnitOptionsPtr
+          .asFunction<int Function()>();
+
+  /// Same as clang_parseTranslationUnit2, but returns the CXTranslationUnit
+  /// instead of an error code. In case of an error this routine returns a NULL
+  /// CXTranslationUnit, without further detailed error codes.
+  CXTranslationUnit clang_parseTranslationUnit(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options,
+  ) {
+    return _clang_parseTranslationUnit(
+      CIdx,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      unsaved_files,
+      num_unsaved_files,
+      options,
+    );
+  }
+
+  late final _clang_parseTranslationUnitPtr = _lookup<
+      ffi.NativeFunction<
+          CXTranslationUnit Function(
+              CXIndex,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Int,
+              ffi.Pointer<CXUnsavedFile>,
+              ffi.UnsignedInt,
+              ffi.UnsignedInt)>>('clang_parseTranslationUnit');
+  late final _clang_parseTranslationUnit =
+      _clang_parseTranslationUnitPtr.asFunction<
+          CXTranslationUnit Function(
+              CXIndex,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              int,
+              ffi.Pointer<CXUnsavedFile>,
+              int,
+              int)>();
+
+  /// Parse the given source file and the translation unit corresponding to that
+  /// file.
+  int clang_parseTranslationUnit2(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+  ) {
+    return _clang_parseTranslationUnit2(
+      CIdx,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      unsaved_files,
+      num_unsaved_files,
+      options,
+      out_TU,
+    );
+  }
+
+  late final _clang_parseTranslationUnit2Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int32 Function(
+              CXIndex,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Int,
+              ffi.Pointer<CXUnsavedFile>,
+              ffi.UnsignedInt,
+              ffi.UnsignedInt,
+              ffi.Pointer<CXTranslationUnit>)>>('clang_parseTranslationUnit2');
+  late final _clang_parseTranslationUnit2 =
+      _clang_parseTranslationUnit2Ptr.asFunction<
+          int Function(
+              CXIndex,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              int,
+              ffi.Pointer<CXUnsavedFile>,
+              int,
+              int,
+              ffi.Pointer<CXTranslationUnit>)>();
+
+  /// Same as clang_parseTranslationUnit2 but requires a full command line for
+  /// command_line_args including argv[0]. This is useful if the standard
+  /// library paths are relative to the binary.
+  int clang_parseTranslationUnit2FullArgv(
+    CXIndex CIdx,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+  ) {
+    return _clang_parseTranslationUnit2FullArgv(
+      CIdx,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      unsaved_files,
+      num_unsaved_files,
+      options,
+      out_TU,
+    );
+  }
+
+  late final _clang_parseTranslationUnit2FullArgvPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int32 Function(
+                  CXIndex,
+                  ffi.Pointer<ffi.Char>,
+                  ffi.Pointer<ffi.Pointer<ffi.Char>>,
+                  ffi.Int,
+                  ffi.Pointer<CXUnsavedFile>,
+                  ffi.UnsignedInt,
+                  ffi.UnsignedInt,
+                  ffi.Pointer<CXTranslationUnit>)>>(
+      'clang_parseTranslationUnit2FullArgv');
+  late final _clang_parseTranslationUnit2FullArgv =
+      _clang_parseTranslationUnit2FullArgvPtr.asFunction<
+          int Function(
+              CXIndex,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              int,
+              ffi.Pointer<CXUnsavedFile>,
+              int,
+              int,
+              ffi.Pointer<CXTranslationUnit>)>();
+
+  /// Returns the set of flags that is suitable for saving a translation unit.
+  int clang_defaultSaveOptions(
+    CXTranslationUnit TU,
+  ) {
+    return _clang_defaultSaveOptions(
+      TU,
+    );
+  }
+
+  late final _clang_defaultSaveOptionsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXTranslationUnit)>>(
+          'clang_defaultSaveOptions');
+  late final _clang_defaultSaveOptions = _clang_defaultSaveOptionsPtr
+      .asFunction<int Function(CXTranslationUnit)>();
+
+  /// Saves a translation unit into a serialized representation of that
+  /// translation unit on disk.
+  int clang_saveTranslationUnit(
+    CXTranslationUnit TU,
+    ffi.Pointer<ffi.Char> FileName,
+    int options,
+  ) {
+    return _clang_saveTranslationUnit(
+      TU,
+      FileName,
+      options,
+    );
+  }
+
+  late final _clang_saveTranslationUnitPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(CXTranslationUnit, ffi.Pointer<ffi.Char>,
+              ffi.UnsignedInt)>>('clang_saveTranslationUnit');
+  late final _clang_saveTranslationUnit =
+      _clang_saveTranslationUnitPtr.asFunction<
+          int Function(CXTranslationUnit, ffi.Pointer<ffi.Char>, int)>();
+
+  /// Suspend a translation unit in order to free memory associated with it.
+  int clang_suspendTranslationUnit(
+    CXTranslationUnit arg0,
+  ) {
+    return _clang_suspendTranslationUnit(
+      arg0,
+    );
+  }
+
+  late final _clang_suspendTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXTranslationUnit)>>(
+          'clang_suspendTranslationUnit');
+  late final _clang_suspendTranslationUnit = _clang_suspendTranslationUnitPtr
+      .asFunction<int Function(CXTranslationUnit)>();
+
+  /// Destroy the specified CXTranslationUnit object.
+  void clang_disposeTranslationUnit(
+    CXTranslationUnit arg0,
+  ) {
+    return _clang_disposeTranslationUnit(
+      arg0,
+    );
+  }
+
+  late final _clang_disposeTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXTranslationUnit)>>(
+          'clang_disposeTranslationUnit');
+  late final _clang_disposeTranslationUnit = _clang_disposeTranslationUnitPtr
+      .asFunction<void Function(CXTranslationUnit)>();
+
+  /// Returns the set of flags that is suitable for reparsing a translation
+  /// unit.
+  int clang_defaultReparseOptions(
+    CXTranslationUnit TU,
+  ) {
+    return _clang_defaultReparseOptions(
+      TU,
+    );
+  }
+
+  late final _clang_defaultReparseOptionsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXTranslationUnit)>>(
+          'clang_defaultReparseOptions');
+  late final _clang_defaultReparseOptions = _clang_defaultReparseOptionsPtr
+      .asFunction<int Function(CXTranslationUnit)>();
+
+  /// Reparse the source files that produced this translation unit.
+  int clang_reparseTranslationUnit(
+    CXTranslationUnit TU,
+    int num_unsaved_files,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int options,
+  ) {
+    return _clang_reparseTranslationUnit(
+      TU,
+      num_unsaved_files,
+      unsaved_files,
+      options,
+    );
+  }
+
+  late final _clang_reparseTranslationUnitPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              CXTranslationUnit,
+              ffi.UnsignedInt,
+              ffi.Pointer<CXUnsavedFile>,
+              ffi.UnsignedInt)>>('clang_reparseTranslationUnit');
+  late final _clang_reparseTranslationUnit =
+      _clang_reparseTranslationUnitPtr.asFunction<
+          int Function(
+              CXTranslationUnit, int, ffi.Pointer<CXUnsavedFile>, int)>();
+
+  /// Returns the human-readable null-terminated C string that represents the
+  /// name of the memory category. This string should never be freed.
+  ffi.Pointer<ffi.Char> clang_getTUResourceUsageName(
+    int kind,
+  ) {
+    return _clang_getTUResourceUsageName(
+      kind,
+    );
+  }
+
+  late final _clang_getTUResourceUsageNamePtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Int32)>>(
+          'clang_getTUResourceUsageName');
+  late final _clang_getTUResourceUsageName = _clang_getTUResourceUsageNamePtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(int)>();
+
+  /// Return the memory usage of a translation unit. This object should be
+  /// released with clang_disposeCXTUResourceUsage().
+  CXTUResourceUsage clang_getCXTUResourceUsage(
+    CXTranslationUnit TU,
+  ) {
+    return _clang_getCXTUResourceUsage(
+      TU,
+    );
+  }
+
+  late final _clang_getCXTUResourceUsagePtr = _lookup<
+          ffi.NativeFunction<CXTUResourceUsage Function(CXTranslationUnit)>>(
+      'clang_getCXTUResourceUsage');
+  late final _clang_getCXTUResourceUsage = _clang_getCXTUResourceUsagePtr
+      .asFunction<CXTUResourceUsage Function(CXTranslationUnit)>();
+
+  void clang_disposeCXTUResourceUsage(
+    CXTUResourceUsage usage,
+  ) {
+    return _clang_disposeCXTUResourceUsage(
+      usage,
+    );
+  }
+
+  late final _clang_disposeCXTUResourceUsagePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXTUResourceUsage)>>(
+          'clang_disposeCXTUResourceUsage');
+  late final _clang_disposeCXTUResourceUsage =
+      _clang_disposeCXTUResourceUsagePtr
+          .asFunction<void Function(CXTUResourceUsage)>();
+
+  /// Get target information for this translation unit.
+  CXTargetInfo clang_getTranslationUnitTargetInfo(
+    CXTranslationUnit CTUnit,
+  ) {
+    return _clang_getTranslationUnitTargetInfo(
+      CTUnit,
+    );
+  }
+
+  late final _clang_getTranslationUnitTargetInfoPtr =
+      _lookup<ffi.NativeFunction<CXTargetInfo Function(CXTranslationUnit)>>(
+          'clang_getTranslationUnitTargetInfo');
+  late final _clang_getTranslationUnitTargetInfo =
+      _clang_getTranslationUnitTargetInfoPtr
+          .asFunction<CXTargetInfo Function(CXTranslationUnit)>();
+
+  /// Destroy the CXTargetInfo object.
+  void clang_TargetInfo_dispose(
+    CXTargetInfo Info,
+  ) {
+    return _clang_TargetInfo_dispose(
+      Info,
+    );
+  }
+
+  late final _clang_TargetInfo_disposePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXTargetInfo)>>(
+          'clang_TargetInfo_dispose');
+  late final _clang_TargetInfo_dispose =
+      _clang_TargetInfo_disposePtr.asFunction<void Function(CXTargetInfo)>();
+
+  /// Get the normalized target triple as a string.
+  CXString clang_TargetInfo_getTriple(
+    CXTargetInfo Info,
+  ) {
+    return _clang_TargetInfo_getTriple(
+      Info,
+    );
+  }
+
+  late final _clang_TargetInfo_getTriplePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXTargetInfo)>>(
+          'clang_TargetInfo_getTriple');
+  late final _clang_TargetInfo_getTriple = _clang_TargetInfo_getTriplePtr
+      .asFunction<CXString Function(CXTargetInfo)>();
+
+  /// Get the pointer width of the target in bits.
+  int clang_TargetInfo_getPointerWidth(
+    CXTargetInfo Info,
+  ) {
+    return _clang_TargetInfo_getPointerWidth(
+      Info,
+    );
+  }
+
+  late final _clang_TargetInfo_getPointerWidthPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXTargetInfo)>>(
+          'clang_TargetInfo_getPointerWidth');
+  late final _clang_TargetInfo_getPointerWidth =
+      _clang_TargetInfo_getPointerWidthPtr
+          .asFunction<int Function(CXTargetInfo)>();
+
+  /// Retrieve the NULL cursor, which represents no entity.
+  CXCursor clang_getNullCursor() {
+    return _clang_getNullCursor();
+  }
+
+  late final _clang_getNullCursorPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function()>>('clang_getNullCursor');
+  late final _clang_getNullCursor =
+      _clang_getNullCursorPtr.asFunction<CXCursor Function()>();
+
+  /// Retrieve the cursor that represents the given translation unit.
+  CXCursor clang_getTranslationUnitCursor(
+    CXTranslationUnit arg0,
+  ) {
+    return _clang_getTranslationUnitCursor(
+      arg0,
+    );
+  }
+
+  late final _clang_getTranslationUnitCursorPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXTranslationUnit)>>(
+          'clang_getTranslationUnitCursor');
+  late final _clang_getTranslationUnitCursor =
+      _clang_getTranslationUnitCursorPtr
+          .asFunction<CXCursor Function(CXTranslationUnit)>();
+
+  /// Determine whether two cursors are equivalent.
+  int clang_equalCursors(
+    CXCursor arg0,
+    CXCursor arg1,
+  ) {
+    return _clang_equalCursors(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_equalCursorsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor, CXCursor)>>(
+          'clang_equalCursors');
+  late final _clang_equalCursors =
+      _clang_equalCursorsPtr.asFunction<int Function(CXCursor, CXCursor)>();
+
+  /// Returns non-zero if cursor is null.
+  int clang_Cursor_isNull(
+    CXCursor cursor,
+  ) {
+    return _clang_Cursor_isNull(
+      cursor,
+    );
+  }
+
+  late final _clang_Cursor_isNullPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXCursor)>>(
+          'clang_Cursor_isNull');
+  late final _clang_Cursor_isNull =
+      _clang_Cursor_isNullPtr.asFunction<int Function(CXCursor)>();
+
+  /// Compute a hash value for the given cursor.
+  int clang_hashCursor(
+    CXCursor arg0,
+  ) {
+    return _clang_hashCursor(
+      arg0,
+    );
+  }
+
+  late final _clang_hashCursorPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_hashCursor');
+  late final _clang_hashCursor =
+      _clang_hashCursorPtr.asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the kind of the given cursor.
+  int clang_getCursorKind(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorKind(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorKindPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>(
+          'clang_getCursorKind');
+  late final _clang_getCursorKind =
+      _clang_getCursorKindPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether the given cursor kind represents a declaration.
+  int clang_isDeclaration(
+    int arg0,
+  ) {
+    return _clang_isDeclaration(
+      arg0,
+    );
+  }
+
+  late final _clang_isDeclarationPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(ffi.Int32)>>(
+          'clang_isDeclaration');
+  late final _clang_isDeclaration =
+      _clang_isDeclarationPtr.asFunction<int Function(int)>();
+
+  /// Determine whether the given declaration is invalid.
+  int clang_isInvalidDeclaration(
+    CXCursor arg0,
+  ) {
+    return _clang_isInvalidDeclaration(
+      arg0,
+    );
+  }
+
+  late final _clang_isInvalidDeclarationPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_isInvalidDeclaration');
+  late final _clang_isInvalidDeclaration =
+      _clang_isInvalidDeclarationPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether the given cursor kind represents a simple reference.
+  int clang_isReference(
+    int arg0,
+  ) {
+    return _clang_isReference(
+      arg0,
+    );
+  }
+
+  late final _clang_isReferencePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(ffi.Int32)>>(
+          'clang_isReference');
+  late final _clang_isReference =
+      _clang_isReferencePtr.asFunction<int Function(int)>();
+
+  /// Determine whether the given cursor kind represents an expression.
+  int clang_isExpression(
+    int arg0,
+  ) {
+    return _clang_isExpression(
+      arg0,
+    );
+  }
+
+  late final _clang_isExpressionPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(ffi.Int32)>>(
+          'clang_isExpression');
+  late final _clang_isExpression =
+      _clang_isExpressionPtr.asFunction<int Function(int)>();
+
+  /// Determine whether the given cursor kind represents a statement.
+  int clang_isStatement(
+    int arg0,
+  ) {
+    return _clang_isStatement(
+      arg0,
+    );
+  }
+
+  late final _clang_isStatementPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(ffi.Int32)>>(
+          'clang_isStatement');
+  late final _clang_isStatement =
+      _clang_isStatementPtr.asFunction<int Function(int)>();
+
+  /// Determine whether the given cursor kind represents an attribute.
+  int clang_isAttribute(
+    int arg0,
+  ) {
+    return _clang_isAttribute(
+      arg0,
+    );
+  }
+
+  late final _clang_isAttributePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(ffi.Int32)>>(
+          'clang_isAttribute');
+  late final _clang_isAttribute =
+      _clang_isAttributePtr.asFunction<int Function(int)>();
+
+  /// Determine whether the given cursor has any attributes.
+  int clang_Cursor_hasAttrs(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_hasAttrs(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_hasAttrsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_hasAttrs');
+  late final _clang_Cursor_hasAttrs =
+      _clang_Cursor_hasAttrsPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether the given cursor kind represents an invalid cursor.
+  int clang_isInvalid(
+    int arg0,
+  ) {
+    return _clang_isInvalid(
+      arg0,
+    );
+  }
+
+  late final _clang_isInvalidPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(ffi.Int32)>>(
+          'clang_isInvalid');
+  late final _clang_isInvalid =
+      _clang_isInvalidPtr.asFunction<int Function(int)>();
+
+  /// Determine whether the given cursor kind represents a translation unit.
+  int clang_isTranslationUnit(
+    int arg0,
+  ) {
+    return _clang_isTranslationUnit(
+      arg0,
+    );
+  }
+
+  late final _clang_isTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(ffi.Int32)>>(
+          'clang_isTranslationUnit');
+  late final _clang_isTranslationUnit =
+      _clang_isTranslationUnitPtr.asFunction<int Function(int)>();
+
+  /// * Determine whether the given cursor represents a preprocessing element,
+  /// such as a preprocessor directive or macro instantiation.
+  int clang_isPreprocessing(
+    int arg0,
+  ) {
+    return _clang_isPreprocessing(
+      arg0,
+    );
+  }
+
+  late final _clang_isPreprocessingPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(ffi.Int32)>>(
+          'clang_isPreprocessing');
+  late final _clang_isPreprocessing =
+      _clang_isPreprocessingPtr.asFunction<int Function(int)>();
+
+  /// * Determine whether the given cursor represents a currently unexposed
+  /// piece of the AST (e.g., CXCursor_UnexposedStmt).
+  int clang_isUnexposed(
+    int arg0,
+  ) {
+    return _clang_isUnexposed(
+      arg0,
+    );
+  }
+
+  late final _clang_isUnexposedPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(ffi.Int32)>>(
+          'clang_isUnexposed');
+  late final _clang_isUnexposed =
+      _clang_isUnexposedPtr.asFunction<int Function(int)>();
+
+  /// Determine the linkage of the entity referred to by a given cursor.
+  int clang_getCursorLinkage(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorLinkage(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorLinkagePtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>(
+          'clang_getCursorLinkage');
+  late final _clang_getCursorLinkage =
+      _clang_getCursorLinkagePtr.asFunction<int Function(CXCursor)>();
+
+  /// Describe the visibility of the entity referred to by a cursor.
+  int clang_getCursorVisibility(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorVisibility(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorVisibilityPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>(
+          'clang_getCursorVisibility');
+  late final _clang_getCursorVisibility =
+      _clang_getCursorVisibilityPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine the availability of the entity that this cursor refers to,
+  /// taking the current target platform into account.
+  int clang_getCursorAvailability(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorAvailability(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorAvailabilityPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>(
+          'clang_getCursorAvailability');
+  late final _clang_getCursorAvailability =
+      _clang_getCursorAvailabilityPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine the availability of the entity that this cursor refers to on any
+  /// platforms for which availability information is known.
+  int clang_getCursorPlatformAvailability(
+    CXCursor cursor,
+    ffi.Pointer<ffi.Int> always_deprecated,
+    ffi.Pointer<CXString> deprecated_message,
+    ffi.Pointer<ffi.Int> always_unavailable,
+    ffi.Pointer<CXString> unavailable_message,
+    ffi.Pointer<CXPlatformAvailability> availability,
+    int availability_size,
+  ) {
+    return _clang_getCursorPlatformAvailability(
+      cursor,
+      always_deprecated,
+      deprecated_message,
+      always_unavailable,
+      unavailable_message,
+      availability,
+      availability_size,
+    );
+  }
+
+  late final _clang_getCursorPlatformAvailabilityPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              CXCursor,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<CXString>,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<CXString>,
+              ffi.Pointer<CXPlatformAvailability>,
+              ffi.Int)>>('clang_getCursorPlatformAvailability');
+  late final _clang_getCursorPlatformAvailability =
+      _clang_getCursorPlatformAvailabilityPtr.asFunction<
+          int Function(
+              CXCursor,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<CXString>,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<CXString>,
+              ffi.Pointer<CXPlatformAvailability>,
+              int)>();
+
+  /// Free the memory associated with a CXPlatformAvailability structure.
+  void clang_disposeCXPlatformAvailability(
+    ffi.Pointer<CXPlatformAvailability> availability,
+  ) {
+    return _clang_disposeCXPlatformAvailability(
+      availability,
+    );
+  }
+
+  late final _clang_disposeCXPlatformAvailabilityPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Void Function(ffi.Pointer<CXPlatformAvailability>)>>(
+      'clang_disposeCXPlatformAvailability');
+  late final _clang_disposeCXPlatformAvailability =
+      _clang_disposeCXPlatformAvailabilityPtr
+          .asFunction<void Function(ffi.Pointer<CXPlatformAvailability>)>();
+
+  /// Determine the "language" of the entity referred to by a given cursor.
+  int clang_getCursorLanguage(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorLanguage(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorLanguagePtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>(
+          'clang_getCursorLanguage');
+  late final _clang_getCursorLanguage =
+      _clang_getCursorLanguagePtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine the "thread-local storage (TLS) kind" of the declaration
+  /// referred to by a cursor.
+  int clang_getCursorTLSKind(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorTLSKind(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorTLSKindPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>(
+          'clang_getCursorTLSKind');
+  late final _clang_getCursorTLSKind =
+      _clang_getCursorTLSKindPtr.asFunction<int Function(CXCursor)>();
+
+  /// Returns the translation unit that a cursor originated from.
+  CXTranslationUnit clang_Cursor_getTranslationUnit(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getTranslationUnit(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getTranslationUnitPtr =
+      _lookup<ffi.NativeFunction<CXTranslationUnit Function(CXCursor)>>(
+          'clang_Cursor_getTranslationUnit');
+  late final _clang_Cursor_getTranslationUnit =
+      _clang_Cursor_getTranslationUnitPtr
+          .asFunction<CXTranslationUnit Function(CXCursor)>();
+
+  /// Creates an empty CXCursorSet.
+  CXCursorSet clang_createCXCursorSet() {
+    return _clang_createCXCursorSet();
+  }
+
+  late final _clang_createCXCursorSetPtr =
+      _lookup<ffi.NativeFunction<CXCursorSet Function()>>(
+          'clang_createCXCursorSet');
+  late final _clang_createCXCursorSet =
+      _clang_createCXCursorSetPtr.asFunction<CXCursorSet Function()>();
+
+  /// Disposes a CXCursorSet and releases its associated memory.
+  void clang_disposeCXCursorSet(
+    CXCursorSet cset,
+  ) {
+    return _clang_disposeCXCursorSet(
+      cset,
+    );
+  }
+
+  late final _clang_disposeCXCursorSetPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXCursorSet)>>(
+          'clang_disposeCXCursorSet');
+  late final _clang_disposeCXCursorSet =
+      _clang_disposeCXCursorSetPtr.asFunction<void Function(CXCursorSet)>();
+
+  /// Queries a CXCursorSet to see if it contains a specific CXCursor.
+  int clang_CXCursorSet_contains(
+    CXCursorSet cset,
+    CXCursor cursor,
+  ) {
+    return _clang_CXCursorSet_contains(
+      cset,
+      cursor,
+    );
+  }
+
+  late final _clang_CXCursorSet_containsPtr = _lookup<
+          ffi.NativeFunction<ffi.UnsignedInt Function(CXCursorSet, CXCursor)>>(
+      'clang_CXCursorSet_contains');
+  late final _clang_CXCursorSet_contains = _clang_CXCursorSet_containsPtr
+      .asFunction<int Function(CXCursorSet, CXCursor)>();
+
+  /// Inserts a CXCursor into a CXCursorSet.
+  int clang_CXCursorSet_insert(
+    CXCursorSet cset,
+    CXCursor cursor,
+  ) {
+    return _clang_CXCursorSet_insert(
+      cset,
+      cursor,
+    );
+  }
+
+  late final _clang_CXCursorSet_insertPtr = _lookup<
+          ffi.NativeFunction<ffi.UnsignedInt Function(CXCursorSet, CXCursor)>>(
+      'clang_CXCursorSet_insert');
+  late final _clang_CXCursorSet_insert = _clang_CXCursorSet_insertPtr
+      .asFunction<int Function(CXCursorSet, CXCursor)>();
+
+  /// Determine the semantic parent of the given cursor.
+  CXCursor clang_getCursorSemanticParent(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorSemanticParent(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorSemanticParentPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXCursor)>>(
+          'clang_getCursorSemanticParent');
+  late final _clang_getCursorSemanticParent = _clang_getCursorSemanticParentPtr
+      .asFunction<CXCursor Function(CXCursor)>();
+
+  /// Determine the lexical parent of the given cursor.
+  CXCursor clang_getCursorLexicalParent(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorLexicalParent(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorLexicalParentPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXCursor)>>(
+          'clang_getCursorLexicalParent');
+  late final _clang_getCursorLexicalParent = _clang_getCursorLexicalParentPtr
+      .asFunction<CXCursor Function(CXCursor)>();
+
+  /// Determine the set of methods that are overridden by the given method.
+  void clang_getOverriddenCursors(
+    CXCursor cursor,
+    ffi.Pointer<ffi.Pointer<CXCursor>> overridden,
+    ffi.Pointer<ffi.UnsignedInt> num_overridden,
+  ) {
+    return _clang_getOverriddenCursors(
+      cursor,
+      overridden,
+      num_overridden,
+    );
+  }
+
+  late final _clang_getOverriddenCursorsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(CXCursor, ffi.Pointer<ffi.Pointer<CXCursor>>,
+              ffi.Pointer<ffi.UnsignedInt>)>>('clang_getOverriddenCursors');
+  late final _clang_getOverriddenCursors =
+      _clang_getOverriddenCursorsPtr.asFunction<
+          void Function(CXCursor, ffi.Pointer<ffi.Pointer<CXCursor>>,
+              ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Free the set of overridden cursors returned by
+  /// clang_getOverriddenCursors().
+  void clang_disposeOverriddenCursors(
+    ffi.Pointer<CXCursor> overridden,
+  ) {
+    return _clang_disposeOverriddenCursors(
+      overridden,
+    );
+  }
+
+  late final _clang_disposeOverriddenCursorsPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<CXCursor>)>>(
+          'clang_disposeOverriddenCursors');
+  late final _clang_disposeOverriddenCursors =
+      _clang_disposeOverriddenCursorsPtr
+          .asFunction<void Function(ffi.Pointer<CXCursor>)>();
+
+  /// Retrieve the file that is included by the given inclusion directive
+  /// cursor.
+  CXFile clang_getIncludedFile(
+    CXCursor cursor,
+  ) {
+    return _clang_getIncludedFile(
+      cursor,
+    );
+  }
+
+  late final _clang_getIncludedFilePtr =
+      _lookup<ffi.NativeFunction<CXFile Function(CXCursor)>>(
+          'clang_getIncludedFile');
+  late final _clang_getIncludedFile =
+      _clang_getIncludedFilePtr.asFunction<CXFile Function(CXCursor)>();
+
+  /// Map a source location to the cursor that describes the entity at that
+  /// location in the source code.
+  CXCursor clang_getCursor(
+    CXTranslationUnit arg0,
+    CXSourceLocation arg1,
+  ) {
+    return _clang_getCursor(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_getCursorPtr = _lookup<
+      ffi.NativeFunction<
+          CXCursor Function(
+              CXTranslationUnit, CXSourceLocation)>>('clang_getCursor');
+  late final _clang_getCursor = _clang_getCursorPtr
+      .asFunction<CXCursor Function(CXTranslationUnit, CXSourceLocation)>();
+
+  /// Retrieve the physical location of the source constructor referenced by the
+  /// given cursor.
+  CXSourceLocation clang_getCursorLocation(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorLocation(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorLocationPtr =
+      _lookup<ffi.NativeFunction<CXSourceLocation Function(CXCursor)>>(
+          'clang_getCursorLocation');
+  late final _clang_getCursorLocation = _clang_getCursorLocationPtr
+      .asFunction<CXSourceLocation Function(CXCursor)>();
+
+  /// Retrieve the physical extent of the source construct referenced by the
+  /// given cursor.
+  CXSourceRange clang_getCursorExtent(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorExtent(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorExtentPtr =
+      _lookup<ffi.NativeFunction<CXSourceRange Function(CXCursor)>>(
+          'clang_getCursorExtent');
+  late final _clang_getCursorExtent =
+      _clang_getCursorExtentPtr.asFunction<CXSourceRange Function(CXCursor)>();
+
+  /// Retrieve the type of a CXCursor (if any).
+  CXType clang_getCursorType(
+    CXCursor C,
+  ) {
+    return _clang_getCursorType(
+      C,
+    );
+  }
+
+  late final _clang_getCursorTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXCursor)>>(
+          'clang_getCursorType');
+  late final _clang_getCursorType =
+      _clang_getCursorTypePtr.asFunction<CXType Function(CXCursor)>();
+
+  /// Pretty-print the underlying type using the rules of the language of the
+  /// translation unit from which it came.
+  CXString clang_getTypeSpelling(
+    CXType CT,
+  ) {
+    return _clang_getTypeSpelling(
+      CT,
+    );
+  }
+
+  late final _clang_getTypeSpellingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXType)>>(
+          'clang_getTypeSpelling');
+  late final _clang_getTypeSpelling =
+      _clang_getTypeSpellingPtr.asFunction<CXString Function(CXType)>();
+
+  /// Retrieve the underlying type of a typedef declaration.
+  CXType clang_getTypedefDeclUnderlyingType(
+    CXCursor C,
+  ) {
+    return _clang_getTypedefDeclUnderlyingType(
+      C,
+    );
+  }
+
+  late final _clang_getTypedefDeclUnderlyingTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXCursor)>>(
+          'clang_getTypedefDeclUnderlyingType');
+  late final _clang_getTypedefDeclUnderlyingType =
+      _clang_getTypedefDeclUnderlyingTypePtr
+          .asFunction<CXType Function(CXCursor)>();
+
+  /// Retrieve the integer type of an enum declaration.
+  CXType clang_getEnumDeclIntegerType(
+    CXCursor C,
+  ) {
+    return _clang_getEnumDeclIntegerType(
+      C,
+    );
+  }
+
+  late final _clang_getEnumDeclIntegerTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXCursor)>>(
+          'clang_getEnumDeclIntegerType');
+  late final _clang_getEnumDeclIntegerType =
+      _clang_getEnumDeclIntegerTypePtr.asFunction<CXType Function(CXCursor)>();
+
+  /// Retrieve the integer value of an enum constant declaration as a signed
+  /// long long.
+  int clang_getEnumConstantDeclValue(
+    CXCursor C,
+  ) {
+    return _clang_getEnumConstantDeclValue(
+      C,
+    );
+  }
+
+  late final _clang_getEnumConstantDeclValuePtr =
+      _lookup<ffi.NativeFunction<ffi.LongLong Function(CXCursor)>>(
+          'clang_getEnumConstantDeclValue');
+  late final _clang_getEnumConstantDeclValue =
+      _clang_getEnumConstantDeclValuePtr.asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the integer value of an enum constant declaration as an unsigned
+  /// long long.
+  int clang_getEnumConstantDeclUnsignedValue(
+    CXCursor C,
+  ) {
+    return _clang_getEnumConstantDeclUnsignedValue(
+      C,
+    );
+  }
+
+  late final _clang_getEnumConstantDeclUnsignedValuePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedLongLong Function(CXCursor)>>(
+          'clang_getEnumConstantDeclUnsignedValue');
+  late final _clang_getEnumConstantDeclUnsignedValue =
+      _clang_getEnumConstantDeclUnsignedValuePtr
+          .asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the bit width of a bit field declaration as an integer.
+  int clang_getFieldDeclBitWidth(
+    CXCursor C,
+  ) {
+    return _clang_getFieldDeclBitWidth(
+      C,
+    );
+  }
+
+  late final _clang_getFieldDeclBitWidthPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXCursor)>>(
+          'clang_getFieldDeclBitWidth');
+  late final _clang_getFieldDeclBitWidth =
+      _clang_getFieldDeclBitWidthPtr.asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the number of non-variadic arguments associated with a given
+  /// cursor.
+  int clang_Cursor_getNumArguments(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getNumArguments(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getNumArgumentsPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXCursor)>>(
+          'clang_Cursor_getNumArguments');
+  late final _clang_Cursor_getNumArguments =
+      _clang_Cursor_getNumArgumentsPtr.asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the argument cursor of a function or method.
+  CXCursor clang_Cursor_getArgument(
+    CXCursor C,
+    int i,
+  ) {
+    return _clang_Cursor_getArgument(
+      C,
+      i,
+    );
+  }
+
+  late final _clang_Cursor_getArgumentPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXCursor, ffi.UnsignedInt)>>(
+          'clang_Cursor_getArgument');
+  late final _clang_Cursor_getArgument = _clang_Cursor_getArgumentPtr
+      .asFunction<CXCursor Function(CXCursor, int)>();
+
+  /// Returns the number of template args of a function decl representing a
+  /// template specialization.
+  int clang_Cursor_getNumTemplateArguments(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getNumTemplateArguments(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getNumTemplateArgumentsPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXCursor)>>(
+          'clang_Cursor_getNumTemplateArguments');
+  late final _clang_Cursor_getNumTemplateArguments =
+      _clang_Cursor_getNumTemplateArgumentsPtr
+          .asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the kind of the I'th template argument of the CXCursor C.
+  int clang_Cursor_getTemplateArgumentKind(
+    CXCursor C,
+    int I,
+  ) {
+    return _clang_Cursor_getTemplateArgumentKind(
+      C,
+      I,
+    );
+  }
+
+  late final _clang_Cursor_getTemplateArgumentKindPtr = _lookup<
+          ffi.NativeFunction<ffi.Int32 Function(CXCursor, ffi.UnsignedInt)>>(
+      'clang_Cursor_getTemplateArgumentKind');
+  late final _clang_Cursor_getTemplateArgumentKind =
+      _clang_Cursor_getTemplateArgumentKindPtr
+          .asFunction<int Function(CXCursor, int)>();
+
+  /// Retrieve a CXType representing the type of a TemplateArgument of a
+  /// function decl representing a template specialization.
+  CXType clang_Cursor_getTemplateArgumentType(
+    CXCursor C,
+    int I,
+  ) {
+    return _clang_Cursor_getTemplateArgumentType(
+      C,
+      I,
+    );
+  }
+
+  late final _clang_Cursor_getTemplateArgumentTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXCursor, ffi.UnsignedInt)>>(
+          'clang_Cursor_getTemplateArgumentType');
+  late final _clang_Cursor_getTemplateArgumentType =
+      _clang_Cursor_getTemplateArgumentTypePtr
+          .asFunction<CXType Function(CXCursor, int)>();
+
+  /// Retrieve the value of an Integral TemplateArgument (of a function decl
+  /// representing a template specialization) as a signed long long.
+  int clang_Cursor_getTemplateArgumentValue(
+    CXCursor C,
+    int I,
+  ) {
+    return _clang_Cursor_getTemplateArgumentValue(
+      C,
+      I,
+    );
+  }
+
+  late final _clang_Cursor_getTemplateArgumentValuePtr = _lookup<
+          ffi.NativeFunction<ffi.LongLong Function(CXCursor, ffi.UnsignedInt)>>(
+      'clang_Cursor_getTemplateArgumentValue');
+  late final _clang_Cursor_getTemplateArgumentValue =
+      _clang_Cursor_getTemplateArgumentValuePtr
+          .asFunction<int Function(CXCursor, int)>();
+
+  /// Retrieve the value of an Integral TemplateArgument (of a function decl
+  /// representing a template specialization) as an unsigned long long.
+  int clang_Cursor_getTemplateArgumentUnsignedValue(
+    CXCursor C,
+    int I,
+  ) {
+    return _clang_Cursor_getTemplateArgumentUnsignedValue(
+      C,
+      I,
+    );
+  }
+
+  late final _clang_Cursor_getTemplateArgumentUnsignedValuePtr = _lookup<
+          ffi.NativeFunction<
+              ffi.UnsignedLongLong Function(CXCursor, ffi.UnsignedInt)>>(
+      'clang_Cursor_getTemplateArgumentUnsignedValue');
+  late final _clang_Cursor_getTemplateArgumentUnsignedValue =
+      _clang_Cursor_getTemplateArgumentUnsignedValuePtr
+          .asFunction<int Function(CXCursor, int)>();
+
+  /// Determine whether two CXTypes represent the same type.
+  int clang_equalTypes(
+    CXType A,
+    CXType B,
+  ) {
+    return _clang_equalTypes(
+      A,
+      B,
+    );
+  }
+
+  late final _clang_equalTypesPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXType, CXType)>>(
+          'clang_equalTypes');
+  late final _clang_equalTypes =
+      _clang_equalTypesPtr.asFunction<int Function(CXType, CXType)>();
+
+  /// Return the canonical type for a CXType.
+  CXType clang_getCanonicalType(
+    CXType T,
+  ) {
+    return _clang_getCanonicalType(
+      T,
+    );
+  }
+
+  late final _clang_getCanonicalTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_getCanonicalType');
+  late final _clang_getCanonicalType =
+      _clang_getCanonicalTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Determine whether a CXType has the "const" qualifier set, without looking
+  /// through typedefs that may have added "const" at a different level.
+  int clang_isConstQualifiedType(
+    CXType T,
+  ) {
+    return _clang_isConstQualifiedType(
+      T,
+    );
+  }
+
+  late final _clang_isConstQualifiedTypePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXType)>>(
+          'clang_isConstQualifiedType');
+  late final _clang_isConstQualifiedType =
+      _clang_isConstQualifiedTypePtr.asFunction<int Function(CXType)>();
+
+  /// Determine whether a CXCursor that is a macro, is function like.
+  int clang_Cursor_isMacroFunctionLike(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isMacroFunctionLike(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isMacroFunctionLikePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isMacroFunctionLike');
+  late final _clang_Cursor_isMacroFunctionLike =
+      _clang_Cursor_isMacroFunctionLikePtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether a CXCursor that is a macro, is a builtin one.
+  int clang_Cursor_isMacroBuiltin(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isMacroBuiltin(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isMacroBuiltinPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isMacroBuiltin');
+  late final _clang_Cursor_isMacroBuiltin =
+      _clang_Cursor_isMacroBuiltinPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether a CXCursor that is a function declaration, is an inline
+  /// declaration.
+  int clang_Cursor_isFunctionInlined(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isFunctionInlined(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isFunctionInlinedPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isFunctionInlined');
+  late final _clang_Cursor_isFunctionInlined =
+      _clang_Cursor_isFunctionInlinedPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether a CXType has the "volatile" qualifier set, without
+  /// looking through typedefs that may have added "volatile" at a different
+  /// level.
+  int clang_isVolatileQualifiedType(
+    CXType T,
+  ) {
+    return _clang_isVolatileQualifiedType(
+      T,
+    );
+  }
+
+  late final _clang_isVolatileQualifiedTypePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXType)>>(
+          'clang_isVolatileQualifiedType');
+  late final _clang_isVolatileQualifiedType =
+      _clang_isVolatileQualifiedTypePtr.asFunction<int Function(CXType)>();
+
+  /// Determine whether a CXType has the "restrict" qualifier set, without
+  /// looking through typedefs that may have added "restrict" at a different
+  /// level.
+  int clang_isRestrictQualifiedType(
+    CXType T,
+  ) {
+    return _clang_isRestrictQualifiedType(
+      T,
+    );
+  }
+
+  late final _clang_isRestrictQualifiedTypePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXType)>>(
+          'clang_isRestrictQualifiedType');
+  late final _clang_isRestrictQualifiedType =
+      _clang_isRestrictQualifiedTypePtr.asFunction<int Function(CXType)>();
+
+  /// Returns the address space of the given type.
+  int clang_getAddressSpace(
+    CXType T,
+  ) {
+    return _clang_getAddressSpace(
+      T,
+    );
+  }
+
+  late final _clang_getAddressSpacePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXType)>>(
+          'clang_getAddressSpace');
+  late final _clang_getAddressSpace =
+      _clang_getAddressSpacePtr.asFunction<int Function(CXType)>();
+
+  /// Returns the typedef name of the given type.
+  CXString clang_getTypedefName(
+    CXType CT,
+  ) {
+    return _clang_getTypedefName(
+      CT,
+    );
+  }
+
+  late final _clang_getTypedefNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXType)>>(
+          'clang_getTypedefName');
+  late final _clang_getTypedefName =
+      _clang_getTypedefNamePtr.asFunction<CXString Function(CXType)>();
+
+  /// For pointer types, returns the type of the pointee.
+  CXType clang_getPointeeType(
+    CXType T,
+  ) {
+    return _clang_getPointeeType(
+      T,
+    );
+  }
+
+  late final _clang_getPointeeTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_getPointeeType');
+  late final _clang_getPointeeType =
+      _clang_getPointeeTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Return the cursor for the declaration of the given type.
+  CXCursor clang_getTypeDeclaration(
+    CXType T,
+  ) {
+    return _clang_getTypeDeclaration(
+      T,
+    );
+  }
+
+  late final _clang_getTypeDeclarationPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXType)>>(
+          'clang_getTypeDeclaration');
+  late final _clang_getTypeDeclaration =
+      _clang_getTypeDeclarationPtr.asFunction<CXCursor Function(CXType)>();
+
+  /// Returns the Objective-C type encoding for the specified declaration.
+  CXString clang_getDeclObjCTypeEncoding(
+    CXCursor C,
+  ) {
+    return _clang_getDeclObjCTypeEncoding(
+      C,
+    );
+  }
+
+  late final _clang_getDeclObjCTypeEncodingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_getDeclObjCTypeEncoding');
+  late final _clang_getDeclObjCTypeEncoding = _clang_getDeclObjCTypeEncodingPtr
+      .asFunction<CXString Function(CXCursor)>();
+
+  /// Returns the Objective-C type encoding for the specified CXType.
+  CXString clang_Type_getObjCEncoding(
+    CXType type,
+  ) {
+    return _clang_Type_getObjCEncoding(
+      type,
+    );
+  }
+
+  late final _clang_Type_getObjCEncodingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXType)>>(
+          'clang_Type_getObjCEncoding');
+  late final _clang_Type_getObjCEncoding =
+      _clang_Type_getObjCEncodingPtr.asFunction<CXString Function(CXType)>();
+
+  /// Retrieve the spelling of a given CXTypeKind.
+  CXString clang_getTypeKindSpelling(
+    int K,
+  ) {
+    return _clang_getTypeKindSpelling(
+      K,
+    );
+  }
+
+  late final _clang_getTypeKindSpellingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(ffi.Int32)>>(
+          'clang_getTypeKindSpelling');
+  late final _clang_getTypeKindSpelling =
+      _clang_getTypeKindSpellingPtr.asFunction<CXString Function(int)>();
+
+  /// Retrieve the calling convention associated with a function type.
+  int clang_getFunctionTypeCallingConv(
+    CXType T,
+  ) {
+    return _clang_getFunctionTypeCallingConv(
+      T,
+    );
+  }
+
+  late final _clang_getFunctionTypeCallingConvPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXType)>>(
+          'clang_getFunctionTypeCallingConv');
+  late final _clang_getFunctionTypeCallingConv =
+      _clang_getFunctionTypeCallingConvPtr.asFunction<int Function(CXType)>();
+
+  /// Retrieve the return type associated with a function type.
+  CXType clang_getResultType(
+    CXType T,
+  ) {
+    return _clang_getResultType(
+      T,
+    );
+  }
+
+  late final _clang_getResultTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_getResultType');
+  late final _clang_getResultType =
+      _clang_getResultTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Retrieve the exception specification type associated with a function type.
+  /// This is a value of type CXCursor_ExceptionSpecificationKind.
+  int clang_getExceptionSpecificationType(
+    CXType T,
+  ) {
+    return _clang_getExceptionSpecificationType(
+      T,
+    );
+  }
+
+  late final _clang_getExceptionSpecificationTypePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXType)>>(
+          'clang_getExceptionSpecificationType');
+  late final _clang_getExceptionSpecificationType =
+      _clang_getExceptionSpecificationTypePtr
+          .asFunction<int Function(CXType)>();
+
+  /// Retrieve the number of non-variadic parameters associated with a function
+  /// type.
+  int clang_getNumArgTypes(
+    CXType T,
+  ) {
+    return _clang_getNumArgTypes(
+      T,
+    );
+  }
+
+  late final _clang_getNumArgTypesPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXType)>>(
+          'clang_getNumArgTypes');
+  late final _clang_getNumArgTypes =
+      _clang_getNumArgTypesPtr.asFunction<int Function(CXType)>();
+
+  /// Retrieve the type of a parameter of a function type.
+  CXType clang_getArgType(
+    CXType T,
+    int i,
+  ) {
+    return _clang_getArgType(
+      T,
+      i,
+    );
+  }
+
+  late final _clang_getArgTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType, ffi.UnsignedInt)>>(
+          'clang_getArgType');
+  late final _clang_getArgType =
+      _clang_getArgTypePtr.asFunction<CXType Function(CXType, int)>();
+
+  /// Retrieves the base type of the ObjCObjectType.
+  CXType clang_Type_getObjCObjectBaseType(
+    CXType T,
+  ) {
+    return _clang_Type_getObjCObjectBaseType(
+      T,
+    );
+  }
+
+  late final _clang_Type_getObjCObjectBaseTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_Type_getObjCObjectBaseType');
+  late final _clang_Type_getObjCObjectBaseType =
+      _clang_Type_getObjCObjectBaseTypePtr
+          .asFunction<CXType Function(CXType)>();
+
+  /// Retrieve the number of protocol references associated with an ObjC
+  /// object/id.
+  int clang_Type_getNumObjCProtocolRefs(
+    CXType T,
+  ) {
+    return _clang_Type_getNumObjCProtocolRefs(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNumObjCProtocolRefsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXType)>>(
+          'clang_Type_getNumObjCProtocolRefs');
+  late final _clang_Type_getNumObjCProtocolRefs =
+      _clang_Type_getNumObjCProtocolRefsPtr.asFunction<int Function(CXType)>();
+
+  /// Retrieve the decl for a protocol reference for an ObjC object/id.
+  CXCursor clang_Type_getObjCProtocolDecl(
+    CXType T,
+    int i,
+  ) {
+    return _clang_Type_getObjCProtocolDecl(
+      T,
+      i,
+    );
+  }
+
+  late final _clang_Type_getObjCProtocolDeclPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXType, ffi.UnsignedInt)>>(
+          'clang_Type_getObjCProtocolDecl');
+  late final _clang_Type_getObjCProtocolDecl =
+      _clang_Type_getObjCProtocolDeclPtr
+          .asFunction<CXCursor Function(CXType, int)>();
+
+  /// Retreive the number of type arguments associated with an ObjC object.
+  int clang_Type_getNumObjCTypeArgs(
+    CXType T,
+  ) {
+    return _clang_Type_getNumObjCTypeArgs(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNumObjCTypeArgsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXType)>>(
+          'clang_Type_getNumObjCTypeArgs');
+  late final _clang_Type_getNumObjCTypeArgs =
+      _clang_Type_getNumObjCTypeArgsPtr.asFunction<int Function(CXType)>();
+
+  /// Retrieve a type argument associated with an ObjC object.
+  CXType clang_Type_getObjCTypeArg(
+    CXType T,
+    int i,
+  ) {
+    return _clang_Type_getObjCTypeArg(
+      T,
+      i,
+    );
+  }
+
+  late final _clang_Type_getObjCTypeArgPtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType, ffi.UnsignedInt)>>(
+          'clang_Type_getObjCTypeArg');
+  late final _clang_Type_getObjCTypeArg =
+      _clang_Type_getObjCTypeArgPtr.asFunction<CXType Function(CXType, int)>();
+
+  /// Return 1 if the CXType is a variadic function type, and 0 otherwise.
+  int clang_isFunctionTypeVariadic(
+    CXType T,
+  ) {
+    return _clang_isFunctionTypeVariadic(
+      T,
+    );
+  }
+
+  late final _clang_isFunctionTypeVariadicPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXType)>>(
+          'clang_isFunctionTypeVariadic');
+  late final _clang_isFunctionTypeVariadic =
+      _clang_isFunctionTypeVariadicPtr.asFunction<int Function(CXType)>();
+
+  /// Retrieve the return type associated with a given cursor.
+  CXType clang_getCursorResultType(
+    CXCursor C,
+  ) {
+    return _clang_getCursorResultType(
+      C,
+    );
+  }
+
+  late final _clang_getCursorResultTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXCursor)>>(
+          'clang_getCursorResultType');
+  late final _clang_getCursorResultType =
+      _clang_getCursorResultTypePtr.asFunction<CXType Function(CXCursor)>();
+
+  /// Retrieve the exception specification type associated with a given cursor.
+  /// This is a value of type CXCursor_ExceptionSpecificationKind.
+  int clang_getCursorExceptionSpecificationType(
+    CXCursor C,
+  ) {
+    return _clang_getCursorExceptionSpecificationType(
+      C,
+    );
+  }
+
+  late final _clang_getCursorExceptionSpecificationTypePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXCursor)>>(
+          'clang_getCursorExceptionSpecificationType');
+  late final _clang_getCursorExceptionSpecificationType =
+      _clang_getCursorExceptionSpecificationTypePtr
+          .asFunction<int Function(CXCursor)>();
+
+  /// Return 1 if the CXType is a POD (plain old data) type, and 0 otherwise.
+  int clang_isPODType(
+    CXType T,
+  ) {
+    return _clang_isPODType(
+      T,
+    );
+  }
+
+  late final _clang_isPODTypePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXType)>>(
+          'clang_isPODType');
+  late final _clang_isPODType =
+      _clang_isPODTypePtr.asFunction<int Function(CXType)>();
+
+  /// Return the element type of an array, complex, or vector type.
+  CXType clang_getElementType(
+    CXType T,
+  ) {
+    return _clang_getElementType(
+      T,
+    );
+  }
+
+  late final _clang_getElementTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_getElementType');
+  late final _clang_getElementType =
+      _clang_getElementTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Return the number of elements of an array or vector type.
+  int clang_getNumElements(
+    CXType T,
+  ) {
+    return _clang_getNumElements(
+      T,
+    );
+  }
+
+  late final _clang_getNumElementsPtr =
+      _lookup<ffi.NativeFunction<ffi.LongLong Function(CXType)>>(
+          'clang_getNumElements');
+  late final _clang_getNumElements =
+      _clang_getNumElementsPtr.asFunction<int Function(CXType)>();
+
+  /// Return the element type of an array type.
+  CXType clang_getArrayElementType(
+    CXType T,
+  ) {
+    return _clang_getArrayElementType(
+      T,
+    );
+  }
+
+  late final _clang_getArrayElementTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_getArrayElementType');
+  late final _clang_getArrayElementType =
+      _clang_getArrayElementTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Return the array size of a constant array.
+  int clang_getArraySize(
+    CXType T,
+  ) {
+    return _clang_getArraySize(
+      T,
+    );
+  }
+
+  late final _clang_getArraySizePtr =
+      _lookup<ffi.NativeFunction<ffi.LongLong Function(CXType)>>(
+          'clang_getArraySize');
+  late final _clang_getArraySize =
+      _clang_getArraySizePtr.asFunction<int Function(CXType)>();
+
+  /// Retrieve the type named by the qualified-id.
+  CXType clang_Type_getNamedType(
+    CXType T,
+  ) {
+    return _clang_Type_getNamedType(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNamedTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_Type_getNamedType');
+  late final _clang_Type_getNamedType =
+      _clang_Type_getNamedTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Determine if a typedef is 'transparent' tag.
+  int clang_Type_isTransparentTagTypedef(
+    CXType T,
+  ) {
+    return _clang_Type_isTransparentTagTypedef(
+      T,
+    );
+  }
+
+  late final _clang_Type_isTransparentTagTypedefPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXType)>>(
+          'clang_Type_isTransparentTagTypedef');
+  late final _clang_Type_isTransparentTagTypedef =
+      _clang_Type_isTransparentTagTypedefPtr.asFunction<int Function(CXType)>();
+
+  /// Retrieve the nullability kind of a pointer type.
+  int clang_Type_getNullability(
+    CXType T,
+  ) {
+    return _clang_Type_getNullability(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNullabilityPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXType)>>(
+          'clang_Type_getNullability');
+  late final _clang_Type_getNullability =
+      _clang_Type_getNullabilityPtr.asFunction<int Function(CXType)>();
+
+  /// Return the alignment of a type in bytes as per C++[expr.alignof] standard.
+  int clang_Type_getAlignOf(
+    CXType T,
+  ) {
+    return _clang_Type_getAlignOf(
+      T,
+    );
+  }
+
+  late final _clang_Type_getAlignOfPtr =
+      _lookup<ffi.NativeFunction<ffi.LongLong Function(CXType)>>(
+          'clang_Type_getAlignOf');
+  late final _clang_Type_getAlignOf =
+      _clang_Type_getAlignOfPtr.asFunction<int Function(CXType)>();
+
+  /// Return the class type of an member pointer type.
+  CXType clang_Type_getClassType(
+    CXType T,
+  ) {
+    return _clang_Type_getClassType(
+      T,
+    );
+  }
+
+  late final _clang_Type_getClassTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_Type_getClassType');
+  late final _clang_Type_getClassType =
+      _clang_Type_getClassTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Return the size of a type in bytes as per C++[expr.sizeof] standard.
+  int clang_Type_getSizeOf(
+    CXType T,
+  ) {
+    return _clang_Type_getSizeOf(
+      T,
+    );
+  }
+
+  late final _clang_Type_getSizeOfPtr =
+      _lookup<ffi.NativeFunction<ffi.LongLong Function(CXType)>>(
+          'clang_Type_getSizeOf');
+  late final _clang_Type_getSizeOf =
+      _clang_Type_getSizeOfPtr.asFunction<int Function(CXType)>();
+
+  /// Return the offset of a field named S in a record of type T in bits as it
+  /// would be returned by __offsetof__ as per C++11[18.2p4]
+  int clang_Type_getOffsetOf(
+    CXType T,
+    ffi.Pointer<ffi.Char> S,
+  ) {
+    return _clang_Type_getOffsetOf(
+      T,
+      S,
+    );
+  }
+
+  late final _clang_Type_getOffsetOfPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.LongLong Function(
+              CXType, ffi.Pointer<ffi.Char>)>>('clang_Type_getOffsetOf');
+  late final _clang_Type_getOffsetOf = _clang_Type_getOffsetOfPtr
+      .asFunction<int Function(CXType, ffi.Pointer<ffi.Char>)>();
+
+  /// Return the type that was modified by this attributed type.
+  CXType clang_Type_getModifiedType(
+    CXType T,
+  ) {
+    return _clang_Type_getModifiedType(
+      T,
+    );
+  }
+
+  late final _clang_Type_getModifiedTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType)>>(
+          'clang_Type_getModifiedType');
+  late final _clang_Type_getModifiedType =
+      _clang_Type_getModifiedTypePtr.asFunction<CXType Function(CXType)>();
+
+  /// Return the offset of the field represented by the Cursor.
+  int clang_Cursor_getOffsetOfField(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getOffsetOfField(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getOffsetOfFieldPtr =
+      _lookup<ffi.NativeFunction<ffi.LongLong Function(CXCursor)>>(
+          'clang_Cursor_getOffsetOfField');
+  late final _clang_Cursor_getOffsetOfField =
+      _clang_Cursor_getOffsetOfFieldPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether the given cursor represents an anonymous tag or
+  /// namespace
+  int clang_Cursor_isAnonymous(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isAnonymous(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isAnonymousPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isAnonymous');
+  late final _clang_Cursor_isAnonymous =
+      _clang_Cursor_isAnonymousPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine whether the given cursor represents an anonymous record
+  /// declaration.
+  int clang_Cursor_isAnonymousRecordDecl(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isAnonymousRecordDecl(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isAnonymousRecordDeclPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isAnonymousRecordDecl');
+  late final _clang_Cursor_isAnonymousRecordDecl =
+      _clang_Cursor_isAnonymousRecordDeclPtr
+          .asFunction<int Function(CXCursor)>();
+
+  /// Determine whether the given cursor represents an inline namespace
+  /// declaration.
+  int clang_Cursor_isInlineNamespace(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isInlineNamespace(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isInlineNamespacePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isInlineNamespace');
+  late final _clang_Cursor_isInlineNamespace =
+      _clang_Cursor_isInlineNamespacePtr.asFunction<int Function(CXCursor)>();
+
+  /// Returns the number of template arguments for given template
+  /// specialization, or -1 if type T is not a template specialization.
+  int clang_Type_getNumTemplateArguments(
+    CXType T,
+  ) {
+    return _clang_Type_getNumTemplateArguments(
+      T,
+    );
+  }
+
+  late final _clang_Type_getNumTemplateArgumentsPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXType)>>(
+          'clang_Type_getNumTemplateArguments');
+  late final _clang_Type_getNumTemplateArguments =
+      _clang_Type_getNumTemplateArgumentsPtr.asFunction<int Function(CXType)>();
+
+  /// Returns the type template argument of a template class specialization at
+  /// given index.
+  CXType clang_Type_getTemplateArgumentAsType(
+    CXType T,
+    int i,
+  ) {
+    return _clang_Type_getTemplateArgumentAsType(
+      T,
+      i,
+    );
+  }
+
+  late final _clang_Type_getTemplateArgumentAsTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXType, ffi.UnsignedInt)>>(
+          'clang_Type_getTemplateArgumentAsType');
+  late final _clang_Type_getTemplateArgumentAsType =
+      _clang_Type_getTemplateArgumentAsTypePtr
+          .asFunction<CXType Function(CXType, int)>();
+
+  /// Retrieve the ref-qualifier kind of a function or method.
+  int clang_Type_getCXXRefQualifier(
+    CXType T,
+  ) {
+    return _clang_Type_getCXXRefQualifier(
+      T,
+    );
+  }
+
+  late final _clang_Type_getCXXRefQualifierPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXType)>>(
+          'clang_Type_getCXXRefQualifier');
+  late final _clang_Type_getCXXRefQualifier =
+      _clang_Type_getCXXRefQualifierPtr.asFunction<int Function(CXType)>();
+
+  /// Returns non-zero if the cursor specifies a Record member that is a
+  /// bitfield.
+  int clang_Cursor_isBitField(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isBitField(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isBitFieldPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isBitField');
+  late final _clang_Cursor_isBitField =
+      _clang_Cursor_isBitFieldPtr.asFunction<int Function(CXCursor)>();
+
+  /// Returns 1 if the base class specified by the cursor with kind
+  /// CX_CXXBaseSpecifier is virtual.
+  int clang_isVirtualBase(
+    CXCursor arg0,
+  ) {
+    return _clang_isVirtualBase(
+      arg0,
+    );
+  }
+
+  late final _clang_isVirtualBasePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_isVirtualBase');
+  late final _clang_isVirtualBase =
+      _clang_isVirtualBasePtr.asFunction<int Function(CXCursor)>();
+
+  /// Returns the access control level for the referenced object.
+  int clang_getCXXAccessSpecifier(
+    CXCursor arg0,
+  ) {
+    return _clang_getCXXAccessSpecifier(
+      arg0,
+    );
+  }
+
+  late final _clang_getCXXAccessSpecifierPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>(
+          'clang_getCXXAccessSpecifier');
+  late final _clang_getCXXAccessSpecifier =
+      _clang_getCXXAccessSpecifierPtr.asFunction<int Function(CXCursor)>();
+
+  /// Returns the storage class for a function or variable declaration.
+  int clang_Cursor_getStorageClass(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getStorageClass(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getStorageClassPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>(
+          'clang_Cursor_getStorageClass');
+  late final _clang_Cursor_getStorageClass =
+      _clang_Cursor_getStorageClassPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine the number of overloaded declarations referenced by a
+  /// CXCursor_OverloadedDeclRef cursor.
+  int clang_getNumOverloadedDecls(
+    CXCursor cursor,
+  ) {
+    return _clang_getNumOverloadedDecls(
+      cursor,
+    );
+  }
+
+  late final _clang_getNumOverloadedDeclsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_getNumOverloadedDecls');
+  late final _clang_getNumOverloadedDecls =
+      _clang_getNumOverloadedDeclsPtr.asFunction<int Function(CXCursor)>();
+
+  /// Retrieve a cursor for one of the overloaded declarations referenced by a
+  /// CXCursor_OverloadedDeclRef cursor.
+  CXCursor clang_getOverloadedDecl(
+    CXCursor cursor,
+    int index,
+  ) {
+    return _clang_getOverloadedDecl(
+      cursor,
+      index,
+    );
+  }
+
+  late final _clang_getOverloadedDeclPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXCursor, ffi.UnsignedInt)>>(
+          'clang_getOverloadedDecl');
+  late final _clang_getOverloadedDecl = _clang_getOverloadedDeclPtr
+      .asFunction<CXCursor Function(CXCursor, int)>();
+
+  /// For cursors representing an iboutletcollection attribute, this function
+  /// returns the collection element type.
+  CXType clang_getIBOutletCollectionType(
+    CXCursor arg0,
+  ) {
+    return _clang_getIBOutletCollectionType(
+      arg0,
+    );
+  }
+
+  late final _clang_getIBOutletCollectionTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXCursor)>>(
+          'clang_getIBOutletCollectionType');
+  late final _clang_getIBOutletCollectionType =
+      _clang_getIBOutletCollectionTypePtr
+          .asFunction<CXType Function(CXCursor)>();
+
+  /// Visit the children of a particular cursor.
+  int clang_visitChildren(
+    CXCursor parent,
+    CXCursorVisitor visitor,
+    CXClientData client_data,
+  ) {
+    return _clang_visitChildren(
+      parent,
+      visitor,
+      client_data,
+    );
+  }
+
+  late final _clang_visitChildrenPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.UnsignedInt Function(
+              CXCursor, CXCursorVisitor, CXClientData)>>('clang_visitChildren');
+  late final _clang_visitChildren = _clang_visitChildrenPtr
+      .asFunction<int Function(CXCursor, CXCursorVisitor, CXClientData)>();
+
+  /// Retrieve a Unified Symbol Resolution (USR) for the entity referenced by
+  /// the given cursor.
+  CXString clang_getCursorUSR(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorUSR(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorUSRPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_getCursorUSR');
+  late final _clang_getCursorUSR =
+      _clang_getCursorUSRPtr.asFunction<CXString Function(CXCursor)>();
+
+  /// Construct a USR for a specified Objective-C class.
+  CXString clang_constructUSR_ObjCClass(
+    ffi.Pointer<ffi.Char> class_name,
+  ) {
+    return _clang_constructUSR_ObjCClass(
+      class_name,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCClassPtr =
+      _lookup<ffi.NativeFunction<CXString Function(ffi.Pointer<ffi.Char>)>>(
+          'clang_constructUSR_ObjCClass');
+  late final _clang_constructUSR_ObjCClass = _clang_constructUSR_ObjCClassPtr
+      .asFunction<CXString Function(ffi.Pointer<ffi.Char>)>();
+
+  /// Construct a USR for a specified Objective-C category.
+  CXString clang_constructUSR_ObjCCategory(
+    ffi.Pointer<ffi.Char> class_name,
+    ffi.Pointer<ffi.Char> category_name,
+  ) {
+    return _clang_constructUSR_ObjCCategory(
+      class_name,
+      category_name,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCCategoryPtr = _lookup<
+      ffi.NativeFunction<
+          CXString Function(ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>)>>('clang_constructUSR_ObjCCategory');
+  late final _clang_constructUSR_ObjCCategory =
+      _clang_constructUSR_ObjCCategoryPtr.asFunction<
+          CXString Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
+
+  /// Construct a USR for a specified Objective-C protocol.
+  CXString clang_constructUSR_ObjCProtocol(
+    ffi.Pointer<ffi.Char> protocol_name,
+  ) {
+    return _clang_constructUSR_ObjCProtocol(
+      protocol_name,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCProtocolPtr =
+      _lookup<ffi.NativeFunction<CXString Function(ffi.Pointer<ffi.Char>)>>(
+          'clang_constructUSR_ObjCProtocol');
+  late final _clang_constructUSR_ObjCProtocol =
+      _clang_constructUSR_ObjCProtocolPtr
+          .asFunction<CXString Function(ffi.Pointer<ffi.Char>)>();
+
+  /// Construct a USR for a specified Objective-C instance variable and the USR
+  /// for its containing class.
+  CXString clang_constructUSR_ObjCIvar(
+    ffi.Pointer<ffi.Char> name,
+    CXString classUSR,
+  ) {
+    return _clang_constructUSR_ObjCIvar(
+      name,
+      classUSR,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCIvarPtr = _lookup<
+          ffi
+          .NativeFunction<CXString Function(ffi.Pointer<ffi.Char>, CXString)>>(
+      'clang_constructUSR_ObjCIvar');
+  late final _clang_constructUSR_ObjCIvar = _clang_constructUSR_ObjCIvarPtr
+      .asFunction<CXString Function(ffi.Pointer<ffi.Char>, CXString)>();
+
+  /// Construct a USR for a specified Objective-C method and the USR for its
+  /// containing class.
+  CXString clang_constructUSR_ObjCMethod(
+    ffi.Pointer<ffi.Char> name,
+    int isInstanceMethod,
+    CXString classUSR,
+  ) {
+    return _clang_constructUSR_ObjCMethod(
+      name,
+      isInstanceMethod,
+      classUSR,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCMethodPtr = _lookup<
+      ffi.NativeFunction<
+          CXString Function(ffi.Pointer<ffi.Char>, ffi.UnsignedInt,
+              CXString)>>('clang_constructUSR_ObjCMethod');
+  late final _clang_constructUSR_ObjCMethod = _clang_constructUSR_ObjCMethodPtr
+      .asFunction<CXString Function(ffi.Pointer<ffi.Char>, int, CXString)>();
+
+  /// Construct a USR for a specified Objective-C property and the USR for its
+  /// containing class.
+  CXString clang_constructUSR_ObjCProperty(
+    ffi.Pointer<ffi.Char> property,
+    CXString classUSR,
+  ) {
+    return _clang_constructUSR_ObjCProperty(
+      property,
+      classUSR,
+    );
+  }
+
+  late final _clang_constructUSR_ObjCPropertyPtr = _lookup<
+          ffi
+          .NativeFunction<CXString Function(ffi.Pointer<ffi.Char>, CXString)>>(
+      'clang_constructUSR_ObjCProperty');
+  late final _clang_constructUSR_ObjCProperty =
+      _clang_constructUSR_ObjCPropertyPtr
+          .asFunction<CXString Function(ffi.Pointer<ffi.Char>, CXString)>();
+
+  /// Retrieve a name for the entity referenced by this cursor.
+  CXString clang_getCursorSpelling(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorSpelling(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorSpellingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_getCursorSpelling');
+  late final _clang_getCursorSpelling =
+      _clang_getCursorSpellingPtr.asFunction<CXString Function(CXCursor)>();
+
+  /// Retrieve a range for a piece that forms the cursors spelling name. Most of
+  /// the times there is only one range for the complete spelling but for
+  /// Objective-C methods and Objective-C message expressions, there are
+  /// multiple pieces for each selector identifier.
+  CXSourceRange clang_Cursor_getSpellingNameRange(
+    CXCursor arg0,
+    int pieceIndex,
+    int options,
+  ) {
+    return _clang_Cursor_getSpellingNameRange(
+      arg0,
+      pieceIndex,
+      options,
+    );
+  }
+
+  late final _clang_Cursor_getSpellingNameRangePtr = _lookup<
+      ffi.NativeFunction<
+          CXSourceRange Function(CXCursor, ffi.UnsignedInt,
+              ffi.UnsignedInt)>>('clang_Cursor_getSpellingNameRange');
+  late final _clang_Cursor_getSpellingNameRange =
+      _clang_Cursor_getSpellingNameRangePtr
+          .asFunction<CXSourceRange Function(CXCursor, int, int)>();
+
+  /// Get a property value for the given printing policy.
+  int clang_PrintingPolicy_getProperty(
+    CXPrintingPolicy Policy,
+    int Property,
+  ) {
+    return _clang_PrintingPolicy_getProperty(
+      Policy,
+      Property,
+    );
+  }
+
+  late final _clang_PrintingPolicy_getPropertyPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.UnsignedInt Function(CXPrintingPolicy,
+              ffi.Int32)>>('clang_PrintingPolicy_getProperty');
+  late final _clang_PrintingPolicy_getProperty =
+      _clang_PrintingPolicy_getPropertyPtr
+          .asFunction<int Function(CXPrintingPolicy, int)>();
+
+  /// Set a property value for the given printing policy.
+  void clang_PrintingPolicy_setProperty(
+    CXPrintingPolicy Policy,
+    int Property,
+    int Value,
+  ) {
+    return _clang_PrintingPolicy_setProperty(
+      Policy,
+      Property,
+      Value,
+    );
+  }
+
+  late final _clang_PrintingPolicy_setPropertyPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(CXPrintingPolicy, ffi.Int32,
+              ffi.UnsignedInt)>>('clang_PrintingPolicy_setProperty');
+  late final _clang_PrintingPolicy_setProperty =
+      _clang_PrintingPolicy_setPropertyPtr
+          .asFunction<void Function(CXPrintingPolicy, int, int)>();
+
+  /// Retrieve the default policy for the cursor.
+  CXPrintingPolicy clang_getCursorPrintingPolicy(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorPrintingPolicy(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorPrintingPolicyPtr =
+      _lookup<ffi.NativeFunction<CXPrintingPolicy Function(CXCursor)>>(
+          'clang_getCursorPrintingPolicy');
+  late final _clang_getCursorPrintingPolicy = _clang_getCursorPrintingPolicyPtr
+      .asFunction<CXPrintingPolicy Function(CXCursor)>();
+
+  /// Release a printing policy.
+  void clang_PrintingPolicy_dispose(
+    CXPrintingPolicy Policy,
+  ) {
+    return _clang_PrintingPolicy_dispose(
+      Policy,
+    );
+  }
+
+  late final _clang_PrintingPolicy_disposePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXPrintingPolicy)>>(
+          'clang_PrintingPolicy_dispose');
+  late final _clang_PrintingPolicy_dispose = _clang_PrintingPolicy_disposePtr
+      .asFunction<void Function(CXPrintingPolicy)>();
+
+  /// Pretty print declarations.
+  CXString clang_getCursorPrettyPrinted(
+    CXCursor Cursor,
+    CXPrintingPolicy Policy,
+  ) {
+    return _clang_getCursorPrettyPrinted(
+      Cursor,
+      Policy,
+    );
+  }
+
+  late final _clang_getCursorPrettyPrintedPtr = _lookup<
+          ffi.NativeFunction<CXString Function(CXCursor, CXPrintingPolicy)>>(
+      'clang_getCursorPrettyPrinted');
+  late final _clang_getCursorPrettyPrinted = _clang_getCursorPrettyPrintedPtr
+      .asFunction<CXString Function(CXCursor, CXPrintingPolicy)>();
+
+  /// Retrieve the display name for the entity referenced by this cursor.
+  CXString clang_getCursorDisplayName(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorDisplayName(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorDisplayNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_getCursorDisplayName');
+  late final _clang_getCursorDisplayName =
+      _clang_getCursorDisplayNamePtr.asFunction<CXString Function(CXCursor)>();
+
+  /// For a cursor that is a reference, retrieve a cursor representing the
+  /// entity that it references.
+  CXCursor clang_getCursorReferenced(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorReferenced(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorReferencedPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXCursor)>>(
+          'clang_getCursorReferenced');
+  late final _clang_getCursorReferenced =
+      _clang_getCursorReferencedPtr.asFunction<CXCursor Function(CXCursor)>();
+
+  /// For a cursor that is either a reference to or a declaration of some
+  /// entity, retrieve a cursor that describes the definition of that entity.
+  CXCursor clang_getCursorDefinition(
+    CXCursor arg0,
+  ) {
+    return _clang_getCursorDefinition(
+      arg0,
+    );
+  }
+
+  late final _clang_getCursorDefinitionPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXCursor)>>(
+          'clang_getCursorDefinition');
+  late final _clang_getCursorDefinition =
+      _clang_getCursorDefinitionPtr.asFunction<CXCursor Function(CXCursor)>();
+
+  /// Determine whether the declaration pointed to by this cursor is also a
+  /// definition of that entity.
+  int clang_isCursorDefinition(
+    CXCursor arg0,
+  ) {
+    return _clang_isCursorDefinition(
+      arg0,
+    );
+  }
+
+  late final _clang_isCursorDefinitionPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_isCursorDefinition');
+  late final _clang_isCursorDefinition =
+      _clang_isCursorDefinitionPtr.asFunction<int Function(CXCursor)>();
+
+  /// Retrieve the canonical cursor corresponding to the given cursor.
+  CXCursor clang_getCanonicalCursor(
+    CXCursor arg0,
+  ) {
+    return _clang_getCanonicalCursor(
+      arg0,
+    );
+  }
+
+  late final _clang_getCanonicalCursorPtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXCursor)>>(
+          'clang_getCanonicalCursor');
+  late final _clang_getCanonicalCursor =
+      _clang_getCanonicalCursorPtr.asFunction<CXCursor Function(CXCursor)>();
+
+  /// If the cursor points to a selector identifier in an Objective-C method or
+  /// message expression, this returns the selector index.
+  int clang_Cursor_getObjCSelectorIndex(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getObjCSelectorIndex(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getObjCSelectorIndexPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXCursor)>>(
+          'clang_Cursor_getObjCSelectorIndex');
+  late final _clang_Cursor_getObjCSelectorIndex =
+      _clang_Cursor_getObjCSelectorIndexPtr
+          .asFunction<int Function(CXCursor)>();
+
+  /// Given a cursor pointing to a C++ method call or an Objective-C message,
+  /// returns non-zero if the method/message is "dynamic", meaning:
+  int clang_Cursor_isDynamicCall(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isDynamicCall(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isDynamicCallPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXCursor)>>(
+          'clang_Cursor_isDynamicCall');
+  late final _clang_Cursor_isDynamicCall =
+      _clang_Cursor_isDynamicCallPtr.asFunction<int Function(CXCursor)>();
+
+  /// Given a cursor pointing to an Objective-C message or property reference,
+  /// or C++ method call, returns the CXType of the receiver.
+  CXType clang_Cursor_getReceiverType(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getReceiverType(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getReceiverTypePtr =
+      _lookup<ffi.NativeFunction<CXType Function(CXCursor)>>(
+          'clang_Cursor_getReceiverType');
+  late final _clang_Cursor_getReceiverType =
+      _clang_Cursor_getReceiverTypePtr.asFunction<CXType Function(CXCursor)>();
+
+  /// Given a cursor that represents a property declaration, return the
+  /// associated property attributes. The bits are formed from
+  /// CXObjCPropertyAttrKind.
+  int clang_Cursor_getObjCPropertyAttributes(
+    CXCursor C,
+    int reserved,
+  ) {
+    return _clang_Cursor_getObjCPropertyAttributes(
+      C,
+      reserved,
+    );
+  }
+
+  late final _clang_Cursor_getObjCPropertyAttributesPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.UnsignedInt Function(CXCursor, ffi.UnsignedInt)>>(
+      'clang_Cursor_getObjCPropertyAttributes');
+  late final _clang_Cursor_getObjCPropertyAttributes =
+      _clang_Cursor_getObjCPropertyAttributesPtr
+          .asFunction<int Function(CXCursor, int)>();
+
+  /// Given a cursor that represents a property declaration, return the name of
+  /// the method that implements the getter.
+  CXString clang_Cursor_getObjCPropertyGetterName(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getObjCPropertyGetterName(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getObjCPropertyGetterNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_Cursor_getObjCPropertyGetterName');
+  late final _clang_Cursor_getObjCPropertyGetterName =
+      _clang_Cursor_getObjCPropertyGetterNamePtr
+          .asFunction<CXString Function(CXCursor)>();
+
+  /// Given a cursor that represents a property declaration, return the name of
+  /// the method that implements the setter, if any.
+  CXString clang_Cursor_getObjCPropertySetterName(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getObjCPropertySetterName(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getObjCPropertySetterNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_Cursor_getObjCPropertySetterName');
+  late final _clang_Cursor_getObjCPropertySetterName =
+      _clang_Cursor_getObjCPropertySetterNamePtr
+          .asFunction<CXString Function(CXCursor)>();
+
+  /// Given a cursor that represents an Objective-C method or parameter
+  /// declaration, return the associated Objective-C qualifiers for the return
+  /// type or the parameter respectively. The bits are formed from
+  /// CXObjCDeclQualifierKind.
+  int clang_Cursor_getObjCDeclQualifiers(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getObjCDeclQualifiers(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getObjCDeclQualifiersPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_getObjCDeclQualifiers');
+  late final _clang_Cursor_getObjCDeclQualifiers =
+      _clang_Cursor_getObjCDeclQualifiersPtr
+          .asFunction<int Function(CXCursor)>();
+
+  /// Given a cursor that represents an Objective-C method or property
+  /// declaration, return non-zero if the declaration was affected by
+  /// "\@optional". Returns zero if the cursor is not such a declaration or it
+  /// is "\@required".
+  int clang_Cursor_isObjCOptional(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isObjCOptional(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isObjCOptionalPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isObjCOptional');
+  late final _clang_Cursor_isObjCOptional =
+      _clang_Cursor_isObjCOptionalPtr.asFunction<int Function(CXCursor)>();
+
+  /// Returns non-zero if the given cursor is a variadic function or method.
+  int clang_Cursor_isVariadic(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_isVariadic(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_isVariadicPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_Cursor_isVariadic');
+  late final _clang_Cursor_isVariadic =
+      _clang_Cursor_isVariadicPtr.asFunction<int Function(CXCursor)>();
+
+  /// Returns non-zero if the given cursor points to a symbol marked with
+  /// external_source_symbol attribute.
+  int clang_Cursor_isExternalSymbol(
+    CXCursor C,
+    ffi.Pointer<CXString> language,
+    ffi.Pointer<CXString> definedIn,
+    ffi.Pointer<ffi.UnsignedInt> isGenerated,
+  ) {
+    return _clang_Cursor_isExternalSymbol(
+      C,
+      language,
+      definedIn,
+      isGenerated,
+    );
+  }
+
+  late final _clang_Cursor_isExternalSymbolPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.UnsignedInt Function(
+              CXCursor,
+              ffi.Pointer<CXString>,
+              ffi.Pointer<CXString>,
+              ffi.Pointer<ffi.UnsignedInt>)>>('clang_Cursor_isExternalSymbol');
+  late final _clang_Cursor_isExternalSymbol =
+      _clang_Cursor_isExternalSymbolPtr.asFunction<
+          int Function(CXCursor, ffi.Pointer<CXString>, ffi.Pointer<CXString>,
+              ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Given a cursor that represents a declaration, return the associated
+  /// comment's source range. The range may include multiple consecutive
+  /// comments with whitespace in between.
+  CXSourceRange clang_Cursor_getCommentRange(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getCommentRange(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getCommentRangePtr =
+      _lookup<ffi.NativeFunction<CXSourceRange Function(CXCursor)>>(
+          'clang_Cursor_getCommentRange');
+  late final _clang_Cursor_getCommentRange = _clang_Cursor_getCommentRangePtr
+      .asFunction<CXSourceRange Function(CXCursor)>();
+
+  /// Given a cursor that represents a declaration, return the associated
+  /// comment text, including comment markers.
+  CXString clang_Cursor_getRawCommentText(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getRawCommentText(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getRawCommentTextPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_Cursor_getRawCommentText');
+  late final _clang_Cursor_getRawCommentText =
+      _clang_Cursor_getRawCommentTextPtr
+          .asFunction<CXString Function(CXCursor)>();
+
+  /// Given a cursor that represents a documentable entity (e.g., declaration),
+  /// return the associated first paragraph.
+  CXString clang_Cursor_getBriefCommentText(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getBriefCommentText(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getBriefCommentTextPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_Cursor_getBriefCommentText');
+  late final _clang_Cursor_getBriefCommentText =
+      _clang_Cursor_getBriefCommentTextPtr
+          .asFunction<CXString Function(CXCursor)>();
+
+  /// Retrieve the CXString representing the mangled name of the cursor.
+  CXString clang_Cursor_getMangling(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getMangling(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getManglingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCursor)>>(
+          'clang_Cursor_getMangling');
+  late final _clang_Cursor_getMangling =
+      _clang_Cursor_getManglingPtr.asFunction<CXString Function(CXCursor)>();
+
+  /// Retrieve the CXStrings representing the mangled symbols of the C++
+  /// constructor or destructor at the cursor.
+  ffi.Pointer<CXStringSet> clang_Cursor_getCXXManglings(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getCXXManglings(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getCXXManglingsPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<CXStringSet> Function(CXCursor)>>(
+          'clang_Cursor_getCXXManglings');
+  late final _clang_Cursor_getCXXManglings = _clang_Cursor_getCXXManglingsPtr
+      .asFunction<ffi.Pointer<CXStringSet> Function(CXCursor)>();
+
+  /// Retrieve the CXStrings representing the mangled symbols of the ObjC class
+  /// interface or implementation at the cursor.
+  ffi.Pointer<CXStringSet> clang_Cursor_getObjCManglings(
+    CXCursor arg0,
+  ) {
+    return _clang_Cursor_getObjCManglings(
+      arg0,
+    );
+  }
+
+  late final _clang_Cursor_getObjCManglingsPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<CXStringSet> Function(CXCursor)>>(
+          'clang_Cursor_getObjCManglings');
+  late final _clang_Cursor_getObjCManglings = _clang_Cursor_getObjCManglingsPtr
+      .asFunction<ffi.Pointer<CXStringSet> Function(CXCursor)>();
+
+  /// Given a CXCursor_ModuleImportDecl cursor, return the associated module.
+  CXModule clang_Cursor_getModule(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_getModule(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_getModulePtr =
+      _lookup<ffi.NativeFunction<CXModule Function(CXCursor)>>(
+          'clang_Cursor_getModule');
+  late final _clang_Cursor_getModule =
+      _clang_Cursor_getModulePtr.asFunction<CXModule Function(CXCursor)>();
+
+  /// Given a CXFile header file, return the module that contains it, if one
+  /// exists.
+  CXModule clang_getModuleForFile(
+    CXTranslationUnit arg0,
+    CXFile arg1,
+  ) {
+    return _clang_getModuleForFile(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_getModuleForFilePtr =
+      _lookup<ffi.NativeFunction<CXModule Function(CXTranslationUnit, CXFile)>>(
+          'clang_getModuleForFile');
+  late final _clang_getModuleForFile = _clang_getModuleForFilePtr
+      .asFunction<CXModule Function(CXTranslationUnit, CXFile)>();
+
+  /// Returns the module file where the provided module object came from.
+  CXFile clang_Module_getASTFile(
+    CXModule Module,
+  ) {
+    return _clang_Module_getASTFile(
+      Module,
+    );
+  }
+
+  late final _clang_Module_getASTFilePtr =
+      _lookup<ffi.NativeFunction<CXFile Function(CXModule)>>(
+          'clang_Module_getASTFile');
+  late final _clang_Module_getASTFile =
+      _clang_Module_getASTFilePtr.asFunction<CXFile Function(CXModule)>();
+
+  /// Returns the parent of a sub-module or NULL if the given module is
+  /// top-level, e.g. for 'std.vector' it will return the 'std' module.
+  CXModule clang_Module_getParent(
+    CXModule Module,
+  ) {
+    return _clang_Module_getParent(
+      Module,
+    );
+  }
+
+  late final _clang_Module_getParentPtr =
+      _lookup<ffi.NativeFunction<CXModule Function(CXModule)>>(
+          'clang_Module_getParent');
+  late final _clang_Module_getParent =
+      _clang_Module_getParentPtr.asFunction<CXModule Function(CXModule)>();
+
+  /// Returns the name of the module, e.g. for the 'std.vector' sub-module it
+  /// will return "vector".
+  CXString clang_Module_getName(
+    CXModule Module,
+  ) {
+    return _clang_Module_getName(
+      Module,
+    );
+  }
+
+  late final _clang_Module_getNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXModule)>>(
+          'clang_Module_getName');
+  late final _clang_Module_getName =
+      _clang_Module_getNamePtr.asFunction<CXString Function(CXModule)>();
+
+  /// Returns the full name of the module, e.g. "std.vector".
+  CXString clang_Module_getFullName(
+    CXModule Module,
+  ) {
+    return _clang_Module_getFullName(
+      Module,
+    );
+  }
+
+  late final _clang_Module_getFullNamePtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXModule)>>(
+          'clang_Module_getFullName');
+  late final _clang_Module_getFullName =
+      _clang_Module_getFullNamePtr.asFunction<CXString Function(CXModule)>();
+
+  /// Returns non-zero if the module is a system one.
+  int clang_Module_isSystem(
+    CXModule Module,
+  ) {
+    return _clang_Module_isSystem(
+      Module,
+    );
+  }
+
+  late final _clang_Module_isSystemPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXModule)>>(
+          'clang_Module_isSystem');
+  late final _clang_Module_isSystem =
+      _clang_Module_isSystemPtr.asFunction<int Function(CXModule)>();
+
+  /// Returns the number of top level headers associated with this module.
+  int clang_Module_getNumTopLevelHeaders(
+    CXTranslationUnit arg0,
+    CXModule Module,
+  ) {
+    return _clang_Module_getNumTopLevelHeaders(
+      arg0,
+      Module,
+    );
+  }
+
+  late final _clang_Module_getNumTopLevelHeadersPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.UnsignedInt Function(CXTranslationUnit,
+              CXModule)>>('clang_Module_getNumTopLevelHeaders');
+  late final _clang_Module_getNumTopLevelHeaders =
+      _clang_Module_getNumTopLevelHeadersPtr
+          .asFunction<int Function(CXTranslationUnit, CXModule)>();
+
+  /// Returns the specified top level header associated with the module.
+  CXFile clang_Module_getTopLevelHeader(
+    CXTranslationUnit arg0,
+    CXModule Module,
+    int Index,
+  ) {
+    return _clang_Module_getTopLevelHeader(
+      arg0,
+      Module,
+      Index,
+    );
+  }
+
+  late final _clang_Module_getTopLevelHeaderPtr = _lookup<
+      ffi.NativeFunction<
+          CXFile Function(CXTranslationUnit, CXModule,
+              ffi.UnsignedInt)>>('clang_Module_getTopLevelHeader');
+  late final _clang_Module_getTopLevelHeader =
+      _clang_Module_getTopLevelHeaderPtr
+          .asFunction<CXFile Function(CXTranslationUnit, CXModule, int)>();
+
+  /// Determine if a C++ constructor is a converting constructor.
+  int clang_CXXConstructor_isConvertingConstructor(
+    CXCursor C,
+  ) {
+    return _clang_CXXConstructor_isConvertingConstructor(
+      C,
+    );
+  }
+
+  late final _clang_CXXConstructor_isConvertingConstructorPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_CXXConstructor_isConvertingConstructor');
+  late final _clang_CXXConstructor_isConvertingConstructor =
+      _clang_CXXConstructor_isConvertingConstructorPtr
+          .asFunction<int Function(CXCursor)>();
+
+  /// Determine if a C++ constructor is a copy constructor.
+  int clang_CXXConstructor_isCopyConstructor(
+    CXCursor C,
+  ) {
+    return _clang_CXXConstructor_isCopyConstructor(
+      C,
+    );
+  }
+
+  late final _clang_CXXConstructor_isCopyConstructorPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_CXXConstructor_isCopyConstructor');
+  late final _clang_CXXConstructor_isCopyConstructor =
+      _clang_CXXConstructor_isCopyConstructorPtr
+          .asFunction<int Function(CXCursor)>();
+
+  /// Determine if a C++ constructor is the default constructor.
+  int clang_CXXConstructor_isDefaultConstructor(
+    CXCursor C,
+  ) {
+    return _clang_CXXConstructor_isDefaultConstructor(
+      C,
+    );
+  }
+
+  late final _clang_CXXConstructor_isDefaultConstructorPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_CXXConstructor_isDefaultConstructor');
+  late final _clang_CXXConstructor_isDefaultConstructor =
+      _clang_CXXConstructor_isDefaultConstructorPtr
+          .asFunction<int Function(CXCursor)>();
+
+  /// Determine if a C++ constructor is a move constructor.
+  int clang_CXXConstructor_isMoveConstructor(
+    CXCursor C,
+  ) {
+    return _clang_CXXConstructor_isMoveConstructor(
+      C,
+    );
+  }
+
+  late final _clang_CXXConstructor_isMoveConstructorPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_CXXConstructor_isMoveConstructor');
+  late final _clang_CXXConstructor_isMoveConstructor =
+      _clang_CXXConstructor_isMoveConstructorPtr
+          .asFunction<int Function(CXCursor)>();
+
+  /// Determine if a C++ field is declared 'mutable'.
+  int clang_CXXField_isMutable(
+    CXCursor C,
+  ) {
+    return _clang_CXXField_isMutable(
+      C,
+    );
+  }
+
+  late final _clang_CXXField_isMutablePtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_CXXField_isMutable');
+  late final _clang_CXXField_isMutable =
+      _clang_CXXField_isMutablePtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine if a C++ method is declared '= default'.
+  int clang_CXXMethod_isDefaulted(
+    CXCursor C,
+  ) {
+    return _clang_CXXMethod_isDefaulted(
+      C,
+    );
+  }
+
+  late final _clang_CXXMethod_isDefaultedPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_CXXMethod_isDefaulted');
+  late final _clang_CXXMethod_isDefaulted =
+      _clang_CXXMethod_isDefaultedPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine if a C++ member function or member function template is pure
+  /// virtual.
+  int clang_CXXMethod_isPureVirtual(
+    CXCursor C,
+  ) {
+    return _clang_CXXMethod_isPureVirtual(
+      C,
+    );
+  }
+
+  late final _clang_CXXMethod_isPureVirtualPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_CXXMethod_isPureVirtual');
+  late final _clang_CXXMethod_isPureVirtual =
+      _clang_CXXMethod_isPureVirtualPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine if a C++ member function or member function template is declared
+  /// 'static'.
+  int clang_CXXMethod_isStatic(
+    CXCursor C,
+  ) {
+    return _clang_CXXMethod_isStatic(
+      C,
+    );
+  }
+
+  late final _clang_CXXMethod_isStaticPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_CXXMethod_isStatic');
+  late final _clang_CXXMethod_isStatic =
+      _clang_CXXMethod_isStaticPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine if a C++ member function or member function template is
+  /// explicitly declared 'virtual' or if it overrides a virtual method from one
+  /// of the base classes.
+  int clang_CXXMethod_isVirtual(
+    CXCursor C,
+  ) {
+    return _clang_CXXMethod_isVirtual(
+      C,
+    );
+  }
+
+  late final _clang_CXXMethod_isVirtualPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_CXXMethod_isVirtual');
+  late final _clang_CXXMethod_isVirtual =
+      _clang_CXXMethod_isVirtualPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine if a C++ record is abstract, i.e. whether a class or struct has
+  /// a pure virtual member function.
+  int clang_CXXRecord_isAbstract(
+    CXCursor C,
+  ) {
+    return _clang_CXXRecord_isAbstract(
+      C,
+    );
+  }
+
+  late final _clang_CXXRecord_isAbstractPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_CXXRecord_isAbstract');
+  late final _clang_CXXRecord_isAbstract =
+      _clang_CXXRecord_isAbstractPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine if an enum declaration refers to a scoped enum.
+  int clang_EnumDecl_isScoped(
+    CXCursor C,
+  ) {
+    return _clang_EnumDecl_isScoped(
+      C,
+    );
+  }
+
+  late final _clang_EnumDecl_isScopedPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_EnumDecl_isScoped');
+  late final _clang_EnumDecl_isScoped =
+      _clang_EnumDecl_isScopedPtr.asFunction<int Function(CXCursor)>();
+
+  /// Determine if a C++ member function or member function template is declared
+  /// 'const'.
+  int clang_CXXMethod_isConst(
+    CXCursor C,
+  ) {
+    return _clang_CXXMethod_isConst(
+      C,
+    );
+  }
+
+  late final _clang_CXXMethod_isConstPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCursor)>>(
+          'clang_CXXMethod_isConst');
+  late final _clang_CXXMethod_isConst =
+      _clang_CXXMethod_isConstPtr.asFunction<int Function(CXCursor)>();
+
+  /// Given a cursor that represents a template, determine the cursor kind of
+  /// the specializations would be generated by instantiating the template.
+  int clang_getTemplateCursorKind(
+    CXCursor C,
+  ) {
+    return _clang_getTemplateCursorKind(
+      C,
+    );
+  }
+
+  late final _clang_getTemplateCursorKindPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCursor)>>(
+          'clang_getTemplateCursorKind');
+  late final _clang_getTemplateCursorKind =
+      _clang_getTemplateCursorKindPtr.asFunction<int Function(CXCursor)>();
+
+  /// Given a cursor that may represent a specialization or instantiation of a
+  /// template, retrieve the cursor that represents the template that it
+  /// specializes or from which it was instantiated.
+  CXCursor clang_getSpecializedCursorTemplate(
+    CXCursor C,
+  ) {
+    return _clang_getSpecializedCursorTemplate(
+      C,
+    );
+  }
+
+  late final _clang_getSpecializedCursorTemplatePtr =
+      _lookup<ffi.NativeFunction<CXCursor Function(CXCursor)>>(
+          'clang_getSpecializedCursorTemplate');
+  late final _clang_getSpecializedCursorTemplate =
+      _clang_getSpecializedCursorTemplatePtr
+          .asFunction<CXCursor Function(CXCursor)>();
+
+  /// Given a cursor that references something else, return the source range
+  /// covering that reference.
+  CXSourceRange clang_getCursorReferenceNameRange(
+    CXCursor C,
+    int NameFlags,
+    int PieceIndex,
+  ) {
+    return _clang_getCursorReferenceNameRange(
+      C,
+      NameFlags,
+      PieceIndex,
+    );
+  }
+
+  late final _clang_getCursorReferenceNameRangePtr = _lookup<
+      ffi.NativeFunction<
+          CXSourceRange Function(CXCursor, ffi.UnsignedInt,
+              ffi.UnsignedInt)>>('clang_getCursorReferenceNameRange');
+  late final _clang_getCursorReferenceNameRange =
+      _clang_getCursorReferenceNameRangePtr
+          .asFunction<CXSourceRange Function(CXCursor, int, int)>();
+
+  /// Get the raw lexical token starting with the given location.
+  ffi.Pointer<CXToken> clang_getToken(
+    CXTranslationUnit TU,
+    CXSourceLocation Location,
+  ) {
+    return _clang_getToken(
+      TU,
+      Location,
+    );
+  }
+
+  late final _clang_getTokenPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<CXToken> Function(
+              CXTranslationUnit, CXSourceLocation)>>('clang_getToken');
+  late final _clang_getToken = _clang_getTokenPtr.asFunction<
+      ffi.Pointer<CXToken> Function(CXTranslationUnit, CXSourceLocation)>();
+
+  /// Determine the kind of the given token.
+  int clang_getTokenKind(
+    CXToken arg0,
+  ) {
+    return _clang_getTokenKind(
+      arg0,
+    );
+  }
+
+  late final _clang_getTokenKindPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXToken)>>(
+          'clang_getTokenKind');
+  late final _clang_getTokenKind =
+      _clang_getTokenKindPtr.asFunction<int Function(CXToken)>();
+
+  /// Determine the spelling of the given token.
+  CXString clang_getTokenSpelling(
+    CXTranslationUnit arg0,
+    CXToken arg1,
+  ) {
+    return _clang_getTokenSpelling(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_getTokenSpellingPtr = _lookup<
+          ffi.NativeFunction<CXString Function(CXTranslationUnit, CXToken)>>(
+      'clang_getTokenSpelling');
+  late final _clang_getTokenSpelling = _clang_getTokenSpellingPtr
+      .asFunction<CXString Function(CXTranslationUnit, CXToken)>();
+
+  /// Retrieve the source location of the given token.
+  CXSourceLocation clang_getTokenLocation(
+    CXTranslationUnit arg0,
+    CXToken arg1,
+  ) {
+    return _clang_getTokenLocation(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_getTokenLocationPtr = _lookup<
+      ffi.NativeFunction<
+          CXSourceLocation Function(
+              CXTranslationUnit, CXToken)>>('clang_getTokenLocation');
+  late final _clang_getTokenLocation = _clang_getTokenLocationPtr
+      .asFunction<CXSourceLocation Function(CXTranslationUnit, CXToken)>();
+
+  /// Retrieve a source range that covers the given token.
+  CXSourceRange clang_getTokenExtent(
+    CXTranslationUnit arg0,
+    CXToken arg1,
+  ) {
+    return _clang_getTokenExtent(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_getTokenExtentPtr = _lookup<
+          ffi
+          .NativeFunction<CXSourceRange Function(CXTranslationUnit, CXToken)>>(
+      'clang_getTokenExtent');
+  late final _clang_getTokenExtent = _clang_getTokenExtentPtr
+      .asFunction<CXSourceRange Function(CXTranslationUnit, CXToken)>();
+
+  /// Tokenize the source code described by the given range into raw lexical
+  /// tokens.
+  void clang_tokenize(
+    CXTranslationUnit TU,
+    CXSourceRange Range,
+    ffi.Pointer<ffi.Pointer<CXToken>> Tokens,
+    ffi.Pointer<ffi.UnsignedInt> NumTokens,
+  ) {
+    return _clang_tokenize(
+      TU,
+      Range,
+      Tokens,
+      NumTokens,
+    );
+  }
+
+  late final _clang_tokenizePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              CXTranslationUnit,
+              CXSourceRange,
+              ffi.Pointer<ffi.Pointer<CXToken>>,
+              ffi.Pointer<ffi.UnsignedInt>)>>('clang_tokenize');
+  late final _clang_tokenize = _clang_tokenizePtr.asFunction<
+      void Function(CXTranslationUnit, CXSourceRange,
+          ffi.Pointer<ffi.Pointer<CXToken>>, ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Annotate the given set of tokens by providing cursors for each token that
+  /// can be mapped to a specific entity within the abstract syntax tree.
+  void clang_annotateTokens(
+    CXTranslationUnit TU,
+    ffi.Pointer<CXToken> Tokens,
+    int NumTokens,
+    ffi.Pointer<CXCursor> Cursors,
+  ) {
+    return _clang_annotateTokens(
+      TU,
+      Tokens,
+      NumTokens,
+      Cursors,
+    );
+  }
+
+  late final _clang_annotateTokensPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(CXTranslationUnit, ffi.Pointer<CXToken>,
+              ffi.UnsignedInt, ffi.Pointer<CXCursor>)>>('clang_annotateTokens');
+  late final _clang_annotateTokens = _clang_annotateTokensPtr.asFunction<
+      void Function(CXTranslationUnit, ffi.Pointer<CXToken>, int,
+          ffi.Pointer<CXCursor>)>();
+
+  /// Free the given set of tokens.
+  void clang_disposeTokens(
+    CXTranslationUnit TU,
+    ffi.Pointer<CXToken> Tokens,
+    int NumTokens,
+  ) {
+    return _clang_disposeTokens(
+      TU,
+      Tokens,
+      NumTokens,
+    );
+  }
+
+  late final _clang_disposeTokensPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(CXTranslationUnit, ffi.Pointer<CXToken>,
+              ffi.UnsignedInt)>>('clang_disposeTokens');
+  late final _clang_disposeTokens = _clang_disposeTokensPtr.asFunction<
+      void Function(CXTranslationUnit, ffi.Pointer<CXToken>, int)>();
+
+  /// These routines are used for testing and debugging, only, and should not be
+  /// relied upon.
+  CXString clang_getCursorKindSpelling(
+    int Kind,
+  ) {
+    return _clang_getCursorKindSpelling(
+      Kind,
+    );
+  }
+
+  late final _clang_getCursorKindSpellingPtr =
+      _lookup<ffi.NativeFunction<CXString Function(ffi.Int32)>>(
+          'clang_getCursorKindSpelling');
+  late final _clang_getCursorKindSpelling =
+      _clang_getCursorKindSpellingPtr.asFunction<CXString Function(int)>();
+
+  void clang_getDefinitionSpellingAndExtent(
+    CXCursor arg0,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> startBuf,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> endBuf,
+    ffi.Pointer<ffi.UnsignedInt> startLine,
+    ffi.Pointer<ffi.UnsignedInt> startColumn,
+    ffi.Pointer<ffi.UnsignedInt> endLine,
+    ffi.Pointer<ffi.UnsignedInt> endColumn,
+  ) {
+    return _clang_getDefinitionSpellingAndExtent(
+      arg0,
+      startBuf,
+      endBuf,
+      startLine,
+      startColumn,
+      endLine,
+      endColumn,
+    );
+  }
+
+  late final _clang_getDefinitionSpellingAndExtentPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Void Function(
+                  CXCursor,
+                  ffi.Pointer<ffi.Pointer<ffi.Char>>,
+                  ffi.Pointer<ffi.Pointer<ffi.Char>>,
+                  ffi.Pointer<ffi.UnsignedInt>,
+                  ffi.Pointer<ffi.UnsignedInt>,
+                  ffi.Pointer<ffi.UnsignedInt>,
+                  ffi.Pointer<ffi.UnsignedInt>)>>(
+      'clang_getDefinitionSpellingAndExtent');
+  late final _clang_getDefinitionSpellingAndExtent =
+      _clang_getDefinitionSpellingAndExtentPtr.asFunction<
+          void Function(
+              CXCursor,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>();
+
+  void clang_enableStackTraces() {
+    return _clang_enableStackTraces();
+  }
+
+  late final _clang_enableStackTracesPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>(
+          'clang_enableStackTraces');
+  late final _clang_enableStackTraces =
+      _clang_enableStackTracesPtr.asFunction<void Function()>();
+
+  void clang_executeOnThread(
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        fn,
+    ffi.Pointer<ffi.Void> user_data,
+    int stack_size,
+  ) {
+    return _clang_executeOnThread(
+      fn,
+      user_data,
+      stack_size,
+    );
+  }
+
+  late final _clang_executeOnThreadPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<
+                  ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>,
+              ffi.Pointer<ffi.Void>,
+              ffi.UnsignedInt)>>('clang_executeOnThread');
+  late final _clang_executeOnThread = _clang_executeOnThreadPtr.asFunction<
+      void Function(
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>,
+          ffi.Pointer<ffi.Void>,
+          int)>();
+
+  /// Determine the kind of a particular chunk within a completion string.
+  int clang_getCompletionChunkKind(
+    CXCompletionString completion_string,
+    int chunk_number,
+  ) {
+    return _clang_getCompletionChunkKind(
+      completion_string,
+      chunk_number,
+    );
+  }
+
+  late final _clang_getCompletionChunkKindPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int32 Function(CXCompletionString,
+              ffi.UnsignedInt)>>('clang_getCompletionChunkKind');
+  late final _clang_getCompletionChunkKind = _clang_getCompletionChunkKindPtr
+      .asFunction<int Function(CXCompletionString, int)>();
+
+  /// Retrieve the text associated with a particular chunk within a completion
+  /// string.
+  CXString clang_getCompletionChunkText(
+    CXCompletionString completion_string,
+    int chunk_number,
+  ) {
+    return _clang_getCompletionChunkText(
+      completion_string,
+      chunk_number,
+    );
+  }
+
+  late final _clang_getCompletionChunkTextPtr = _lookup<
+      ffi.NativeFunction<
+          CXString Function(CXCompletionString,
+              ffi.UnsignedInt)>>('clang_getCompletionChunkText');
+  late final _clang_getCompletionChunkText = _clang_getCompletionChunkTextPtr
+      .asFunction<CXString Function(CXCompletionString, int)>();
+
+  /// Retrieve the completion string associated with a particular chunk within a
+  /// completion string.
+  CXCompletionString clang_getCompletionChunkCompletionString(
+    CXCompletionString completion_string,
+    int chunk_number,
+  ) {
+    return _clang_getCompletionChunkCompletionString(
+      completion_string,
+      chunk_number,
+    );
+  }
+
+  late final _clang_getCompletionChunkCompletionStringPtr = _lookup<
+      ffi.NativeFunction<
+          CXCompletionString Function(CXCompletionString,
+              ffi.UnsignedInt)>>('clang_getCompletionChunkCompletionString');
+  late final _clang_getCompletionChunkCompletionString =
+      _clang_getCompletionChunkCompletionStringPtr
+          .asFunction<CXCompletionString Function(CXCompletionString, int)>();
+
+  /// Retrieve the number of chunks in the given code-completion string.
+  int clang_getNumCompletionChunks(
+    CXCompletionString completion_string,
+  ) {
+    return _clang_getNumCompletionChunks(
+      completion_string,
+    );
+  }
+
+  late final _clang_getNumCompletionChunksPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCompletionString)>>(
+          'clang_getNumCompletionChunks');
+  late final _clang_getNumCompletionChunks = _clang_getNumCompletionChunksPtr
+      .asFunction<int Function(CXCompletionString)>();
+
+  /// Determine the priority of this code completion.
+  int clang_getCompletionPriority(
+    CXCompletionString completion_string,
+  ) {
+    return _clang_getCompletionPriority(
+      completion_string,
+    );
+  }
+
+  late final _clang_getCompletionPriorityPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCompletionString)>>(
+          'clang_getCompletionPriority');
+  late final _clang_getCompletionPriority = _clang_getCompletionPriorityPtr
+      .asFunction<int Function(CXCompletionString)>();
+
+  /// Determine the availability of the entity that this code-completion string
+  /// refers to.
+  int clang_getCompletionAvailability(
+    CXCompletionString completion_string,
+  ) {
+    return _clang_getCompletionAvailability(
+      completion_string,
+    );
+  }
+
+  late final _clang_getCompletionAvailabilityPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXCompletionString)>>(
+          'clang_getCompletionAvailability');
+  late final _clang_getCompletionAvailability =
+      _clang_getCompletionAvailabilityPtr
+          .asFunction<int Function(CXCompletionString)>();
+
+  /// Retrieve the number of annotations associated with the given completion
+  /// string.
+  int clang_getCompletionNumAnnotations(
+    CXCompletionString completion_string,
+  ) {
+    return _clang_getCompletionNumAnnotations(
+      completion_string,
+    );
+  }
+
+  late final _clang_getCompletionNumAnnotationsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXCompletionString)>>(
+          'clang_getCompletionNumAnnotations');
+  late final _clang_getCompletionNumAnnotations =
+      _clang_getCompletionNumAnnotationsPtr
+          .asFunction<int Function(CXCompletionString)>();
+
+  /// Retrieve the annotation associated with the given completion string.
+  CXString clang_getCompletionAnnotation(
+    CXCompletionString completion_string,
+    int annotation_number,
+  ) {
+    return _clang_getCompletionAnnotation(
+      completion_string,
+      annotation_number,
+    );
+  }
+
+  late final _clang_getCompletionAnnotationPtr = _lookup<
+      ffi.NativeFunction<
+          CXString Function(CXCompletionString,
+              ffi.UnsignedInt)>>('clang_getCompletionAnnotation');
+  late final _clang_getCompletionAnnotation = _clang_getCompletionAnnotationPtr
+      .asFunction<CXString Function(CXCompletionString, int)>();
+
+  /// Retrieve the parent context of the given completion string.
+  CXString clang_getCompletionParent(
+    CXCompletionString completion_string,
+    ffi.Pointer<ffi.Int32> kind,
+  ) {
+    return _clang_getCompletionParent(
+      completion_string,
+      kind,
+    );
+  }
+
+  late final _clang_getCompletionParentPtr = _lookup<
+      ffi.NativeFunction<
+          CXString Function(CXCompletionString,
+              ffi.Pointer<ffi.Int32>)>>('clang_getCompletionParent');
+  late final _clang_getCompletionParent =
+      _clang_getCompletionParentPtr.asFunction<
+          CXString Function(CXCompletionString, ffi.Pointer<ffi.Int32>)>();
+
+  /// Retrieve the brief documentation comment attached to the declaration that
+  /// corresponds to the given completion string.
+  CXString clang_getCompletionBriefComment(
+    CXCompletionString completion_string,
+  ) {
+    return _clang_getCompletionBriefComment(
+      completion_string,
+    );
+  }
+
+  late final _clang_getCompletionBriefCommentPtr =
+      _lookup<ffi.NativeFunction<CXString Function(CXCompletionString)>>(
+          'clang_getCompletionBriefComment');
+  late final _clang_getCompletionBriefComment =
+      _clang_getCompletionBriefCommentPtr
+          .asFunction<CXString Function(CXCompletionString)>();
+
+  /// Retrieve a completion string for an arbitrary declaration or macro
+  /// definition cursor.
+  CXCompletionString clang_getCursorCompletionString(
+    CXCursor cursor,
+  ) {
+    return _clang_getCursorCompletionString(
+      cursor,
+    );
+  }
+
+  late final _clang_getCursorCompletionStringPtr =
+      _lookup<ffi.NativeFunction<CXCompletionString Function(CXCursor)>>(
+          'clang_getCursorCompletionString');
+  late final _clang_getCursorCompletionString =
+      _clang_getCursorCompletionStringPtr
+          .asFunction<CXCompletionString Function(CXCursor)>();
+
+  /// Retrieve the number of fix-its for the given completion index.
+  int clang_getCompletionNumFixIts(
+    ffi.Pointer<CXCodeCompleteResults> results,
+    int completion_index,
+  ) {
+    return _clang_getCompletionNumFixIts(
+      results,
+      completion_index,
+    );
+  }
+
+  late final _clang_getCompletionNumFixItsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.UnsignedInt Function(ffi.Pointer<CXCodeCompleteResults>,
+              ffi.UnsignedInt)>>('clang_getCompletionNumFixIts');
+  late final _clang_getCompletionNumFixIts = _clang_getCompletionNumFixItsPtr
+      .asFunction<int Function(ffi.Pointer<CXCodeCompleteResults>, int)>();
+
+  /// Fix-its that *must* be applied before inserting the text for the
+  /// corresponding completion.
+  CXString clang_getCompletionFixIt(
+    ffi.Pointer<CXCodeCompleteResults> results,
+    int completion_index,
+    int fixit_index,
+    ffi.Pointer<CXSourceRange> replacement_range,
+  ) {
+    return _clang_getCompletionFixIt(
+      results,
+      completion_index,
+      fixit_index,
+      replacement_range,
+    );
+  }
+
+  late final _clang_getCompletionFixItPtr = _lookup<
+      ffi.NativeFunction<
+          CXString Function(
+              ffi.Pointer<CXCodeCompleteResults>,
+              ffi.UnsignedInt,
+              ffi.UnsignedInt,
+              ffi.Pointer<CXSourceRange>)>>('clang_getCompletionFixIt');
+  late final _clang_getCompletionFixIt =
+      _clang_getCompletionFixItPtr.asFunction<
+          CXString Function(ffi.Pointer<CXCodeCompleteResults>, int, int,
+              ffi.Pointer<CXSourceRange>)>();
+
+  /// Returns a default set of code-completion options that can be passed to
+  /// clang_codeCompleteAt().
+  int clang_defaultCodeCompleteOptions() {
+    return _clang_defaultCodeCompleteOptions();
+  }
+
+  late final _clang_defaultCodeCompleteOptionsPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function()>>(
+          'clang_defaultCodeCompleteOptions');
+  late final _clang_defaultCodeCompleteOptions =
+      _clang_defaultCodeCompleteOptionsPtr.asFunction<int Function()>();
+
+  /// Perform code completion at a given location in a translation unit.
+  ffi.Pointer<CXCodeCompleteResults> clang_codeCompleteAt(
+    CXTranslationUnit TU,
+    ffi.Pointer<ffi.Char> complete_filename,
+    int complete_line,
+    int complete_column,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    int options,
+  ) {
+    return _clang_codeCompleteAt(
+      TU,
+      complete_filename,
+      complete_line,
+      complete_column,
+      unsaved_files,
+      num_unsaved_files,
+      options,
+    );
+  }
+
+  late final _clang_codeCompleteAtPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<CXCodeCompleteResults> Function(
+              CXTranslationUnit,
+              ffi.Pointer<ffi.Char>,
+              ffi.UnsignedInt,
+              ffi.UnsignedInt,
+              ffi.Pointer<CXUnsavedFile>,
+              ffi.UnsignedInt,
+              ffi.UnsignedInt)>>('clang_codeCompleteAt');
+  late final _clang_codeCompleteAt = _clang_codeCompleteAtPtr.asFunction<
+      ffi.Pointer<CXCodeCompleteResults> Function(
+          CXTranslationUnit,
+          ffi.Pointer<ffi.Char>,
+          int,
+          int,
+          ffi.Pointer<CXUnsavedFile>,
+          int,
+          int)>();
+
+  /// Sort the code-completion results in case-insensitive alphabetical order.
+  void clang_sortCodeCompletionResults(
+    ffi.Pointer<CXCompletionResult> Results,
+    int NumResults,
+  ) {
+    return _clang_sortCodeCompletionResults(
+      Results,
+      NumResults,
+    );
+  }
+
+  late final _clang_sortCodeCompletionResultsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<CXCompletionResult>,
+              ffi.UnsignedInt)>>('clang_sortCodeCompletionResults');
+  late final _clang_sortCodeCompletionResults =
+      _clang_sortCodeCompletionResultsPtr
+          .asFunction<void Function(ffi.Pointer<CXCompletionResult>, int)>();
+
+  /// Free the given set of code-completion results.
+  void clang_disposeCodeCompleteResults(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+  ) {
+    return _clang_disposeCodeCompleteResults(
+      Results,
+    );
+  }
+
+  late final _clang_disposeCodeCompleteResultsPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Void Function(ffi.Pointer<CXCodeCompleteResults>)>>(
+      'clang_disposeCodeCompleteResults');
+  late final _clang_disposeCodeCompleteResults =
+      _clang_disposeCodeCompleteResultsPtr
+          .asFunction<void Function(ffi.Pointer<CXCodeCompleteResults>)>();
+
+  /// Determine the number of diagnostics produced prior to the location where
+  /// code completion was performed.
+  int clang_codeCompleteGetNumDiagnostics(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+  ) {
+    return _clang_codeCompleteGetNumDiagnostics(
+      Results,
+    );
+  }
+
+  late final _clang_codeCompleteGetNumDiagnosticsPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.UnsignedInt Function(ffi.Pointer<CXCodeCompleteResults>)>>(
+      'clang_codeCompleteGetNumDiagnostics');
+  late final _clang_codeCompleteGetNumDiagnostics =
+      _clang_codeCompleteGetNumDiagnosticsPtr
+          .asFunction<int Function(ffi.Pointer<CXCodeCompleteResults>)>();
+
+  /// Retrieve a diagnostic associated with the given code completion.
+  CXDiagnostic clang_codeCompleteGetDiagnostic(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+    int Index,
+  ) {
+    return _clang_codeCompleteGetDiagnostic(
+      Results,
+      Index,
+    );
+  }
+
+  late final _clang_codeCompleteGetDiagnosticPtr = _lookup<
+      ffi.NativeFunction<
+          CXDiagnostic Function(ffi.Pointer<CXCodeCompleteResults>,
+              ffi.UnsignedInt)>>('clang_codeCompleteGetDiagnostic');
+  late final _clang_codeCompleteGetDiagnostic =
+      _clang_codeCompleteGetDiagnosticPtr.asFunction<
+          CXDiagnostic Function(ffi.Pointer<CXCodeCompleteResults>, int)>();
+
+  /// Determines what completions are appropriate for the context the given code
+  /// completion.
+  int clang_codeCompleteGetContexts(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+  ) {
+    return _clang_codeCompleteGetContexts(
+      Results,
+    );
+  }
+
+  late final _clang_codeCompleteGetContextsPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.UnsignedLongLong Function(
+                  ffi.Pointer<CXCodeCompleteResults>)>>(
+      'clang_codeCompleteGetContexts');
+  late final _clang_codeCompleteGetContexts = _clang_codeCompleteGetContextsPtr
+      .asFunction<int Function(ffi.Pointer<CXCodeCompleteResults>)>();
+
+  /// Returns the cursor kind for the container for the current code completion
+  /// context. The container is only guaranteed to be set for contexts where a
+  /// container exists (i.e. member accesses or Objective-C message sends); if
+  /// there is not a container, this function will return CXCursor_InvalidCode.
+  int clang_codeCompleteGetContainerKind(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+    ffi.Pointer<ffi.UnsignedInt> IsIncomplete,
+  ) {
+    return _clang_codeCompleteGetContainerKind(
+      Results,
+      IsIncomplete,
+    );
+  }
+
+  late final _clang_codeCompleteGetContainerKindPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int32 Function(ffi.Pointer<CXCodeCompleteResults>,
+                  ffi.Pointer<ffi.UnsignedInt>)>>(
+      'clang_codeCompleteGetContainerKind');
+  late final _clang_codeCompleteGetContainerKind =
+      _clang_codeCompleteGetContainerKindPtr.asFunction<
+          int Function(ffi.Pointer<CXCodeCompleteResults>,
+              ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Returns the USR for the container for the current code completion context.
+  /// If there is not a container for the current context, this function will
+  /// return the empty string.
+  CXString clang_codeCompleteGetContainerUSR(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+  ) {
+    return _clang_codeCompleteGetContainerUSR(
+      Results,
+    );
+  }
+
+  late final _clang_codeCompleteGetContainerUSRPtr = _lookup<
+          ffi.NativeFunction<
+              CXString Function(ffi.Pointer<CXCodeCompleteResults>)>>(
+      'clang_codeCompleteGetContainerUSR');
+  late final _clang_codeCompleteGetContainerUSR =
+      _clang_codeCompleteGetContainerUSRPtr
+          .asFunction<CXString Function(ffi.Pointer<CXCodeCompleteResults>)>();
+
+  /// Returns the currently-entered selector for an Objective-C message send,
+  /// formatted like "initWithFoo:bar:". Only guaranteed to return a non-empty
+  /// string for CXCompletionContext_ObjCInstanceMessage and
+  /// CXCompletionContext_ObjCClassMessage.
+  CXString clang_codeCompleteGetObjCSelector(
+    ffi.Pointer<CXCodeCompleteResults> Results,
+  ) {
+    return _clang_codeCompleteGetObjCSelector(
+      Results,
+    );
+  }
+
+  late final _clang_codeCompleteGetObjCSelectorPtr = _lookup<
+          ffi.NativeFunction<
+              CXString Function(ffi.Pointer<CXCodeCompleteResults>)>>(
+      'clang_codeCompleteGetObjCSelector');
+  late final _clang_codeCompleteGetObjCSelector =
+      _clang_codeCompleteGetObjCSelectorPtr
+          .asFunction<CXString Function(ffi.Pointer<CXCodeCompleteResults>)>();
+
+  /// Return a version string, suitable for showing to a user, but not intended
+  /// to be parsed (the format is not guaranteed to be stable).
+  CXString clang_getClangVersion() {
+    return _clang_getClangVersion();
+  }
+
+  late final _clang_getClangVersionPtr =
+      _lookup<ffi.NativeFunction<CXString Function()>>('clang_getClangVersion');
+  late final _clang_getClangVersion =
+      _clang_getClangVersionPtr.asFunction<CXString Function()>();
+
+  /// Enable/disable crash recovery.
+  void clang_toggleCrashRecovery(
+    int isEnabled,
+  ) {
+    return _clang_toggleCrashRecovery(
+      isEnabled,
+    );
+  }
+
+  late final _clang_toggleCrashRecoveryPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.UnsignedInt)>>(
+          'clang_toggleCrashRecovery');
+  late final _clang_toggleCrashRecovery =
+      _clang_toggleCrashRecoveryPtr.asFunction<void Function(int)>();
+
+  /// Visit the set of preprocessor inclusions in a translation unit. The
+  /// visitor function is called with the provided data for every included file.
+  /// This does not include headers included by the PCH file (unless one is
+  /// inspecting the inclusions in the PCH file itself).
+  void clang_getInclusions(
+    CXTranslationUnit tu,
+    CXInclusionVisitor visitor,
+    CXClientData client_data,
+  ) {
+    return _clang_getInclusions(
+      tu,
+      visitor,
+      client_data,
+    );
+  }
+
+  late final _clang_getInclusionsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(CXTranslationUnit, CXInclusionVisitor,
+              CXClientData)>>('clang_getInclusions');
+  late final _clang_getInclusions = _clang_getInclusionsPtr.asFunction<
+      void Function(CXTranslationUnit, CXInclusionVisitor, CXClientData)>();
+
+  /// If cursor is a statement declaration tries to evaluate the statement and
+  /// if its variable, tries to evaluate its initializer, into its corresponding
+  /// type.
+  CXEvalResult clang_Cursor_Evaluate(
+    CXCursor C,
+  ) {
+    return _clang_Cursor_Evaluate(
+      C,
+    );
+  }
+
+  late final _clang_Cursor_EvaluatePtr =
+      _lookup<ffi.NativeFunction<CXEvalResult Function(CXCursor)>>(
+          'clang_Cursor_Evaluate');
+  late final _clang_Cursor_Evaluate =
+      _clang_Cursor_EvaluatePtr.asFunction<CXEvalResult Function(CXCursor)>();
+
+  /// Returns the kind of the evaluated result.
+  int clang_EvalResult_getKind(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getKind(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getKindPtr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(CXEvalResult)>>(
+          'clang_EvalResult_getKind');
+  late final _clang_EvalResult_getKind =
+      _clang_EvalResult_getKindPtr.asFunction<int Function(CXEvalResult)>();
+
+  /// Returns the evaluation result as integer if the kind is Int.
+  int clang_EvalResult_getAsInt(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsInt(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsIntPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(CXEvalResult)>>(
+          'clang_EvalResult_getAsInt');
+  late final _clang_EvalResult_getAsInt =
+      _clang_EvalResult_getAsIntPtr.asFunction<int Function(CXEvalResult)>();
+
+  /// Returns the evaluation result as a long long integer if the kind is Int.
+  /// This prevents overflows that may happen if the result is returned with
+  /// clang_EvalResult_getAsInt.
+  int clang_EvalResult_getAsLongLong(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsLongLong(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsLongLongPtr =
+      _lookup<ffi.NativeFunction<ffi.LongLong Function(CXEvalResult)>>(
+          'clang_EvalResult_getAsLongLong');
+  late final _clang_EvalResult_getAsLongLong =
+      _clang_EvalResult_getAsLongLongPtr
+          .asFunction<int Function(CXEvalResult)>();
+
+  /// Returns a non-zero value if the kind is Int and the evaluation result
+  /// resulted in an unsigned integer.
+  int clang_EvalResult_isUnsignedInt(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_isUnsignedInt(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_isUnsignedIntPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXEvalResult)>>(
+          'clang_EvalResult_isUnsignedInt');
+  late final _clang_EvalResult_isUnsignedInt =
+      _clang_EvalResult_isUnsignedIntPtr
+          .asFunction<int Function(CXEvalResult)>();
+
+  /// Returns the evaluation result as an unsigned integer if the kind is Int
+  /// and clang_EvalResult_isUnsignedInt is non-zero.
+  int clang_EvalResult_getAsUnsigned(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsUnsigned(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsUnsignedPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedLongLong Function(CXEvalResult)>>(
+          'clang_EvalResult_getAsUnsigned');
+  late final _clang_EvalResult_getAsUnsigned =
+      _clang_EvalResult_getAsUnsignedPtr
+          .asFunction<int Function(CXEvalResult)>();
+
+  /// Returns the evaluation result as double if the kind is double.
+  double clang_EvalResult_getAsDouble(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsDouble(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsDoublePtr =
+      _lookup<ffi.NativeFunction<ffi.Double Function(CXEvalResult)>>(
+          'clang_EvalResult_getAsDouble');
+  late final _clang_EvalResult_getAsDouble = _clang_EvalResult_getAsDoublePtr
+      .asFunction<double Function(CXEvalResult)>();
+
+  /// Returns the evaluation result as a constant string if the kind is other
+  /// than Int or float. User must not free this pointer, instead call
+  /// clang_EvalResult_dispose on the CXEvalResult returned by
+  /// clang_Cursor_Evaluate.
+  ffi.Pointer<ffi.Char> clang_EvalResult_getAsStr(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_getAsStr(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_getAsStrPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(CXEvalResult)>>(
+          'clang_EvalResult_getAsStr');
+  late final _clang_EvalResult_getAsStr = _clang_EvalResult_getAsStrPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(CXEvalResult)>();
+
+  /// Disposes the created Eval memory.
+  void clang_EvalResult_dispose(
+    CXEvalResult E,
+  ) {
+    return _clang_EvalResult_dispose(
+      E,
+    );
+  }
+
+  late final _clang_EvalResult_disposePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXEvalResult)>>(
+          'clang_EvalResult_dispose');
+  late final _clang_EvalResult_dispose =
+      _clang_EvalResult_disposePtr.asFunction<void Function(CXEvalResult)>();
+
+  /// Retrieve a remapping.
+  CXRemapping clang_getRemappings(
+    ffi.Pointer<ffi.Char> path,
+  ) {
+    return _clang_getRemappings(
+      path,
+    );
+  }
+
+  late final _clang_getRemappingsPtr =
+      _lookup<ffi.NativeFunction<CXRemapping Function(ffi.Pointer<ffi.Char>)>>(
+          'clang_getRemappings');
+  late final _clang_getRemappings = _clang_getRemappingsPtr
+      .asFunction<CXRemapping Function(ffi.Pointer<ffi.Char>)>();
+
+  /// Retrieve a remapping.
+  CXRemapping clang_getRemappingsFromFileList(
+    ffi.Pointer<ffi.Pointer<ffi.Char>> filePaths,
+    int numFiles,
+  ) {
+    return _clang_getRemappingsFromFileList(
+      filePaths,
+      numFiles,
+    );
+  }
+
+  late final _clang_getRemappingsFromFileListPtr = _lookup<
+      ffi.NativeFunction<
+          CXRemapping Function(ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.UnsignedInt)>>('clang_getRemappingsFromFileList');
+  late final _clang_getRemappingsFromFileList =
+      _clang_getRemappingsFromFileListPtr.asFunction<
+          CXRemapping Function(ffi.Pointer<ffi.Pointer<ffi.Char>>, int)>();
+
+  /// Determine the number of remappings.
+  int clang_remap_getNumFiles(
+    CXRemapping arg0,
+  ) {
+    return _clang_remap_getNumFiles(
+      arg0,
+    );
+  }
+
+  late final _clang_remap_getNumFilesPtr =
+      _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(CXRemapping)>>(
+          'clang_remap_getNumFiles');
+  late final _clang_remap_getNumFiles =
+      _clang_remap_getNumFilesPtr.asFunction<int Function(CXRemapping)>();
+
+  /// Get the original and the associated filename from the remapping.
+  void clang_remap_getFilenames(
+    CXRemapping arg0,
+    int index,
+    ffi.Pointer<CXString> original,
+    ffi.Pointer<CXString> transformed,
+  ) {
+    return _clang_remap_getFilenames(
+      arg0,
+      index,
+      original,
+      transformed,
+    );
+  }
+
+  late final _clang_remap_getFilenamesPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(CXRemapping, ffi.UnsignedInt, ffi.Pointer<CXString>,
+              ffi.Pointer<CXString>)>>('clang_remap_getFilenames');
+  late final _clang_remap_getFilenames =
+      _clang_remap_getFilenamesPtr.asFunction<
+          void Function(CXRemapping, int, ffi.Pointer<CXString>,
+              ffi.Pointer<CXString>)>();
+
+  /// Dispose the remapping.
+  void clang_remap_dispose(
+    CXRemapping arg0,
+  ) {
+    return _clang_remap_dispose(
+      arg0,
+    );
+  }
+
+  late final _clang_remap_disposePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXRemapping)>>(
+          'clang_remap_dispose');
+  late final _clang_remap_dispose =
+      _clang_remap_disposePtr.asFunction<void Function(CXRemapping)>();
+
+  /// Find references of a declaration in a specific file.
+  int clang_findReferencesInFile(
+    CXCursor cursor,
+    CXFile file,
+    CXCursorAndRangeVisitor visitor,
+  ) {
+    return _clang_findReferencesInFile(
+      cursor,
+      file,
+      visitor,
+    );
+  }
+
+  late final _clang_findReferencesInFilePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int32 Function(CXCursor, CXFile,
+              CXCursorAndRangeVisitor)>>('clang_findReferencesInFile');
+  late final _clang_findReferencesInFile = _clang_findReferencesInFilePtr
+      .asFunction<int Function(CXCursor, CXFile, CXCursorAndRangeVisitor)>();
+
+  /// Find #import/#include directives in a specific file.
+  int clang_findIncludesInFile(
+    CXTranslationUnit TU,
+    CXFile file,
+    CXCursorAndRangeVisitor visitor,
+  ) {
+    return _clang_findIncludesInFile(
+      TU,
+      file,
+      visitor,
+    );
+  }
+
+  late final _clang_findIncludesInFilePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int32 Function(CXTranslationUnit, CXFile,
+              CXCursorAndRangeVisitor)>>('clang_findIncludesInFile');
+  late final _clang_findIncludesInFile =
+      _clang_findIncludesInFilePtr.asFunction<
+          int Function(CXTranslationUnit, CXFile, CXCursorAndRangeVisitor)>();
+
+  int clang_index_isEntityObjCContainerKind(
+    int arg0,
+  ) {
+    return _clang_index_isEntityObjCContainerKind(
+      arg0,
+    );
+  }
+
+  late final _clang_index_isEntityObjCContainerKindPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int32)>>(
+          'clang_index_isEntityObjCContainerKind');
+  late final _clang_index_isEntityObjCContainerKind =
+      _clang_index_isEntityObjCContainerKindPtr.asFunction<int Function(int)>();
+
+  ffi.Pointer<CXIdxObjCContainerDeclInfo> clang_index_getObjCContainerDeclInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getObjCContainerDeclInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getObjCContainerDeclInfoPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Pointer<CXIdxObjCContainerDeclInfo> Function(
+                  ffi.Pointer<CXIdxDeclInfo>)>>(
+      'clang_index_getObjCContainerDeclInfo');
+  late final _clang_index_getObjCContainerDeclInfo =
+      _clang_index_getObjCContainerDeclInfoPtr.asFunction<
+          ffi.Pointer<CXIdxObjCContainerDeclInfo> Function(
+              ffi.Pointer<CXIdxDeclInfo>)>();
+
+  ffi.Pointer<CXIdxObjCInterfaceDeclInfo> clang_index_getObjCInterfaceDeclInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getObjCInterfaceDeclInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getObjCInterfaceDeclInfoPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Pointer<CXIdxObjCInterfaceDeclInfo> Function(
+                  ffi.Pointer<CXIdxDeclInfo>)>>(
+      'clang_index_getObjCInterfaceDeclInfo');
+  late final _clang_index_getObjCInterfaceDeclInfo =
+      _clang_index_getObjCInterfaceDeclInfoPtr.asFunction<
+          ffi.Pointer<CXIdxObjCInterfaceDeclInfo> Function(
+              ffi.Pointer<CXIdxDeclInfo>)>();
+
+  ffi.Pointer<CXIdxObjCCategoryDeclInfo> clang_index_getObjCCategoryDeclInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getObjCCategoryDeclInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getObjCCategoryDeclInfoPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Pointer<CXIdxObjCCategoryDeclInfo> Function(
+                  ffi.Pointer<CXIdxDeclInfo>)>>(
+      'clang_index_getObjCCategoryDeclInfo');
+  late final _clang_index_getObjCCategoryDeclInfo =
+      _clang_index_getObjCCategoryDeclInfoPtr.asFunction<
+          ffi.Pointer<CXIdxObjCCategoryDeclInfo> Function(
+              ffi.Pointer<CXIdxDeclInfo>)>();
+
+  ffi.Pointer<CXIdxObjCProtocolRefListInfo>
+      clang_index_getObjCProtocolRefListInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getObjCProtocolRefListInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getObjCProtocolRefListInfoPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Pointer<CXIdxObjCProtocolRefListInfo> Function(
+                  ffi.Pointer<CXIdxDeclInfo>)>>(
+      'clang_index_getObjCProtocolRefListInfo');
+  late final _clang_index_getObjCProtocolRefListInfo =
+      _clang_index_getObjCProtocolRefListInfoPtr.asFunction<
+          ffi.Pointer<CXIdxObjCProtocolRefListInfo> Function(
+              ffi.Pointer<CXIdxDeclInfo>)>();
+
+  ffi.Pointer<CXIdxObjCPropertyDeclInfo> clang_index_getObjCPropertyDeclInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getObjCPropertyDeclInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getObjCPropertyDeclInfoPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Pointer<CXIdxObjCPropertyDeclInfo> Function(
+                  ffi.Pointer<CXIdxDeclInfo>)>>(
+      'clang_index_getObjCPropertyDeclInfo');
+  late final _clang_index_getObjCPropertyDeclInfo =
+      _clang_index_getObjCPropertyDeclInfoPtr.asFunction<
+          ffi.Pointer<CXIdxObjCPropertyDeclInfo> Function(
+              ffi.Pointer<CXIdxDeclInfo>)>();
+
+  ffi.Pointer<CXIdxIBOutletCollectionAttrInfo>
+      clang_index_getIBOutletCollectionAttrInfo(
+    ffi.Pointer<CXIdxAttrInfo> arg0,
+  ) {
+    return _clang_index_getIBOutletCollectionAttrInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getIBOutletCollectionAttrInfoPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Pointer<CXIdxIBOutletCollectionAttrInfo> Function(
+                  ffi.Pointer<CXIdxAttrInfo>)>>(
+      'clang_index_getIBOutletCollectionAttrInfo');
+  late final _clang_index_getIBOutletCollectionAttrInfo =
+      _clang_index_getIBOutletCollectionAttrInfoPtr.asFunction<
+          ffi.Pointer<CXIdxIBOutletCollectionAttrInfo> Function(
+              ffi.Pointer<CXIdxAttrInfo>)>();
+
+  ffi.Pointer<CXIdxCXXClassDeclInfo> clang_index_getCXXClassDeclInfo(
+    ffi.Pointer<CXIdxDeclInfo> arg0,
+  ) {
+    return _clang_index_getCXXClassDeclInfo(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getCXXClassDeclInfoPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<CXIdxCXXClassDeclInfo> Function(
+              ffi.Pointer<CXIdxDeclInfo>)>>('clang_index_getCXXClassDeclInfo');
+  late final _clang_index_getCXXClassDeclInfo =
+      _clang_index_getCXXClassDeclInfoPtr.asFunction<
+          ffi.Pointer<CXIdxCXXClassDeclInfo> Function(
+              ffi.Pointer<CXIdxDeclInfo>)>();
+
+  /// For retrieving a custom CXIdxClientContainer attached to a container.
+  CXIdxClientContainer clang_index_getClientContainer(
+    ffi.Pointer<CXIdxContainerInfo> arg0,
+  ) {
+    return _clang_index_getClientContainer(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getClientContainerPtr = _lookup<
+          ffi.NativeFunction<
+              CXIdxClientContainer Function(ffi.Pointer<CXIdxContainerInfo>)>>(
+      'clang_index_getClientContainer');
+  late final _clang_index_getClientContainer =
+      _clang_index_getClientContainerPtr.asFunction<
+          CXIdxClientContainer Function(ffi.Pointer<CXIdxContainerInfo>)>();
+
+  /// For setting a custom CXIdxClientContainer attached to a container.
+  void clang_index_setClientContainer(
+    ffi.Pointer<CXIdxContainerInfo> arg0,
+    CXIdxClientContainer arg1,
+  ) {
+    return _clang_index_setClientContainer(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_index_setClientContainerPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<CXIdxContainerInfo>,
+              CXIdxClientContainer)>>('clang_index_setClientContainer');
+  late final _clang_index_setClientContainer =
+      _clang_index_setClientContainerPtr.asFunction<
+          void Function(
+              ffi.Pointer<CXIdxContainerInfo>, CXIdxClientContainer)>();
+
+  /// For retrieving a custom CXIdxClientEntity attached to an entity.
+  CXIdxClientEntity clang_index_getClientEntity(
+    ffi.Pointer<CXIdxEntityInfo> arg0,
+  ) {
+    return _clang_index_getClientEntity(
+      arg0,
+    );
+  }
+
+  late final _clang_index_getClientEntityPtr = _lookup<
+      ffi.NativeFunction<
+          CXIdxClientEntity Function(
+              ffi.Pointer<CXIdxEntityInfo>)>>('clang_index_getClientEntity');
+  late final _clang_index_getClientEntity = _clang_index_getClientEntityPtr
+      .asFunction<CXIdxClientEntity Function(ffi.Pointer<CXIdxEntityInfo>)>();
+
+  /// For setting a custom CXIdxClientEntity attached to an entity.
+  void clang_index_setClientEntity(
+    ffi.Pointer<CXIdxEntityInfo> arg0,
+    CXIdxClientEntity arg1,
+  ) {
+    return _clang_index_setClientEntity(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _clang_index_setClientEntityPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<CXIdxEntityInfo>,
+              CXIdxClientEntity)>>('clang_index_setClientEntity');
+  late final _clang_index_setClientEntity =
+      _clang_index_setClientEntityPtr.asFunction<
+          void Function(ffi.Pointer<CXIdxEntityInfo>, CXIdxClientEntity)>();
+
+  /// An indexing action/session, to be applied to one or multiple translation
+  /// units.
+  CXIndexAction clang_IndexAction_create(
+    CXIndex CIdx,
+  ) {
+    return _clang_IndexAction_create(
+      CIdx,
+    );
+  }
+
+  late final _clang_IndexAction_createPtr =
+      _lookup<ffi.NativeFunction<CXIndexAction Function(CXIndex)>>(
+          'clang_IndexAction_create');
+  late final _clang_IndexAction_create = _clang_IndexAction_createPtr
+      .asFunction<CXIndexAction Function(CXIndex)>();
+
+  /// Destroy the given index action.
+  void clang_IndexAction_dispose(
+    CXIndexAction arg0,
+  ) {
+    return _clang_IndexAction_dispose(
+      arg0,
+    );
+  }
+
+  late final _clang_IndexAction_disposePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(CXIndexAction)>>(
+          'clang_IndexAction_dispose');
+  late final _clang_IndexAction_dispose =
+      _clang_IndexAction_disposePtr.asFunction<void Function(CXIndexAction)>();
+
+  /// Index the given source file and the translation unit corresponding to that
+  /// file via callbacks implemented through #IndexerCallbacks.
+  int clang_indexSourceFile(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    int index_callbacks_size,
+    int index_options,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+    int TU_options,
+  ) {
+    return _clang_indexSourceFile(
+      arg0,
+      client_data,
+      index_callbacks,
+      index_callbacks_size,
+      index_options,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      unsaved_files,
+      num_unsaved_files,
+      out_TU,
+      TU_options,
+    );
+  }
+
+  late final _clang_indexSourceFilePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              CXIndexAction,
+              CXClientData,
+              ffi.Pointer<IndexerCallbacks>,
+              ffi.UnsignedInt,
+              ffi.UnsignedInt,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Int,
+              ffi.Pointer<CXUnsavedFile>,
+              ffi.UnsignedInt,
+              ffi.Pointer<CXTranslationUnit>,
+              ffi.UnsignedInt)>>('clang_indexSourceFile');
+  late final _clang_indexSourceFile = _clang_indexSourceFilePtr.asFunction<
+      int Function(
+          CXIndexAction,
+          CXClientData,
+          ffi.Pointer<IndexerCallbacks>,
+          int,
+          int,
+          ffi.Pointer<ffi.Char>,
+          ffi.Pointer<ffi.Pointer<ffi.Char>>,
+          int,
+          ffi.Pointer<CXUnsavedFile>,
+          int,
+          ffi.Pointer<CXTranslationUnit>,
+          int)>();
+
+  /// Same as clang_indexSourceFile but requires a full command line for
+  /// command_line_args including argv[0]. This is useful if the standard
+  /// library paths are relative to the binary.
+  int clang_indexSourceFileFullArgv(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    int index_callbacks_size,
+    int index_options,
+    ffi.Pointer<ffi.Char> source_filename,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> command_line_args,
+    int num_command_line_args,
+    ffi.Pointer<CXUnsavedFile> unsaved_files,
+    int num_unsaved_files,
+    ffi.Pointer<CXTranslationUnit> out_TU,
+    int TU_options,
+  ) {
+    return _clang_indexSourceFileFullArgv(
+      arg0,
+      client_data,
+      index_callbacks,
+      index_callbacks_size,
+      index_options,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      unsaved_files,
+      num_unsaved_files,
+      out_TU,
+      TU_options,
+    );
+  }
+
+  late final _clang_indexSourceFileFullArgvPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              CXIndexAction,
+              CXClientData,
+              ffi.Pointer<IndexerCallbacks>,
+              ffi.UnsignedInt,
+              ffi.UnsignedInt,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Int,
+              ffi.Pointer<CXUnsavedFile>,
+              ffi.UnsignedInt,
+              ffi.Pointer<CXTranslationUnit>,
+              ffi.UnsignedInt)>>('clang_indexSourceFileFullArgv');
+  late final _clang_indexSourceFileFullArgv =
+      _clang_indexSourceFileFullArgvPtr.asFunction<
+          int Function(
+              CXIndexAction,
+              CXClientData,
+              ffi.Pointer<IndexerCallbacks>,
+              int,
+              int,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              int,
+              ffi.Pointer<CXUnsavedFile>,
+              int,
+              ffi.Pointer<CXTranslationUnit>,
+              int)>();
+
+  /// Index the given translation unit via callbacks implemented through
+  /// #IndexerCallbacks.
+  int clang_indexTranslationUnit(
+    CXIndexAction arg0,
+    CXClientData client_data,
+    ffi.Pointer<IndexerCallbacks> index_callbacks,
+    int index_callbacks_size,
+    int index_options,
+    CXTranslationUnit arg5,
+  ) {
+    return _clang_indexTranslationUnit(
+      arg0,
+      client_data,
+      index_callbacks,
+      index_callbacks_size,
+      index_options,
+      arg5,
+    );
+  }
+
+  late final _clang_indexTranslationUnitPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              CXIndexAction,
+              CXClientData,
+              ffi.Pointer<IndexerCallbacks>,
+              ffi.UnsignedInt,
+              ffi.UnsignedInt,
+              CXTranslationUnit)>>('clang_indexTranslationUnit');
+  late final _clang_indexTranslationUnit =
+      _clang_indexTranslationUnitPtr.asFunction<
+          int Function(CXIndexAction, CXClientData,
+              ffi.Pointer<IndexerCallbacks>, int, int, CXTranslationUnit)>();
+
+  /// Retrieve the CXIdxFile, file, line, column, and offset represented by the
+  /// given CXIdxLoc.
+  void clang_indexLoc_getFileLocation(
+    CXIdxLoc loc,
+    ffi.Pointer<CXIdxClientFile> indexFile,
+    ffi.Pointer<CXFile> file,
+    ffi.Pointer<ffi.UnsignedInt> line,
+    ffi.Pointer<ffi.UnsignedInt> column,
+    ffi.Pointer<ffi.UnsignedInt> offset,
+  ) {
+    return _clang_indexLoc_getFileLocation(
+      loc,
+      indexFile,
+      file,
+      line,
+      column,
+      offset,
+    );
+  }
+
+  late final _clang_indexLoc_getFileLocationPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              CXIdxLoc,
+              ffi.Pointer<CXIdxClientFile>,
+              ffi.Pointer<CXFile>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>>('clang_indexLoc_getFileLocation');
+  late final _clang_indexLoc_getFileLocation =
+      _clang_indexLoc_getFileLocationPtr.asFunction<
+          void Function(
+              CXIdxLoc,
+              ffi.Pointer<CXIdxClientFile>,
+              ffi.Pointer<CXFile>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>,
+              ffi.Pointer<ffi.UnsignedInt>)>();
+
+  /// Retrieve the CXSourceLocation represented by the given CXIdxLoc.
+  CXSourceLocation clang_indexLoc_getCXSourceLocation(
+    CXIdxLoc loc,
+  ) {
+    return _clang_indexLoc_getCXSourceLocation(
+      loc,
+    );
+  }
+
+  late final _clang_indexLoc_getCXSourceLocationPtr =
+      _lookup<ffi.NativeFunction<CXSourceLocation Function(CXIdxLoc)>>(
+          'clang_indexLoc_getCXSourceLocation');
+  late final _clang_indexLoc_getCXSourceLocation =
+      _clang_indexLoc_getCXSourceLocationPtr
+          .asFunction<CXSourceLocation Function(CXIdxLoc)>();
+
+  /// Visit the fields of a particular type.
+  int clang_Type_visitFields(
+    CXType T,
+    CXFieldVisitor visitor,
+    CXClientData client_data,
+  ) {
+    return _clang_Type_visitFields(
+      T,
+      visitor,
+      client_data,
+    );
+  }
+
+  late final _clang_Type_visitFieldsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.UnsignedInt Function(
+              CXType, CXFieldVisitor, CXClientData)>>('clang_Type_visitFields');
+  late final _clang_Type_visitFields = _clang_Type_visitFieldsPtr
+      .asFunction<int Function(CXType, CXFieldVisitor, CXClientData)>();
+}
+
+/// Error codes returned by libclang routines.
+abstract class CXErrorCode {
+  /// No error.
+  static const int CXError_Success = 0;
+
+  /// A generic error code, no further details are available.
+  static const int CXError_Failure = 1;
+
+  /// libclang crashed while performing the requested operation.
+  static const int CXError_Crashed = 2;
+
+  /// The function detected that the arguments violate the function contract.
+  static const int CXError_InvalidArguments = 3;
+
+  /// An AST deserialization error has occurred.
+  static const int CXError_ASTReadError = 4;
+}
+
+/// A character string.
+final class CXString extends ffi.Struct {
+  external ffi.Pointer<ffi.Void> data;
+
+  @ffi.UnsignedInt()
+  external int private_flags;
+}
+
+final class CXStringSet extends ffi.Struct {
+  external ffi.Pointer<CXString> Strings;
+
+  @ffi.UnsignedInt()
+  external int Count;
+}
+
+final class CXVirtualFileOverlayImpl extends ffi.Opaque {}
+
+/// Object encapsulating information about overlaying virtual file/directories
+/// over the real file system.
+typedef CXVirtualFileOverlay = ffi.Pointer<CXVirtualFileOverlayImpl>;
+
+final class CXModuleMapDescriptorImpl extends ffi.Opaque {}
+
+/// Object encapsulating information about a module.map file.
+typedef CXModuleMapDescriptor = ffi.Pointer<CXModuleMapDescriptorImpl>;
+
+final class CXTargetInfoImpl extends ffi.Opaque {}
+
+final class CXTranslationUnitImpl extends ffi.Opaque {}
+
+/// Provides the contents of a file that has not yet been saved to disk.
+final class CXUnsavedFile extends ffi.Struct {
+  /// The file whose contents have not yet been saved.
+  external ffi.Pointer<ffi.Char> Filename;
+
+  /// A buffer containing the unsaved contents of this file.
+  external ffi.Pointer<ffi.Char> Contents;
+
+  /// The length of the unsaved contents of this buffer.
+  @ffi.UnsignedLong()
+  external int Length;
+}
+
+/// Describes the availability of a particular entity, which indicates whether
+/// the use of this entity will result in a warning or error due to it being
+/// deprecated or unavailable.
+abstract class CXAvailabilityKind {
+  /// The entity is available.
+  static const int CXAvailability_Available = 0;
+
+  /// The entity is available, but has been deprecated (and its use is not
+  /// recommended).
+  static const int CXAvailability_Deprecated = 1;
+
+  /// The entity is not available; any use of it will be an error.
+  static const int CXAvailability_NotAvailable = 2;
+
+  /// The entity is available, but not accessible; any use of it will be an
+  /// error.
+  static const int CXAvailability_NotAccessible = 3;
+}
+
+/// Describes a version number of the form major.minor.subminor.
+final class CXVersion extends ffi.Struct {
+  /// The major version number, e.g., the '10' in '10.7.3'. A negative value
+  /// indicates that there is no version number at all.
+  @ffi.Int()
+  external int Major;
+
+  /// The minor version number, e.g., the '7' in '10.7.3'. This value will be
+  /// negative if no minor version number was provided, e.g., for version '10'.
+  @ffi.Int()
+  external int Minor;
+
+  /// The subminor version number, e.g., the '3' in '10.7.3'. This value will be
+  /// negative if no minor or subminor version number was provided, e.g., in
+  /// version '10' or '10.7'.
+  @ffi.Int()
+  external int Subminor;
+}
+
+/// Describes the exception specification of a cursor.
+abstract class CXCursor_ExceptionSpecificationKind {
+  /// The cursor has no exception specification.
+  static const int CXCursor_ExceptionSpecificationKind_None = 0;
+
+  /// The cursor has exception specification throw()
+  static const int CXCursor_ExceptionSpecificationKind_DynamicNone = 1;
+
+  /// The cursor has exception specification throw(T1, T2)
+  static const int CXCursor_ExceptionSpecificationKind_Dynamic = 2;
+
+  /// The cursor has exception specification throw(...).
+  static const int CXCursor_ExceptionSpecificationKind_MSAny = 3;
+
+  /// The cursor has exception specification basic noexcept.
+  static const int CXCursor_ExceptionSpecificationKind_BasicNoexcept = 4;
+
+  /// The cursor has exception specification computed noexcept.
+  static const int CXCursor_ExceptionSpecificationKind_ComputedNoexcept = 5;
+
+  /// The exception specification has not yet been evaluated.
+  static const int CXCursor_ExceptionSpecificationKind_Unevaluated = 6;
+
+  /// The exception specification has not yet been instantiated.
+  static const int CXCursor_ExceptionSpecificationKind_Uninstantiated = 7;
+
+  /// The exception specification has not been parsed yet.
+  static const int CXCursor_ExceptionSpecificationKind_Unparsed = 8;
+
+  /// The cursor has a __declspec(nothrow) exception specification.
+  static const int CXCursor_ExceptionSpecificationKind_NoThrow = 9;
+}
+
+/// An "index" that consists of a set of translation units that would typically
+/// be linked together into an executable or library.
+typedef CXIndex = ffi.Pointer<ffi.Void>;
+
+abstract class CXGlobalOptFlags {
+  /// Used to indicate that no special CXIndex options are needed.
+  static const int CXGlobalOpt_None = 0;
+
+  /// Used to indicate that threads that libclang creates for indexing purposes
+  /// should use background priority.
+  static const int CXGlobalOpt_ThreadBackgroundPriorityForIndexing = 1;
+
+  /// Used to indicate that threads that libclang creates for editing purposes
+  /// should use background priority.
+  static const int CXGlobalOpt_ThreadBackgroundPriorityForEditing = 2;
+
+  /// Used to indicate that all threads that libclang creates should use
+  /// background priority.
+  static const int CXGlobalOpt_ThreadBackgroundPriorityForAll = 3;
+}
+
+/// A particular source file that is part of a translation unit.
+typedef CXFile = ffi.Pointer<ffi.Void>;
+
+/// Uniquely identifies a CXFile, that refers to the same underlying file,
+/// across an indexing session.
+final class CXFileUniqueID extends ffi.Struct {
+  @ffi.Array.multi([3])
+  external ffi.Array<ffi.UnsignedLongLong> data;
+}
+
+/// A single translation unit, which resides in an index.
+typedef CXTranslationUnit = ffi.Pointer<CXTranslationUnitImpl>;
+
+/// Identifies a specific source location within a translation unit.
+final class CXSourceLocation extends ffi.Struct {
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
+
+  @ffi.UnsignedInt()
+  external int int_data;
+}
+
+/// Identifies a half-open character range in the source code.
+final class CXSourceRange extends ffi.Struct {
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
+
+  @ffi.UnsignedInt()
+  external int begin_int_data;
+
+  @ffi.UnsignedInt()
+  external int end_int_data;
+}
+
+/// Identifies an array of ranges.
+final class CXSourceRangeList extends ffi.Struct {
+  /// The number of ranges in the ranges array.
+  @ffi.UnsignedInt()
+  external int count;
+
+  /// An array of CXSourceRanges.
+  external ffi.Pointer<CXSourceRange> ranges;
+}
+
+/// Describes the severity of a particular diagnostic.
+abstract class CXDiagnosticSeverity {
+  /// A diagnostic that has been suppressed, e.g., by a command-line option.
+  static const int CXDiagnostic_Ignored = 0;
+
+  /// This diagnostic is a note that should be attached to the previous
+  /// (non-note) diagnostic.
+  static const int CXDiagnostic_Note = 1;
+
+  /// This diagnostic indicates suspicious code that may not be wrong.
+  static const int CXDiagnostic_Warning = 2;
+
+  /// This diagnostic indicates that the code is ill-formed.
+  static const int CXDiagnostic_Error = 3;
+
+  /// This diagnostic indicates that the code is ill-formed such that future
+  /// parser recovery is unlikely to produce useful results.
+  static const int CXDiagnostic_Fatal = 4;
+}
+
+/// A group of CXDiagnostics.
+typedef CXDiagnosticSet = ffi.Pointer<ffi.Void>;
+
+/// A single diagnostic, containing the diagnostic's severity, location, text,
+/// source ranges, and fix-it hints.
+typedef CXDiagnostic = ffi.Pointer<ffi.Void>;
+
+/// Describes the kind of error that occurred (if any) in a call to
+/// clang_loadDiagnostics.
+abstract class CXLoadDiag_Error {
+  /// Indicates that no error occurred.
+  static const int CXLoadDiag_None = 0;
+
+  /// Indicates that an unknown error occurred while attempting to deserialize
+  /// diagnostics.
+  static const int CXLoadDiag_Unknown = 1;
+
+  /// Indicates that the file containing the serialized diagnostics could not be
+  /// opened.
+  static const int CXLoadDiag_CannotLoad = 2;
+
+  /// Indicates that the serialized diagnostics file is invalid or corrupt.
+  static const int CXLoadDiag_InvalidFile = 3;
+}
+
+/// Options to control the display of diagnostics.
+abstract class CXDiagnosticDisplayOptions {
+  /// Display the source-location information where the diagnostic was located.
+  static const int CXDiagnostic_DisplaySourceLocation = 1;
+
+  /// If displaying the source-location information of the diagnostic, also
+  /// include the column number.
+  static const int CXDiagnostic_DisplayColumn = 2;
+
+  /// If displaying the source-location information of the diagnostic, also
+  /// include information about source ranges in a machine-parsable format.
+  static const int CXDiagnostic_DisplaySourceRanges = 4;
+
+  /// Display the option name associated with this diagnostic, if any.
+  static const int CXDiagnostic_DisplayOption = 8;
+
+  /// Display the category number associated with this diagnostic, if any.
+  static const int CXDiagnostic_DisplayCategoryId = 16;
+
+  /// Display the category name associated with this diagnostic, if any.
+  static const int CXDiagnostic_DisplayCategoryName = 32;
+}
+
+/// Flags that control the creation of translation units.
+abstract class CXTranslationUnit_Flags {
+  /// Used to indicate that no special translation-unit options are needed.
+  static const int CXTranslationUnit_None = 0;
+
+  /// Used to indicate that the parser should construct a "detailed"
+  /// preprocessing record, including all macro definitions and instantiations.
+  static const int CXTranslationUnit_DetailedPreprocessingRecord = 1;
+
+  /// Used to indicate that the translation unit is incomplete.
+  static const int CXTranslationUnit_Incomplete = 2;
+
+  /// Used to indicate that the translation unit should be built with an
+  /// implicit precompiled header for the preamble.
+  static const int CXTranslationUnit_PrecompiledPreamble = 4;
+
+  /// Used to indicate that the translation unit should cache some
+  /// code-completion results with each reparse of the source file.
+  static const int CXTranslationUnit_CacheCompletionResults = 8;
+
+  /// Used to indicate that the translation unit will be serialized with
+  /// clang_saveTranslationUnit.
+  static const int CXTranslationUnit_ForSerialization = 16;
+
+  /// DEPRECATED: Enabled chained precompiled preambles in C++.
+  static const int CXTranslationUnit_CXXChainedPCH = 32;
+
+  /// Used to indicate that function/method bodies should be skipped while
+  /// parsing.
+  static const int CXTranslationUnit_SkipFunctionBodies = 64;
+
+  /// Used to indicate that brief documentation comments should be included into
+  /// the set of code completions returned from this translation unit.
+  static const int CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 128;
+
+  /// Used to indicate that the precompiled preamble should be created on the
+  /// first parse. Otherwise it will be created on the first reparse. This
+  /// trades runtime on the first parse (serializing the preamble takes time)
+  /// for reduced runtime on the second parse (can now reuse the preamble).
+  static const int CXTranslationUnit_CreatePreambleOnFirstParse = 256;
+
+  /// Do not stop processing when fatal errors are encountered.
+  static const int CXTranslationUnit_KeepGoing = 512;
+
+  /// Sets the preprocessor in a mode for parsing a single file only.
+  static const int CXTranslationUnit_SingleFileParse = 1024;
+
+  /// Used in combination with CXTranslationUnit_SkipFunctionBodies to constrain
+  /// the skipping of function bodies to the preamble.
+  static const int CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 2048;
+
+  /// Used to indicate that attributed types should be included in CXType.
+  static const int CXTranslationUnit_IncludeAttributedTypes = 4096;
+
+  /// Used to indicate that implicit attributes should be visited.
+  static const int CXTranslationUnit_VisitImplicitAttributes = 8192;
+
+  /// Used to indicate that non-errors from included files should be ignored.
+  static const int CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles = 16384;
+
+  /// Tells the preprocessor not to skip excluded conditional blocks.
+  static const int CXTranslationUnit_RetainExcludedConditionalBlocks = 32768;
+}
+
+/// Flags that control how translation units are saved.
+abstract class CXSaveTranslationUnit_Flags {
+  /// Used to indicate that no special saving options are needed.
+  static const int CXSaveTranslationUnit_None = 0;
+}
+
+/// Describes the kind of error that occurred (if any) in a call to
+/// clang_saveTranslationUnit().
+abstract class CXSaveError {
+  /// Indicates that no error occurred while saving a translation unit.
+  static const int CXSaveError_None = 0;
+
+  /// Indicates that an unknown error occurred while attempting to save the
+  /// file.
+  static const int CXSaveError_Unknown = 1;
+
+  /// Indicates that errors during translation prevented this attempt to save
+  /// the translation unit.
+  static const int CXSaveError_TranslationErrors = 2;
+
+  /// Indicates that the translation unit to be saved was somehow invalid (e.g.,
+  /// NULL).
+  static const int CXSaveError_InvalidTU = 3;
+}
+
+/// Flags that control the reparsing of translation units.
+abstract class CXReparse_Flags {
+  /// Used to indicate that no special reparsing options are needed.
+  static const int CXReparse_None = 0;
+}
+
+/// Categorizes how memory is being used by a translation unit.
+abstract class CXTUResourceUsageKind {
+  static const int CXTUResourceUsage_AST = 1;
+  static const int CXTUResourceUsage_Identifiers = 2;
+  static const int CXTUResourceUsage_Selectors = 3;
+  static const int CXTUResourceUsage_GlobalCompletionResults = 4;
+  static const int CXTUResourceUsage_SourceManagerContentCache = 5;
+  static const int CXTUResourceUsage_AST_SideTables = 6;
+  static const int CXTUResourceUsage_SourceManager_Membuffer_Malloc = 7;
+  static const int CXTUResourceUsage_SourceManager_Membuffer_MMap = 8;
+  static const int CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9;
+  static const int CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10;
+  static const int CXTUResourceUsage_Preprocessor = 11;
+  static const int CXTUResourceUsage_PreprocessingRecord = 12;
+  static const int CXTUResourceUsage_SourceManager_DataStructures = 13;
+  static const int CXTUResourceUsage_Preprocessor_HeaderSearch = 14;
+  static const int CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = 1;
+  static const int CXTUResourceUsage_MEMORY_IN_BYTES_END = 14;
+  static const int CXTUResourceUsage_First = 1;
+  static const int CXTUResourceUsage_Last = 14;
+}
+
+final class CXTUResourceUsageEntry extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  @ffi.UnsignedLong()
+  external int amount;
+}
+
+/// The memory usage of a CXTranslationUnit, broken into categories.
+final class CXTUResourceUsage extends ffi.Struct {
+  external ffi.Pointer<ffi.Void> data;
+
+  @ffi.UnsignedInt()
+  external int numEntries;
+
+  external ffi.Pointer<CXTUResourceUsageEntry> entries;
+}
+
+/// An opaque type representing target information for a given translation unit.
+typedef CXTargetInfo = ffi.Pointer<CXTargetInfoImpl>;
+
+/// Describes the kind of entity that a cursor refers to.
+abstract class CXCursorKind {
+  /// A declaration whose specific kind is not exposed via this interface.
+  static const int CXCursor_UnexposedDecl = 1;
+
+  /// A C or C++ struct.
+  static const int CXCursor_StructDecl = 2;
+
+  /// A C or C++ union.
+  static const int CXCursor_UnionDecl = 3;
+
+  /// A C++ class.
+  static const int CXCursor_ClassDecl = 4;
+
+  /// An enumeration.
+  static const int CXCursor_EnumDecl = 5;
+
+  /// A field (in C) or non-static data member (in C++) in a struct, union, or
+  /// C++ class.
+  static const int CXCursor_FieldDecl = 6;
+
+  /// An enumerator constant.
+  static const int CXCursor_EnumConstantDecl = 7;
+
+  /// A function.
+  static const int CXCursor_FunctionDecl = 8;
+
+  /// A variable.
+  static const int CXCursor_VarDecl = 9;
+
+  /// A function or method parameter.
+  static const int CXCursor_ParmDecl = 10;
+
+  /// An Objective-C @interface.
+  static const int CXCursor_ObjCInterfaceDecl = 11;
+
+  /// An Objective-C @interface for a category.
+  static const int CXCursor_ObjCCategoryDecl = 12;
+
+  /// An Objective-C @protocol declaration.
+  static const int CXCursor_ObjCProtocolDecl = 13;
+
+  /// An Objective-C @property declaration.
+  static const int CXCursor_ObjCPropertyDecl = 14;
+
+  /// An Objective-C instance variable.
+  static const int CXCursor_ObjCIvarDecl = 15;
+
+  /// An Objective-C instance method.
+  static const int CXCursor_ObjCInstanceMethodDecl = 16;
+
+  /// An Objective-C class method.
+  static const int CXCursor_ObjCClassMethodDecl = 17;
+
+  /// An Objective-C @implementation.
+  static const int CXCursor_ObjCImplementationDecl = 18;
+
+  /// An Objective-C @implementation for a category.
+  static const int CXCursor_ObjCCategoryImplDecl = 19;
+
+  /// A typedef.
+  static const int CXCursor_TypedefDecl = 20;
+
+  /// A C++ class method.
+  static const int CXCursor_CXXMethod = 21;
+
+  /// A C++ namespace.
+  static const int CXCursor_Namespace = 22;
+
+  /// A linkage specification, e.g. 'extern "C"'.
+  static const int CXCursor_LinkageSpec = 23;
+
+  /// A C++ constructor.
+  static const int CXCursor_Constructor = 24;
+
+  /// A C++ destructor.
+  static const int CXCursor_Destructor = 25;
+
+  /// A C++ conversion function.
+  static const int CXCursor_ConversionFunction = 26;
+
+  /// A C++ template type parameter.
+  static const int CXCursor_TemplateTypeParameter = 27;
+
+  /// A C++ non-type template parameter.
+  static const int CXCursor_NonTypeTemplateParameter = 28;
+
+  /// A C++ template template parameter.
+  static const int CXCursor_TemplateTemplateParameter = 29;
+
+  /// A C++ function template.
+  static const int CXCursor_FunctionTemplate = 30;
+
+  /// A C++ class template.
+  static const int CXCursor_ClassTemplate = 31;
+
+  /// A C++ class template partial specialization.
+  static const int CXCursor_ClassTemplatePartialSpecialization = 32;
+
+  /// A C++ namespace alias declaration.
+  static const int CXCursor_NamespaceAlias = 33;
+
+  /// A C++ using directive.
+  static const int CXCursor_UsingDirective = 34;
+
+  /// A C++ using declaration.
+  static const int CXCursor_UsingDeclaration = 35;
+
+  /// A C++ alias declaration
+  static const int CXCursor_TypeAliasDecl = 36;
+
+  /// An Objective-C @synthesize definition.
+  static const int CXCursor_ObjCSynthesizeDecl = 37;
+
+  /// An Objective-C @dynamic definition.
+  static const int CXCursor_ObjCDynamicDecl = 38;
+
+  /// An access specifier.
+  static const int CXCursor_CXXAccessSpecifier = 39;
+  static const int CXCursor_FirstDecl = 1;
+  static const int CXCursor_LastDecl = 39;
+  static const int CXCursor_FirstRef = 40;
+  static const int CXCursor_ObjCSuperClassRef = 40;
+  static const int CXCursor_ObjCProtocolRef = 41;
+  static const int CXCursor_ObjCClassRef = 42;
+
+  /// A reference to a type declaration.
+  static const int CXCursor_TypeRef = 43;
+  static const int CXCursor_CXXBaseSpecifier = 44;
+
+  /// A reference to a class template, function template, template template
+  /// parameter, or class template partial specialization.
+  static const int CXCursor_TemplateRef = 45;
+
+  /// A reference to a namespace or namespace alias.
+  static const int CXCursor_NamespaceRef = 46;
+
+  /// A reference to a member of a struct, union, or class that occurs in some
+  /// non-expression context, e.g., a designated initializer.
+  static const int CXCursor_MemberRef = 47;
+
+  /// A reference to a labeled statement.
+  static const int CXCursor_LabelRef = 48;
+
+  /// A reference to a set of overloaded functions or function templates that
+  /// has not yet been resolved to a specific function or function template.
+  static const int CXCursor_OverloadedDeclRef = 49;
+
+  /// A reference to a variable that occurs in some non-expression context,
+  /// e.g., a C++ lambda capture list.
+  static const int CXCursor_VariableRef = 50;
+  static const int CXCursor_LastRef = 50;
+  static const int CXCursor_FirstInvalid = 70;
+  static const int CXCursor_InvalidFile = 70;
+  static const int CXCursor_NoDeclFound = 71;
+  static const int CXCursor_NotImplemented = 72;
+  static const int CXCursor_InvalidCode = 73;
+  static const int CXCursor_LastInvalid = 73;
+  static const int CXCursor_FirstExpr = 100;
+
+  /// An expression whose specific kind is not exposed via this interface.
+  static const int CXCursor_UnexposedExpr = 100;
+
+  /// An expression that refers to some value declaration, such as a function,
+  /// variable, or enumerator.
+  static const int CXCursor_DeclRefExpr = 101;
+
+  /// An expression that refers to a member of a struct, union, class,
+  /// Objective-C class, etc.
+  static const int CXCursor_MemberRefExpr = 102;
+
+  /// An expression that calls a function.
+  static const int CXCursor_CallExpr = 103;
+
+  /// An expression that sends a message to an Objective-C object or class.
+  static const int CXCursor_ObjCMessageExpr = 104;
+
+  /// An expression that represents a block literal.
+  static const int CXCursor_BlockExpr = 105;
+
+  /// An integer literal.
+  static const int CXCursor_IntegerLiteral = 106;
+
+  /// A floating point number literal.
+  static const int CXCursor_FloatingLiteral = 107;
+
+  /// An imaginary number literal.
+  static const int CXCursor_ImaginaryLiteral = 108;
+
+  /// A string literal.
+  static const int CXCursor_StringLiteral = 109;
+
+  /// A character literal.
+  static const int CXCursor_CharacterLiteral = 110;
+
+  /// A parenthesized expression, e.g. "(1)".
+  static const int CXCursor_ParenExpr = 111;
+
+  /// This represents the unary-expression's (except sizeof and alignof).
+  static const int CXCursor_UnaryOperator = 112;
+
+  /// [C99 6.5.2.1] Array Subscripting.
+  static const int CXCursor_ArraySubscriptExpr = 113;
+
+  /// A builtin binary operation expression such as "x + y" or "x <= y".
+  static const int CXCursor_BinaryOperator = 114;
+
+  /// Compound assignment such as "+=".
+  static const int CXCursor_CompoundAssignOperator = 115;
+
+  /// The ?: ternary operator.
+  static const int CXCursor_ConditionalOperator = 116;
+
+  /// An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++
+  /// [expr.cast]), which uses the syntax (Type)expr.
+  static const int CXCursor_CStyleCastExpr = 117;
+
+  /// [C99 6.5.2.5]
+  static const int CXCursor_CompoundLiteralExpr = 118;
+
+  /// Describes an C or C++ initializer list.
+  static const int CXCursor_InitListExpr = 119;
+
+  /// The GNU address of label extension, representing &&label.
+  static const int CXCursor_AddrLabelExpr = 120;
+
+  /// This is the GNU Statement Expression extension: ({int X=4; X;})
+  static const int CXCursor_StmtExpr = 121;
+
+  /// Represents a C11 generic selection.
+  static const int CXCursor_GenericSelectionExpr = 122;
+
+  /// Implements the GNU __null extension, which is a name for a null pointer
+  /// constant that has integral type (e.g., int or long) and is the same size
+  /// and alignment as a pointer.
+  static const int CXCursor_GNUNullExpr = 123;
+
+  /// C++'s static_cast<> expression.
+  static const int CXCursor_CXXStaticCastExpr = 124;
+
+  /// C++'s dynamic_cast<> expression.
+  static const int CXCursor_CXXDynamicCastExpr = 125;
+
+  /// C++'s reinterpret_cast<> expression.
+  static const int CXCursor_CXXReinterpretCastExpr = 126;
+
+  /// C++'s const_cast<> expression.
+  static const int CXCursor_CXXConstCastExpr = 127;
+
+  /// Represents an explicit C++ type conversion that uses "functional" notion
+  /// (C++ [expr.type.conv]).
+  static const int CXCursor_CXXFunctionalCastExpr = 128;
+
+  /// A C++ typeid expression (C++ [expr.typeid]).
+  static const int CXCursor_CXXTypeidExpr = 129;
+
+  /// [C++ 2.13.5] C++ Boolean Literal.
+  static const int CXCursor_CXXBoolLiteralExpr = 130;
+
+  /// [C++0x 2.14.7] C++ Pointer Literal.
+  static const int CXCursor_CXXNullPtrLiteralExpr = 131;
+
+  /// Represents the "this" expression in C++
+  static const int CXCursor_CXXThisExpr = 132;
+
+  /// [C++ 15] C++ Throw Expression.
+  static const int CXCursor_CXXThrowExpr = 133;
+
+  /// A new expression for memory allocation and constructor calls, e.g: "new
+  /// CXXNewExpr(foo)".
+  static const int CXCursor_CXXNewExpr = 134;
+
+  /// A delete expression for memory deallocation and destructor calls, e.g.
+  /// "delete[] pArray".
+  static const int CXCursor_CXXDeleteExpr = 135;
+
+  /// A unary expression. (noexcept, sizeof, or other traits)
+  static const int CXCursor_UnaryExpr = 136;
+
+  /// An Objective-C string literal i.e. "foo".
+  static const int CXCursor_ObjCStringLiteral = 137;
+
+  /// An Objective-C @encode expression.
+  static const int CXCursor_ObjCEncodeExpr = 138;
+
+  /// An Objective-C @selector expression.
+  static const int CXCursor_ObjCSelectorExpr = 139;
+
+  /// An Objective-C @protocol expression.
+  static const int CXCursor_ObjCProtocolExpr = 140;
+
+  /// An Objective-C "bridged" cast expression, which casts between Objective-C
+  /// pointers and C pointers, transferring ownership in the process.
+  static const int CXCursor_ObjCBridgedCastExpr = 141;
+
+  /// Represents a C++0x pack expansion that produces a sequence of expressions.
+  static const int CXCursor_PackExpansionExpr = 142;
+
+  /// Represents an expression that computes the length of a parameter pack.
+  static const int CXCursor_SizeOfPackExpr = 143;
+  static const int CXCursor_LambdaExpr = 144;
+
+  /// Objective-c Boolean Literal.
+  static const int CXCursor_ObjCBoolLiteralExpr = 145;
+
+  /// Represents the "self" expression in an Objective-C method.
+  static const int CXCursor_ObjCSelfExpr = 146;
+
+  /// OpenMP 4.0 [2.4, Array Section].
+  static const int CXCursor_OMPArraySectionExpr = 147;
+
+  /// Represents an (...) check.
+  static const int CXCursor_ObjCAvailabilityCheckExpr = 148;
+
+  /// Fixed point literal
+  static const int CXCursor_FixedPointLiteral = 149;
+  static const int CXCursor_LastExpr = 149;
+  static const int CXCursor_FirstStmt = 200;
+
+  /// A statement whose specific kind is not exposed via this interface.
+  static const int CXCursor_UnexposedStmt = 200;
+
+  /// A labelled statement in a function.
+  static const int CXCursor_LabelStmt = 201;
+
+  /// A group of statements like { stmt stmt }.
+  static const int CXCursor_CompoundStmt = 202;
+
+  /// A case statement.
+  static const int CXCursor_CaseStmt = 203;
+
+  /// A default statement.
+  static const int CXCursor_DefaultStmt = 204;
+
+  /// An if statement
+  static const int CXCursor_IfStmt = 205;
+
+  /// A switch statement.
+  static const int CXCursor_SwitchStmt = 206;
+
+  /// A while statement.
+  static const int CXCursor_WhileStmt = 207;
+
+  /// A do statement.
+  static const int CXCursor_DoStmt = 208;
+
+  /// A for statement.
+  static const int CXCursor_ForStmt = 209;
+
+  /// A goto statement.
+  static const int CXCursor_GotoStmt = 210;
+
+  /// An indirect goto statement.
+  static const int CXCursor_IndirectGotoStmt = 211;
+
+  /// A continue statement.
+  static const int CXCursor_ContinueStmt = 212;
+
+  /// A break statement.
+  static const int CXCursor_BreakStmt = 213;
+
+  /// A return statement.
+  static const int CXCursor_ReturnStmt = 214;
+
+  /// A GCC inline assembly statement extension.
+  static const int CXCursor_GCCAsmStmt = 215;
+  static const int CXCursor_AsmStmt = 215;
+
+  /// Objective-C's overall @try-@catch-@finally statement.
+  static const int CXCursor_ObjCAtTryStmt = 216;
+
+  /// Objective-C's @catch statement.
+  static const int CXCursor_ObjCAtCatchStmt = 217;
+
+  /// Objective-C's @finally statement.
+  static const int CXCursor_ObjCAtFinallyStmt = 218;
+
+  /// Objective-C's @throw statement.
+  static const int CXCursor_ObjCAtThrowStmt = 219;
+
+  /// Objective-C's @synchronized statement.
+  static const int CXCursor_ObjCAtSynchronizedStmt = 220;
+
+  /// Objective-C's autorelease pool statement.
+  static const int CXCursor_ObjCAutoreleasePoolStmt = 221;
+
+  /// Objective-C's collection statement.
+  static const int CXCursor_ObjCForCollectionStmt = 222;
+
+  /// C++'s catch statement.
+  static const int CXCursor_CXXCatchStmt = 223;
+
+  /// C++'s try statement.
+  static const int CXCursor_CXXTryStmt = 224;
+
+  /// C++'s for (* : *) statement.
+  static const int CXCursor_CXXForRangeStmt = 225;
+
+  /// Windows Structured Exception Handling's try statement.
+  static const int CXCursor_SEHTryStmt = 226;
+
+  /// Windows Structured Exception Handling's except statement.
+  static const int CXCursor_SEHExceptStmt = 227;
+
+  /// Windows Structured Exception Handling's finally statement.
+  static const int CXCursor_SEHFinallyStmt = 228;
+
+  /// A MS inline assembly statement extension.
+  static const int CXCursor_MSAsmStmt = 229;
+
+  /// The null statement ";": C99 6.8.3p3.
+  static const int CXCursor_NullStmt = 230;
+
+  /// Adaptor class for mixing declarations with statements and expressions.
+  static const int CXCursor_DeclStmt = 231;
+
+  /// OpenMP parallel directive.
+  static const int CXCursor_OMPParallelDirective = 232;
+
+  /// OpenMP SIMD directive.
+  static const int CXCursor_OMPSimdDirective = 233;
+
+  /// OpenMP for directive.
+  static const int CXCursor_OMPForDirective = 234;
+
+  /// OpenMP sections directive.
+  static const int CXCursor_OMPSectionsDirective = 235;
+
+  /// OpenMP section directive.
+  static const int CXCursor_OMPSectionDirective = 236;
+
+  /// OpenMP single directive.
+  static const int CXCursor_OMPSingleDirective = 237;
+
+  /// OpenMP parallel for directive.
+  static const int CXCursor_OMPParallelForDirective = 238;
+
+  /// OpenMP parallel sections directive.
+  static const int CXCursor_OMPParallelSectionsDirective = 239;
+
+  /// OpenMP task directive.
+  static const int CXCursor_OMPTaskDirective = 240;
+
+  /// OpenMP master directive.
+  static const int CXCursor_OMPMasterDirective = 241;
+
+  /// OpenMP critical directive.
+  static const int CXCursor_OMPCriticalDirective = 242;
+
+  /// OpenMP taskyield directive.
+  static const int CXCursor_OMPTaskyieldDirective = 243;
+
+  /// OpenMP barrier directive.
+  static const int CXCursor_OMPBarrierDirective = 244;
+
+  /// OpenMP taskwait directive.
+  static const int CXCursor_OMPTaskwaitDirective = 245;
+
+  /// OpenMP flush directive.
+  static const int CXCursor_OMPFlushDirective = 246;
+
+  /// Windows Structured Exception Handling's leave statement.
+  static const int CXCursor_SEHLeaveStmt = 247;
+
+  /// OpenMP ordered directive.
+  static const int CXCursor_OMPOrderedDirective = 248;
+
+  /// OpenMP atomic directive.
+  static const int CXCursor_OMPAtomicDirective = 249;
+
+  /// OpenMP for SIMD directive.
+  static const int CXCursor_OMPForSimdDirective = 250;
+
+  /// OpenMP parallel for SIMD directive.
+  static const int CXCursor_OMPParallelForSimdDirective = 251;
+
+  /// OpenMP target directive.
+  static const int CXCursor_OMPTargetDirective = 252;
+
+  /// OpenMP teams directive.
+  static const int CXCursor_OMPTeamsDirective = 253;
+
+  /// OpenMP taskgroup directive.
+  static const int CXCursor_OMPTaskgroupDirective = 254;
+
+  /// OpenMP cancellation point directive.
+  static const int CXCursor_OMPCancellationPointDirective = 255;
+
+  /// OpenMP cancel directive.
+  static const int CXCursor_OMPCancelDirective = 256;
+
+  /// OpenMP target data directive.
+  static const int CXCursor_OMPTargetDataDirective = 257;
+
+  /// OpenMP taskloop directive.
+  static const int CXCursor_OMPTaskLoopDirective = 258;
+
+  /// OpenMP taskloop simd directive.
+  static const int CXCursor_OMPTaskLoopSimdDirective = 259;
+
+  /// OpenMP distribute directive.
+  static const int CXCursor_OMPDistributeDirective = 260;
+
+  /// OpenMP target enter data directive.
+  static const int CXCursor_OMPTargetEnterDataDirective = 261;
+
+  /// OpenMP target exit data directive.
+  static const int CXCursor_OMPTargetExitDataDirective = 262;
+
+  /// OpenMP target parallel directive.
+  static const int CXCursor_OMPTargetParallelDirective = 263;
+
+  /// OpenMP target parallel for directive.
+  static const int CXCursor_OMPTargetParallelForDirective = 264;
+
+  /// OpenMP target update directive.
+  static const int CXCursor_OMPTargetUpdateDirective = 265;
+
+  /// OpenMP distribute parallel for directive.
+  static const int CXCursor_OMPDistributeParallelForDirective = 266;
+
+  /// OpenMP distribute parallel for simd directive.
+  static const int CXCursor_OMPDistributeParallelForSimdDirective = 267;
+
+  /// OpenMP distribute simd directive.
+  static const int CXCursor_OMPDistributeSimdDirective = 268;
+
+  /// OpenMP target parallel for simd directive.
+  static const int CXCursor_OMPTargetParallelForSimdDirective = 269;
+
+  /// OpenMP target simd directive.
+  static const int CXCursor_OMPTargetSimdDirective = 270;
+
+  /// OpenMP teams distribute directive.
+  static const int CXCursor_OMPTeamsDistributeDirective = 271;
+
+  /// OpenMP teams distribute simd directive.
+  static const int CXCursor_OMPTeamsDistributeSimdDirective = 272;
+
+  /// OpenMP teams distribute parallel for simd directive.
+  static const int CXCursor_OMPTeamsDistributeParallelForSimdDirective = 273;
+
+  /// OpenMP teams distribute parallel for directive.
+  static const int CXCursor_OMPTeamsDistributeParallelForDirective = 274;
+
+  /// OpenMP target teams directive.
+  static const int CXCursor_OMPTargetTeamsDirective = 275;
+
+  /// OpenMP target teams distribute directive.
+  static const int CXCursor_OMPTargetTeamsDistributeDirective = 276;
+
+  /// OpenMP target teams distribute parallel for directive.
+  static const int CXCursor_OMPTargetTeamsDistributeParallelForDirective = 277;
+
+  /// OpenMP target teams distribute parallel for simd directive.
+  static const int CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective =
+      278;
+
+  /// OpenMP target teams distribute simd directive.
+  static const int CXCursor_OMPTargetTeamsDistributeSimdDirective = 279;
+
+  /// C++2a std::bit_cast expression.
+  static const int CXCursor_BuiltinBitCastExpr = 280;
+
+  /// OpenMP master taskloop directive.
+  static const int CXCursor_OMPMasterTaskLoopDirective = 281;
+
+  /// OpenMP parallel master taskloop directive.
+  static const int CXCursor_OMPParallelMasterTaskLoopDirective = 282;
+
+  /// OpenMP master taskloop simd directive.
+  static const int CXCursor_OMPMasterTaskLoopSimdDirective = 283;
+
+  /// OpenMP parallel master taskloop simd directive.
+  static const int CXCursor_OMPParallelMasterTaskLoopSimdDirective = 284;
+
+  /// OpenMP parallel master directive.
+  static const int CXCursor_OMPParallelMasterDirective = 285;
+  static const int CXCursor_LastStmt = 285;
+
+  /// Cursor that represents the translation unit itself.
+  static const int CXCursor_TranslationUnit = 300;
+  static const int CXCursor_FirstAttr = 400;
+
+  /// An attribute whose specific kind is not exposed via this interface.
+  static const int CXCursor_UnexposedAttr = 400;
+  static const int CXCursor_IBActionAttr = 401;
+  static const int CXCursor_IBOutletAttr = 402;
+  static const int CXCursor_IBOutletCollectionAttr = 403;
+  static const int CXCursor_CXXFinalAttr = 404;
+  static const int CXCursor_CXXOverrideAttr = 405;
+  static const int CXCursor_AnnotateAttr = 406;
+  static const int CXCursor_AsmLabelAttr = 407;
+  static const int CXCursor_PackedAttr = 408;
+  static const int CXCursor_PureAttr = 409;
+  static const int CXCursor_ConstAttr = 410;
+  static const int CXCursor_NoDuplicateAttr = 411;
+  static const int CXCursor_CUDAConstantAttr = 412;
+  static const int CXCursor_CUDADeviceAttr = 413;
+  static const int CXCursor_CUDAGlobalAttr = 414;
+  static const int CXCursor_CUDAHostAttr = 415;
+  static const int CXCursor_CUDASharedAttr = 416;
+  static const int CXCursor_VisibilityAttr = 417;
+  static const int CXCursor_DLLExport = 418;
+  static const int CXCursor_DLLImport = 419;
+  static const int CXCursor_NSReturnsRetained = 420;
+  static const int CXCursor_NSReturnsNotRetained = 421;
+  static const int CXCursor_NSReturnsAutoreleased = 422;
+  static const int CXCursor_NSConsumesSelf = 423;
+  static const int CXCursor_NSConsumed = 424;
+  static const int CXCursor_ObjCException = 425;
+  static const int CXCursor_ObjCNSObject = 426;
+  static const int CXCursor_ObjCIndependentClass = 427;
+  static const int CXCursor_ObjCPreciseLifetime = 428;
+  static const int CXCursor_ObjCReturnsInnerPointer = 429;
+  static const int CXCursor_ObjCRequiresSuper = 430;
+  static const int CXCursor_ObjCRootClass = 431;
+  static const int CXCursor_ObjCSubclassingRestricted = 432;
+  static const int CXCursor_ObjCExplicitProtocolImpl = 433;
+  static const int CXCursor_ObjCDesignatedInitializer = 434;
+  static const int CXCursor_ObjCRuntimeVisible = 435;
+  static const int CXCursor_ObjCBoxable = 436;
+  static const int CXCursor_FlagEnum = 437;
+  static const int CXCursor_ConvergentAttr = 438;
+  static const int CXCursor_WarnUnusedAttr = 439;
+  static const int CXCursor_WarnUnusedResultAttr = 440;
+  static const int CXCursor_AlignedAttr = 441;
+  static const int CXCursor_LastAttr = 441;
+  static const int CXCursor_PreprocessingDirective = 500;
+  static const int CXCursor_MacroDefinition = 501;
+  static const int CXCursor_MacroExpansion = 502;
+  static const int CXCursor_MacroInstantiation = 502;
+  static const int CXCursor_InclusionDirective = 503;
+  static const int CXCursor_FirstPreprocessing = 500;
+  static const int CXCursor_LastPreprocessing = 503;
+
+  /// A module import declaration.
+  static const int CXCursor_ModuleImportDecl = 600;
+  static const int CXCursor_TypeAliasTemplateDecl = 601;
+
+  /// A static_assert or _Static_assert node
+  static const int CXCursor_StaticAssert = 602;
+
+  /// a friend declaration.
+  static const int CXCursor_FriendDecl = 603;
+  static const int CXCursor_FirstExtraDecl = 600;
+  static const int CXCursor_LastExtraDecl = 603;
+
+  /// A code completion overload candidate.
+  static const int CXCursor_OverloadCandidate = 700;
+}
+
+/// A cursor representing some element in the abstract syntax tree for a
+/// translation unit.
+final class CXCursor extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  @ffi.Int()
+  external int xdata;
+
+  @ffi.Array.multi([3])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
+}
+
+/// Describe the linkage of the entity referred to by a cursor.
+abstract class CXLinkageKind {
+  /// This value indicates that no linkage information is available for a
+  /// provided CXCursor.
+  static const int CXLinkage_Invalid = 0;
+
+  /// This is the linkage for variables, parameters, and so on that have
+  /// automatic storage. This covers normal (non-extern) local variables.
+  static const int CXLinkage_NoLinkage = 1;
+
+  /// This is the linkage for static variables and static functions.
+  static const int CXLinkage_Internal = 2;
+
+  /// This is the linkage for entities with external linkage that live in C++
+  /// anonymous namespaces.
+  static const int CXLinkage_UniqueExternal = 3;
+
+  /// This is the linkage for entities with true, external linkage.
+  static const int CXLinkage_External = 4;
+}
+
+abstract class CXVisibilityKind {
+  /// This value indicates that no visibility information is available for a
+  /// provided CXCursor.
+  static const int CXVisibility_Invalid = 0;
+
+  /// Symbol not seen by the linker.
+  static const int CXVisibility_Hidden = 1;
+
+  /// Symbol seen by the linker but resolves to a symbol inside this object.
+  static const int CXVisibility_Protected = 2;
+
+  /// Symbol seen by the linker and acts like a normal symbol.
+  static const int CXVisibility_Default = 3;
+}
+
+/// Describes the availability of a given entity on a particular platform, e.g.,
+/// a particular class might only be available on Mac OS 10.7 or newer.
+final class CXPlatformAvailability extends ffi.Struct {
+  /// A string that describes the platform for which this structure provides
+  /// availability information.
+  external CXString Platform;
+
+  /// The version number in which this entity was introduced.
+  external CXVersion Introduced;
+
+  /// The version number in which this entity was deprecated (but is still
+  /// available).
+  external CXVersion Deprecated;
+
+  /// The version number in which this entity was obsoleted, and therefore is no
+  /// longer available.
+  external CXVersion Obsoleted;
+
+  /// Whether the entity is unconditionally unavailable on this platform.
+  @ffi.Int()
+  external int Unavailable;
+
+  /// An optional message to provide to a user of this API, e.g., to suggest
+  /// replacement APIs.
+  external CXString Message;
+}
+
+/// Describe the "language" of the entity referred to by a cursor.
+abstract class CXLanguageKind {
+  static const int CXLanguage_Invalid = 0;
+  static const int CXLanguage_C = 1;
+  static const int CXLanguage_ObjC = 2;
+  static const int CXLanguage_CPlusPlus = 3;
+}
+
+/// Describe the "thread-local storage (TLS) kind" of the declaration referred
+/// to by a cursor.
+abstract class CXTLSKind {
+  static const int CXTLS_None = 0;
+  static const int CXTLS_Dynamic = 1;
+  static const int CXTLS_Static = 2;
+}
+
+final class CXCursorSetImpl extends ffi.Opaque {}
+
+/// A fast container representing a set of CXCursors.
+typedef CXCursorSet = ffi.Pointer<CXCursorSetImpl>;
+
+/// Describes the kind of type
+abstract class CXTypeKind {
+  /// Represents an invalid type (e.g., where no type is available).
+  static const int CXType_Invalid = 0;
+
+  /// A type whose specific kind is not exposed via this interface.
+  static const int CXType_Unexposed = 1;
+  static const int CXType_Void = 2;
+  static const int CXType_Bool = 3;
+  static const int CXType_Char_U = 4;
+  static const int CXType_UChar = 5;
+  static const int CXType_Char16 = 6;
+  static const int CXType_Char32 = 7;
+  static const int CXType_UShort = 8;
+  static const int CXType_UInt = 9;
+  static const int CXType_ULong = 10;
+  static const int CXType_ULongLong = 11;
+  static const int CXType_UInt128 = 12;
+  static const int CXType_Char_S = 13;
+  static const int CXType_SChar = 14;
+  static const int CXType_WChar = 15;
+  static const int CXType_Short = 16;
+  static const int CXType_Int = 17;
+  static const int CXType_Long = 18;
+  static const int CXType_LongLong = 19;
+  static const int CXType_Int128 = 20;
+  static const int CXType_Float = 21;
+  static const int CXType_Double = 22;
+  static const int CXType_LongDouble = 23;
+  static const int CXType_NullPtr = 24;
+  static const int CXType_Overload = 25;
+  static const int CXType_Dependent = 26;
+  static const int CXType_ObjCId = 27;
+  static const int CXType_ObjCClass = 28;
+  static const int CXType_ObjCSel = 29;
+  static const int CXType_Float128 = 30;
+  static const int CXType_Half = 31;
+  static const int CXType_Float16 = 32;
+  static const int CXType_ShortAccum = 33;
+  static const int CXType_Accum = 34;
+  static const int CXType_LongAccum = 35;
+  static const int CXType_UShortAccum = 36;
+  static const int CXType_UAccum = 37;
+  static const int CXType_ULongAccum = 38;
+  static const int CXType_FirstBuiltin = 2;
+  static const int CXType_LastBuiltin = 38;
+  static const int CXType_Complex = 100;
+  static const int CXType_Pointer = 101;
+  static const int CXType_BlockPointer = 102;
+  static const int CXType_LValueReference = 103;
+  static const int CXType_RValueReference = 104;
+  static const int CXType_Record = 105;
+  static const int CXType_Enum = 106;
+  static const int CXType_Typedef = 107;
+  static const int CXType_ObjCInterface = 108;
+  static const int CXType_ObjCObjectPointer = 109;
+  static const int CXType_FunctionNoProto = 110;
+  static const int CXType_FunctionProto = 111;
+  static const int CXType_ConstantArray = 112;
+  static const int CXType_Vector = 113;
+  static const int CXType_IncompleteArray = 114;
+  static const int CXType_VariableArray = 115;
+  static const int CXType_DependentSizedArray = 116;
+  static const int CXType_MemberPointer = 117;
+  static const int CXType_Auto = 118;
+
+  /// Represents a type that was referred to using an elaborated type keyword.
+  static const int CXType_Elaborated = 119;
+  static const int CXType_Pipe = 120;
+  static const int CXType_OCLImage1dRO = 121;
+  static const int CXType_OCLImage1dArrayRO = 122;
+  static const int CXType_OCLImage1dBufferRO = 123;
+  static const int CXType_OCLImage2dRO = 124;
+  static const int CXType_OCLImage2dArrayRO = 125;
+  static const int CXType_OCLImage2dDepthRO = 126;
+  static const int CXType_OCLImage2dArrayDepthRO = 127;
+  static const int CXType_OCLImage2dMSAARO = 128;
+  static const int CXType_OCLImage2dArrayMSAARO = 129;
+  static const int CXType_OCLImage2dMSAADepthRO = 130;
+  static const int CXType_OCLImage2dArrayMSAADepthRO = 131;
+  static const int CXType_OCLImage3dRO = 132;
+  static const int CXType_OCLImage1dWO = 133;
+  static const int CXType_OCLImage1dArrayWO = 134;
+  static const int CXType_OCLImage1dBufferWO = 135;
+  static const int CXType_OCLImage2dWO = 136;
+  static const int CXType_OCLImage2dArrayWO = 137;
+  static const int CXType_OCLImage2dDepthWO = 138;
+  static const int CXType_OCLImage2dArrayDepthWO = 139;
+  static const int CXType_OCLImage2dMSAAWO = 140;
+  static const int CXType_OCLImage2dArrayMSAAWO = 141;
+  static const int CXType_OCLImage2dMSAADepthWO = 142;
+  static const int CXType_OCLImage2dArrayMSAADepthWO = 143;
+  static const int CXType_OCLImage3dWO = 144;
+  static const int CXType_OCLImage1dRW = 145;
+  static const int CXType_OCLImage1dArrayRW = 146;
+  static const int CXType_OCLImage1dBufferRW = 147;
+  static const int CXType_OCLImage2dRW = 148;
+  static const int CXType_OCLImage2dArrayRW = 149;
+  static const int CXType_OCLImage2dDepthRW = 150;
+  static const int CXType_OCLImage2dArrayDepthRW = 151;
+  static const int CXType_OCLImage2dMSAARW = 152;
+  static const int CXType_OCLImage2dArrayMSAARW = 153;
+  static const int CXType_OCLImage2dMSAADepthRW = 154;
+  static const int CXType_OCLImage2dArrayMSAADepthRW = 155;
+  static const int CXType_OCLImage3dRW = 156;
+  static const int CXType_OCLSampler = 157;
+  static const int CXType_OCLEvent = 158;
+  static const int CXType_OCLQueue = 159;
+  static const int CXType_OCLReserveID = 160;
+  static const int CXType_ObjCObject = 161;
+  static const int CXType_ObjCTypeParam = 162;
+  static const int CXType_Attributed = 163;
+  static const int CXType_OCLIntelSubgroupAVCMcePayload = 164;
+  static const int CXType_OCLIntelSubgroupAVCImePayload = 165;
+  static const int CXType_OCLIntelSubgroupAVCRefPayload = 166;
+  static const int CXType_OCLIntelSubgroupAVCSicPayload = 167;
+  static const int CXType_OCLIntelSubgroupAVCMceResult = 168;
+  static const int CXType_OCLIntelSubgroupAVCImeResult = 169;
+  static const int CXType_OCLIntelSubgroupAVCRefResult = 170;
+  static const int CXType_OCLIntelSubgroupAVCSicResult = 171;
+  static const int CXType_OCLIntelSubgroupAVCImeResultSingleRefStreamout = 172;
+  static const int CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout = 173;
+  static const int CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174;
+  static const int CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175;
+  static const int CXType_ExtVector = 176;
+}
+
+/// Describes the calling convention of a function type
+abstract class CXCallingConv {
+  static const int CXCallingConv_Default = 0;
+  static const int CXCallingConv_C = 1;
+  static const int CXCallingConv_X86StdCall = 2;
+  static const int CXCallingConv_X86FastCall = 3;
+  static const int CXCallingConv_X86ThisCall = 4;
+  static const int CXCallingConv_X86Pascal = 5;
+  static const int CXCallingConv_AAPCS = 6;
+  static const int CXCallingConv_AAPCS_VFP = 7;
+  static const int CXCallingConv_X86RegCall = 8;
+  static const int CXCallingConv_IntelOclBicc = 9;
+  static const int CXCallingConv_Win64 = 10;
+  static const int CXCallingConv_X86_64Win64 = 10;
+  static const int CXCallingConv_X86_64SysV = 11;
+  static const int CXCallingConv_X86VectorCall = 12;
+  static const int CXCallingConv_Swift = 13;
+  static const int CXCallingConv_PreserveMost = 14;
+  static const int CXCallingConv_PreserveAll = 15;
+  static const int CXCallingConv_AArch64VectorCall = 16;
+  static const int CXCallingConv_Invalid = 100;
+  static const int CXCallingConv_Unexposed = 200;
+}
+
+/// The type of an element in the abstract syntax tree.
+final class CXType extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> data;
+}
+
+/// Describes the kind of a template argument.
+abstract class CXTemplateArgumentKind {
+  static const int CXTemplateArgumentKind_Null = 0;
+  static const int CXTemplateArgumentKind_Type = 1;
+  static const int CXTemplateArgumentKind_Declaration = 2;
+  static const int CXTemplateArgumentKind_NullPtr = 3;
+  static const int CXTemplateArgumentKind_Integral = 4;
+  static const int CXTemplateArgumentKind_Template = 5;
+  static const int CXTemplateArgumentKind_TemplateExpansion = 6;
+  static const int CXTemplateArgumentKind_Expression = 7;
+  static const int CXTemplateArgumentKind_Pack = 8;
+  static const int CXTemplateArgumentKind_Invalid = 9;
+}
+
+abstract class CXTypeNullabilityKind {
+  /// Values of this type can never be null.
+  static const int CXTypeNullability_NonNull = 0;
+
+  /// Values of this type can be null.
+  static const int CXTypeNullability_Nullable = 1;
+
+  /// Whether values of this type can be null is (explicitly) unspecified. This
+  /// captures a (fairly rare) case where we can't conclude anything about the
+  /// nullability of the type even though it has been considered.
+  static const int CXTypeNullability_Unspecified = 2;
+
+  /// Nullability is not applicable to this type.
+  static const int CXTypeNullability_Invalid = 3;
+}
+
+/// List the possible error codes for clang_Type_getSizeOf,
+/// clang_Type_getAlignOf, clang_Type_getOffsetOf and clang_Cursor_getOffsetOf.
+abstract class CXTypeLayoutError {
+  /// Type is of kind CXType_Invalid.
+  static const int CXTypeLayoutError_Invalid = -1;
+
+  /// The type is an incomplete Type.
+  static const int CXTypeLayoutError_Incomplete = -2;
+
+  /// The type is a dependent Type.
+  static const int CXTypeLayoutError_Dependent = -3;
+
+  /// The type is not a constant size type.
+  static const int CXTypeLayoutError_NotConstantSize = -4;
+
+  /// The Field name is not valid for this record.
+  static const int CXTypeLayoutError_InvalidFieldName = -5;
+
+  /// The type is undeduced.
+  static const int CXTypeLayoutError_Undeduced = -6;
+}
+
+abstract class CXRefQualifierKind {
+  /// No ref-qualifier was provided.
+  static const int CXRefQualifier_None = 0;
+
+  /// An lvalue ref-qualifier was provided ( &).
+  static const int CXRefQualifier_LValue = 1;
+
+  /// An rvalue ref-qualifier was provided ( &&).
+  static const int CXRefQualifier_RValue = 2;
+}
+
+/// Represents the C++ access control level to a base class for a cursor with
+/// kind CX_CXXBaseSpecifier.
+abstract class CX_CXXAccessSpecifier {
+  static const int CX_CXXInvalidAccessSpecifier = 0;
+  static const int CX_CXXPublic = 1;
+  static const int CX_CXXProtected = 2;
+  static const int CX_CXXPrivate = 3;
+}
+
+/// Represents the storage classes as declared in the source. CX_SC_Invalid was
+/// added for the case that the passed cursor in not a declaration.
+abstract class CX_StorageClass {
+  static const int CX_SC_Invalid = 0;
+  static const int CX_SC_None = 1;
+  static const int CX_SC_Extern = 2;
+  static const int CX_SC_Static = 3;
+  static const int CX_SC_PrivateExtern = 4;
+  static const int CX_SC_OpenCLWorkGroupLocal = 5;
+  static const int CX_SC_Auto = 6;
+  static const int CX_SC_Register = 7;
+}
+
+/// Describes how the traversal of the children of a particular cursor should
+/// proceed after visiting a particular child cursor.
+abstract class CXChildVisitResult {
+  /// Terminates the cursor traversal.
+  static const int CXChildVisit_Break = 0;
+
+  /// Continues the cursor traversal with the next sibling of the cursor just
+  /// visited, without visiting its children.
+  static const int CXChildVisit_Continue = 1;
+
+  /// Recursively traverse the children of this cursor, using the same visitor
+  /// and client data.
+  static const int CXChildVisit_Recurse = 2;
+}
+
+/// Visitor invoked for each cursor found by a traversal.
+typedef CXCursorVisitor
+    = ffi.Pointer<ffi.NativeFunction<CXCursorVisitorFunction>>;
+typedef CXCursorVisitorFunction = ffi.Int32 Function(
+    CXCursor cursor, CXCursor parent, CXClientData client_data);
+typedef DartCXCursorVisitorFunction = int Function(
+    CXCursor cursor, CXCursor parent, CXClientData client_data);
+
+/// Opaque pointer representing client data that will be passed through to
+/// various callbacks and visitors.
+typedef CXClientData = ffi.Pointer<ffi.Void>;
+
+/// Properties for the printing policy.
+abstract class CXPrintingPolicyProperty {
+  static const int CXPrintingPolicy_Indentation = 0;
+  static const int CXPrintingPolicy_SuppressSpecifiers = 1;
+  static const int CXPrintingPolicy_SuppressTagKeyword = 2;
+  static const int CXPrintingPolicy_IncludeTagDefinition = 3;
+  static const int CXPrintingPolicy_SuppressScope = 4;
+  static const int CXPrintingPolicy_SuppressUnwrittenScope = 5;
+  static const int CXPrintingPolicy_SuppressInitializers = 6;
+  static const int CXPrintingPolicy_ConstantArraySizeAsWritten = 7;
+  static const int CXPrintingPolicy_AnonymousTagLocations = 8;
+  static const int CXPrintingPolicy_SuppressStrongLifetime = 9;
+  static const int CXPrintingPolicy_SuppressLifetimeQualifiers = 10;
+  static const int CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors = 11;
+  static const int CXPrintingPolicy_Bool = 12;
+  static const int CXPrintingPolicy_Restrict = 13;
+  static const int CXPrintingPolicy_Alignof = 14;
+  static const int CXPrintingPolicy_UnderscoreAlignof = 15;
+  static const int CXPrintingPolicy_UseVoidForZeroParams = 16;
+  static const int CXPrintingPolicy_TerseOutput = 17;
+  static const int CXPrintingPolicy_PolishForDeclaration = 18;
+  static const int CXPrintingPolicy_Half = 19;
+  static const int CXPrintingPolicy_MSWChar = 20;
+  static const int CXPrintingPolicy_IncludeNewlines = 21;
+  static const int CXPrintingPolicy_MSVCFormatting = 22;
+  static const int CXPrintingPolicy_ConstantsAsWritten = 23;
+  static const int CXPrintingPolicy_SuppressImplicitBase = 24;
+  static const int CXPrintingPolicy_FullyQualifiedName = 25;
+  static const int CXPrintingPolicy_LastProperty = 25;
+}
+
+/// Opaque pointer representing a policy that controls pretty printing for
+/// clang_getCursorPrettyPrinted.
+typedef CXPrintingPolicy = ffi.Pointer<ffi.Void>;
+
+/// Property attributes for a CXCursor_ObjCPropertyDecl.
+abstract class CXObjCPropertyAttrKind {
+  static const int CXObjCPropertyAttr_noattr = 0;
+  static const int CXObjCPropertyAttr_readonly = 1;
+  static const int CXObjCPropertyAttr_getter = 2;
+  static const int CXObjCPropertyAttr_assign = 4;
+  static const int CXObjCPropertyAttr_readwrite = 8;
+  static const int CXObjCPropertyAttr_retain = 16;
+  static const int CXObjCPropertyAttr_copy = 32;
+  static const int CXObjCPropertyAttr_nonatomic = 64;
+  static const int CXObjCPropertyAttr_setter = 128;
+  static const int CXObjCPropertyAttr_atomic = 256;
+  static const int CXObjCPropertyAttr_weak = 512;
+  static const int CXObjCPropertyAttr_strong = 1024;
+  static const int CXObjCPropertyAttr_unsafe_unretained = 2048;
+  static const int CXObjCPropertyAttr_class = 4096;
+}
+
+/// 'Qualifiers' written next to the return and parameter types in Objective-C
+/// method declarations.
+abstract class CXObjCDeclQualifierKind {
+  static const int CXObjCDeclQualifier_None = 0;
+  static const int CXObjCDeclQualifier_In = 1;
+  static const int CXObjCDeclQualifier_Inout = 2;
+  static const int CXObjCDeclQualifier_Out = 4;
+  static const int CXObjCDeclQualifier_Bycopy = 8;
+  static const int CXObjCDeclQualifier_Byref = 16;
+  static const int CXObjCDeclQualifier_Oneway = 32;
+}
+
+/// The functions in this group provide access to information about modules.
+typedef CXModule = ffi.Pointer<ffi.Void>;
+
+abstract class CXNameRefFlags {
+  /// Include the nested-name-specifier, e.g. Foo:: in x.Foo::y, in the range.
+  static const int CXNameRange_WantQualifier = 1;
+
+  /// Include the explicit template arguments, e.g. <int> in x.f<int>, in the
+  /// range.
+  static const int CXNameRange_WantTemplateArgs = 2;
+
+  /// If the name is non-contiguous, return the full spanning range.
+  static const int CXNameRange_WantSinglePiece = 4;
+}
+
+/// Describes a kind of token.
+abstract class CXTokenKind {
+  /// A token that contains some kind of punctuation.
+  static const int CXToken_Punctuation = 0;
+
+  /// A language keyword.
+  static const int CXToken_Keyword = 1;
+
+  /// An identifier (that is not a keyword).
+  static const int CXToken_Identifier = 2;
+
+  /// A numeric, string, or character literal.
+  static const int CXToken_Literal = 3;
+
+  /// A comment.
+  static const int CXToken_Comment = 4;
+}
+
+/// Describes a single preprocessing token.
+final class CXToken extends ffi.Struct {
+  @ffi.Array.multi([4])
+  external ffi.Array<ffi.UnsignedInt> int_data;
+
+  external ffi.Pointer<ffi.Void> ptr_data;
+}
+
+/// A single result of code completion.
+final class CXCompletionResult extends ffi.Struct {
+  /// The kind of entity that this completion refers to.
+  @ffi.Int32()
+  external int CursorKind;
+
+  /// The code-completion string that describes how to insert this
+  /// code-completion result into the editing buffer.
+  external CXCompletionString CompletionString;
+}
+
+/// A semantic string that describes a code-completion result.
+typedef CXCompletionString = ffi.Pointer<ffi.Void>;
+
+/// Describes a single piece of text within a code-completion string.
+abstract class CXCompletionChunkKind {
+  /// A code-completion string that describes "optional" text that could be a
+  /// part of the template (but is not required).
+  static const int CXCompletionChunk_Optional = 0;
+
+  /// Text that a user would be expected to type to get this code-completion
+  /// result.
+  static const int CXCompletionChunk_TypedText = 1;
+
+  /// Text that should be inserted as part of a code-completion result.
+  static const int CXCompletionChunk_Text = 2;
+
+  /// Placeholder text that should be replaced by the user.
+  static const int CXCompletionChunk_Placeholder = 3;
+
+  /// Informative text that should be displayed but never inserted as part of
+  /// the template.
+  static const int CXCompletionChunk_Informative = 4;
+
+  /// Text that describes the current parameter when code-completion is
+  /// referring to function call, message send, or template specialization.
+  static const int CXCompletionChunk_CurrentParameter = 5;
+
+  /// A left parenthesis ('('), used to initiate a function call or signal the
+  /// beginning of a function parameter list.
+  static const int CXCompletionChunk_LeftParen = 6;
+
+  /// A right parenthesis (')'), used to finish a function call or signal the
+  /// end of a function parameter list.
+  static const int CXCompletionChunk_RightParen = 7;
+
+  /// A left bracket ('[').
+  static const int CXCompletionChunk_LeftBracket = 8;
+
+  /// A right bracket (']').
+  static const int CXCompletionChunk_RightBracket = 9;
+
+  /// A left brace ('{').
+  static const int CXCompletionChunk_LeftBrace = 10;
+
+  /// A right brace ('}').
+  static const int CXCompletionChunk_RightBrace = 11;
+
+  /// A left angle bracket ('<').
+  static const int CXCompletionChunk_LeftAngle = 12;
+
+  /// A right angle bracket ('>').
+  static const int CXCompletionChunk_RightAngle = 13;
+
+  /// A comma separator (',').
+  static const int CXCompletionChunk_Comma = 14;
+
+  /// Text that specifies the result type of a given result.
+  static const int CXCompletionChunk_ResultType = 15;
+
+  /// A colon (':').
+  static const int CXCompletionChunk_Colon = 16;
+
+  /// A semicolon (';').
+  static const int CXCompletionChunk_SemiColon = 17;
+
+  /// An '=' sign.
+  static const int CXCompletionChunk_Equal = 18;
+
+  /// Horizontal space (' ').
+  static const int CXCompletionChunk_HorizontalSpace = 19;
+
+  /// Vertical space ('\n'), after which it is generally a good idea to perform
+  /// indentation.
+  static const int CXCompletionChunk_VerticalSpace = 20;
+}
+
+/// Contains the results of code-completion.
+final class CXCodeCompleteResults extends ffi.Struct {
+  /// The code-completion results.
+  external ffi.Pointer<CXCompletionResult> Results;
+
+  /// The number of code-completion results stored in the Results array.
+  @ffi.UnsignedInt()
+  external int NumResults;
+}
+
+/// Flags that can be passed to clang_codeCompleteAt() to modify its behavior.
+abstract class CXCodeComplete_Flags {
+  /// Whether to include macros within the set of code completions returned.
+  static const int CXCodeComplete_IncludeMacros = 1;
+
+  /// Whether to include code patterns for language constructs within the set of
+  /// code completions, e.g., for loops.
+  static const int CXCodeComplete_IncludeCodePatterns = 2;
+
+  /// Whether to include brief documentation within the set of code completions
+  /// returned.
+  static const int CXCodeComplete_IncludeBriefComments = 4;
+
+  /// Whether to speed up completion by omitting top- or namespace-level
+  /// entities defined in the preamble. There's no guarantee any particular
+  /// entity is omitted. This may be useful if the headers are indexed
+  /// externally.
+  static const int CXCodeComplete_SkipPreamble = 8;
+
+  /// Whether to include completions with small fix-its, e.g. change '.' to '->'
+  /// on member access, etc.
+  static const int CXCodeComplete_IncludeCompletionsWithFixIts = 16;
+}
+
+/// Bits that represent the context under which completion is occurring.
+abstract class CXCompletionContext {
+  /// The context for completions is unexposed, as only Clang results should be
+  /// included. (This is equivalent to having no context bits set.)
+  static const int CXCompletionContext_Unexposed = 0;
+
+  /// Completions for any possible type should be included in the results.
+  static const int CXCompletionContext_AnyType = 1;
+
+  /// Completions for any possible value (variables, function calls, etc.)
+  /// should be included in the results.
+  static const int CXCompletionContext_AnyValue = 2;
+
+  /// Completions for values that resolve to an Objective-C object should be
+  /// included in the results.
+  static const int CXCompletionContext_ObjCObjectValue = 4;
+
+  /// Completions for values that resolve to an Objective-C selector should be
+  /// included in the results.
+  static const int CXCompletionContext_ObjCSelectorValue = 8;
+
+  /// Completions for values that resolve to a C++ class type should be included
+  /// in the results.
+  static const int CXCompletionContext_CXXClassTypeValue = 16;
+
+  /// Completions for fields of the member being accessed using the dot operator
+  /// should be included in the results.
+  static const int CXCompletionContext_DotMemberAccess = 32;
+
+  /// Completions for fields of the member being accessed using the arrow
+  /// operator should be included in the results.
+  static const int CXCompletionContext_ArrowMemberAccess = 64;
+
+  /// Completions for properties of the Objective-C object being accessed using
+  /// the dot operator should be included in the results.
+  static const int CXCompletionContext_ObjCPropertyAccess = 128;
+
+  /// Completions for enum tags should be included in the results.
+  static const int CXCompletionContext_EnumTag = 256;
+
+  /// Completions for union tags should be included in the results.
+  static const int CXCompletionContext_UnionTag = 512;
+
+  /// Completions for struct tags should be included in the results.
+  static const int CXCompletionContext_StructTag = 1024;
+
+  /// Completions for C++ class names should be included in the results.
+  static const int CXCompletionContext_ClassTag = 2048;
+
+  /// Completions for C++ namespaces and namespace aliases should be included in
+  /// the results.
+  static const int CXCompletionContext_Namespace = 4096;
+
+  /// Completions for C++ nested name specifiers should be included in the
+  /// results.
+  static const int CXCompletionContext_NestedNameSpecifier = 8192;
+
+  /// Completions for Objective-C interfaces (classes) should be included in the
+  /// results.
+  static const int CXCompletionContext_ObjCInterface = 16384;
+
+  /// Completions for Objective-C protocols should be included in the results.
+  static const int CXCompletionContext_ObjCProtocol = 32768;
+
+  /// Completions for Objective-C categories should be included in the results.
+  static const int CXCompletionContext_ObjCCategory = 65536;
+
+  /// Completions for Objective-C instance messages should be included in the
+  /// results.
+  static const int CXCompletionContext_ObjCInstanceMessage = 131072;
+
+  /// Completions for Objective-C class messages should be included in the
+  /// results.
+  static const int CXCompletionContext_ObjCClassMessage = 262144;
+
+  /// Completions for Objective-C selector names should be included in the
+  /// results.
+  static const int CXCompletionContext_ObjCSelectorName = 524288;
+
+  /// Completions for preprocessor macro names should be included in the
+  /// results.
+  static const int CXCompletionContext_MacroName = 1048576;
+
+  /// Natural language completions should be included in the results.
+  static const int CXCompletionContext_NaturalLanguage = 2097152;
+
+  /// #include file completions should be included in the results.
+  static const int CXCompletionContext_IncludedFile = 4194304;
+
+  /// The current context is unknown, so set all contexts.
+  static const int CXCompletionContext_Unknown = 8388607;
+}
+
+/// Visitor invoked for each file in a translation unit (used with
+/// clang_getInclusions()).
+typedef CXInclusionVisitor
+    = ffi.Pointer<ffi.NativeFunction<CXInclusionVisitorFunction>>;
+typedef CXInclusionVisitorFunction = ffi.Void Function(
+    CXFile included_file,
+    ffi.Pointer<CXSourceLocation> inclusion_stack,
+    ffi.UnsignedInt include_len,
+    CXClientData client_data);
+typedef DartCXInclusionVisitorFunction = void Function(
+    CXFile included_file,
+    ffi.Pointer<CXSourceLocation> inclusion_stack,
+    int include_len,
+    CXClientData client_data);
+
+abstract class CXEvalResultKind {
+  static const int CXEval_Int = 1;
+  static const int CXEval_Float = 2;
+  static const int CXEval_ObjCStrLiteral = 3;
+  static const int CXEval_StrLiteral = 4;
+  static const int CXEval_CFStr = 5;
+  static const int CXEval_Other = 6;
+  static const int CXEval_UnExposed = 0;
+}
+
+/// Evaluation result of a cursor
+typedef CXEvalResult = ffi.Pointer<ffi.Void>;
+
+/// A remapping of original source files and their translated files.
+typedef CXRemapping = ffi.Pointer<ffi.Void>;
+
+/// @{
+abstract class CXVisitorResult {
+  static const int CXVisit_Break = 0;
+  static const int CXVisit_Continue = 1;
+}
+
+final class CXCursorAndRangeVisitor extends ffi.Struct {
+  external ffi.Pointer<ffi.Void> context;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int32 Function(
+              ffi.Pointer<ffi.Void>, CXCursor, CXSourceRange)>> visit;
+}
+
+abstract class CXResult {
+  /// Function returned successfully.
+  static const int CXResult_Success = 0;
+
+  /// One of the parameters was invalid for the function.
+  static const int CXResult_Invalid = 1;
+
+  /// The function was terminated by a callback (e.g. it returned CXVisit_Break)
+  static const int CXResult_VisitBreak = 2;
+}
+
+/// Source location passed to index callbacks.
+final class CXIdxLoc extends ffi.Struct {
+  @ffi.Array.multi([2])
+  external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
+
+  @ffi.UnsignedInt()
+  external int int_data;
+}
+
+/// Data for ppIncludedFile callback.
+final class CXIdxIncludedFileInfo extends ffi.Struct {
+  /// Location of '#' in the #include/#import directive.
+  external CXIdxLoc hashLoc;
+
+  /// Filename as written in the #include/#import directive.
+  external ffi.Pointer<ffi.Char> filename;
+
+  /// The actual file that the #include/#import directive resolved to.
+  external CXFile file;
+
+  @ffi.Int()
+  external int isImport;
+
+  @ffi.Int()
+  external int isAngled;
+
+  /// Non-zero if the directive was automatically turned into a module import.
+  @ffi.Int()
+  external int isModuleImport;
+}
+
+/// Data for IndexerCallbacks#importedASTFile.
+final class CXIdxImportedASTFileInfo extends ffi.Struct {
+  /// Top level AST file containing the imported PCH, module or submodule.
+  external CXFile file;
+
+  /// The imported module or NULL if the AST file is a PCH.
+  external CXModule module;
+
+  /// Location where the file is imported. Applicable only for modules.
+  external CXIdxLoc loc;
+
+  /// Non-zero if an inclusion directive was automatically turned into a module
+  /// import. Applicable only for modules.
+  @ffi.Int()
+  external int isImplicit;
+}
+
+abstract class CXIdxEntityKind {
+  static const int CXIdxEntity_Unexposed = 0;
+  static const int CXIdxEntity_Typedef = 1;
+  static const int CXIdxEntity_Function = 2;
+  static const int CXIdxEntity_Variable = 3;
+  static const int CXIdxEntity_Field = 4;
+  static const int CXIdxEntity_EnumConstant = 5;
+  static const int CXIdxEntity_ObjCClass = 6;
+  static const int CXIdxEntity_ObjCProtocol = 7;
+  static const int CXIdxEntity_ObjCCategory = 8;
+  static const int CXIdxEntity_ObjCInstanceMethod = 9;
+  static const int CXIdxEntity_ObjCClassMethod = 10;
+  static const int CXIdxEntity_ObjCProperty = 11;
+  static const int CXIdxEntity_ObjCIvar = 12;
+  static const int CXIdxEntity_Enum = 13;
+  static const int CXIdxEntity_Struct = 14;
+  static const int CXIdxEntity_Union = 15;
+  static const int CXIdxEntity_CXXClass = 16;
+  static const int CXIdxEntity_CXXNamespace = 17;
+  static const int CXIdxEntity_CXXNamespaceAlias = 18;
+  static const int CXIdxEntity_CXXStaticVariable = 19;
+  static const int CXIdxEntity_CXXStaticMethod = 20;
+  static const int CXIdxEntity_CXXInstanceMethod = 21;
+  static const int CXIdxEntity_CXXConstructor = 22;
+  static const int CXIdxEntity_CXXDestructor = 23;
+  static const int CXIdxEntity_CXXConversionFunction = 24;
+  static const int CXIdxEntity_CXXTypeAlias = 25;
+  static const int CXIdxEntity_CXXInterface = 26;
+}
+
+abstract class CXIdxEntityLanguage {
+  static const int CXIdxEntityLang_None = 0;
+  static const int CXIdxEntityLang_C = 1;
+  static const int CXIdxEntityLang_ObjC = 2;
+  static const int CXIdxEntityLang_CXX = 3;
+  static const int CXIdxEntityLang_Swift = 4;
+}
+
+/// Extra C++ template information for an entity. This can apply to:
+/// CXIdxEntity_Function CXIdxEntity_CXXClass CXIdxEntity_CXXStaticMethod
+/// CXIdxEntity_CXXInstanceMethod CXIdxEntity_CXXConstructor
+/// CXIdxEntity_CXXConversionFunction CXIdxEntity_CXXTypeAlias
+abstract class CXIdxEntityCXXTemplateKind {
+  static const int CXIdxEntity_NonTemplate = 0;
+  static const int CXIdxEntity_Template = 1;
+  static const int CXIdxEntity_TemplatePartialSpecialization = 2;
+  static const int CXIdxEntity_TemplateSpecialization = 3;
+}
+
+abstract class CXIdxAttrKind {
+  static const int CXIdxAttr_Unexposed = 0;
+  static const int CXIdxAttr_IBAction = 1;
+  static const int CXIdxAttr_IBOutlet = 2;
+  static const int CXIdxAttr_IBOutletCollection = 3;
+}
+
+final class CXIdxAttrInfo extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  external CXCursor cursor;
+
+  external CXIdxLoc loc;
+}
+
+final class CXIdxEntityInfo extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  @ffi.Int32()
+  external int templateKind;
+
+  @ffi.Int32()
+  external int lang;
+
+  external ffi.Pointer<ffi.Char> name;
+
+  external ffi.Pointer<ffi.Char> USR;
+
+  external CXCursor cursor;
+
+  external ffi.Pointer<ffi.Pointer<CXIdxAttrInfo>> attributes;
+
+  @ffi.UnsignedInt()
+  external int numAttributes;
+}
+
+final class CXIdxContainerInfo extends ffi.Struct {
+  external CXCursor cursor;
+}
+
+final class CXIdxIBOutletCollectionAttrInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxAttrInfo> attrInfo;
+
+  external ffi.Pointer<CXIdxEntityInfo> objcClass;
+
+  external CXCursor classCursor;
+
+  external CXIdxLoc classLoc;
+}
+
+abstract class CXIdxDeclInfoFlags {
+  static const int CXIdxDeclFlag_Skipped = 1;
+}
+
+final class CXIdxDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxEntityInfo> entityInfo;
+
+  external CXCursor cursor;
+
+  external CXIdxLoc loc;
+
+  external ffi.Pointer<CXIdxContainerInfo> semanticContainer;
+
+  /// Generally same as #semanticContainer but can be different in cases like
+  /// out-of-line C++ member functions.
+  external ffi.Pointer<CXIdxContainerInfo> lexicalContainer;
+
+  @ffi.Int()
+  external int isRedeclaration;
+
+  @ffi.Int()
+  external int isDefinition;
+
+  @ffi.Int()
+  external int isContainer;
+
+  external ffi.Pointer<CXIdxContainerInfo> declAsContainer;
+
+  /// Whether the declaration exists in code or was created implicitly by the
+  /// compiler, e.g. implicit Objective-C methods for properties.
+  @ffi.Int()
+  external int isImplicit;
+
+  external ffi.Pointer<ffi.Pointer<CXIdxAttrInfo>> attributes;
+
+  @ffi.UnsignedInt()
+  external int numAttributes;
+
+  @ffi.UnsignedInt()
+  external int flags;
+}
+
+abstract class CXIdxObjCContainerKind {
+  static const int CXIdxObjCContainer_ForwardRef = 0;
+  static const int CXIdxObjCContainer_Interface = 1;
+  static const int CXIdxObjCContainer_Implementation = 2;
+}
+
+final class CXIdxObjCContainerDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxDeclInfo> declInfo;
+
+  @ffi.Int32()
+  external int kind;
+}
+
+final class CXIdxBaseClassInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxEntityInfo> base;
+
+  external CXCursor cursor;
+
+  external CXIdxLoc loc;
+}
+
+final class CXIdxObjCProtocolRefInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxEntityInfo> protocol;
+
+  external CXCursor cursor;
+
+  external CXIdxLoc loc;
+}
+
+final class CXIdxObjCProtocolRefListInfo extends ffi.Struct {
+  external ffi.Pointer<ffi.Pointer<CXIdxObjCProtocolRefInfo>> protocols;
+
+  @ffi.UnsignedInt()
+  external int numProtocols;
+}
+
+final class CXIdxObjCInterfaceDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxObjCContainerDeclInfo> containerInfo;
+
+  external ffi.Pointer<CXIdxBaseClassInfo> superInfo;
+
+  external ffi.Pointer<CXIdxObjCProtocolRefListInfo> protocols;
+}
+
+final class CXIdxObjCCategoryDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxObjCContainerDeclInfo> containerInfo;
+
+  external ffi.Pointer<CXIdxEntityInfo> objcClass;
+
+  external CXCursor classCursor;
+
+  external CXIdxLoc classLoc;
+
+  external ffi.Pointer<CXIdxObjCProtocolRefListInfo> protocols;
+}
+
+final class CXIdxObjCPropertyDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxDeclInfo> declInfo;
+
+  external ffi.Pointer<CXIdxEntityInfo> getter;
+
+  external ffi.Pointer<CXIdxEntityInfo> setter;
+}
+
+final class CXIdxCXXClassDeclInfo extends ffi.Struct {
+  external ffi.Pointer<CXIdxDeclInfo> declInfo;
+
+  external ffi.Pointer<ffi.Pointer<CXIdxBaseClassInfo>> bases;
+
+  @ffi.UnsignedInt()
+  external int numBases;
+}
+
+/// Data for IndexerCallbacks#indexEntityReference.
+abstract class CXIdxEntityRefKind {
+  /// The entity is referenced directly in user's code.
+  static const int CXIdxEntityRef_Direct = 1;
+
+  /// An implicit reference, e.g. a reference of an Objective-C method via the
+  /// dot syntax.
+  static const int CXIdxEntityRef_Implicit = 2;
+}
+
+/// Roles that are attributed to symbol occurrences.
+abstract class CXSymbolRole {
+  static const int CXSymbolRole_None = 0;
+  static const int CXSymbolRole_Declaration = 1;
+  static const int CXSymbolRole_Definition = 2;
+  static const int CXSymbolRole_Reference = 4;
+  static const int CXSymbolRole_Read = 8;
+  static const int CXSymbolRole_Write = 16;
+  static const int CXSymbolRole_Call = 32;
+  static const int CXSymbolRole_Dynamic = 64;
+  static const int CXSymbolRole_AddressOf = 128;
+  static const int CXSymbolRole_Implicit = 256;
+}
+
+/// Data for IndexerCallbacks#indexEntityReference.
+final class CXIdxEntityRefInfo extends ffi.Struct {
+  @ffi.Int32()
+  external int kind;
+
+  /// Reference cursor.
+  external CXCursor cursor;
+
+  external CXIdxLoc loc;
+
+  /// The entity that gets referenced.
+  external ffi.Pointer<CXIdxEntityInfo> referencedEntity;
+
+  /// Immediate "parent" of the reference. For example:
+  external ffi.Pointer<CXIdxEntityInfo> parentEntity;
+
+  /// Lexical container context of the reference.
+  external ffi.Pointer<CXIdxContainerInfo> container;
+
+  /// Sets of symbol roles of the reference.
+  @ffi.Int32()
+  external int role;
+}
+
+/// A group of callbacks used by #clang_indexSourceFile and
+/// #clang_indexTranslationUnit.
+final class IndexerCallbacks extends ffi.Struct {
+  /// Called periodically to check whether indexing should be aborted. Should
+  /// return 0 to continue, and non-zero to abort.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  CXClientData client_data, ffi.Pointer<ffi.Void> reserved)>>
+      abortQuery;
+
+  /// Called at the end of indexing; passes the complete diagnostic set.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Void Function(
+                  CXClientData, CXDiagnosticSet, ffi.Pointer<ffi.Void>)>>
+      diagnostic;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          CXIdxClientFile Function(CXClientData client_data, CXFile mainFile,
+              ffi.Pointer<ffi.Void> reserved)>> enteredMainFile;
+
+  /// Called when a file gets #included/#imported.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              CXIdxClientFile Function(
+                  CXClientData, ffi.Pointer<CXIdxIncludedFileInfo>)>>
+      ppIncludedFile;
+
+  /// Called when a AST file (PCH or module) gets imported.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              CXIdxClientASTFile Function(
+                  CXClientData, ffi.Pointer<CXIdxImportedASTFileInfo>)>>
+      importedASTFile;
+
+  /// Called at the beginning of indexing a translation unit.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              CXIdxClientContainer Function(
+                  CXClientData client_data, ffi.Pointer<ffi.Void> reserved)>>
+      startedTranslationUnit;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Void Function(CXClientData, ffi.Pointer<CXIdxDeclInfo>)>>
+      indexDeclaration;
+
+  /// Called to index a reference of an entity.
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Void Function(CXClientData, ffi.Pointer<CXIdxEntityRefInfo>)>>
+      indexEntityReference;
+}
+
+/// The client's data object that is associated with a CXFile.
+typedef CXIdxClientFile = ffi.Pointer<ffi.Void>;
+
+/// The client's data object that is associated with an AST file (PCH or
+/// module).
+typedef CXIdxClientASTFile = ffi.Pointer<ffi.Void>;
+
+/// The client's data object that is associated with a semantic container of
+/// entities.
+typedef CXIdxClientContainer = ffi.Pointer<ffi.Void>;
+
+/// The client's data object that is associated with a semantic entity.
+typedef CXIdxClientEntity = ffi.Pointer<ffi.Void>;
+
+/// An indexing action/session, to be applied to one or multiple translation
+/// units.
+typedef CXIndexAction = ffi.Pointer<ffi.Void>;
+
+abstract class CXIndexOptFlags {
+  /// Used to indicate that no special indexing options are needed.
+  static const int CXIndexOpt_None = 0;
+
+  /// Used to indicate that IndexerCallbacks#indexEntityReference should be
+  /// invoked for only one reference of an entity per source file that does not
+  /// also include a declaration/definition of the entity.
+  static const int CXIndexOpt_SuppressRedundantRefs = 1;
+
+  /// Function-local symbols should be indexed. If this is not set
+  /// function-local symbols will be ignored.
+  static const int CXIndexOpt_IndexFunctionLocalSymbols = 2;
+
+  /// Implicit function/class template instantiations should be indexed. If this
+  /// is not set, implicit instantiations will be ignored.
+  static const int CXIndexOpt_IndexImplicitTemplateInstantiations = 4;
+
+  /// Suppress all compiler warnings when parsing for indexing.
+  static const int CXIndexOpt_SuppressWarnings = 8;
+
+  /// Skip a function/method body that was already parsed during an indexing
+  /// session associated with a CXIndexAction object. Bodies in system headers
+  /// are always skipped.
+  static const int CXIndexOpt_SkipParsedBodiesInSession = 16;
+}
+
+/// Visitor invoked for each field found by a traversal.
+typedef CXFieldVisitor
+    = ffi.Pointer<ffi.NativeFunction<CXFieldVisitorFunction>>;
+typedef CXFieldVisitorFunction = ffi.Int32 Function(
+    CXCursor C, CXClientData client_data);
+typedef DartCXFieldVisitorFunction = int Function(
+    CXCursor C, CXClientData client_data);
+
+const int CINDEX_VERSION_MAJOR = 0;
+
+const int CINDEX_VERSION_MINOR = 59;
+
+const int CINDEX_VERSION = 59;
+
+const String CINDEX_VERSION_STRING = '0.59';
diff --git a/pkgs/ffigen/test/large_integration_tests/_expected_sqlite_bindings.dart b/pkgs/ffigen/test/large_integration_tests/_expected_sqlite_bindings.dart
new file mode 100644
index 0000000..ae907cc
--- /dev/null
+++ b/pkgs/ffigen/test/large_integration_tests/_expected_sqlite_bindings.dart
@@ -0,0 +1,12904 @@
+// ignore_for_file: camel_case_types, non_constant_identifier_names
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Bindings to SQLite.
+class SQLite {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  SQLite(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  SQLite.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  /// CAPI3REF: Run-Time Library Version Numbers
+  /// KEYWORDS: sqlite3_version sqlite3_sourceid
+  ///
+  /// These interfaces provide the same information as the [SQLITE_VERSION],
+  /// [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
+  /// but are associated with the library instead of the header file.  ^(Cautious
+  /// programmers might include assert() statements in their application to
+  /// verify that values returned by these interfaces match the macros in
+  /// the header, and thus ensure that the application is
+  /// compiled with matching library and header files.
+  ///
+  /// <blockquote><pre>
+  /// assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
+  /// assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
+  /// assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
+  /// </pre></blockquote>)^
+  ///
+  /// ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION]
+  /// macro.  ^The sqlite3_libversion() function returns a pointer to the
+  /// to the sqlite3_version[] string constant.  The sqlite3_libversion()
+  /// function is provided for use in DLLs since DLL users usually do not have
+  /// direct access to string constants within the DLL.  ^The
+  /// sqlite3_libversion_number() function returns an integer equal to
+  /// [SQLITE_VERSION_NUMBER].  ^(The sqlite3_sourceid() function returns
+  /// a pointer to a string constant whose value is the same as the
+  /// [SQLITE_SOURCE_ID] C preprocessor macro.  Except if SQLite is built
+  /// using an edited copy of [the amalgamation], then the last four characters
+  /// of the hash might be different from [SQLITE_SOURCE_ID].)^
+  ///
+  /// See also: [sqlite_version()] and [sqlite_source_id()].
+  late final ffi.Pointer<ffi.Pointer<ffi.Char>> _sqlite3_version =
+      _lookup<ffi.Pointer<ffi.Char>>('sqlite3_version');
+
+  ffi.Pointer<ffi.Char> get sqlite3_version => _sqlite3_version.value;
+
+  set sqlite3_version(ffi.Pointer<ffi.Char> value) =>
+      _sqlite3_version.value = value;
+
+  ffi.Pointer<ffi.Char> sqlite3_libversion() {
+    return _sqlite3_libversion();
+  }
+
+  late final _sqlite3_libversionPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
+          'sqlite3_libversion');
+  late final _sqlite3_libversion =
+      _sqlite3_libversionPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();
+
+  ffi.Pointer<ffi.Char> sqlite3_sourceid() {
+    return _sqlite3_sourceid();
+  }
+
+  late final _sqlite3_sourceidPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
+          'sqlite3_sourceid');
+  late final _sqlite3_sourceid =
+      _sqlite3_sourceidPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();
+
+  int sqlite3_libversion_number() {
+    return _sqlite3_libversion_number();
+  }
+
+  late final _sqlite3_libversion_numberPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function()>>(
+          'sqlite3_libversion_number');
+  late final _sqlite3_libversion_number =
+      _sqlite3_libversion_numberPtr.asFunction<int Function()>();
+
+  int sqlite3_compileoption_used(
+    ffi.Pointer<ffi.Char> zOptName,
+  ) {
+    return _sqlite3_compileoption_used(
+      zOptName,
+    );
+  }
+
+  late final _sqlite3_compileoption_usedPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Char>)>>(
+          'sqlite3_compileoption_used');
+  late final _sqlite3_compileoption_used = _sqlite3_compileoption_usedPtr
+      .asFunction<int Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_compileoption_get(
+    int N,
+  ) {
+    return _sqlite3_compileoption_get(
+      N,
+    );
+  }
+
+  late final _sqlite3_compileoption_getPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Int)>>(
+          'sqlite3_compileoption_get');
+  late final _sqlite3_compileoption_get = _sqlite3_compileoption_getPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(int)>();
+
+  /// CAPI3REF: Test To See If The Library Is Threadsafe
+  ///
+  /// ^The sqlite3_threadsafe() function returns zero if and only if
+  /// SQLite was compiled with mutexing code omitted due to the
+  /// [SQLITE_THREADSAFE] compile-time option being set to 0.
+  ///
+  /// SQLite can be compiled with or without mutexes.  When
+  /// the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes
+  /// are enabled and SQLite is threadsafe.  When the
+  /// [SQLITE_THREADSAFE] macro is 0,
+  /// the mutexes are omitted.  Without the mutexes, it is not safe
+  /// to use SQLite concurrently from more than one thread.
+  ///
+  /// Enabling mutexes incurs a measurable performance penalty.
+  /// So if speed is of utmost importance, it makes sense to disable
+  /// the mutexes.  But for maximum safety, mutexes should be enabled.
+  /// ^The default behavior is for mutexes to be enabled.
+  ///
+  /// This interface can be used by an application to make sure that the
+  /// version of SQLite that it is linking against was compiled with
+  /// the desired setting of the [SQLITE_THREADSAFE] macro.
+  ///
+  /// This interface only reports on the compile-time mutex setting
+  /// of the [SQLITE_THREADSAFE] flag.  If SQLite is compiled with
+  /// SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
+  /// can be fully or partially disabled using a call to [sqlite3_config()]
+  /// with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
+  /// or [SQLITE_CONFIG_SERIALIZED].  ^(The return value of the
+  /// sqlite3_threadsafe() function shows only the compile-time setting of
+  /// thread safety, not any run-time changes to that setting made by
+  /// sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
+  /// is unchanged by calls to sqlite3_config().)^
+  ///
+  /// See the [threading mode] documentation for additional information.
+  int sqlite3_threadsafe() {
+    return _sqlite3_threadsafe();
+  }
+
+  late final _sqlite3_threadsafePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function()>>('sqlite3_threadsafe');
+  late final _sqlite3_threadsafe =
+      _sqlite3_threadsafePtr.asFunction<int Function()>();
+
+  /// CAPI3REF: Closing A Database Connection
+  /// DESTRUCTOR: sqlite3
+  ///
+  /// ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
+  /// for the [sqlite3] object.
+  /// ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
+  /// the [sqlite3] object is successfully destroyed and all associated
+  /// resources are deallocated.
+  ///
+  /// Ideally, applications should [sqlite3_finalize | finalize] all
+  /// [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
+  /// [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
+  /// with the [sqlite3] object prior to attempting to close the object.
+  /// ^If the database connection is associated with unfinalized prepared
+  /// statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
+  /// sqlite3_close() will leave the database connection open and return
+  /// [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
+  /// statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
+  /// it returns [SQLITE_OK] regardless, but instead of deallocating the database
+  /// connection immediately, it marks the database connection as an unusable
+  /// "zombie" and makes arrangements to automatically deallocate the database
+  /// connection after all prepared statements are finalized, all BLOB handles
+  /// are closed, and all backups have finished. The sqlite3_close_v2() interface
+  /// is intended for use with host languages that are garbage collected, and
+  /// where the order in which destructors are called is arbitrary.
+  ///
+  /// ^If an [sqlite3] object is destroyed while a transaction is open,
+  /// the transaction is automatically rolled back.
+  ///
+  /// The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
+  /// must be either a NULL
+  /// pointer or an [sqlite3] object pointer obtained
+  /// from [sqlite3_open()], [sqlite3_open16()], or
+  /// [sqlite3_open_v2()], and not previously closed.
+  /// ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
+  /// argument is a harmless no-op.
+  int sqlite3_close(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_close(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_closePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_close');
+  late final _sqlite3_close =
+      _sqlite3_closePtr.asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  int sqlite3_close_v2(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_close_v2(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_close_v2Ptr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_close_v2');
+  late final _sqlite3_close_v2 =
+      _sqlite3_close_v2Ptr.asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: One-Step Query Execution Interface
+  /// METHOD: sqlite3
+  ///
+  /// The sqlite3_exec() interface is a convenience wrapper around
+  /// [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
+  /// that allows an application to run multiple statements of SQL
+  /// without having to use a lot of C code.
+  ///
+  /// ^The sqlite3_exec() interface runs zero or more UTF-8 encoded,
+  /// semicolon-separate SQL statements passed into its 2nd argument,
+  /// in the context of the [database connection] passed in as its 1st
+  /// argument.  ^If the callback function of the 3rd argument to
+  /// sqlite3_exec() is not NULL, then it is invoked for each result row
+  /// coming out of the evaluated SQL statements.  ^The 4th argument to
+  /// sqlite3_exec() is relayed through to the 1st argument of each
+  /// callback invocation.  ^If the callback pointer to sqlite3_exec()
+  /// is NULL, then no callback is ever invoked and result rows are
+  /// ignored.
+  ///
+  /// ^If an error occurs while evaluating the SQL statements passed into
+  /// sqlite3_exec(), then execution of the current statement stops and
+  /// subsequent statements are skipped.  ^If the 5th parameter to sqlite3_exec()
+  /// is not NULL then any error message is written into memory obtained
+  /// from [sqlite3_malloc()] and passed back through the 5th parameter.
+  /// To avoid memory leaks, the application should invoke [sqlite3_free()]
+  /// on error message strings returned through the 5th parameter of
+  /// sqlite3_exec() after the error message string is no longer needed.
+  /// ^If the 5th parameter to sqlite3_exec() is not NULL and no errors
+  /// occur, then sqlite3_exec() sets the pointer in its 5th parameter to
+  /// NULL before returning.
+  ///
+  /// ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec()
+  /// routine returns SQLITE_ABORT without invoking the callback again and
+  /// without running any subsequent SQL statements.
+  ///
+  /// ^The 2nd argument to the sqlite3_exec() callback function is the
+  /// number of columns in the result.  ^The 3rd argument to the sqlite3_exec()
+  /// callback is an array of pointers to strings obtained as if from
+  /// [sqlite3_column_text()], one for each column.  ^If an element of a
+  /// result row is NULL then the corresponding string pointer for the
+  /// sqlite3_exec() callback is a NULL pointer.  ^The 4th argument to the
+  /// sqlite3_exec() callback is an array of pointers to strings where each
+  /// entry represents the name of corresponding result column as obtained
+  /// from [sqlite3_column_name()].
+  ///
+  /// ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer
+  /// to an empty string, or a pointer that contains only whitespace and/or
+  /// SQL comments, then no SQL statements are evaluated and the database
+  /// is not changed.
+  ///
+  /// Restrictions:
+  ///
+  /// <ul>
+  /// <li> The application must ensure that the 1st parameter to sqlite3_exec()
+  /// is a valid and open [database connection].
+  /// <li> The application must not close the [database connection] specified by
+  /// the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
+  /// <li> The application must not modify the SQL statement text passed into
+  /// the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
+  /// </ul>
+  int sqlite3_exec(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.Char> sql,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Int Function(
+                    ffi.Pointer<ffi.Void>,
+                    ffi.Int,
+                    ffi.Pointer<ffi.Pointer<ffi.Char>>,
+                    ffi.Pointer<ffi.Pointer<ffi.Char>>)>>
+        callback,
+    ffi.Pointer<ffi.Void> arg3,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> errmsg,
+  ) {
+    return _sqlite3_exec(
+      arg0,
+      sql,
+      callback,
+      arg3,
+      errmsg,
+    );
+  }
+
+  late final _sqlite3_execPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Pointer<ffi.Char>>,
+                          ffi.Pointer<ffi.Pointer<ffi.Char>>)>>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>)>>('sqlite3_exec');
+  late final _sqlite3_exec = _sqlite3_execPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Char>,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Int Function(
+                      ffi.Pointer<ffi.Void>,
+                      ffi.Int,
+                      ffi.Pointer<ffi.Pointer<ffi.Char>>,
+                      ffi.Pointer<ffi.Pointer<ffi.Char>>)>>,
+          ffi.Pointer<ffi.Void>,
+          ffi.Pointer<ffi.Pointer<ffi.Char>>)>();
+
+  /// CAPI3REF: Initialize The SQLite Library
+  ///
+  /// ^The sqlite3_initialize() routine initializes the
+  /// SQLite library.  ^The sqlite3_shutdown() routine
+  /// deallocates any resources that were allocated by sqlite3_initialize().
+  /// These routines are designed to aid in process initialization and
+  /// shutdown on embedded systems.  Workstation applications using
+  /// SQLite normally do not need to invoke either of these routines.
+  ///
+  /// A call to sqlite3_initialize() is an "effective" call if it is
+  /// the first time sqlite3_initialize() is invoked during the lifetime of
+  /// the process, or if it is the first time sqlite3_initialize() is invoked
+  /// following a call to sqlite3_shutdown().  ^(Only an effective call
+  /// of sqlite3_initialize() does any initialization.  All other calls
+  /// are harmless no-ops.)^
+  ///
+  /// A call to sqlite3_shutdown() is an "effective" call if it is the first
+  /// call to sqlite3_shutdown() since the last sqlite3_initialize().  ^(Only
+  /// an effective call to sqlite3_shutdown() does any deinitialization.
+  /// All other valid calls to sqlite3_shutdown() are harmless no-ops.)^
+  ///
+  /// The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown()
+  /// is not.  The sqlite3_shutdown() interface must only be called from a
+  /// single thread.  All open [database connections] must be closed and all
+  /// other SQLite resources must be deallocated prior to invoking
+  /// sqlite3_shutdown().
+  ///
+  /// Among other things, ^sqlite3_initialize() will invoke
+  /// sqlite3_os_init().  Similarly, ^sqlite3_shutdown()
+  /// will invoke sqlite3_os_end().
+  ///
+  /// ^The sqlite3_initialize() routine returns [SQLITE_OK] on success.
+  /// ^If for some reason, sqlite3_initialize() is unable to initialize
+  /// the library (perhaps it is unable to allocate a needed resource such
+  /// as a mutex) it returns an [error code] other than [SQLITE_OK].
+  ///
+  /// ^The sqlite3_initialize() routine is called internally by many other
+  /// SQLite interfaces so that an application usually does not need to
+  /// invoke sqlite3_initialize() directly.  For example, [sqlite3_open()]
+  /// calls sqlite3_initialize() so the SQLite library will be automatically
+  /// initialized when [sqlite3_open()] is called if it has not be initialized
+  /// already.  ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT]
+  /// compile-time option, then the automatic calls to sqlite3_initialize()
+  /// are omitted and the application must call sqlite3_initialize() directly
+  /// prior to using any other SQLite interface.  For maximum portability,
+  /// it is recommended that applications always invoke sqlite3_initialize()
+  /// directly prior to using any other SQLite interface.  Future releases
+  /// of SQLite may require this.  In other words, the behavior exhibited
+  /// when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the
+  /// default behavior in some future release of SQLite.
+  ///
+  /// The sqlite3_os_init() routine does operating-system specific
+  /// initialization of the SQLite library.  The sqlite3_os_end()
+  /// routine undoes the effect of sqlite3_os_init().  Typical tasks
+  /// performed by these routines include allocation or deallocation
+  /// of static resources, initialization of global variables,
+  /// setting up a default [sqlite3_vfs] module, or setting up
+  /// a default configuration using [sqlite3_config()].
+  ///
+  /// The application should never invoke either sqlite3_os_init()
+  /// or sqlite3_os_end() directly.  The application should only invoke
+  /// sqlite3_initialize() and sqlite3_shutdown().  The sqlite3_os_init()
+  /// interface is called automatically by sqlite3_initialize() and
+  /// sqlite3_os_end() is called by sqlite3_shutdown().  Appropriate
+  /// implementations for sqlite3_os_init() and sqlite3_os_end()
+  /// are built into SQLite when it is compiled for Unix, Windows, or OS/2.
+  /// When [custom builds | built for other platforms]
+  /// (using the [SQLITE_OS_OTHER=1] compile-time
+  /// option) the application must supply a suitable implementation for
+  /// sqlite3_os_init() and sqlite3_os_end().  An application-supplied
+  /// implementation of sqlite3_os_init() or sqlite3_os_end()
+  /// must return [SQLITE_OK] on success and some other [error code] upon
+  /// failure.
+  int sqlite3_initialize() {
+    return _sqlite3_initialize();
+  }
+
+  late final _sqlite3_initializePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function()>>('sqlite3_initialize');
+  late final _sqlite3_initialize =
+      _sqlite3_initializePtr.asFunction<int Function()>();
+
+  int sqlite3_shutdown() {
+    return _sqlite3_shutdown();
+  }
+
+  late final _sqlite3_shutdownPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function()>>('sqlite3_shutdown');
+  late final _sqlite3_shutdown =
+      _sqlite3_shutdownPtr.asFunction<int Function()>();
+
+  int sqlite3_os_init() {
+    return _sqlite3_os_init();
+  }
+
+  late final _sqlite3_os_initPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function()>>('sqlite3_os_init');
+  late final _sqlite3_os_init =
+      _sqlite3_os_initPtr.asFunction<int Function()>();
+
+  int sqlite3_os_end() {
+    return _sqlite3_os_end();
+  }
+
+  late final _sqlite3_os_endPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function()>>('sqlite3_os_end');
+  late final _sqlite3_os_end = _sqlite3_os_endPtr.asFunction<int Function()>();
+
+  /// CAPI3REF: Configuring The SQLite Library
+  ///
+  /// The sqlite3_config() interface is used to make global configuration
+  /// changes to SQLite in order to tune SQLite to the specific needs of
+  /// the application.  The default configuration is recommended for most
+  /// applications and so this routine is usually not necessary.  It is
+  /// provided to support rare applications with unusual needs.
+  ///
+  /// <b>The sqlite3_config() interface is not threadsafe. The application
+  /// must ensure that no other SQLite interfaces are invoked by other
+  /// threads while sqlite3_config() is running.</b>
+  ///
+  /// The sqlite3_config() interface
+  /// may only be invoked prior to library initialization using
+  /// [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
+  /// ^If sqlite3_config() is called after [sqlite3_initialize()] and before
+  /// [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
+  /// Note, however, that ^sqlite3_config() can be called as part of the
+  /// implementation of an application-defined [sqlite3_os_init()].
+  ///
+  /// The first argument to sqlite3_config() is an integer
+  /// [configuration option] that determines
+  /// what property of SQLite is to be configured.  Subsequent arguments
+  /// vary depending on the [configuration option]
+  /// in the first argument.
+  ///
+  /// ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
+  /// ^If the option is unknown or SQLite is unable to set the option
+  /// then this routine returns a non-zero [error code].
+  int sqlite3_config(
+    int arg0,
+  ) {
+    return _sqlite3_config(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_configPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int)>>('sqlite3_config');
+  late final _sqlite3_config =
+      _sqlite3_configPtr.asFunction<int Function(int)>();
+
+  /// CAPI3REF: Configure database connections
+  /// METHOD: sqlite3
+  ///
+  /// The sqlite3_db_config() interface is used to make configuration
+  /// changes to a [database connection].  The interface is similar to
+  /// [sqlite3_config()] except that the changes apply to a single
+  /// [database connection] (specified in the first argument).
+  ///
+  /// The second argument to sqlite3_db_config(D,V,...)  is the
+  /// [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code
+  /// that indicates what aspect of the [database connection] is being configured.
+  /// Subsequent arguments vary depending on the configuration verb.
+  ///
+  /// ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
+  /// the call is considered successful.
+  int sqlite3_db_config(
+    ffi.Pointer<sqlite3> arg0,
+    int op,
+  ) {
+    return _sqlite3_db_config(
+      arg0,
+      op,
+    );
+  }
+
+  late final _sqlite3_db_configPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>, ffi.Int)>>(
+      'sqlite3_db_config');
+  late final _sqlite3_db_config = _sqlite3_db_configPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>, int)>();
+
+  /// CAPI3REF: Enable Or Disable Extended Result Codes
+  /// METHOD: sqlite3
+  ///
+  /// ^The sqlite3_extended_result_codes() routine enables or disables the
+  /// [extended result codes] feature of SQLite. ^The extended result
+  /// codes are disabled by default for historical compatibility.
+  int sqlite3_extended_result_codes(
+    ffi.Pointer<sqlite3> arg0,
+    int onoff,
+  ) {
+    return _sqlite3_extended_result_codes(
+      arg0,
+      onoff,
+    );
+  }
+
+  late final _sqlite3_extended_result_codesPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>, ffi.Int)>>(
+      'sqlite3_extended_result_codes');
+  late final _sqlite3_extended_result_codes = _sqlite3_extended_result_codesPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>, int)>();
+
+  /// CAPI3REF: Last Insert Rowid
+  /// METHOD: sqlite3
+  ///
+  /// ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
+  /// has a unique 64-bit signed
+  /// integer key called the [ROWID | "rowid"]. ^The rowid is always available
+  /// as an undeclared column named ROWID, OID, or _ROWID_ as long as those
+  /// names are not also used by explicitly declared columns. ^If
+  /// the table has a column of type [INTEGER PRIMARY KEY] then that column
+  /// is another alias for the rowid.
+  ///
+  /// ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
+  /// the most recent successful [INSERT] into a rowid table or [virtual table]
+  /// on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
+  /// recorded. ^If no successful [INSERT]s into rowid tables have ever occurred
+  /// on the database connection D, then sqlite3_last_insert_rowid(D) returns
+  /// zero.
+  ///
+  /// As well as being set automatically as rows are inserted into database
+  /// tables, the value returned by this function may be set explicitly by
+  /// [sqlite3_set_last_insert_rowid()]
+  ///
+  /// Some virtual table implementations may INSERT rows into rowid tables as
+  /// part of committing a transaction (e.g. to flush data accumulated in memory
+  /// to disk). In this case subsequent calls to this function return the rowid
+  /// associated with these internal INSERT operations, which leads to
+  /// unintuitive results. Virtual table implementations that do write to rowid
+  /// tables in this way can avoid this problem by restoring the original
+  /// rowid value using [sqlite3_set_last_insert_rowid()] before returning
+  /// control to the user.
+  ///
+  /// ^(If an [INSERT] occurs within a trigger then this routine will
+  /// return the [rowid] of the inserted row as long as the trigger is
+  /// running. Once the trigger program ends, the value returned
+  /// by this routine reverts to what it was before the trigger was fired.)^
+  ///
+  /// ^An [INSERT] that fails due to a constraint violation is not a
+  /// successful [INSERT] and does not change the value returned by this
+  /// routine.  ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
+  /// and INSERT OR ABORT make no changes to the return value of this
+  /// routine when their insertion fails.  ^(When INSERT OR REPLACE
+  /// encounters a constraint violation, it does not fail.  The
+  /// INSERT continues to completion after deleting rows that caused
+  /// the constraint problem so INSERT OR REPLACE will always change
+  /// the return value of this interface.)^
+  ///
+  /// ^For the purposes of this routine, an [INSERT] is considered to
+  /// be successful even if it is subsequently rolled back.
+  ///
+  /// This function is accessible to SQL statements via the
+  /// [last_insert_rowid() SQL function].
+  ///
+  /// If a separate thread performs a new [INSERT] on the same
+  /// database connection while the [sqlite3_last_insert_rowid()]
+  /// function is running and thus changes the last insert [rowid],
+  /// then the value returned by [sqlite3_last_insert_rowid()] is
+  /// unpredictable and might not equal either the old or the new
+  /// last insert [rowid].
+  int sqlite3_last_insert_rowid(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_last_insert_rowid(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_last_insert_rowidPtr =
+      _lookup<ffi.NativeFunction<sqlite3_int64 Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_last_insert_rowid');
+  late final _sqlite3_last_insert_rowid = _sqlite3_last_insert_rowidPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: Set the Last Insert Rowid value.
+  /// METHOD: sqlite3
+  ///
+  /// The sqlite3_set_last_insert_rowid(D, R) method allows the application to
+  /// set the value returned by calling sqlite3_last_insert_rowid(D) to R
+  /// without inserting a row into the database.
+  void sqlite3_set_last_insert_rowid(
+    ffi.Pointer<sqlite3> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_set_last_insert_rowid(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_set_last_insert_rowidPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3>,
+              sqlite3_int64)>>('sqlite3_set_last_insert_rowid');
+  late final _sqlite3_set_last_insert_rowid = _sqlite3_set_last_insert_rowidPtr
+      .asFunction<void Function(ffi.Pointer<sqlite3>, int)>();
+
+  /// CAPI3REF: Count The Number Of Rows Modified
+  /// METHOD: sqlite3
+  ///
+  /// ^This function returns the number of rows modified, inserted or
+  /// deleted by the most recently completed INSERT, UPDATE or DELETE
+  /// statement on the database connection specified by the only parameter.
+  /// ^Executing any other type of SQL statement does not modify the value
+  /// returned by this function.
+  ///
+  /// ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
+  /// considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
+  /// [foreign key actions] or [REPLACE] constraint resolution are not counted.
+  ///
+  /// Changes to a view that are intercepted by
+  /// [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value
+  /// returned by sqlite3_changes() immediately after an INSERT, UPDATE or
+  /// DELETE statement run on a view is always zero. Only changes made to real
+  /// tables are counted.
+  ///
+  /// Things are more complicated if the sqlite3_changes() function is
+  /// executed while a trigger program is running. This may happen if the
+  /// program uses the [changes() SQL function], or if some other callback
+  /// function invokes sqlite3_changes() directly. Essentially:
+  ///
+  /// <ul>
+  /// <li> ^(Before entering a trigger program the value returned by
+  /// sqlite3_changes() function is saved. After the trigger program
+  /// has finished, the original value is restored.)^
+  ///
+  /// <li> ^(Within a trigger program each INSERT, UPDATE and DELETE
+  /// statement sets the value returned by sqlite3_changes()
+  /// upon completion as normal. Of course, this value will not include
+  /// any changes performed by sub-triggers, as the sqlite3_changes()
+  /// value will be saved and restored after each sub-trigger has run.)^
+  /// </ul>
+  ///
+  /// ^This means that if the changes() SQL function (or similar) is used
+  /// by the first INSERT, UPDATE or DELETE statement within a trigger, it
+  /// returns the value as set when the calling statement began executing.
+  /// ^If it is used by the second or subsequent such statement within a trigger
+  /// program, the value returned reflects the number of rows modified by the
+  /// previous INSERT, UPDATE or DELETE statement within the same trigger.
+  ///
+  /// If a separate thread makes changes on the same database connection
+  /// while [sqlite3_changes()] is running then the value returned
+  /// is unpredictable and not meaningful.
+  ///
+  /// See also:
+  /// <ul>
+  /// <li> the [sqlite3_total_changes()] interface
+  /// <li> the [count_changes pragma]
+  /// <li> the [changes() SQL function]
+  /// <li> the [data_version pragma]
+  /// </ul>
+  int sqlite3_changes(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_changes(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_changesPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_changes');
+  late final _sqlite3_changes =
+      _sqlite3_changesPtr.asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: Total Number Of Rows Modified
+  /// METHOD: sqlite3
+  ///
+  /// ^This function returns the total number of rows inserted, modified or
+  /// deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
+  /// since the database connection was opened, including those executed as
+  /// part of trigger programs. ^Executing any other type of SQL statement
+  /// does not affect the value returned by sqlite3_total_changes().
+  ///
+  /// ^Changes made as part of [foreign key actions] are included in the
+  /// count, but those made as part of REPLACE constraint resolution are
+  /// not. ^Changes to a view that are intercepted by INSTEAD OF triggers
+  /// are not counted.
+  ///
+  /// The [sqlite3_total_changes(D)] interface only reports the number
+  /// of rows that changed due to SQL statement run against database
+  /// connection D.  Any changes by other database connections are ignored.
+  /// To detect changes against a database file from other database
+  /// connections use the [PRAGMA data_version] command or the
+  /// [SQLITE_FCNTL_DATA_VERSION] [file control].
+  ///
+  /// If a separate thread makes changes on the same database connection
+  /// while [sqlite3_total_changes()] is running then the value
+  /// returned is unpredictable and not meaningful.
+  ///
+  /// See also:
+  /// <ul>
+  /// <li> the [sqlite3_changes()] interface
+  /// <li> the [count_changes pragma]
+  /// <li> the [changes() SQL function]
+  /// <li> the [data_version pragma]
+  /// <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
+  /// </ul>
+  int sqlite3_total_changes(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_total_changes(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_total_changesPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_total_changes');
+  late final _sqlite3_total_changes = _sqlite3_total_changesPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: Interrupt A Long-Running Query
+  /// METHOD: sqlite3
+  ///
+  /// ^This function causes any pending database operation to abort and
+  /// return at its earliest opportunity. This routine is typically
+  /// called in response to a user action such as pressing "Cancel"
+  /// or Ctrl-C where the user wants a long query operation to halt
+  /// immediately.
+  ///
+  /// ^It is safe to call this routine from a thread different from the
+  /// thread that is currently running the database operation.  But it
+  /// is not safe to call this routine with a [database connection] that
+  /// is closed or might close before sqlite3_interrupt() returns.
+  ///
+  /// ^If an SQL operation is very nearly finished at the time when
+  /// sqlite3_interrupt() is called, then it might not have an opportunity
+  /// to be interrupted and might continue to completion.
+  ///
+  /// ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT].
+  /// ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE
+  /// that is inside an explicit transaction, then the entire transaction
+  /// will be rolled back automatically.
+  ///
+  /// ^The sqlite3_interrupt(D) call is in effect until all currently running
+  /// SQL statements on [database connection] D complete.  ^Any new SQL statements
+  /// that are started after the sqlite3_interrupt() call and before the
+  /// running statement count reaches zero are interrupted as if they had been
+  /// running prior to the sqlite3_interrupt() call.  ^New SQL statements
+  /// that are started after the running statement count reaches zero are
+  /// not effected by the sqlite3_interrupt().
+  /// ^A call to sqlite3_interrupt(D) that occurs when there are no running
+  /// SQL statements is a no-op and has no effect on SQL statements
+  /// that are started after the sqlite3_interrupt() call returns.
+  void sqlite3_interrupt(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_interrupt(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_interruptPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_interrupt');
+  late final _sqlite3_interrupt =
+      _sqlite3_interruptPtr.asFunction<void Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: Determine If An SQL Statement Is Complete
+  ///
+  /// These routines are useful during command-line input to determine if the
+  /// currently entered text seems to form a complete SQL statement or
+  /// if additional input is needed before sending the text into
+  /// SQLite for parsing.  ^These routines return 1 if the input string
+  /// appears to be a complete SQL statement.  ^A statement is judged to be
+  /// complete if it ends with a semicolon token and is not a prefix of a
+  /// well-formed CREATE TRIGGER statement.  ^Semicolons that are embedded within
+  /// string literals or quoted identifier names or comments are not
+  /// independent tokens (they are part of the token in which they are
+  /// embedded) and thus do not count as a statement terminator.  ^Whitespace
+  /// and comments that follow the final semicolon are ignored.
+  ///
+  /// ^These routines return 0 if the statement is incomplete.  ^If a
+  /// memory allocation fails, then SQLITE_NOMEM is returned.
+  ///
+  /// ^These routines do not parse the SQL statements thus
+  /// will not detect syntactically incorrect SQL.
+  ///
+  /// ^(If SQLite has not been initialized using [sqlite3_initialize()] prior
+  /// to invoking sqlite3_complete16() then sqlite3_initialize() is invoked
+  /// automatically by sqlite3_complete16().  If that initialization fails,
+  /// then the return value from sqlite3_complete16() will be non-zero
+  /// regardless of whether or not the input SQL is complete.)^
+  ///
+  /// The input to [sqlite3_complete()] must be a zero-terminated
+  /// UTF-8 string.
+  ///
+  /// The input to [sqlite3_complete16()] must be a zero-terminated
+  /// UTF-16 string in native byte order.
+  int sqlite3_complete(
+    ffi.Pointer<ffi.Char> sql,
+  ) {
+    return _sqlite3_complete(
+      sql,
+    );
+  }
+
+  late final _sqlite3_completePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Char>)>>(
+          'sqlite3_complete');
+  late final _sqlite3_complete =
+      _sqlite3_completePtr.asFunction<int Function(ffi.Pointer<ffi.Char>)>();
+
+  int sqlite3_complete16(
+    ffi.Pointer<ffi.Void> sql,
+  ) {
+    return _sqlite3_complete16(
+      sql,
+    );
+  }
+
+  late final _sqlite3_complete16Ptr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>(
+          'sqlite3_complete16');
+  late final _sqlite3_complete16 =
+      _sqlite3_complete16Ptr.asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
+  /// KEYWORDS: {busy-handler callback} {busy handler}
+  /// METHOD: sqlite3
+  ///
+  /// ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
+  /// that might be invoked with argument P whenever
+  /// an attempt is made to access a database table associated with
+  /// [database connection] D when another thread
+  /// or process has the table locked.
+  /// The sqlite3_busy_handler() interface is used to implement
+  /// [sqlite3_busy_timeout()] and [PRAGMA busy_timeout].
+  ///
+  /// ^If the busy callback is NULL, then [SQLITE_BUSY]
+  /// is returned immediately upon encountering the lock.  ^If the busy callback
+  /// is not NULL, then the callback might be invoked with two arguments.
+  ///
+  /// ^The first argument to the busy handler is a copy of the void* pointer which
+  /// is the third argument to sqlite3_busy_handler().  ^The second argument to
+  /// the busy handler callback is the number of times that the busy handler has
+  /// been invoked previously for the same locking event.  ^If the
+  /// busy callback returns 0, then no additional attempts are made to
+  /// access the database and [SQLITE_BUSY] is returned
+  /// to the application.
+  /// ^If the callback returns non-zero, then another attempt
+  /// is made to access the database and the cycle repeats.
+  ///
+  /// The presence of a busy handler does not guarantee that it will be invoked
+  /// when there is lock contention. ^If SQLite determines that invoking the busy
+  /// handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY]
+  /// to the application instead of invoking the
+  /// busy handler.
+  /// Consider a scenario where one process is holding a read lock that
+  /// it is trying to promote to a reserved lock and
+  /// a second process is holding a reserved lock that it is trying
+  /// to promote to an exclusive lock.  The first process cannot proceed
+  /// because it is blocked by the second and the second process cannot
+  /// proceed because it is blocked by the first.  If both processes
+  /// invoke the busy handlers, neither will make any progress.  Therefore,
+  /// SQLite returns [SQLITE_BUSY] for the first process, hoping that this
+  /// will induce the first process to release its read lock and allow
+  /// the second process to proceed.
+  ///
+  /// ^The default busy callback is NULL.
+  ///
+  /// ^(There can only be a single busy handler defined for each
+  /// [database connection].  Setting a new busy handler clears any
+  /// previously set handler.)^  ^Note that calling [sqlite3_busy_timeout()]
+  /// or evaluating [PRAGMA busy_timeout=N] will change the
+  /// busy handler and thus clear any previously set busy handler.
+  ///
+  /// The busy callback should not take any actions which modify the
+  /// database connection that invoked the busy handler.  In other words,
+  /// the busy handler is not reentrant.  Any such actions
+  /// result in undefined behavior.
+  ///
+  /// A busy handler must not close the database connection
+  /// or [prepared statement] that invoked the busy handler.
+  int sqlite3_busy_handler(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<
+            ffi
+            .NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int)>>
+        arg1,
+    ffi.Pointer<ffi.Void> arg2,
+  ) {
+    return _sqlite3_busy_handler(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_busy_handlerPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_busy_handler');
+  late final _sqlite3_busy_handler = _sqlite3_busy_handlerPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int)>>,
+          ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Set A Busy Timeout
+  /// METHOD: sqlite3
+  ///
+  /// ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
+  /// for a specified amount of time when a table is locked.  ^The handler
+  /// will sleep multiple times until at least "ms" milliseconds of sleeping
+  /// have accumulated.  ^After at least "ms" milliseconds of sleeping,
+  /// the handler returns 0 which causes [sqlite3_step()] to return
+  /// [SQLITE_BUSY].
+  ///
+  /// ^Calling this routine with an argument less than or equal to zero
+  /// turns off all busy handlers.
+  ///
+  /// ^(There can only be a single busy handler for a particular
+  /// [database connection] at any given moment.  If another busy handler
+  /// was defined  (using [sqlite3_busy_handler()]) prior to calling
+  /// this routine, that other busy handler is cleared.)^
+  ///
+  /// See also:  [PRAGMA busy_timeout]
+  int sqlite3_busy_timeout(
+    ffi.Pointer<sqlite3> arg0,
+    int ms,
+  ) {
+    return _sqlite3_busy_timeout(
+      arg0,
+      ms,
+    );
+  }
+
+  late final _sqlite3_busy_timeoutPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>, ffi.Int)>>(
+      'sqlite3_busy_timeout');
+  late final _sqlite3_busy_timeout = _sqlite3_busy_timeoutPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>, int)>();
+
+  /// CAPI3REF: Convenience Routines For Running Queries
+  /// METHOD: sqlite3
+  ///
+  /// This is a legacy interface that is preserved for backwards compatibility.
+  /// Use of this interface is not recommended.
+  ///
+  /// Definition: A <b>result table</b> is memory data structure created by the
+  /// [sqlite3_get_table()] interface.  A result table records the
+  /// complete query results from one or more queries.
+  ///
+  /// The table conceptually has a number of rows and columns.  But
+  /// these numbers are not part of the result table itself.  These
+  /// numbers are obtained separately.  Let N be the number of rows
+  /// and M be the number of columns.
+  ///
+  /// A result table is an array of pointers to zero-terminated UTF-8 strings.
+  /// There are (N+1)*M elements in the array.  The first M pointers point
+  /// to zero-terminated strings that  contain the names of the columns.
+  /// The remaining entries all point to query results.  NULL values result
+  /// in NULL pointers.  All other values are in their UTF-8 zero-terminated
+  /// string representation as returned by [sqlite3_column_text()].
+  ///
+  /// A result table might consist of one or more memory allocations.
+  /// It is not safe to pass a result table directly to [sqlite3_free()].
+  /// A result table should be deallocated using [sqlite3_free_table()].
+  ///
+  /// ^(As an example of the result table format, suppose a query result
+  /// is as follows:
+  ///
+  /// <blockquote><pre>
+  /// Name        | Age
+  /// -----------------------
+  /// Alice       | 43
+  /// Bob         | 28
+  /// Cindy       | 21
+  /// </pre></blockquote>
+  ///
+  /// There are two columns (M==2) and three rows (N==3).  Thus the
+  /// result table has 8 entries.  Suppose the result table is stored
+  /// in an array named azResult.  Then azResult holds this content:
+  ///
+  /// <blockquote><pre>
+  /// azResult&#91;0] = "Name";
+  /// azResult&#91;1] = "Age";
+  /// azResult&#91;2] = "Alice";
+  /// azResult&#91;3] = "43";
+  /// azResult&#91;4] = "Bob";
+  /// azResult&#91;5] = "28";
+  /// azResult&#91;6] = "Cindy";
+  /// azResult&#91;7] = "21";
+  /// </pre></blockquote>)^
+  ///
+  /// ^The sqlite3_get_table() function evaluates one or more
+  /// semicolon-separated SQL statements in the zero-terminated UTF-8
+  /// string of its 2nd parameter and returns a result table to the
+  /// pointer given in its 3rd parameter.
+  ///
+  /// After the application has finished with the result from sqlite3_get_table(),
+  /// it must pass the result table pointer to sqlite3_free_table() in order to
+  /// release the memory that was malloced.  Because of the way the
+  /// [sqlite3_malloc()] happens within sqlite3_get_table(), the calling
+  /// function must not try to call [sqlite3_free()] directly.  Only
+  /// [sqlite3_free_table()] is able to release the memory properly and safely.
+  ///
+  /// The sqlite3_get_table() interface is implemented as a wrapper around
+  /// [sqlite3_exec()].  The sqlite3_get_table() routine does not have access
+  /// to any internal data structures of SQLite.  It uses only the public
+  /// interface defined here.  As a consequence, errors that occur in the
+  /// wrapper layer outside of the internal [sqlite3_exec()] call are not
+  /// reflected in subsequent calls to [sqlite3_errcode()] or
+  /// [sqlite3_errmsg()].
+  int sqlite3_get_table(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zSql,
+    ffi.Pointer<ffi.Pointer<ffi.Pointer<ffi.Char>>> pazResult,
+    ffi.Pointer<ffi.Int> pnRow,
+    ffi.Pointer<ffi.Int> pnColumn,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> pzErrmsg,
+  ) {
+    return _sqlite3_get_table(
+      db,
+      zSql,
+      pazResult,
+      pnRow,
+      pnColumn,
+      pzErrmsg,
+    );
+  }
+
+  late final _sqlite3_get_tablePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Pointer<ffi.Char>>>,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>)>>('sqlite3_get_table');
+  late final _sqlite3_get_table = _sqlite3_get_tablePtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Char>,
+          ffi.Pointer<ffi.Pointer<ffi.Pointer<ffi.Char>>>,
+          ffi.Pointer<ffi.Int>,
+          ffi.Pointer<ffi.Int>,
+          ffi.Pointer<ffi.Pointer<ffi.Char>>)>();
+
+  void sqlite3_free_table(
+    ffi.Pointer<ffi.Pointer<ffi.Char>> result,
+  ) {
+    return _sqlite3_free_table(
+      result,
+    );
+  }
+
+  late final _sqlite3_free_tablePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<ffi.Pointer<ffi.Char>>)>>('sqlite3_free_table');
+  late final _sqlite3_free_table = _sqlite3_free_tablePtr
+      .asFunction<void Function(ffi.Pointer<ffi.Pointer<ffi.Char>>)>();
+
+  /// CAPI3REF: Formatted String Printing Functions
+  ///
+  /// These routines are work-alikes of the "printf()" family of functions
+  /// from the standard C library.
+  /// These routines understand most of the common formatting options from
+  /// the standard library printf()
+  /// plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).
+  /// See the [built-in printf()] documentation for details.
+  ///
+  /// ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
+  /// results into memory obtained from [sqlite3_malloc64()].
+  /// The strings returned by these two routines should be
+  /// released by [sqlite3_free()].  ^Both routines return a
+  /// NULL pointer if [sqlite3_malloc64()] is unable to allocate enough
+  /// memory to hold the resulting string.
+  ///
+  /// ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
+  /// the standard C library.  The result is written into the
+  /// buffer supplied as the second parameter whose size is given by
+  /// the first parameter. Note that the order of the
+  /// first two parameters is reversed from snprintf().)^  This is an
+  /// historical accident that cannot be fixed without breaking
+  /// backwards compatibility.  ^(Note also that sqlite3_snprintf()
+  /// returns a pointer to its buffer instead of the number of
+  /// characters actually written into the buffer.)^  We admit that
+  /// the number of characters written would be a more useful return
+  /// value but we cannot change the implementation of sqlite3_snprintf()
+  /// now without breaking compatibility.
+  ///
+  /// ^As long as the buffer size is greater than zero, sqlite3_snprintf()
+  /// guarantees that the buffer is always zero-terminated.  ^The first
+  /// parameter "n" is the total size of the buffer, including space for
+  /// the zero terminator.  So the longest string that can be completely
+  /// written will be n-1 characters.
+  ///
+  /// ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
+  ///
+  /// See also:  [built-in printf()], [printf() SQL function]
+  ffi.Pointer<ffi.Char> sqlite3_mprintf(
+    ffi.Pointer<ffi.Char> arg0,
+  ) {
+    return _sqlite3_mprintf(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_mprintfPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<ffi.Char>)>>('sqlite3_mprintf');
+  late final _sqlite3_mprintf = _sqlite3_mprintfPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_snprintf(
+    int arg0,
+    ffi.Pointer<ffi.Char> arg1,
+    ffi.Pointer<ffi.Char> arg2,
+  ) {
+    return _sqlite3_snprintf(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_snprintfPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Int, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_snprintf');
+  late final _sqlite3_snprintf = _sqlite3_snprintfPtr.asFunction<
+      ffi.Pointer<ffi.Char> Function(
+          int, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: Memory Allocation Subsystem
+  ///
+  /// The SQLite core uses these three routines for all of its own
+  /// internal memory allocation needs. "Core" in the previous sentence
+  /// does not include operating-system specific [VFS] implementation.  The
+  /// Windows VFS uses native malloc() and free() for some operations.
+  ///
+  /// ^The sqlite3_malloc() routine returns a pointer to a block
+  /// of memory at least N bytes in length, where N is the parameter.
+  /// ^If sqlite3_malloc() is unable to obtain sufficient free
+  /// memory, it returns a NULL pointer.  ^If the parameter N to
+  /// sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
+  /// a NULL pointer.
+  ///
+  /// ^The sqlite3_malloc64(N) routine works just like
+  /// sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead
+  /// of a signed 32-bit integer.
+  ///
+  /// ^Calling sqlite3_free() with a pointer previously returned
+  /// by sqlite3_malloc() or sqlite3_realloc() releases that memory so
+  /// that it might be reused.  ^The sqlite3_free() routine is
+  /// a no-op if is called with a NULL pointer.  Passing a NULL pointer
+  /// to sqlite3_free() is harmless.  After being freed, memory
+  /// should neither be read nor written.  Even reading previously freed
+  /// memory might result in a segmentation fault or other severe error.
+  /// Memory corruption, a segmentation fault, or other severe error
+  /// might result if sqlite3_free() is called with a non-NULL pointer that
+  /// was not obtained from sqlite3_malloc() or sqlite3_realloc().
+  ///
+  /// ^The sqlite3_realloc(X,N) interface attempts to resize a
+  /// prior memory allocation X to be at least N bytes.
+  /// ^If the X parameter to sqlite3_realloc(X,N)
+  /// is a NULL pointer then its behavior is identical to calling
+  /// sqlite3_malloc(N).
+  /// ^If the N parameter to sqlite3_realloc(X,N) is zero or
+  /// negative then the behavior is exactly the same as calling
+  /// sqlite3_free(X).
+  /// ^sqlite3_realloc(X,N) returns a pointer to a memory allocation
+  /// of at least N bytes in size or NULL if insufficient memory is available.
+  /// ^If M is the size of the prior allocation, then min(N,M) bytes
+  /// of the prior allocation are copied into the beginning of buffer returned
+  /// by sqlite3_realloc(X,N) and the prior allocation is freed.
+  /// ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the
+  /// prior allocation is not freed.
+  ///
+  /// ^The sqlite3_realloc64(X,N) interfaces works the same as
+  /// sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead
+  /// of a 32-bit signed integer.
+  ///
+  /// ^If X is a memory allocation previously obtained from sqlite3_malloc(),
+  /// sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then
+  /// sqlite3_msize(X) returns the size of that memory allocation in bytes.
+  /// ^The value returned by sqlite3_msize(X) might be larger than the number
+  /// of bytes requested when X was allocated.  ^If X is a NULL pointer then
+  /// sqlite3_msize(X) returns zero.  If X points to something that is not
+  /// the beginning of memory allocation, or if it points to a formerly
+  /// valid memory allocation that has now been freed, then the behavior
+  /// of sqlite3_msize(X) is undefined and possibly harmful.
+  ///
+  /// ^The memory returned by sqlite3_malloc(), sqlite3_realloc(),
+  /// sqlite3_malloc64(), and sqlite3_realloc64()
+  /// is always aligned to at least an 8 byte boundary, or to a
+  /// 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
+  /// option is used.
+  ///
+  /// The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
+  /// must be either NULL or else pointers obtained from a prior
+  /// invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
+  /// not yet been released.
+  ///
+  /// The application must not read or write any part of
+  /// a block of memory after it has been released using
+  /// [sqlite3_free()] or [sqlite3_realloc()].
+  ffi.Pointer<ffi.Void> sqlite3_malloc(
+    int arg0,
+  ) {
+    return _sqlite3_malloc(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_mallocPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Int)>>(
+          'sqlite3_malloc');
+  late final _sqlite3_malloc =
+      _sqlite3_mallocPtr.asFunction<ffi.Pointer<ffi.Void> Function(int)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_malloc64(
+    int arg0,
+  ) {
+    return _sqlite3_malloc64(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_malloc64Ptr = _lookup<
+          ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(sqlite3_uint64)>>(
+      'sqlite3_malloc64');
+  late final _sqlite3_malloc64 =
+      _sqlite3_malloc64Ptr.asFunction<ffi.Pointer<ffi.Void> Function(int)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_realloc(
+    ffi.Pointer<ffi.Void> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_realloc(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_reallocPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Int)>>('sqlite3_realloc');
+  late final _sqlite3_realloc = _sqlite3_reallocPtr
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>, int)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_realloc64(
+    ffi.Pointer<ffi.Void> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_realloc64(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_realloc64Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, sqlite3_uint64)>>('sqlite3_realloc64');
+  late final _sqlite3_realloc64 = _sqlite3_realloc64Ptr
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>, int)>();
+
+  void sqlite3_free(
+    ffi.Pointer<ffi.Void> arg0,
+  ) {
+    return _sqlite3_free(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_freePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
+          'sqlite3_free');
+  late final _sqlite3_free =
+      _sqlite3_freePtr.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
+
+  int sqlite3_msize(
+    ffi.Pointer<ffi.Void> arg0,
+  ) {
+    return _sqlite3_msize(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_msizePtr = _lookup<
+          ffi.NativeFunction<sqlite3_uint64 Function(ffi.Pointer<ffi.Void>)>>(
+      'sqlite3_msize');
+  late final _sqlite3_msize =
+      _sqlite3_msizePtr.asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Memory Allocator Statistics
+  ///
+  /// SQLite provides these two interfaces for reporting on the status
+  /// of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
+  /// routines, which form the built-in memory allocation subsystem.
+  ///
+  /// ^The [sqlite3_memory_used()] routine returns the number of bytes
+  /// of memory currently outstanding (malloced but not freed).
+  /// ^The [sqlite3_memory_highwater()] routine returns the maximum
+  /// value of [sqlite3_memory_used()] since the high-water mark
+  /// was last reset.  ^The values returned by [sqlite3_memory_used()] and
+  /// [sqlite3_memory_highwater()] include any overhead
+  /// added by SQLite in its implementation of [sqlite3_malloc()],
+  /// but not overhead added by the any underlying system library
+  /// routines that [sqlite3_malloc()] may call.
+  ///
+  /// ^The memory high-water mark is reset to the current value of
+  /// [sqlite3_memory_used()] if and only if the parameter to
+  /// [sqlite3_memory_highwater()] is true.  ^The value returned
+  /// by [sqlite3_memory_highwater(1)] is the high-water mark
+  /// prior to the reset.
+  int sqlite3_memory_used() {
+    return _sqlite3_memory_used();
+  }
+
+  late final _sqlite3_memory_usedPtr =
+      _lookup<ffi.NativeFunction<sqlite3_int64 Function()>>(
+          'sqlite3_memory_used');
+  late final _sqlite3_memory_used =
+      _sqlite3_memory_usedPtr.asFunction<int Function()>();
+
+  int sqlite3_memory_highwater(
+    int resetFlag,
+  ) {
+    return _sqlite3_memory_highwater(
+      resetFlag,
+    );
+  }
+
+  late final _sqlite3_memory_highwaterPtr =
+      _lookup<ffi.NativeFunction<sqlite3_int64 Function(ffi.Int)>>(
+          'sqlite3_memory_highwater');
+  late final _sqlite3_memory_highwater =
+      _sqlite3_memory_highwaterPtr.asFunction<int Function(int)>();
+
+  /// CAPI3REF: Pseudo-Random Number Generator
+  ///
+  /// SQLite contains a high-quality pseudo-random number generator (PRNG) used to
+  /// select random [ROWID | ROWIDs] when inserting new records into a table that
+  /// already uses the largest possible [ROWID].  The PRNG is also used for
+  /// the built-in random() and randomblob() SQL functions.  This interface allows
+  /// applications to access the same PRNG for other purposes.
+  ///
+  /// ^A call to this routine stores N bytes of randomness into buffer P.
+  /// ^The P parameter can be a NULL pointer.
+  ///
+  /// ^If this routine has not been previously called or if the previous
+  /// call had N less than one or a NULL pointer for P, then the PRNG is
+  /// seeded using randomness obtained from the xRandomness method of
+  /// the default [sqlite3_vfs] object.
+  /// ^If the previous call to this routine had an N of 1 or more and a
+  /// non-NULL P then the pseudo-randomness is generated
+  /// internally and without recourse to the [sqlite3_vfs] xRandomness
+  /// method.
+  void sqlite3_randomness(
+    int N,
+    ffi.Pointer<ffi.Void> P,
+  ) {
+    return _sqlite3_randomness(
+      N,
+      P,
+    );
+  }
+
+  late final _sqlite3_randomnessPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Void Function(ffi.Int, ffi.Pointer<ffi.Void>)>>(
+      'sqlite3_randomness');
+  late final _sqlite3_randomness = _sqlite3_randomnessPtr
+      .asFunction<void Function(int, ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Compile-Time Authorization Callbacks
+  /// METHOD: sqlite3
+  /// KEYWORDS: {authorizer callback}
+  ///
+  /// ^This routine registers an authorizer callback with a particular
+  /// [database connection], supplied in the first argument.
+  /// ^The authorizer callback is invoked as SQL statements are being compiled
+  /// by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
+  /// [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()],
+  /// and [sqlite3_prepare16_v3()].  ^At various
+  /// points during the compilation process, as logic is being created
+  /// to perform various actions, the authorizer callback is invoked to
+  /// see if those actions are allowed.  ^The authorizer callback should
+  /// return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the
+  /// specific action but allow the SQL statement to continue to be
+  /// compiled, or [SQLITE_DENY] to cause the entire SQL statement to be
+  /// rejected with an error.  ^If the authorizer callback returns
+  /// any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY]
+  /// then the [sqlite3_prepare_v2()] or equivalent call that triggered
+  /// the authorizer will fail with an error message.
+  ///
+  /// When the callback returns [SQLITE_OK], that means the operation
+  /// requested is ok.  ^When the callback returns [SQLITE_DENY], the
+  /// [sqlite3_prepare_v2()] or equivalent call that triggered the
+  /// authorizer will fail with an error message explaining that
+  /// access is denied.
+  ///
+  /// ^The first parameter to the authorizer callback is a copy of the third
+  /// parameter to the sqlite3_set_authorizer() interface. ^The second parameter
+  /// to the callback is an integer [SQLITE_COPY | action code] that specifies
+  /// the particular action to be authorized. ^The third through sixth parameters
+  /// to the callback are either NULL pointers or zero-terminated strings
+  /// that contain additional details about the action to be authorized.
+  /// Applications must always be prepared to encounter a NULL pointer in any
+  /// of the third through the sixth parameters of the authorization callback.
+  ///
+  /// ^If the action code is [SQLITE_READ]
+  /// and the callback returns [SQLITE_IGNORE] then the
+  /// [prepared statement] statement is constructed to substitute
+  /// a NULL value in place of the table column that would have
+  /// been read if [SQLITE_OK] had been returned.  The [SQLITE_IGNORE]
+  /// return can be used to deny an untrusted user access to individual
+  /// columns of a table.
+  /// ^When a table is referenced by a [SELECT] but no column values are
+  /// extracted from that table (for example in a query like
+  /// "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
+  /// is invoked once for that table with a column name that is an empty string.
+  /// ^If the action code is [SQLITE_DELETE] and the callback returns
+  /// [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
+  /// [truncate optimization] is disabled and all rows are deleted individually.
+  ///
+  /// An authorizer is used when [sqlite3_prepare | preparing]
+  /// SQL statements from an untrusted source, to ensure that the SQL statements
+  /// do not try to access data they are not allowed to see, or that they do not
+  /// try to execute malicious statements that damage the database.  For
+  /// example, an application may allow a user to enter arbitrary
+  /// SQL queries for evaluation by a database.  But the application does
+  /// not want the user to be able to make arbitrary changes to the
+  /// database.  An authorizer could then be put in place while the
+  /// user-entered SQL is being [sqlite3_prepare | prepared] that
+  /// disallows everything except [SELECT] statements.
+  ///
+  /// Applications that need to process SQL from untrusted sources
+  /// might also consider lowering resource limits using [sqlite3_limit()]
+  /// and limiting database size using the [max_page_count] [PRAGMA]
+  /// in addition to using an authorizer.
+  ///
+  /// ^(Only a single authorizer can be in place on a database connection
+  /// at a time.  Each call to sqlite3_set_authorizer overrides the
+  /// previous call.)^  ^Disable the authorizer by installing a NULL callback.
+  /// The authorizer is disabled by default.
+  ///
+  /// The authorizer callback must not do anything that will modify
+  /// the database connection that invoked the authorizer callback.
+  /// Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
+  /// database connections for the meaning of "modify" in this paragraph.
+  ///
+  /// ^When [sqlite3_prepare_v2()] is used to prepare a statement, the
+  /// statement might be re-prepared during [sqlite3_step()] due to a
+  /// schema change.  Hence, the application should ensure that the
+  /// correct authorizer callback remains in place during the [sqlite3_step()].
+  ///
+  /// ^Note that the authorizer callback is invoked only during
+  /// [sqlite3_prepare()] or its variants.  Authorization is not
+  /// performed during statement evaluation in [sqlite3_step()], unless
+  /// as stated in the previous paragraph, sqlite3_step() invokes
+  /// sqlite3_prepare_v2() to reprepare a statement after a schema change.
+  int sqlite3_set_authorizer(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Int Function(
+                    ffi.Pointer<ffi.Void>,
+                    ffi.Int,
+                    ffi.Pointer<ffi.Char>,
+                    ffi.Pointer<ffi.Char>,
+                    ffi.Pointer<ffi.Char>,
+                    ffi.Pointer<ffi.Char>)>>
+        xAuth,
+    ffi.Pointer<ffi.Void> pUserData,
+  ) {
+    return _sqlite3_set_authorizer(
+      arg0,
+      xAuth,
+      pUserData,
+    );
+  }
+
+  late final _sqlite3_set_authorizerPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Char>,
+                          ffi.Pointer<ffi.Char>,
+                          ffi.Pointer<ffi.Char>,
+                          ffi.Pointer<ffi.Char>)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_set_authorizer');
+  late final _sqlite3_set_authorizer = _sqlite3_set_authorizerPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Int Function(
+                      ffi.Pointer<ffi.Void>,
+                      ffi.Int,
+                      ffi.Pointer<ffi.Char>,
+                      ffi.Pointer<ffi.Char>,
+                      ffi.Pointer<ffi.Char>,
+                      ffi.Pointer<ffi.Char>)>>,
+          ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Tracing And Profiling Functions
+  /// METHOD: sqlite3
+  ///
+  /// These routines are deprecated. Use the [sqlite3_trace_v2()] interface
+  /// instead of the routines described here.
+  ///
+  /// These routines register callback functions that can be used for
+  /// tracing and profiling the execution of SQL statements.
+  ///
+  /// ^The callback function registered by sqlite3_trace() is invoked at
+  /// various times when an SQL statement is being run by [sqlite3_step()].
+  /// ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the
+  /// SQL statement text as the statement first begins executing.
+  /// ^(Additional sqlite3_trace() callbacks might occur
+  /// as each triggered subprogram is entered.  The callbacks for triggers
+  /// contain a UTF-8 SQL comment that identifies the trigger.)^
+  ///
+  /// The [SQLITE_TRACE_SIZE_LIMIT] compile-time option can be used to limit
+  /// the length of [bound parameter] expansion in the output of sqlite3_trace().
+  ///
+  /// ^The callback function registered by sqlite3_profile() is invoked
+  /// as each SQL statement finishes.  ^The profile callback contains
+  /// the original statement text and an estimate of wall-clock time
+  /// of how long that statement took to run.  ^The profile callback
+  /// time is in units of nanoseconds, however the current implementation
+  /// is only capable of millisecond resolution so the six least significant
+  /// digits in the time are meaningless.  Future versions of SQLite
+  /// might provide greater resolution on the profiler callback.  Invoking
+  /// either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the
+  /// profile callback.
+  ffi.Pointer<ffi.Void> sqlite3_trace(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(
+                    ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>)>>
+        xTrace,
+    ffi.Pointer<ffi.Void> arg2,
+  ) {
+    return _sqlite3_trace(
+      arg0,
+      xTrace,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_tracePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_trace');
+  late final _sqlite3_trace = _sqlite3_tracePtr.asFunction<
+      ffi.Pointer<ffi.Void> Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>)>>,
+          ffi.Pointer<ffi.Void>)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_profile(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>,
+                    sqlite3_uint64)>>
+        xProfile,
+    ffi.Pointer<ffi.Void> arg2,
+  ) {
+    return _sqlite3_profile(
+      arg0,
+      xProfile,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_profilePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<ffi.Void>,
+                          ffi.Pointer<ffi.Char>, sqlite3_uint64)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_profile');
+  late final _sqlite3_profile = _sqlite3_profilePtr.asFunction<
+      ffi.Pointer<ffi.Void> Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Void Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Char>, sqlite3_uint64)>>,
+          ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: SQL Trace Hook
+  /// METHOD: sqlite3
+  ///
+  /// ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback
+  /// function X against [database connection] D, using property mask M
+  /// and context pointer P.  ^If the X callback is
+  /// NULL or if the M mask is zero, then tracing is disabled.  The
+  /// M argument should be the bitwise OR-ed combination of
+  /// zero or more [SQLITE_TRACE] constants.
+  ///
+  /// ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides
+  /// (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().
+  ///
+  /// ^The X callback is invoked whenever any of the events identified by
+  /// mask M occur.  ^The integer return value from the callback is currently
+  /// ignored, though this may change in future releases.  Callback
+  /// implementations should return zero to ensure future compatibility.
+  ///
+  /// ^A trace callback is invoked with four arguments: callback(T,C,P,X).
+  /// ^The T argument is one of the [SQLITE_TRACE]
+  /// constants to indicate why the callback was invoked.
+  /// ^The C argument is a copy of the context pointer.
+  /// The P and X arguments are pointers whose meanings depend on T.
+  ///
+  /// The sqlite3_trace_v2() interface is intended to replace the legacy
+  /// interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
+  /// are deprecated.
+  int sqlite3_trace_v2(
+    ffi.Pointer<sqlite3> arg0,
+    int uMask,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Int Function(ffi.UnsignedInt, ffi.Pointer<ffi.Void>,
+                    ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>
+        xCallback,
+    ffi.Pointer<ffi.Void> pCtx,
+  ) {
+    return _sqlite3_trace_v2(
+      arg0,
+      uMask,
+      xCallback,
+      pCtx,
+    );
+  }
+
+  late final _sqlite3_trace_v2Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.UnsignedInt,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(ffi.UnsignedInt, ffi.Pointer<ffi.Void>,
+                          ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_trace_v2');
+  late final _sqlite3_trace_v2 = _sqlite3_trace_v2Ptr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Int Function(ffi.UnsignedInt, ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>,
+          ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Query Progress Callbacks
+  /// METHOD: sqlite3
+  ///
+  /// ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
+  /// function X to be invoked periodically during long running calls to
+  /// [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
+  /// database connection D.  An example use for this
+  /// interface is to keep a GUI updated during a large query.
+  ///
+  /// ^The parameter P is passed through as the only parameter to the
+  /// callback function X.  ^The parameter N is the approximate number of
+  /// [virtual machine instructions] that are evaluated between successive
+  /// invocations of the callback X.  ^If N is less than one then the progress
+  /// handler is disabled.
+  ///
+  /// ^Only a single progress handler may be defined at one time per
+  /// [database connection]; setting a new progress handler cancels the
+  /// old one.  ^Setting parameter X to NULL disables the progress handler.
+  /// ^The progress handler is also disabled by setting N to a value less
+  /// than 1.
+  ///
+  /// ^If the progress callback returns non-zero, the operation is
+  /// interrupted.  This feature can be used to implement a
+  /// "Cancel" button on a GUI progress dialog box.
+  ///
+  /// The progress handler callback must not do anything that will modify
+  /// the database connection that invoked the progress handler.
+  /// Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
+  /// database connections for the meaning of "modify" in this paragraph.
+  void sqlite3_progress_handler(
+    ffi.Pointer<sqlite3> arg0,
+    int arg1,
+    ffi.Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
+        arg2,
+    ffi.Pointer<ffi.Void> arg3,
+  ) {
+    return _sqlite3_progress_handler(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+    );
+  }
+
+  late final _sqlite3_progress_handlerPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Int,
+              ffi.Pointer<
+                  ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_progress_handler');
+  late final _sqlite3_progress_handler =
+      _sqlite3_progress_handlerPtr.asFunction<
+          void Function(
+              ffi.Pointer<sqlite3>,
+              int,
+              ffi.Pointer<
+                  ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>,
+              ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Opening A New Database Connection
+  /// CONSTRUCTOR: sqlite3
+  ///
+  /// ^These routines open an SQLite database file as specified by the
+  /// filename argument. ^The filename argument is interpreted as UTF-8 for
+  /// sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
+  /// order for sqlite3_open16(). ^(A [database connection] handle is usually
+  /// returned in *ppDb, even if an error occurs.  The only exception is that
+  /// if SQLite is unable to allocate memory to hold the [sqlite3] object,
+  /// a NULL will be written into *ppDb instead of a pointer to the [sqlite3]
+  /// object.)^ ^(If the database is opened (and/or created) successfully, then
+  /// [SQLITE_OK] is returned.  Otherwise an [error code] is returned.)^ ^The
+  /// [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
+  /// an English language description of the error following a failure of any
+  /// of the sqlite3_open() routines.
+  ///
+  /// ^The default encoding will be UTF-8 for databases created using
+  /// sqlite3_open() or sqlite3_open_v2().  ^The default encoding for databases
+  /// created using sqlite3_open16() will be UTF-16 in the native byte order.
+  ///
+  /// Whether or not an error occurs when it is opened, resources
+  /// associated with the [database connection] handle should be released by
+  /// passing it to [sqlite3_close()] when it is no longer required.
+  ///
+  /// The sqlite3_open_v2() interface works like sqlite3_open()
+  /// except that it accepts two additional parameters for additional control
+  /// over the new database connection.  ^(The flags parameter to
+  /// sqlite3_open_v2() must include, at a minimum, one of the following
+  /// three flag combinations:)^
+  ///
+  /// <dl>
+  /// ^(<dt>[SQLITE_OPEN_READONLY]</dt>
+  /// <dd>The database is opened in read-only mode.  If the database does not
+  /// already exist, an error is returned.</dd>)^
+  ///
+  /// ^(<dt>[SQLITE_OPEN_READWRITE]</dt>
+  /// <dd>The database is opened for reading and writing if possible, or reading
+  /// only if the file is write protected by the operating system.  In either
+  /// case the database must already exist, otherwise an error is returned.</dd>)^
+  ///
+  /// ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
+  /// <dd>The database is opened for reading and writing, and is created if
+  /// it does not already exist. This is the behavior that is always used for
+  /// sqlite3_open() and sqlite3_open16().</dd>)^
+  /// </dl>
+  ///
+  /// In addition to the required flags, the following optional flags are
+  /// also supported:
+  ///
+  /// <dl>
+  /// ^(<dt>[SQLITE_OPEN_URI]</dt>
+  /// <dd>The filename can be interpreted as a URI if this flag is set.</dd>)^
+  ///
+  /// ^(<dt>[SQLITE_OPEN_MEMORY]</dt>
+  /// <dd>The database will be opened as an in-memory database.  The database
+  /// is named by the "filename" argument for the purposes of cache-sharing,
+  /// if shared cache mode is enabled, but the "filename" is otherwise ignored.
+  /// </dd>)^
+  ///
+  /// ^(<dt>[SQLITE_OPEN_NOMUTEX]</dt>
+  /// <dd>The new database connection will use the "multi-thread"
+  /// [threading mode].)^  This means that separate threads are allowed
+  /// to use SQLite at the same time, as long as each thread is using
+  /// a different [database connection].
+  ///
+  /// ^(<dt>[SQLITE_OPEN_FULLMUTEX]</dt>
+  /// <dd>The new database connection will use the "serialized"
+  /// [threading mode].)^  This means the multiple threads can safely
+  /// attempt to use the same database connection at the same time.
+  /// (Mutexes will block any actual concurrency, but in this mode
+  /// there is no harm in trying.)
+  ///
+  /// ^(<dt>[SQLITE_OPEN_SHAREDCACHE]</dt>
+  /// <dd>The database is opened [shared cache] enabled, overriding
+  /// the default shared cache setting provided by
+  /// [sqlite3_enable_shared_cache()].)^
+  ///
+  /// ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
+  /// <dd>The database is opened [shared cache] disabled, overriding
+  /// the default shared cache setting provided by
+  /// [sqlite3_enable_shared_cache()].)^
+  ///
+  /// [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
+  /// <dd>The database filename is not allowed to be a symbolic link</dd>
+  /// </dl>)^
+  ///
+  /// If the 3rd parameter to sqlite3_open_v2() is not one of the
+  /// required combinations shown above optionally combined with other
+  /// [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
+  /// then the behavior is undefined.
+  ///
+  /// ^The fourth parameter to sqlite3_open_v2() is the name of the
+  /// [sqlite3_vfs] object that defines the operating system interface that
+  /// the new database connection should use.  ^If the fourth parameter is
+  /// a NULL pointer then the default [sqlite3_vfs] object is used.
+  ///
+  /// ^If the filename is ":memory:", then a private, temporary in-memory database
+  /// is created for the connection.  ^This in-memory database will vanish when
+  /// the database connection is closed.  Future versions of SQLite might
+  /// make use of additional special filenames that begin with the ":" character.
+  /// It is recommended that when a database filename actually does begin with
+  /// a ":" character you should prefix the filename with a pathname such as
+  /// "./" to avoid ambiguity.
+  ///
+  /// ^If the filename is an empty string, then a private, temporary
+  /// on-disk database will be created.  ^This private database will be
+  /// automatically deleted as soon as the database connection is closed.
+  ///
+  /// [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3>
+  ///
+  /// ^If [URI filename] interpretation is enabled, and the filename argument
+  /// begins with "file:", then the filename is interpreted as a URI. ^URI
+  /// filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
+  /// set in the third argument to sqlite3_open_v2(), or if it has
+  /// been enabled globally using the [SQLITE_CONFIG_URI] option with the
+  /// [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
+  /// URI filename interpretation is turned off
+  /// by default, but future releases of SQLite might enable URI filename
+  /// interpretation by default.  See "[URI filenames]" for additional
+  /// information.
+  ///
+  /// URI filenames are parsed according to RFC 3986. ^If the URI contains an
+  /// authority, then it must be either an empty string or the string
+  /// "localhost". ^If the authority is not an empty string or "localhost", an
+  /// error is returned to the caller. ^The fragment component of a URI, if
+  /// present, is ignored.
+  ///
+  /// ^SQLite uses the path component of the URI as the name of the disk file
+  /// which contains the database. ^If the path begins with a '/' character,
+  /// then it is interpreted as an absolute path. ^If the path does not begin
+  /// with a '/' (meaning that the authority section is omitted from the URI)
+  /// then the path is interpreted as a relative path.
+  /// ^(On windows, the first component of an absolute path
+  /// is a drive specification (e.g. "C:").)^
+  ///
+  /// [[core URI query parameters]]
+  /// The query component of a URI may contain parameters that are interpreted
+  /// either by SQLite itself, or by a [VFS | custom VFS implementation].
+  /// SQLite and its built-in [VFSes] interpret the
+  /// following query parameters:
+  ///
+  /// <ul>
+  /// <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
+  /// a VFS object that provides the operating system interface that should
+  /// be used to access the database file on disk. ^If this option is set to
+  /// an empty string the default VFS object is used. ^Specifying an unknown
+  /// VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is
+  /// present, then the VFS specified by the option takes precedence over
+  /// the value passed as the fourth parameter to sqlite3_open_v2().
+  ///
+  /// <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw",
+  /// "rwc", or "memory". Attempting to set it to any other value is
+  /// an error)^.
+  /// ^If "ro" is specified, then the database is opened for read-only
+  /// access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the
+  /// third argument to sqlite3_open_v2(). ^If the mode option is set to
+  /// "rw", then the database is opened for read-write (but not create)
+  /// access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had
+  /// been set. ^Value "rwc" is equivalent to setting both
+  /// SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE.  ^If the mode option is
+  /// set to "memory" then a pure [in-memory database] that never reads
+  /// or writes from disk is used. ^It is an error to specify a value for
+  /// the mode parameter that is less restrictive than that specified by
+  /// the flags passed in the third parameter to sqlite3_open_v2().
+  ///
+  /// <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or
+  /// "private". ^Setting it to "shared" is equivalent to setting the
+  /// SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to
+  /// sqlite3_open_v2(). ^Setting the cache parameter to "private" is
+  /// equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
+  /// ^If sqlite3_open_v2() is used and the "cache" parameter is present in
+  /// a URI filename, its value overrides any behavior requested by setting
+  /// SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
+  ///
+  /// <li> <b>psow</b>: ^The psow parameter indicates whether or not the
+  /// [powersafe overwrite] property does or does not apply to the
+  /// storage media on which the database file resides.
+  ///
+  /// <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
+  /// which if set disables file locking in rollback journal modes.  This
+  /// is useful for accessing a database on a filesystem that does not
+  /// support locking.  Caution:  Database corruption might result if two
+  /// or more processes write to the same database and any one of those
+  /// processes uses nolock=1.
+  ///
+  /// <li> <b>immutable</b>: ^The immutable parameter is a boolean query
+  /// parameter that indicates that the database file is stored on
+  /// read-only media.  ^When immutable is set, SQLite assumes that the
+  /// database file cannot be changed, even by a process with higher
+  /// privilege, and so the database is opened read-only and all locking
+  /// and change detection is disabled.  Caution: Setting the immutable
+  /// property on a database file that does in fact change can result
+  /// in incorrect query results and/or [SQLITE_CORRUPT] errors.
+  /// See also: [SQLITE_IOCAP_IMMUTABLE].
+  ///
+  /// </ul>
+  ///
+  /// ^Specifying an unknown parameter in the query component of a URI is not an
+  /// error.  Future versions of SQLite might understand additional query
+  /// parameters.  See "[query parameters with special meaning to SQLite]" for
+  /// additional information.
+  ///
+  /// [[URI filename examples]] <h3>URI filename examples</h3>
+  ///
+  /// <table border="1" align=center cellpadding=5>
+  /// <tr><th> URI filenames <th> Results
+  /// <tr><td> file:data.db <td>
+  /// Open the file "data.db" in the current directory.
+  /// <tr><td> file:/home/fred/data.db<br>
+  /// file:///home/fred/data.db <br>
+  /// file://localhost/home/fred/data.db <br> <td>
+  /// Open the database file "/home/fred/data.db".
+  /// <tr><td> file://darkstar/home/fred/data.db <td>
+  /// An error. "darkstar" is not a recognized authority.
+  /// <tr><td style="white-space:nowrap">
+  /// file:///C:/Documents%20and%20Settings/fred/Desktop/data.db
+  /// <td> Windows only: Open the file "data.db" on fred's desktop on drive
+  /// C:. Note that the %20 escaping in this example is not strictly
+  /// necessary - space characters can be used literally
+  /// in URI filenames.
+  /// <tr><td> file:data.db?mode=ro&cache=private <td>
+  /// Open file "data.db" in the current directory for read-only access.
+  /// Regardless of whether or not shared-cache mode is enabled by
+  /// default, use a private cache.
+  /// <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td>
+  /// Open file "/home/fred/data.db". Use the special VFS "unix-dotfile"
+  /// that uses dot-files in place of posix advisory locking.
+  /// <tr><td> file:data.db?mode=readonly <td>
+  /// An error. "readonly" is not a valid option for the "mode" parameter.
+  /// </table>
+  ///
+  /// ^URI hexadecimal escape sequences (%HH) are supported within the path and
+  /// query components of a URI. A hexadecimal escape sequence consists of a
+  /// percent sign - "%" - followed by exactly two hexadecimal digits
+  /// specifying an octet value. ^Before the path or query components of a
+  /// URI filename are interpreted, they are encoded using UTF-8 and all
+  /// hexadecimal escape sequences replaced by a single byte containing the
+  /// corresponding octet. If this process generates an invalid UTF-8 encoding,
+  /// the results are undefined.
+  ///
+  /// <b>Note to Windows users:</b>  The encoding used for the filename argument
+  /// of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever
+  /// codepage is currently defined.  Filenames containing international
+  /// characters must be converted to UTF-8 prior to passing them into
+  /// sqlite3_open() or sqlite3_open_v2().
+  ///
+  /// <b>Note to Windows Runtime users:</b>  The temporary directory must be set
+  /// prior to calling sqlite3_open() or sqlite3_open_v2().  Otherwise, various
+  /// features that require the use of temporary files may fail.
+  ///
+  /// See also: [sqlite3_temp_directory]
+  int sqlite3_open(
+    ffi.Pointer<ffi.Char> filename,
+    ffi.Pointer<ffi.Pointer<sqlite3>> ppDb,
+  ) {
+    return _sqlite3_open(
+      filename,
+      ppDb,
+    );
+  }
+
+  late final _sqlite3_openPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<sqlite3>>)>>('sqlite3_open');
+  late final _sqlite3_open = _sqlite3_openPtr.asFunction<
+      int Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Pointer<sqlite3>>)>();
+
+  int sqlite3_open16(
+    ffi.Pointer<ffi.Void> filename,
+    ffi.Pointer<ffi.Pointer<sqlite3>> ppDb,
+  ) {
+    return _sqlite3_open16(
+      filename,
+      ppDb,
+    );
+  }
+
+  late final _sqlite3_open16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Pointer<sqlite3>>)>>('sqlite3_open16');
+  late final _sqlite3_open16 = _sqlite3_open16Ptr.asFunction<
+      int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Pointer<sqlite3>>)>();
+
+  int sqlite3_open_v2(
+    ffi.Pointer<ffi.Char> filename,
+    ffi.Pointer<ffi.Pointer<sqlite3>> ppDb,
+    int flags,
+    ffi.Pointer<ffi.Char> zVfs,
+  ) {
+    return _sqlite3_open_v2(
+      filename,
+      ppDb,
+      flags,
+      zVfs,
+    );
+  }
+
+  late final _sqlite3_open_v2Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<sqlite3>>,
+              ffi.Int,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_open_v2');
+  late final _sqlite3_open_v2 = _sqlite3_open_v2Ptr.asFunction<
+      int Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Pointer<sqlite3>>,
+          int, ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: Obtain Values For URI Parameters
+  ///
+  /// These are utility routines, useful to [VFS|custom VFS implementations],
+  /// that check if a database file was a URI that contained a specific query
+  /// parameter, and if so obtains the value of that query parameter.
+  ///
+  /// The first parameter to these interfaces (hereafter referred to
+  /// as F) must be one of:
+  /// <ul>
+  /// <li> A database filename pointer created by the SQLite core and
+  /// passed into the xOpen() method of a VFS implemention, or
+  /// <li> A filename obtained from [sqlite3_db_filename()], or
+  /// <li> A new filename constructed using [sqlite3_create_filename()].
+  /// </ul>
+  /// If the F parameter is not one of the above, then the behavior is
+  /// undefined and probably undesirable.  Older versions of SQLite were
+  /// more tolerant of invalid F parameters than newer versions.
+  ///
+  /// If F is a suitable filename (as described in the previous paragraph)
+  /// and if P is the name of the query parameter, then
+  /// sqlite3_uri_parameter(F,P) returns the value of the P
+  /// parameter if it exists or a NULL pointer if P does not appear as a
+  /// query parameter on F.  If P is a query parameter of F and it
+  /// has no explicit value, then sqlite3_uri_parameter(F,P) returns
+  /// a pointer to an empty string.
+  ///
+  /// The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean
+  /// parameter and returns true (1) or false (0) according to the value
+  /// of P.  The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the
+  /// value of query parameter P is one of "yes", "true", or "on" in any
+  /// case or if the value begins with a non-zero number.  The
+  /// sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of
+  /// query parameter P is one of "no", "false", or "off" in any case or
+  /// if the value begins with a numeric zero.  If P is not a query
+  /// parameter on F or if the value of P does not match any of the
+  /// above, then sqlite3_uri_boolean(F,P,B) returns (B!=0).
+  ///
+  /// The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
+  /// 64-bit signed integer and returns that integer, or D if P does not
+  /// exist.  If the value of P is something other than an integer, then
+  /// zero is returned.
+  ///
+  /// The sqlite3_uri_key(F,N) returns a pointer to the name (not
+  /// the value) of the N-th query parameter for filename F, or a NULL
+  /// pointer if N is less than zero or greater than the number of query
+  /// parameters minus 1.  The N value is zero-based so N should be 0 to obtain
+  /// the name of the first query parameter, 1 for the second parameter, and
+  /// so forth.
+  ///
+  /// If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and
+  /// sqlite3_uri_boolean(F,P,B) returns B.  If F is not a NULL pointer and
+  /// is not a database file pathname pointer that the SQLite core passed
+  /// into the xOpen VFS method, then the behavior of this routine is undefined
+  /// and probably undesirable.
+  ///
+  /// Beginning with SQLite [version 3.31.0] ([dateof:3.31.0]) the input F
+  /// parameter can also be the name of a rollback journal file or WAL file
+  /// in addition to the main database file.  Prior to version 3.31.0, these
+  /// routines would only work if F was the name of the main database file.
+  /// When the F parameter is the name of the rollback journal or WAL file,
+  /// it has access to all the same query parameters as were found on the
+  /// main database file.
+  ///
+  /// See the [URI filename] documentation for additional information.
+  ffi.Pointer<ffi.Char> sqlite3_uri_parameter(
+    ffi.Pointer<ffi.Char> zFilename,
+    ffi.Pointer<ffi.Char> zParam,
+  ) {
+    return _sqlite3_uri_parameter(
+      zFilename,
+      zParam,
+    );
+  }
+
+  late final _sqlite3_uri_parameterPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_uri_parameter');
+  late final _sqlite3_uri_parameter = _sqlite3_uri_parameterPtr.asFunction<
+      ffi.Pointer<ffi.Char> Function(
+          ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
+
+  int sqlite3_uri_boolean(
+    ffi.Pointer<ffi.Char> zFile,
+    ffi.Pointer<ffi.Char> zParam,
+    int bDefault,
+  ) {
+    return _sqlite3_uri_boolean(
+      zFile,
+      zParam,
+      bDefault,
+    );
+  }
+
+  late final _sqlite3_uri_booleanPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>,
+              ffi.Int)>>('sqlite3_uri_boolean');
+  late final _sqlite3_uri_boolean = _sqlite3_uri_booleanPtr.asFunction<
+      int Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>, int)>();
+
+  int sqlite3_uri_int64(
+    ffi.Pointer<ffi.Char> arg0,
+    ffi.Pointer<ffi.Char> arg1,
+    int arg2,
+  ) {
+    return _sqlite3_uri_int64(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_uri_int64Ptr = _lookup<
+      ffi.NativeFunction<
+          sqlite3_int64 Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>,
+              sqlite3_int64)>>('sqlite3_uri_int64');
+  late final _sqlite3_uri_int64 = _sqlite3_uri_int64Ptr.asFunction<
+      int Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>, int)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_uri_key(
+    ffi.Pointer<ffi.Char> zFilename,
+    int N,
+  ) {
+    return _sqlite3_uri_key(
+      zFilename,
+      N,
+    );
+  }
+
+  late final _sqlite3_uri_keyPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<ffi.Char>, ffi.Int)>>('sqlite3_uri_key');
+  late final _sqlite3_uri_key = _sqlite3_uri_keyPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>, int)>();
+
+  /// CAPI3REF:  Translate filenames
+  ///
+  /// These routines are available to [VFS|custom VFS implementations] for
+  /// translating filenames between the main database file, the journal file,
+  /// and the WAL file.
+  ///
+  /// If F is the name of an sqlite database file, journal file, or WAL file
+  /// passed by the SQLite core into the VFS, then sqlite3_filename_database(F)
+  /// returns the name of the corresponding database file.
+  ///
+  /// If F is the name of an sqlite database file, journal file, or WAL file
+  /// passed by the SQLite core into the VFS, or if F is a database filename
+  /// obtained from [sqlite3_db_filename()], then sqlite3_filename_journal(F)
+  /// returns the name of the corresponding rollback journal file.
+  ///
+  /// If F is the name of an sqlite database file, journal file, or WAL file
+  /// that was passed by the SQLite core into the VFS, or if F is a database
+  /// filename obtained from [sqlite3_db_filename()], then
+  /// sqlite3_filename_wal(F) returns the name of the corresponding
+  /// WAL file.
+  ///
+  /// In all of the above, if F is not the name of a database, journal or WAL
+  /// filename passed into the VFS from the SQLite core and F is not the
+  /// return value from [sqlite3_db_filename()], then the result is
+  /// undefined and is likely a memory access violation.
+  ffi.Pointer<ffi.Char> sqlite3_filename_database(
+    ffi.Pointer<ffi.Char> arg0,
+  ) {
+    return _sqlite3_filename_database(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_filename_databasePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<ffi.Char>)>>('sqlite3_filename_database');
+  late final _sqlite3_filename_database = _sqlite3_filename_databasePtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_filename_journal(
+    ffi.Pointer<ffi.Char> arg0,
+  ) {
+    return _sqlite3_filename_journal(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_filename_journalPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<ffi.Char>)>>('sqlite3_filename_journal');
+  late final _sqlite3_filename_journal = _sqlite3_filename_journalPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_filename_wal(
+    ffi.Pointer<ffi.Char> arg0,
+  ) {
+    return _sqlite3_filename_wal(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_filename_walPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<ffi.Char>)>>('sqlite3_filename_wal');
+  late final _sqlite3_filename_wal = _sqlite3_filename_walPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF:  Database File Corresponding To A Journal
+  ///
+  /// ^If X is the name of a rollback or WAL-mode journal file that is
+  /// passed into the xOpen method of [sqlite3_vfs], then
+  /// sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
+  /// object that represents the main database file.
+  ///
+  /// This routine is intended for use in custom [VFS] implementations
+  /// only.  It is not a general-purpose interface.
+  /// The argument sqlite3_file_object(X) must be a filename pointer that
+  /// has been passed into [sqlite3_vfs].xOpen method where the
+  /// flags parameter to xOpen contains one of the bits
+  /// [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL].  Any other use
+  /// of this routine results in undefined and probably undesirable
+  /// behavior.
+  ffi.Pointer<sqlite3_file> sqlite3_database_file_object(
+    ffi.Pointer<ffi.Char> arg0,
+  ) {
+    return _sqlite3_database_file_object(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_database_file_objectPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3_file> Function(
+              ffi.Pointer<ffi.Char>)>>('sqlite3_database_file_object');
+  late final _sqlite3_database_file_object = _sqlite3_database_file_objectPtr
+      .asFunction<ffi.Pointer<sqlite3_file> Function(ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: Create and Destroy VFS Filenames
+  ///
+  /// These interfces are provided for use by [VFS shim] implementations and
+  /// are not useful outside of that context.
+  ///
+  /// The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of
+  /// database filename D with corresponding journal file J and WAL file W and
+  /// with N URI parameters key/values pairs in the array P.  The result from
+  /// sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that
+  /// is safe to pass to routines like:
+  /// <ul>
+  /// <li> [sqlite3_uri_parameter()],
+  /// <li> [sqlite3_uri_boolean()],
+  /// <li> [sqlite3_uri_int64()],
+  /// <li> [sqlite3_uri_key()],
+  /// <li> [sqlite3_filename_database()],
+  /// <li> [sqlite3_filename_journal()], or
+  /// <li> [sqlite3_filename_wal()].
+  /// </ul>
+  /// If a memory allocation error occurs, sqlite3_create_filename() might
+  /// return a NULL pointer.  The memory obtained from sqlite3_create_filename(X)
+  /// must be released by a corresponding call to sqlite3_free_filename(Y).
+  ///
+  /// The P parameter in sqlite3_create_filename(D,J,W,N,P) should be an array
+  /// of 2*N pointers to strings.  Each pair of pointers in this array corresponds
+  /// to a key and value for a query parameter.  The P parameter may be a NULL
+  /// pointer if N is zero.  None of the 2*N pointers in the P array may be
+  /// NULL pointers and key pointers should not be empty strings.
+  /// None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
+  /// be NULL pointers, though they can be empty strings.
+  ///
+  /// The sqlite3_free_filename(Y) routine releases a memory allocation
+  /// previously obtained from sqlite3_create_filename().  Invoking
+  /// sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
+  ///
+  /// If the Y parameter to sqlite3_free_filename(Y) is anything other
+  /// than a NULL pointer or a pointer previously acquired from
+  /// sqlite3_create_filename(), then bad things such as heap
+  /// corruption or segfaults may occur. The value Y should be
+  /// used again after sqlite3_free_filename(Y) has been called.  This means
+  /// that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y,
+  /// then the corresponding [sqlite3_module.xClose() method should also be
+  /// invoked prior to calling sqlite3_free_filename(Y).
+  ffi.Pointer<ffi.Char> sqlite3_create_filename(
+    ffi.Pointer<ffi.Char> zDatabase,
+    ffi.Pointer<ffi.Char> zJournal,
+    ffi.Pointer<ffi.Char> zWal,
+    int nParam,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> azParam,
+  ) {
+    return _sqlite3_create_filename(
+      zDatabase,
+      zJournal,
+      zWal,
+      nParam,
+      azParam,
+    );
+  }
+
+  late final _sqlite3_create_filenamePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>)>>('sqlite3_create_filename');
+  late final _sqlite3_create_filename = _sqlite3_create_filenamePtr.asFunction<
+      ffi.Pointer<ffi.Char> Function(
+          ffi.Pointer<ffi.Char>,
+          ffi.Pointer<ffi.Char>,
+          ffi.Pointer<ffi.Char>,
+          int,
+          ffi.Pointer<ffi.Pointer<ffi.Char>>)>();
+
+  void sqlite3_free_filename(
+    ffi.Pointer<ffi.Char> arg0,
+  ) {
+    return _sqlite3_free_filename(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_free_filenamePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Char>)>>(
+          'sqlite3_free_filename');
+  late final _sqlite3_free_filename = _sqlite3_free_filenamePtr
+      .asFunction<void Function(ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: Error Codes And Messages
+  /// METHOD: sqlite3
+  ///
+  /// ^If the most recent sqlite3_* API call associated with
+  /// [database connection] D failed, then the sqlite3_errcode(D) interface
+  /// returns the numeric [result code] or [extended result code] for that
+  /// API call.
+  /// ^The sqlite3_extended_errcode()
+  /// interface is the same except that it always returns the
+  /// [extended result code] even when extended result codes are
+  /// disabled.
+  ///
+  /// The values returned by sqlite3_errcode() and/or
+  /// sqlite3_extended_errcode() might change with each API call.
+  /// Except, there are some interfaces that are guaranteed to never
+  /// change the value of the error code.  The error-code preserving
+  /// interfaces are:
+  ///
+  /// <ul>
+  /// <li> sqlite3_errcode()
+  /// <li> sqlite3_extended_errcode()
+  /// <li> sqlite3_errmsg()
+  /// <li> sqlite3_errmsg16()
+  /// </ul>
+  ///
+  /// ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
+  /// text that describes the error, as either UTF-8 or UTF-16 respectively.
+  /// ^(Memory to hold the error message string is managed internally.
+  /// The application does not need to worry about freeing the result.
+  /// However, the error string might be overwritten or deallocated by
+  /// subsequent calls to other SQLite interface functions.)^
+  ///
+  /// ^The sqlite3_errstr() interface returns the English-language text
+  /// that describes the [result code], as UTF-8.
+  /// ^(Memory to hold the error message string is managed internally
+  /// and must not be freed by the application)^.
+  ///
+  /// When the serialized [threading mode] is in use, it might be the
+  /// case that a second error occurs on a separate thread in between
+  /// the time of the first error and the call to these interfaces.
+  /// When that happens, the second error will be reported since these
+  /// interfaces always report the most recent result.  To avoid
+  /// this, each thread can obtain exclusive use of the [database connection] D
+  /// by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning
+  /// to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
+  /// all calls to the interfaces listed here are completed.
+  ///
+  /// If an interface fails with SQLITE_MISUSE, that means the interface
+  /// was invoked incorrectly by the application.  In that case, the
+  /// error code and message may or may not be set.
+  int sqlite3_errcode(
+    ffi.Pointer<sqlite3> db,
+  ) {
+    return _sqlite3_errcode(
+      db,
+    );
+  }
+
+  late final _sqlite3_errcodePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_errcode');
+  late final _sqlite3_errcode =
+      _sqlite3_errcodePtr.asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  int sqlite3_extended_errcode(
+    ffi.Pointer<sqlite3> db,
+  ) {
+    return _sqlite3_extended_errcode(
+      db,
+    );
+  }
+
+  late final _sqlite3_extended_errcodePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_extended_errcode');
+  late final _sqlite3_extended_errcode = _sqlite3_extended_errcodePtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_errmsg(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_errmsg(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_errmsgPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<sqlite3>)>>('sqlite3_errmsg');
+  late final _sqlite3_errmsg = _sqlite3_errmsgPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3>)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_errmsg16(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_errmsg16(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_errmsg16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3>)>>('sqlite3_errmsg16');
+  late final _sqlite3_errmsg16 = _sqlite3_errmsg16Ptr
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3>)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_errstr(
+    int arg0,
+  ) {
+    return _sqlite3_errstr(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_errstrPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Int)>>(
+          'sqlite3_errstr');
+  late final _sqlite3_errstr =
+      _sqlite3_errstrPtr.asFunction<ffi.Pointer<ffi.Char> Function(int)>();
+
+  /// CAPI3REF: Run-time Limits
+  /// METHOD: sqlite3
+  ///
+  /// ^(This interface allows the size of various constructs to be limited
+  /// on a connection by connection basis.  The first parameter is the
+  /// [database connection] whose limit is to be set or queried.  The
+  /// second parameter is one of the [limit categories] that define a
+  /// class of constructs to be size limited.  The third parameter is the
+  /// new limit for that construct.)^
+  ///
+  /// ^If the new limit is a negative number, the limit is unchanged.
+  /// ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a
+  /// [limits | hard upper bound]
+  /// set at compile-time by a C preprocessor macro called
+  /// [limits | SQLITE_MAX_<i>NAME</i>].
+  /// (The "_LIMIT_" in the name is changed to "_MAX_".))^
+  /// ^Attempts to increase a limit above its hard upper bound are
+  /// silently truncated to the hard upper bound.
+  ///
+  /// ^Regardless of whether or not the limit was changed, the
+  /// [sqlite3_limit()] interface returns the prior value of the limit.
+  /// ^Hence, to find the current value of a limit without changing it,
+  /// simply invoke this interface with the third parameter set to -1.
+  ///
+  /// Run-time limits are intended for use in applications that manage
+  /// both their own internal database and also databases that are controlled
+  /// by untrusted external sources.  An example application might be a
+  /// web browser that has its own databases for storing history and
+  /// separate databases controlled by JavaScript applications downloaded
+  /// off the Internet.  The internal databases can be given the
+  /// large, default limits.  Databases managed by external sources can
+  /// be given much smaller limits designed to prevent a denial of service
+  /// attack.  Developers might also want to use the [sqlite3_set_authorizer()]
+  /// interface to further control untrusted SQL.  The size of the database
+  /// created by an untrusted script can be contained using the
+  /// [max_page_count] [PRAGMA].
+  ///
+  /// New run-time limit categories may be added in future releases.
+  int sqlite3_limit(
+    ffi.Pointer<sqlite3> arg0,
+    int id,
+    int newVal,
+  ) {
+    return _sqlite3_limit(
+      arg0,
+      id,
+      newVal,
+    );
+  }
+
+  late final _sqlite3_limitPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>, ffi.Int, ffi.Int)>>('sqlite3_limit');
+  late final _sqlite3_limit = _sqlite3_limitPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>, int, int)>();
+
+  /// CAPI3REF: Compiling An SQL Statement
+  /// KEYWORDS: {SQL statement compiler}
+  /// METHOD: sqlite3
+  /// CONSTRUCTOR: sqlite3_stmt
+  ///
+  /// To execute an SQL statement, it must first be compiled into a byte-code
+  /// program using one of these routines.  Or, in other words, these routines
+  /// are constructors for the [prepared statement] object.
+  ///
+  /// The preferred routine to use is [sqlite3_prepare_v2()].  The
+  /// [sqlite3_prepare()] interface is legacy and should be avoided.
+  /// [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used
+  /// for special purposes.
+  ///
+  /// The use of the UTF-8 interfaces is preferred, as SQLite currently
+  /// does all parsing using UTF-8.  The UTF-16 interfaces are provided
+  /// as a convenience.  The UTF-16 interfaces work by converting the
+  /// input text into UTF-8, then invoking the corresponding UTF-8 interface.
+  ///
+  /// The first argument, "db", is a [database connection] obtained from a
+  /// prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
+  /// [sqlite3_open16()].  The database connection must not have been closed.
+  ///
+  /// The second argument, "zSql", is the statement to be compiled, encoded
+  /// as either UTF-8 or UTF-16.  The sqlite3_prepare(), sqlite3_prepare_v2(),
+  /// and sqlite3_prepare_v3()
+  /// interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(),
+  /// and sqlite3_prepare16_v3() use UTF-16.
+  ///
+  /// ^If the nByte argument is negative, then zSql is read up to the
+  /// first zero terminator. ^If nByte is positive, then it is the
+  /// number of bytes read from zSql.  ^If nByte is zero, then no prepared
+  /// statement is generated.
+  /// If the caller knows that the supplied string is nul-terminated, then
+  /// there is a small performance advantage to passing an nByte parameter that
+  /// is the number of bytes in the input string <i>including</i>
+  /// the nul-terminator.
+  ///
+  /// ^If pzTail is not NULL then *pzTail is made to point to the first byte
+  /// past the end of the first SQL statement in zSql.  These routines only
+  /// compile the first statement in zSql, so *pzTail is left pointing to
+  /// what remains uncompiled.
+  ///
+  /// ^*ppStmt is left pointing to a compiled [prepared statement] that can be
+  /// executed using [sqlite3_step()].  ^If there is an error, *ppStmt is set
+  /// to NULL.  ^If the input text contains no SQL (if the input is an empty
+  /// string or a comment) then *ppStmt is set to NULL.
+  /// The calling procedure is responsible for deleting the compiled
+  /// SQL statement using [sqlite3_finalize()] after it has finished with it.
+  /// ppStmt may not be NULL.
+  ///
+  /// ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK];
+  /// otherwise an [error code] is returned.
+  ///
+  /// The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(),
+  /// and sqlite3_prepare16_v3() interfaces are recommended for all new programs.
+  /// The older interfaces (sqlite3_prepare() and sqlite3_prepare16())
+  /// are retained for backwards compatibility, but their use is discouraged.
+  /// ^In the "vX" interfaces, the prepared statement
+  /// that is returned (the [sqlite3_stmt] object) contains a copy of the
+  /// original SQL text. This causes the [sqlite3_step()] interface to
+  /// behave differently in three ways:
+  ///
+  /// <ol>
+  /// <li>
+  /// ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it
+  /// always used to do, [sqlite3_step()] will automatically recompile the SQL
+  /// statement and try to run it again. As many as [SQLITE_MAX_SCHEMA_RETRY]
+  /// retries will occur before sqlite3_step() gives up and returns an error.
+  /// </li>
+  ///
+  /// <li>
+  /// ^When an error occurs, [sqlite3_step()] will return one of the detailed
+  /// [error codes] or [extended error codes].  ^The legacy behavior was that
+  /// [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
+  /// and the application would have to make a second call to [sqlite3_reset()]
+  /// in order to find the underlying cause of the problem. With the "v2" prepare
+  /// interfaces, the underlying reason for the error is returned immediately.
+  /// </li>
+  ///
+  /// <li>
+  /// ^If the specific value bound to a [parameter | host parameter] in the
+  /// WHERE clause might influence the choice of query plan for a statement,
+  /// then the statement will be automatically recompiled, as if there had been
+  /// a schema change, on the first [sqlite3_step()] call following any change
+  /// to the [sqlite3_bind_text | bindings] of that [parameter].
+  /// ^The specific value of a WHERE-clause [parameter] might influence the
+  /// choice of query plan if the parameter is the left-hand side of a [LIKE]
+  /// or [GLOB] operator or if the parameter is compared to an indexed column
+  /// and the [SQLITE_ENABLE_STAT4] compile-time option is enabled.
+  /// </li>
+  /// </ol>
+  ///
+  /// <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
+  /// the extra prepFlags parameter, which is a bit array consisting of zero or
+  /// more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags.  ^The
+  /// sqlite3_prepare_v2() interface works exactly the same as
+  /// sqlite3_prepare_v3() with a zero prepFlags parameter.
+  int sqlite3_prepare(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zSql,
+    int nByte,
+    ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> pzTail,
+  ) {
+    return _sqlite3_prepare(
+      db,
+      zSql,
+      nByte,
+      ppStmt,
+      pzTail,
+    );
+  }
+
+  late final _sqlite3_preparePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>)>>('sqlite3_prepare');
+  late final _sqlite3_prepare = _sqlite3_preparePtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Char>,
+          int,
+          ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+          ffi.Pointer<ffi.Pointer<ffi.Char>>)>();
+
+  int sqlite3_prepare_v2(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zSql,
+    int nByte,
+    ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> pzTail,
+  ) {
+    return _sqlite3_prepare_v2(
+      db,
+      zSql,
+      nByte,
+      ppStmt,
+      pzTail,
+    );
+  }
+
+  late final _sqlite3_prepare_v2Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>)>>('sqlite3_prepare_v2');
+  late final _sqlite3_prepare_v2 = _sqlite3_prepare_v2Ptr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Char>,
+          int,
+          ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+          ffi.Pointer<ffi.Pointer<ffi.Char>>)>();
+
+  int sqlite3_prepare_v3(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zSql,
+    int nByte,
+    int prepFlags,
+    ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> pzTail,
+  ) {
+    return _sqlite3_prepare_v3(
+      db,
+      zSql,
+      nByte,
+      prepFlags,
+      ppStmt,
+      pzTail,
+    );
+  }
+
+  late final _sqlite3_prepare_v3Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Int,
+              ffi.UnsignedInt,
+              ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>)>>('sqlite3_prepare_v3');
+  late final _sqlite3_prepare_v3 = _sqlite3_prepare_v3Ptr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Char>,
+          int,
+          int,
+          ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+          ffi.Pointer<ffi.Pointer<ffi.Char>>)>();
+
+  int sqlite3_prepare16(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Void> zSql,
+    int nByte,
+    ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
+    ffi.Pointer<ffi.Pointer<ffi.Void>> pzTail,
+  ) {
+    return _sqlite3_prepare16(
+      db,
+      zSql,
+      nByte,
+      ppStmt,
+      pzTail,
+    );
+  }
+
+  late final _sqlite3_prepare16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+              ffi.Pointer<ffi.Pointer<ffi.Void>>)>>('sqlite3_prepare16');
+  late final _sqlite3_prepare16 = _sqlite3_prepare16Ptr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Void>,
+          int,
+          ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+          ffi.Pointer<ffi.Pointer<ffi.Void>>)>();
+
+  int sqlite3_prepare16_v2(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Void> zSql,
+    int nByte,
+    ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
+    ffi.Pointer<ffi.Pointer<ffi.Void>> pzTail,
+  ) {
+    return _sqlite3_prepare16_v2(
+      db,
+      zSql,
+      nByte,
+      ppStmt,
+      pzTail,
+    );
+  }
+
+  late final _sqlite3_prepare16_v2Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+              ffi.Pointer<ffi.Pointer<ffi.Void>>)>>('sqlite3_prepare16_v2');
+  late final _sqlite3_prepare16_v2 = _sqlite3_prepare16_v2Ptr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Void>,
+          int,
+          ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+          ffi.Pointer<ffi.Pointer<ffi.Void>>)>();
+
+  int sqlite3_prepare16_v3(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Void> zSql,
+    int nByte,
+    int prepFlags,
+    ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
+    ffi.Pointer<ffi.Pointer<ffi.Void>> pzTail,
+  ) {
+    return _sqlite3_prepare16_v3(
+      db,
+      zSql,
+      nByte,
+      prepFlags,
+      ppStmt,
+      pzTail,
+    );
+  }
+
+  late final _sqlite3_prepare16_v3Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Int,
+              ffi.UnsignedInt,
+              ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+              ffi.Pointer<ffi.Pointer<ffi.Void>>)>>('sqlite3_prepare16_v3');
+  late final _sqlite3_prepare16_v3 = _sqlite3_prepare16_v3Ptr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Void>,
+          int,
+          int,
+          ffi.Pointer<ffi.Pointer<sqlite3_stmt>>,
+          ffi.Pointer<ffi.Pointer<ffi.Void>>)>();
+
+  /// CAPI3REF: Retrieving Statement SQL
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8
+  /// SQL text used to create [prepared statement] P if P was
+  /// created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
+  /// [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
+  /// ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
+  /// string containing the SQL text of prepared statement P with
+  /// [bound parameters] expanded.
+  /// ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
+  /// string containing the normalized SQL text of prepared statement P.  The
+  /// semantics used to normalize a SQL statement are unspecified and subject
+  /// to change.  At a minimum, literal values will be replaced with suitable
+  /// placeholders.
+  ///
+  /// ^(For example, if a prepared statement is created using the SQL
+  /// text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
+  /// and parameter :xyz is unbound, then sqlite3_sql() will return
+  /// the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
+  /// will return "SELECT 2345,NULL".)^
+  ///
+  /// ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory
+  /// is available to hold the result, or if the result would exceed the
+  /// the maximum string length determined by the [SQLITE_LIMIT_LENGTH].
+  ///
+  /// ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
+  /// bound parameter expansions.  ^The [SQLITE_OMIT_TRACE] compile-time
+  /// option causes sqlite3_expanded_sql() to always return NULL.
+  ///
+  /// ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
+  /// are managed by SQLite and are automatically freed when the prepared
+  /// statement is finalized.
+  /// ^The string returned by sqlite3_expanded_sql(P), on the other hand,
+  /// is obtained from [sqlite3_malloc()] and must be free by the application
+  /// by passing it to [sqlite3_free()].
+  ffi.Pointer<ffi.Char> sqlite3_sql(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    return _sqlite3_sql(
+      pStmt,
+    );
+  }
+
+  late final _sqlite3_sqlPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<sqlite3_stmt>)>>('sqlite3_sql');
+  late final _sqlite3_sql = _sqlite3_sqlPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_expanded_sql(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    return _sqlite3_expanded_sql(
+      pStmt,
+    );
+  }
+
+  late final _sqlite3_expanded_sqlPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<sqlite3_stmt>)>>('sqlite3_expanded_sql');
+  late final _sqlite3_expanded_sql = _sqlite3_expanded_sqlPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_normalized_sql(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    return _sqlite3_normalized_sql(
+      pStmt,
+    );
+  }
+
+  late final _sqlite3_normalized_sqlPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<sqlite3_stmt>)>>('sqlite3_normalized_sql');
+  late final _sqlite3_normalized_sql = _sqlite3_normalized_sqlPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Determine If An SQL Statement Writes The Database
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
+  /// and only if the [prepared statement] X makes no direct changes to
+  /// the content of the database file.
+  ///
+  /// Note that [application-defined SQL functions] or
+  /// [virtual tables] might change the database indirectly as a side effect.
+  /// ^(For example, if an application defines a function "eval()" that
+  /// calls [sqlite3_exec()], then the following SQL statement would
+  /// change the database file through side-effects:
+  ///
+  /// <blockquote><pre>
+  /// SELECT eval('DELETE FROM t1') FROM t2;
+  /// </pre></blockquote>
+  ///
+  /// But because the [SELECT] statement does not change the database file
+  /// directly, sqlite3_stmt_readonly() would still return true.)^
+  ///
+  /// ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK],
+  /// [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true,
+  /// since the statements themselves do not actually modify the database but
+  /// rather they control the timing of when other statements modify the
+  /// database.  ^The [ATTACH] and [DETACH] statements also cause
+  /// sqlite3_stmt_readonly() to return true since, while those statements
+  /// change the configuration of a database connection, they do not make
+  /// changes to the content of the database files on disk.
+  /// ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since
+  /// [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
+  /// [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
+  /// sqlite3_stmt_readonly() returns false for those commands.
+  int sqlite3_stmt_readonly(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    return _sqlite3_stmt_readonly(
+      pStmt,
+    );
+  }
+
+  late final _sqlite3_stmt_readonlyPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_stmt_readonly');
+  late final _sqlite3_stmt_readonly = _sqlite3_stmt_readonlyPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^The sqlite3_stmt_isexplain(S) interface returns 1 if the
+  /// prepared statement S is an EXPLAIN statement, or 2 if the
+  /// statement S is an EXPLAIN QUERY PLAN.
+  /// ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is
+  /// an ordinary statement or a NULL pointer.
+  int sqlite3_stmt_isexplain(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    return _sqlite3_stmt_isexplain(
+      pStmt,
+    );
+  }
+
+  late final _sqlite3_stmt_isexplainPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_stmt_isexplain');
+  late final _sqlite3_stmt_isexplain = _sqlite3_stmt_isexplainPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Determine If A Prepared Statement Has Been Reset
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
+  /// [prepared statement] S has been stepped at least once using
+  /// [sqlite3_step(S)] but has neither run to completion (returned
+  /// [SQLITE_DONE] from [sqlite3_step(S)]) nor
+  /// been reset using [sqlite3_reset(S)].  ^The sqlite3_stmt_busy(S)
+  /// interface returns false if S is a NULL pointer.  If S is not a
+  /// NULL pointer and is not a pointer to a valid [prepared statement]
+  /// object, then the behavior is undefined and probably undesirable.
+  ///
+  /// This interface can be used in combination [sqlite3_next_stmt()]
+  /// to locate all prepared statements associated with a database
+  /// connection that are in need of being reset.  This can be used,
+  /// for example, in diagnostic routines to search for prepared
+  /// statements that are holding a transaction open.
+  int sqlite3_stmt_busy(
+    ffi.Pointer<sqlite3_stmt> arg0,
+  ) {
+    return _sqlite3_stmt_busy(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_stmt_busyPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_stmt_busy');
+  late final _sqlite3_stmt_busy = _sqlite3_stmt_busyPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Binding Values To Prepared Statements
+  /// KEYWORDS: {host parameter} {host parameters} {host parameter name}
+  /// KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
+  /// literals may be replaced by a [parameter] that matches one of following
+  /// templates:
+  ///
+  /// <ul>
+  /// <li>  ?
+  /// <li>  ?NNN
+  /// <li>  :VVV
+  /// <li>  @VVV
+  /// <li>  $VVV
+  /// </ul>
+  ///
+  /// In the templates above, NNN represents an integer literal,
+  /// and VVV represents an alphanumeric identifier.)^  ^The values of these
+  /// parameters (also called "host parameter names" or "SQL parameters")
+  /// can be set using the sqlite3_bind_*() routines defined here.
+  ///
+  /// ^The first argument to the sqlite3_bind_*() routines is always
+  /// a pointer to the [sqlite3_stmt] object returned from
+  /// [sqlite3_prepare_v2()] or its variants.
+  ///
+  /// ^The second argument is the index of the SQL parameter to be set.
+  /// ^The leftmost SQL parameter has an index of 1.  ^When the same named
+  /// SQL parameter is used more than once, second and subsequent
+  /// occurrences have the same index as the first occurrence.
+  /// ^The index for named parameters can be looked up using the
+  /// [sqlite3_bind_parameter_index()] API if desired.  ^The index
+  /// for "?NNN" parameters is the value of NNN.
+  /// ^The NNN value must be between 1 and the [sqlite3_limit()]
+  /// parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 32766).
+  ///
+  /// ^The third argument is the value to bind to the parameter.
+  /// ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
+  /// or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
+  /// is ignored and the end result is the same as sqlite3_bind_null().
+  /// ^If the third parameter to sqlite3_bind_text() is not NULL, then
+  /// it should be a pointer to well-formed UTF8 text.
+  /// ^If the third parameter to sqlite3_bind_text16() is not NULL, then
+  /// it should be a pointer to well-formed UTF16 text.
+  /// ^If the third parameter to sqlite3_bind_text64() is not NULL, then
+  /// it should be a pointer to a well-formed unicode string that is
+  /// either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
+  /// otherwise.
+  ///
+  /// [[byte-order determination rules]] ^The byte-order of
+  /// UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
+  /// found in first character, which is removed, or in the absence of a BOM
+  /// the byte order is the native byte order of the host
+  /// machine for sqlite3_bind_text16() or the byte order specified in
+  /// the 6th parameter for sqlite3_bind_text64().)^
+  /// ^If UTF16 input text contains invalid unicode
+  /// characters, then SQLite might change those invalid characters
+  /// into the unicode replacement character: U+FFFD.
+  ///
+  /// ^(In those routines that have a fourth argument, its value is the
+  /// number of bytes in the parameter.  To be clear: the value is the
+  /// number of <u>bytes</u> in the value, not the number of characters.)^
+  /// ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16()
+  /// is negative, then the length of the string is
+  /// the number of bytes up to the first zero terminator.
+  /// If the fourth parameter to sqlite3_bind_blob() is negative, then
+  /// the behavior is undefined.
+  /// If a non-negative fourth parameter is provided to sqlite3_bind_text()
+  /// or sqlite3_bind_text16() or sqlite3_bind_text64() then
+  /// that parameter must be the byte offset
+  /// where the NUL terminator would occur assuming the string were NUL
+  /// terminated.  If any NUL characters occurs at byte offsets less than
+  /// the value of the fourth parameter then the resulting string value will
+  /// contain embedded NULs.  The result of expressions involving strings
+  /// with embedded NULs is undefined.
+  ///
+  /// ^The fifth argument to the BLOB and string binding interfaces
+  /// is a destructor used to dispose of the BLOB or
+  /// string after SQLite has finished with it.  ^The destructor is called
+  /// to dispose of the BLOB or string even if the call to the bind API fails,
+  /// except the destructor is not called if the third parameter is a NULL
+  /// pointer or the fourth parameter is negative.
+  /// ^If the fifth argument is
+  /// the special value [SQLITE_STATIC], then SQLite assumes that the
+  /// information is in static, unmanaged space and does not need to be freed.
+  /// ^If the fifth argument has the value [SQLITE_TRANSIENT], then
+  /// SQLite makes its own private copy of the data immediately, before
+  /// the sqlite3_bind_*() routine returns.
+  ///
+  /// ^The sixth argument to sqlite3_bind_text64() must be one of
+  /// [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
+  /// to specify the encoding of the text in the third parameter.  If
+  /// the sixth argument to sqlite3_bind_text64() is not one of the
+  /// allowed values shown above, or if the text encoding is different
+  /// from the encoding specified by the sixth parameter, then the behavior
+  /// is undefined.
+  ///
+  /// ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
+  /// is filled with zeroes.  ^A zeroblob uses a fixed amount of memory
+  /// (just an integer to hold its size) while it is being processed.
+  /// Zeroblobs are intended to serve as placeholders for BLOBs whose
+  /// content is later written using
+  /// [sqlite3_blob_open | incremental BLOB I/O] routines.
+  /// ^A negative value for the zeroblob results in a zero-length BLOB.
+  ///
+  /// ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
+  /// [prepared statement] S to have an SQL value of NULL, but to also be
+  /// associated with the pointer P of type T.  ^D is either a NULL pointer or
+  /// a pointer to a destructor function for P. ^SQLite will invoke the
+  /// destructor D with a single argument of P when it is finished using
+  /// P.  The T parameter should be a static string, preferably a string
+  /// literal. The sqlite3_bind_pointer() routine is part of the
+  /// [pointer passing interface] added for SQLite 3.20.0.
+  ///
+  /// ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
+  /// for the [prepared statement] or with a prepared statement for which
+  /// [sqlite3_step()] has been called more recently than [sqlite3_reset()],
+  /// then the call will return [SQLITE_MISUSE].  If any sqlite3_bind_()
+  /// routine is passed a [prepared statement] that has been finalized, the
+  /// result is undefined and probably harmful.
+  ///
+  /// ^Bindings are not cleared by the [sqlite3_reset()] routine.
+  /// ^Unbound parameters are interpreted as NULL.
+  ///
+  /// ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an
+  /// [error code] if anything goes wrong.
+  /// ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB
+  /// exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or
+  /// [SQLITE_MAX_LENGTH].
+  /// ^[SQLITE_RANGE] is returned if the parameter
+  /// index is out of range.  ^[SQLITE_NOMEM] is returned if malloc() fails.
+  ///
+  /// See also: [sqlite3_bind_parameter_count()],
+  /// [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
+  int sqlite3_bind_blob(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    ffi.Pointer<ffi.Void> arg2,
+    int n,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg4,
+  ) {
+    return _sqlite3_bind_blob(
+      arg0,
+      arg1,
+      arg2,
+      n,
+      arg4,
+    );
+  }
+
+  late final _sqlite3_bind_blobPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_stmt>,
+              ffi.Int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Int,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>)>>)>>('sqlite3_bind_blob');
+  late final _sqlite3_bind_blob = _sqlite3_bind_blobPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3_stmt>,
+          int,
+          ffi.Pointer<ffi.Void>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  int sqlite3_bind_blob64(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    ffi.Pointer<ffi.Void> arg2,
+    int arg3,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg4,
+  ) {
+    return _sqlite3_bind_blob64(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+      arg4,
+    );
+  }
+
+  late final _sqlite3_bind_blob64Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_stmt>,
+              ffi.Int,
+              ffi.Pointer<ffi.Void>,
+              sqlite3_uint64,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>)>>)>>('sqlite3_bind_blob64');
+  late final _sqlite3_bind_blob64 = _sqlite3_bind_blob64Ptr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3_stmt>,
+          int,
+          ffi.Pointer<ffi.Void>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  int sqlite3_bind_double(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    double arg2,
+  ) {
+    return _sqlite3_bind_double(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_bind_doublePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_stmt>, ffi.Int,
+              ffi.Double)>>('sqlite3_bind_double');
+  late final _sqlite3_bind_double = _sqlite3_bind_doublePtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int, double)>();
+
+  int sqlite3_bind_int(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    int arg2,
+  ) {
+    return _sqlite3_bind_int(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_bind_intPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_stmt>, ffi.Int,
+              ffi.Int)>>('sqlite3_bind_int');
+  late final _sqlite3_bind_int = _sqlite3_bind_intPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int, int)>();
+
+  int sqlite3_bind_int64(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    int arg2,
+  ) {
+    return _sqlite3_bind_int64(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_bind_int64Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_stmt>, ffi.Int,
+              sqlite3_int64)>>('sqlite3_bind_int64');
+  late final _sqlite3_bind_int64 = _sqlite3_bind_int64Ptr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int, int)>();
+
+  int sqlite3_bind_null(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_bind_null(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_bind_nullPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_bind_null');
+  late final _sqlite3_bind_null = _sqlite3_bind_nullPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  int sqlite3_bind_text(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    ffi.Pointer<ffi.Char> arg2,
+    int arg3,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg4,
+  ) {
+    return _sqlite3_bind_text(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+      arg4,
+    );
+  }
+
+  late final _sqlite3_bind_textPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_stmt>,
+              ffi.Int,
+              ffi.Pointer<ffi.Char>,
+              ffi.Int,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>)>>)>>('sqlite3_bind_text');
+  late final _sqlite3_bind_text = _sqlite3_bind_textPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3_stmt>,
+          int,
+          ffi.Pointer<ffi.Char>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  int sqlite3_bind_text16(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    ffi.Pointer<ffi.Void> arg2,
+    int arg3,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg4,
+  ) {
+    return _sqlite3_bind_text16(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+      arg4,
+    );
+  }
+
+  late final _sqlite3_bind_text16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_stmt>,
+              ffi.Int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Int,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>)>>)>>('sqlite3_bind_text16');
+  late final _sqlite3_bind_text16 = _sqlite3_bind_text16Ptr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3_stmt>,
+          int,
+          ffi.Pointer<ffi.Void>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  int sqlite3_bind_text64(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    ffi.Pointer<ffi.Char> arg2,
+    int arg3,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg4,
+    int encoding,
+  ) {
+    return _sqlite3_bind_text64(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+      arg4,
+      encoding,
+    );
+  }
+
+  late final _sqlite3_bind_text64Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_stmt>,
+              ffi.Int,
+              ffi.Pointer<ffi.Char>,
+              sqlite3_uint64,
+              ffi.Pointer<
+                  ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>,
+              ffi.UnsignedChar)>>('sqlite3_bind_text64');
+  late final _sqlite3_bind_text64 = _sqlite3_bind_text64Ptr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3_stmt>,
+          int,
+          ffi.Pointer<ffi.Char>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>,
+          int)>();
+
+  int sqlite3_bind_value(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    ffi.Pointer<sqlite3_value> arg2,
+  ) {
+    return _sqlite3_bind_value(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_bind_valuePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_stmt>, ffi.Int,
+              ffi.Pointer<sqlite3_value>)>>('sqlite3_bind_value');
+  late final _sqlite3_bind_value = _sqlite3_bind_valuePtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3_stmt>, int, ffi.Pointer<sqlite3_value>)>();
+
+  int sqlite3_bind_pointer(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    ffi.Pointer<ffi.Void> arg2,
+    ffi.Pointer<ffi.Char> arg3,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg4,
+  ) {
+    return _sqlite3_bind_pointer(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+      arg4,
+    );
+  }
+
+  late final _sqlite3_bind_pointerPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_stmt>,
+              ffi.Int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>)>>)>>('sqlite3_bind_pointer');
+  late final _sqlite3_bind_pointer = _sqlite3_bind_pointerPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3_stmt>,
+          int,
+          ffi.Pointer<ffi.Void>,
+          ffi.Pointer<ffi.Char>,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  int sqlite3_bind_zeroblob(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    int n,
+  ) {
+    return _sqlite3_bind_zeroblob(
+      arg0,
+      arg1,
+      n,
+    );
+  }
+
+  late final _sqlite3_bind_zeroblobPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_stmt>, ffi.Int,
+              ffi.Int)>>('sqlite3_bind_zeroblob');
+  late final _sqlite3_bind_zeroblob = _sqlite3_bind_zeroblobPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int, int)>();
+
+  int sqlite3_bind_zeroblob64(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+    int arg2,
+  ) {
+    return _sqlite3_bind_zeroblob64(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_bind_zeroblob64Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_stmt>, ffi.Int,
+              sqlite3_uint64)>>('sqlite3_bind_zeroblob64');
+  late final _sqlite3_bind_zeroblob64 = _sqlite3_bind_zeroblob64Ptr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int, int)>();
+
+  /// CAPI3REF: Number Of SQL Parameters
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^This routine can be used to find the number of [SQL parameters]
+  /// in a [prepared statement].  SQL parameters are tokens of the
+  /// form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
+  /// placeholders for values that are [sqlite3_bind_blob | bound]
+  /// to the parameters at a later time.
+  ///
+  /// ^(This routine actually returns the index of the largest (rightmost)
+  /// parameter. For all forms except ?NNN, this will correspond to the
+  /// number of unique parameters.  If parameters of the ?NNN form are used,
+  /// there may be gaps in the list.)^
+  ///
+  /// See also: [sqlite3_bind_blob|sqlite3_bind()],
+  /// [sqlite3_bind_parameter_name()], and
+  /// [sqlite3_bind_parameter_index()].
+  int sqlite3_bind_parameter_count(
+    ffi.Pointer<sqlite3_stmt> arg0,
+  ) {
+    return _sqlite3_bind_parameter_count(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_bind_parameter_countPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_bind_parameter_count');
+  late final _sqlite3_bind_parameter_count = _sqlite3_bind_parameter_countPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Name Of A Host Parameter
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^The sqlite3_bind_parameter_name(P,N) interface returns
+  /// the name of the N-th [SQL parameter] in the [prepared statement] P.
+  /// ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
+  /// have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
+  /// respectively.
+  /// In other words, the initial ":" or "$" or "@" or "?"
+  /// is included as part of the name.)^
+  /// ^Parameters of the form "?" without a following integer have no name
+  /// and are referred to as "nameless" or "anonymous parameters".
+  ///
+  /// ^The first host parameter has an index of 1, not 0.
+  ///
+  /// ^If the value N is out of range or if the N-th parameter is
+  /// nameless, then NULL is returned.  ^The returned string is
+  /// always in UTF-8 encoding even if the named parameter was
+  /// originally specified as UTF-16 in [sqlite3_prepare16()],
+  /// [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
+  ///
+  /// See also: [sqlite3_bind_blob|sqlite3_bind()],
+  /// [sqlite3_bind_parameter_count()], and
+  /// [sqlite3_bind_parameter_index()].
+  ffi.Pointer<ffi.Char> sqlite3_bind_parameter_name(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_bind_parameter_name(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_bind_parameter_namePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>,
+              ffi.Int)>>('sqlite3_bind_parameter_name');
+  late final _sqlite3_bind_parameter_name =
+      _sqlite3_bind_parameter_namePtr.asFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  /// CAPI3REF: Index Of A Parameter With A Given Name
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^Return the index of an SQL parameter given its name.  ^The
+  /// index value returned is suitable for use as the second
+  /// parameter to [sqlite3_bind_blob|sqlite3_bind()].  ^A zero
+  /// is returned if no matching parameter is found.  ^The parameter
+  /// name must be given in UTF-8 even if the original statement
+  /// was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or
+  /// [sqlite3_prepare16_v3()].
+  ///
+  /// See also: [sqlite3_bind_blob|sqlite3_bind()],
+  /// [sqlite3_bind_parameter_count()], and
+  /// [sqlite3_bind_parameter_name()].
+  int sqlite3_bind_parameter_index(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    ffi.Pointer<ffi.Char> zName,
+  ) {
+    return _sqlite3_bind_parameter_index(
+      arg0,
+      zName,
+    );
+  }
+
+  late final _sqlite3_bind_parameter_indexPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_stmt>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_bind_parameter_index');
+  late final _sqlite3_bind_parameter_index =
+      _sqlite3_bind_parameter_indexPtr.asFunction<
+          int Function(ffi.Pointer<sqlite3_stmt>, ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: Reset All Bindings On A Prepared Statement
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^Contrary to the intuition of many, [sqlite3_reset()] does not reset
+  /// the [sqlite3_bind_blob | bindings] on a [prepared statement].
+  /// ^Use this routine to reset all host parameters to NULL.
+  int sqlite3_clear_bindings(
+    ffi.Pointer<sqlite3_stmt> arg0,
+  ) {
+    return _sqlite3_clear_bindings(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_clear_bindingsPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_clear_bindings');
+  late final _sqlite3_clear_bindings = _sqlite3_clear_bindingsPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Number Of Columns In A Result Set
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^Return the number of columns in the result set returned by the
+  /// [prepared statement]. ^If this routine returns 0, that means the
+  /// [prepared statement] returns no data (for example an [UPDATE]).
+  /// ^However, just because this routine returns a positive number does not
+  /// mean that one or more rows of data will be returned.  ^A SELECT statement
+  /// will always have a positive sqlite3_column_count() but depending on the
+  /// WHERE clause constraints and the table content, it might return no rows.
+  ///
+  /// See also: [sqlite3_data_count()]
+  int sqlite3_column_count(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    return _sqlite3_column_count(
+      pStmt,
+    );
+  }
+
+  late final _sqlite3_column_countPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_column_count');
+  late final _sqlite3_column_count = _sqlite3_column_countPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Column Names In A Result Set
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^These routines return the name assigned to a particular column
+  /// in the result set of a [SELECT] statement.  ^The sqlite3_column_name()
+  /// interface returns a pointer to a zero-terminated UTF-8 string
+  /// and sqlite3_column_name16() returns a pointer to a zero-terminated
+  /// UTF-16 string.  ^The first parameter is the [prepared statement]
+  /// that implements the [SELECT] statement. ^The second parameter is the
+  /// column number.  ^The leftmost column is number 0.
+  ///
+  /// ^The returned string pointer is valid until either the [prepared statement]
+  /// is destroyed by [sqlite3_finalize()] or until the statement is automatically
+  /// reprepared by the first call to [sqlite3_step()] for a particular run
+  /// or until the next call to
+  /// sqlite3_column_name() or sqlite3_column_name16() on the same column.
+  ///
+  /// ^If sqlite3_malloc() fails during the processing of either routine
+  /// (for example during a conversion from UTF-8 to UTF-16) then a
+  /// NULL pointer is returned.
+  ///
+  /// ^The name of a result column is the value of the "AS" clause for
+  /// that column, if there is an AS clause.  If there is no AS clause
+  /// then the name of the column is unspecified and may change from
+  /// one release of SQLite to the next.
+  ffi.Pointer<ffi.Char> sqlite3_column_name(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int N,
+  ) {
+    return _sqlite3_column_name(
+      arg0,
+      N,
+    );
+  }
+
+  late final _sqlite3_column_namePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_name');
+  late final _sqlite3_column_name = _sqlite3_column_namePtr.asFunction<
+      ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_column_name16(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int N,
+  ) {
+    return _sqlite3_column_name16(
+      arg0,
+      N,
+    );
+  }
+
+  late final _sqlite3_column_name16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_name16');
+  late final _sqlite3_column_name16 = _sqlite3_column_name16Ptr.asFunction<
+      ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  /// CAPI3REF: Source Of Data In A Query Result
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^These routines provide a means to determine the database, table, and
+  /// table column that is the origin of a particular result column in
+  /// [SELECT] statement.
+  /// ^The name of the database or table or column can be returned as
+  /// either a UTF-8 or UTF-16 string.  ^The _database_ routines return
+  /// the database name, the _table_ routines return the table name, and
+  /// the origin_ routines return the column name.
+  /// ^The returned string is valid until the [prepared statement] is destroyed
+  /// using [sqlite3_finalize()] or until the statement is automatically
+  /// reprepared by the first call to [sqlite3_step()] for a particular run
+  /// or until the same information is requested
+  /// again in a different encoding.
+  ///
+  /// ^The names returned are the original un-aliased names of the
+  /// database, table, and column.
+  ///
+  /// ^The first argument to these interfaces is a [prepared statement].
+  /// ^These functions return information about the Nth result column returned by
+  /// the statement, where N is the second function argument.
+  /// ^The left-most column is column 0 for these routines.
+  ///
+  /// ^If the Nth column returned by the statement is an expression or
+  /// subquery and is not a column value, then all of these functions return
+  /// NULL.  ^These routines might also return NULL if a memory allocation error
+  /// occurs.  ^Otherwise, they return the name of the attached database, table,
+  /// or column that query result column was extracted from.
+  ///
+  /// ^As with all other SQLite APIs, those whose names end with "16" return
+  /// UTF-16 encoded strings and the other functions return UTF-8.
+  ///
+  /// ^These APIs are only available if the library was compiled with the
+  /// [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol.
+  ///
+  /// If two or more threads call one or more
+  /// [sqlite3_column_database_name | column metadata interfaces]
+  /// for the same [prepared statement] and result column
+  /// at the same time then the results are undefined.
+  ffi.Pointer<ffi.Char> sqlite3_column_database_name(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_column_database_name(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_column_database_namePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>,
+              ffi.Int)>>('sqlite3_column_database_name');
+  late final _sqlite3_column_database_name =
+      _sqlite3_column_database_namePtr.asFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_column_database_name16(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_column_database_name16(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_column_database_name16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_stmt>,
+              ffi.Int)>>('sqlite3_column_database_name16');
+  late final _sqlite3_column_database_name16 =
+      _sqlite3_column_database_name16Ptr.asFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_column_table_name(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_column_table_name(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_column_table_namePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>,
+              ffi.Int)>>('sqlite3_column_table_name');
+  late final _sqlite3_column_table_name =
+      _sqlite3_column_table_namePtr.asFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_column_table_name16(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_column_table_name16(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_column_table_name16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_stmt>,
+              ffi.Int)>>('sqlite3_column_table_name16');
+  late final _sqlite3_column_table_name16 =
+      _sqlite3_column_table_name16Ptr.asFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_column_origin_name(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_column_origin_name(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_column_origin_namePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>,
+              ffi.Int)>>('sqlite3_column_origin_name');
+  late final _sqlite3_column_origin_name =
+      _sqlite3_column_origin_namePtr.asFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_column_origin_name16(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_column_origin_name16(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_column_origin_name16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_stmt>,
+              ffi.Int)>>('sqlite3_column_origin_name16');
+  late final _sqlite3_column_origin_name16 =
+      _sqlite3_column_origin_name16Ptr.asFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  /// CAPI3REF: Declared Datatype Of A Query Result
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^(The first parameter is a [prepared statement].
+  /// If this statement is a [SELECT] statement and the Nth column of the
+  /// returned result set of that [SELECT] is a table column (not an
+  /// expression or subquery) then the declared type of the table
+  /// column is returned.)^  ^If the Nth column of the result set is an
+  /// expression or subquery, then a NULL pointer is returned.
+  /// ^The returned string is always UTF-8 encoded.
+  ///
+  /// ^(For example, given the database schema:
+  ///
+  /// CREATE TABLE t1(c1 VARIANT);
+  ///
+  /// and the following statement to be compiled:
+  ///
+  /// SELECT c1 + 1, c1 FROM t1;
+  ///
+  /// this routine would return the string "VARIANT" for the second result
+  /// column (i==1), and a NULL pointer for the first result column (i==0).)^
+  ///
+  /// ^SQLite uses dynamic run-time typing.  ^So just because a column
+  /// is declared to contain a particular type does not mean that the
+  /// data stored in that column is of the declared type.  SQLite is
+  /// strongly typed, but the typing is dynamic not static.  ^Type
+  /// is associated with individual values, not with the containers
+  /// used to hold those values.
+  ffi.Pointer<ffi.Char> sqlite3_column_decltype(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_column_decltype(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_column_decltypePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_decltype');
+  late final _sqlite3_column_decltype = _sqlite3_column_decltypePtr.asFunction<
+      ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_column_decltype16(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_column_decltype16(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_column_decltype16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_stmt>,
+              ffi.Int)>>('sqlite3_column_decltype16');
+  late final _sqlite3_column_decltype16 =
+      _sqlite3_column_decltype16Ptr.asFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  /// CAPI3REF: Evaluate An SQL Statement
+  /// METHOD: sqlite3_stmt
+  ///
+  /// After a [prepared statement] has been prepared using any of
+  /// [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()],
+  /// or [sqlite3_prepare16_v3()] or one of the legacy
+  /// interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
+  /// must be called one or more times to evaluate the statement.
+  ///
+  /// The details of the behavior of the sqlite3_step() interface depend
+  /// on whether the statement was prepared using the newer "vX" interfaces
+  /// [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()],
+  /// [sqlite3_prepare16_v2()] or the older legacy
+  /// interfaces [sqlite3_prepare()] and [sqlite3_prepare16()].  The use of the
+  /// new "vX" interface is recommended for new applications but the legacy
+  /// interface will continue to be supported.
+  ///
+  /// ^In the legacy interface, the return value will be either [SQLITE_BUSY],
+  /// [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
+  /// ^With the "v2" interface, any of the other [result codes] or
+  /// [extended result codes] might be returned as well.
+  ///
+  /// ^[SQLITE_BUSY] means that the database engine was unable to acquire the
+  /// database locks it needs to do its job.  ^If the statement is a [COMMIT]
+  /// or occurs outside of an explicit transaction, then you can retry the
+  /// statement.  If the statement is not a [COMMIT] and occurs within an
+  /// explicit transaction then you should rollback the transaction before
+  /// continuing.
+  ///
+  /// ^[SQLITE_DONE] means that the statement has finished executing
+  /// successfully.  sqlite3_step() should not be called again on this virtual
+  /// machine without first calling [sqlite3_reset()] to reset the virtual
+  /// machine back to its initial state.
+  ///
+  /// ^If the SQL statement being executed returns any data, then [SQLITE_ROW]
+  /// is returned each time a new row of data is ready for processing by the
+  /// caller. The values may be accessed using the [column access functions].
+  /// sqlite3_step() is called again to retrieve the next row of data.
+  ///
+  /// ^[SQLITE_ERROR] means that a run-time error (such as a constraint
+  /// violation) has occurred.  sqlite3_step() should not be called again on
+  /// the VM. More information may be found by calling [sqlite3_errmsg()].
+  /// ^With the legacy interface, a more specific error code (for example,
+  /// [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
+  /// can be obtained by calling [sqlite3_reset()] on the
+  /// [prepared statement].  ^In the "v2" interface,
+  /// the more specific error code is returned directly by sqlite3_step().
+  ///
+  /// [SQLITE_MISUSE] means that the this routine was called inappropriately.
+  /// Perhaps it was called on a [prepared statement] that has
+  /// already been [sqlite3_finalize | finalized] or on one that had
+  /// previously returned [SQLITE_ERROR] or [SQLITE_DONE].  Or it could
+  /// be the case that the same database connection is being used by two or
+  /// more threads at the same moment in time.
+  ///
+  /// For all versions of SQLite up to and including 3.6.23.1, a call to
+  /// [sqlite3_reset()] was required after sqlite3_step() returned anything
+  /// other than [SQLITE_ROW] before any subsequent invocation of
+  /// sqlite3_step().  Failure to reset the prepared statement using
+  /// [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
+  /// sqlite3_step().  But after [version 3.6.23.1] ([dateof:3.6.23.1],
+  /// sqlite3_step() began
+  /// calling [sqlite3_reset()] automatically in this circumstance rather
+  /// than returning [SQLITE_MISUSE].  This is not considered a compatibility
+  /// break because any application that ever receives an SQLITE_MISUSE error
+  /// is broken by definition.  The [SQLITE_OMIT_AUTORESET] compile-time option
+  /// can be used to restore the legacy behavior.
+  ///
+  /// <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
+  /// API always returns a generic error code, [SQLITE_ERROR], following any
+  /// error other than [SQLITE_BUSY] and [SQLITE_MISUSE].  You must call
+  /// [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
+  /// specific [error codes] that better describes the error.
+  /// We admit that this is a goofy design.  The problem has been fixed
+  /// with the "v2" interface.  If you prepare all of your SQL statements
+  /// using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()]
+  /// or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead
+  /// of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
+  /// then the more specific [error codes] are returned directly
+  /// by sqlite3_step().  The use of the "vX" interfaces is recommended.
+  int sqlite3_step(
+    ffi.Pointer<sqlite3_stmt> arg0,
+  ) {
+    return _sqlite3_step(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_stepPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_step');
+  late final _sqlite3_step =
+      _sqlite3_stepPtr.asFunction<int Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Number of columns in a result set
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^The sqlite3_data_count(P) interface returns the number of columns in the
+  /// current row of the result set of [prepared statement] P.
+  /// ^If prepared statement P does not have results ready to return
+  /// (via calls to the [sqlite3_column_int | sqlite3_column()] family of
+  /// interfaces) then sqlite3_data_count(P) returns 0.
+  /// ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
+  /// ^The sqlite3_data_count(P) routine returns 0 if the previous call to
+  /// [sqlite3_step](P) returned [SQLITE_DONE].  ^The sqlite3_data_count(P)
+  /// will return non-zero if previous call to [sqlite3_step](P) returned
+  /// [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
+  /// where it always returns zero since each step of that multi-step
+  /// pragma returns 0 columns of data.
+  ///
+  /// See also: [sqlite3_column_count()]
+  int sqlite3_data_count(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    return _sqlite3_data_count(
+      pStmt,
+    );
+  }
+
+  late final _sqlite3_data_countPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_data_count');
+  late final _sqlite3_data_count = _sqlite3_data_countPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Result Values From A Query
+  /// KEYWORDS: {column access functions}
+  /// METHOD: sqlite3_stmt
+  ///
+  /// <b>Summary:</b>
+  /// <blockquote><table border=0 cellpadding=0 cellspacing=0>
+  /// <tr><td><b>sqlite3_column_blob</b><td>&rarr;<td>BLOB result
+  /// <tr><td><b>sqlite3_column_double</b><td>&rarr;<td>REAL result
+  /// <tr><td><b>sqlite3_column_int</b><td>&rarr;<td>32-bit INTEGER result
+  /// <tr><td><b>sqlite3_column_int64</b><td>&rarr;<td>64-bit INTEGER result
+  /// <tr><td><b>sqlite3_column_text</b><td>&rarr;<td>UTF-8 TEXT result
+  /// <tr><td><b>sqlite3_column_text16</b><td>&rarr;<td>UTF-16 TEXT result
+  /// <tr><td><b>sqlite3_column_value</b><td>&rarr;<td>The result as an
+  /// [sqlite3_value|unprotected sqlite3_value] object.
+  /// <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
+  /// <tr><td><b>sqlite3_column_bytes</b><td>&rarr;<td>Size of a BLOB
+  /// or a UTF-8 TEXT result in bytes
+  /// <tr><td><b>sqlite3_column_bytes16&nbsp;&nbsp;</b>
+  /// <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
+  /// TEXT in bytes
+  /// <tr><td><b>sqlite3_column_type</b><td>&rarr;<td>Default
+  /// datatype of the result
+  /// </table></blockquote>
+  ///
+  /// <b>Details:</b>
+  ///
+  /// ^These routines return information about a single column of the current
+  /// result row of a query.  ^In every case the first argument is a pointer
+  /// to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
+  /// that was returned from [sqlite3_prepare_v2()] or one of its variants)
+  /// and the second argument is the index of the column for which information
+  /// should be returned. ^The leftmost column of the result set has the index 0.
+  /// ^The number of columns in the result can be determined using
+  /// [sqlite3_column_count()].
+  ///
+  /// If the SQL statement does not currently point to a valid row, or if the
+  /// column index is out of range, the result is undefined.
+  /// These routines may only be called when the most recent call to
+  /// [sqlite3_step()] has returned [SQLITE_ROW] and neither
+  /// [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
+  /// If any of these routines are called after [sqlite3_reset()] or
+  /// [sqlite3_finalize()] or after [sqlite3_step()] has returned
+  /// something other than [SQLITE_ROW], the results are undefined.
+  /// If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
+  /// are called from a different thread while any of these routines
+  /// are pending, then the results are undefined.
+  ///
+  /// The first six interfaces (_blob, _double, _int, _int64, _text, and _text16)
+  /// each return the value of a result column in a specific data format.  If
+  /// the result column is not initially in the requested format (for example,
+  /// if the query returns an integer but the sqlite3_column_text() interface
+  /// is used to extract the value) then an automatic type conversion is performed.
+  ///
+  /// ^The sqlite3_column_type() routine returns the
+  /// [SQLITE_INTEGER | datatype code] for the initial data type
+  /// of the result column.  ^The returned value is one of [SQLITE_INTEGER],
+  /// [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].
+  /// The return value of sqlite3_column_type() can be used to decide which
+  /// of the first six interface should be used to extract the column value.
+  /// The value returned by sqlite3_column_type() is only meaningful if no
+  /// automatic type conversions have occurred for the value in question.
+  /// After a type conversion, the result of calling sqlite3_column_type()
+  /// is undefined, though harmless.  Future
+  /// versions of SQLite may change the behavior of sqlite3_column_type()
+  /// following a type conversion.
+  ///
+  /// If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes()
+  /// or sqlite3_column_bytes16() interfaces can be used to determine the size
+  /// of that BLOB or string.
+  ///
+  /// ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
+  /// routine returns the number of bytes in that BLOB or string.
+  /// ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts
+  /// the string to UTF-8 and then returns the number of bytes.
+  /// ^If the result is a numeric value then sqlite3_column_bytes() uses
+  /// [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns
+  /// the number of bytes in that string.
+  /// ^If the result is NULL, then sqlite3_column_bytes() returns zero.
+  ///
+  /// ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16()
+  /// routine returns the number of bytes in that BLOB or string.
+  /// ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts
+  /// the string to UTF-16 and then returns the number of bytes.
+  /// ^If the result is a numeric value then sqlite3_column_bytes16() uses
+  /// [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns
+  /// the number of bytes in that string.
+  /// ^If the result is NULL, then sqlite3_column_bytes16() returns zero.
+  ///
+  /// ^The values returned by [sqlite3_column_bytes()] and
+  /// [sqlite3_column_bytes16()] do not include the zero terminators at the end
+  /// of the string.  ^For clarity: the values returned by
+  /// [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of
+  /// bytes in the string, not the number of characters.
+  ///
+  /// ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
+  /// even empty strings, are always zero-terminated.  ^The return
+  /// value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
+  ///
+  /// <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
+  /// [unprotected sqlite3_value] object.  In a multithreaded environment,
+  /// an unprotected sqlite3_value object may only be used safely with
+  /// [sqlite3_bind_value()] and [sqlite3_result_value()].
+  /// If the [unprotected sqlite3_value] object returned by
+  /// [sqlite3_column_value()] is used in any other way, including calls
+  /// to routines like [sqlite3_value_int()], [sqlite3_value_text()],
+  /// or [sqlite3_value_bytes()], the behavior is not threadsafe.
+  /// Hence, the sqlite3_column_value() interface
+  /// is normally only useful within the implementation of
+  /// [application-defined SQL functions] or [virtual tables], not within
+  /// top-level application code.
+  ///
+  /// The these routines may attempt to convert the datatype of the result.
+  /// ^For example, if the internal representation is FLOAT and a text result
+  /// is requested, [sqlite3_snprintf()] is used internally to perform the
+  /// conversion automatically.  ^(The following table details the conversions
+  /// that are applied:
+  ///
+  /// <blockquote>
+  /// <table border="1">
+  /// <tr><th> Internal<br>Type <th> Requested<br>Type <th>  Conversion
+  ///
+  /// <tr><td>  NULL    <td> INTEGER   <td> Result is 0
+  /// <tr><td>  NULL    <td>  FLOAT    <td> Result is 0.0
+  /// <tr><td>  NULL    <td>   TEXT    <td> Result is a NULL pointer
+  /// <tr><td>  NULL    <td>   BLOB    <td> Result is a NULL pointer
+  /// <tr><td> INTEGER  <td>  FLOAT    <td> Convert from integer to float
+  /// <tr><td> INTEGER  <td>   TEXT    <td> ASCII rendering of the integer
+  /// <tr><td> INTEGER  <td>   BLOB    <td> Same as INTEGER->TEXT
+  /// <tr><td>  FLOAT   <td> INTEGER   <td> [CAST] to INTEGER
+  /// <tr><td>  FLOAT   <td>   TEXT    <td> ASCII rendering of the float
+  /// <tr><td>  FLOAT   <td>   BLOB    <td> [CAST] to BLOB
+  /// <tr><td>  TEXT    <td> INTEGER   <td> [CAST] to INTEGER
+  /// <tr><td>  TEXT    <td>  FLOAT    <td> [CAST] to REAL
+  /// <tr><td>  TEXT    <td>   BLOB    <td> No change
+  /// <tr><td>  BLOB    <td> INTEGER   <td> [CAST] to INTEGER
+  /// <tr><td>  BLOB    <td>  FLOAT    <td> [CAST] to REAL
+  /// <tr><td>  BLOB    <td>   TEXT    <td> Add a zero terminator if needed
+  /// </table>
+  /// </blockquote>)^
+  ///
+  /// Note that when type conversions occur, pointers returned by prior
+  /// calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
+  /// sqlite3_column_text16() may be invalidated.
+  /// Type conversions and pointer invalidations might occur
+  /// in the following cases:
+  ///
+  /// <ul>
+  /// <li> The initial content is a BLOB and sqlite3_column_text() or
+  /// sqlite3_column_text16() is called.  A zero-terminator might
+  /// need to be added to the string.</li>
+  /// <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or
+  /// sqlite3_column_text16() is called.  The content must be converted
+  /// to UTF-16.</li>
+  /// <li> The initial content is UTF-16 text and sqlite3_column_bytes() or
+  /// sqlite3_column_text() is called.  The content must be converted
+  /// to UTF-8.</li>
+  /// </ul>
+  ///
+  /// ^Conversions between UTF-16be and UTF-16le are always done in place and do
+  /// not invalidate a prior pointer, though of course the content of the buffer
+  /// that the prior pointer references will have been modified.  Other kinds
+  /// of conversion are done in place when it is possible, but sometimes they
+  /// are not possible and in those cases prior pointers are invalidated.
+  ///
+  /// The safest policy is to invoke these routines
+  /// in one of the following ways:
+  ///
+  /// <ul>
+  /// <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
+  /// <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
+  /// <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
+  /// </ul>
+  ///
+  /// In other words, you should call sqlite3_column_text(),
+  /// sqlite3_column_blob(), or sqlite3_column_text16() first to force the result
+  /// into the desired format, then invoke sqlite3_column_bytes() or
+  /// sqlite3_column_bytes16() to find the size of the result.  Do not mix calls
+  /// to sqlite3_column_text() or sqlite3_column_blob() with calls to
+  /// sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16()
+  /// with calls to sqlite3_column_bytes().
+  ///
+  /// ^The pointers returned are valid until a type conversion occurs as
+  /// described above, or until [sqlite3_step()] or [sqlite3_reset()] or
+  /// [sqlite3_finalize()] is called.  ^The memory space used to hold strings
+  /// and BLOBs is freed automatically.  Do not pass the pointers returned
+  /// from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
+  /// [sqlite3_free()].
+  ///
+  /// As long as the input parameters are correct, these routines will only
+  /// fail if an out-of-memory error occurs during a format conversion.
+  /// Only the following subset of interfaces are subject to out-of-memory
+  /// errors:
+  ///
+  /// <ul>
+  /// <li> sqlite3_column_blob()
+  /// <li> sqlite3_column_text()
+  /// <li> sqlite3_column_text16()
+  /// <li> sqlite3_column_bytes()
+  /// <li> sqlite3_column_bytes16()
+  /// </ul>
+  ///
+  /// If an out-of-memory error occurs, then the return value from these
+  /// routines is the same as if the column had contained an SQL NULL value.
+  /// Valid SQL NULL returns can be distinguished from out-of-memory errors
+  /// by invoking the [sqlite3_errcode()] immediately after the suspect
+  /// return value is obtained and before any
+  /// other SQLite interface is called on the same [database connection].
+  ffi.Pointer<ffi.Void> sqlite3_column_blob(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    return _sqlite3_column_blob(
+      arg0,
+      iCol,
+    );
+  }
+
+  late final _sqlite3_column_blobPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_blob');
+  late final _sqlite3_column_blob = _sqlite3_column_blobPtr.asFunction<
+      ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  double sqlite3_column_double(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    return _sqlite3_column_double(
+      arg0,
+      iCol,
+    );
+  }
+
+  late final _sqlite3_column_doublePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Double Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_double');
+  late final _sqlite3_column_double = _sqlite3_column_doublePtr
+      .asFunction<double Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  int sqlite3_column_int(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    return _sqlite3_column_int(
+      arg0,
+      iCol,
+    );
+  }
+
+  late final _sqlite3_column_intPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_int');
+  late final _sqlite3_column_int = _sqlite3_column_intPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  int sqlite3_column_int64(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    return _sqlite3_column_int64(
+      arg0,
+      iCol,
+    );
+  }
+
+  late final _sqlite3_column_int64Ptr = _lookup<
+      ffi.NativeFunction<
+          sqlite3_int64 Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_int64');
+  late final _sqlite3_column_int64 = _sqlite3_column_int64Ptr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  ffi.Pointer<ffi.UnsignedChar> sqlite3_column_text(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    return _sqlite3_column_text(
+      arg0,
+      iCol,
+    );
+  }
+
+  late final _sqlite3_column_textPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.UnsignedChar> Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_text');
+  late final _sqlite3_column_text = _sqlite3_column_textPtr.asFunction<
+      ffi.Pointer<ffi.UnsignedChar> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_column_text16(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    return _sqlite3_column_text16(
+      arg0,
+      iCol,
+    );
+  }
+
+  late final _sqlite3_column_text16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_text16');
+  late final _sqlite3_column_text16 = _sqlite3_column_text16Ptr.asFunction<
+      ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  ffi.Pointer<sqlite3_value> sqlite3_column_value(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    return _sqlite3_column_value(
+      arg0,
+      iCol,
+    );
+  }
+
+  late final _sqlite3_column_valuePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3_value> Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_value');
+  late final _sqlite3_column_value = _sqlite3_column_valuePtr.asFunction<
+      ffi.Pointer<sqlite3_value> Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  int sqlite3_column_bytes(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    return _sqlite3_column_bytes(
+      arg0,
+      iCol,
+    );
+  }
+
+  late final _sqlite3_column_bytesPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_bytes');
+  late final _sqlite3_column_bytes = _sqlite3_column_bytesPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  int sqlite3_column_bytes16(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    return _sqlite3_column_bytes16(
+      arg0,
+      iCol,
+    );
+  }
+
+  late final _sqlite3_column_bytes16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_bytes16');
+  late final _sqlite3_column_bytes16 = _sqlite3_column_bytes16Ptr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  int sqlite3_column_type(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int iCol,
+  ) {
+    return _sqlite3_column_type(
+      arg0,
+      iCol,
+    );
+  }
+
+  late final _sqlite3_column_typePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_stmt>, ffi.Int)>>('sqlite3_column_type');
+  late final _sqlite3_column_type = _sqlite3_column_typePtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int)>();
+
+  /// CAPI3REF: Destroy A Prepared Statement Object
+  /// DESTRUCTOR: sqlite3_stmt
+  ///
+  /// ^The sqlite3_finalize() function is called to delete a [prepared statement].
+  /// ^If the most recent evaluation of the statement encountered no errors
+  /// or if the statement is never been evaluated, then sqlite3_finalize() returns
+  /// SQLITE_OK.  ^If the most recent evaluation of statement S failed, then
+  /// sqlite3_finalize(S) returns the appropriate [error code] or
+  /// [extended error code].
+  ///
+  /// ^The sqlite3_finalize(S) routine can be called at any point during
+  /// the life cycle of [prepared statement] S:
+  /// before statement S is ever evaluated, after
+  /// one or more calls to [sqlite3_reset()], or after any call
+  /// to [sqlite3_step()] regardless of whether or not the statement has
+  /// completed execution.
+  ///
+  /// ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.
+  ///
+  /// The application must finalize every [prepared statement] in order to avoid
+  /// resource leaks.  It is a grievous error for the application to try to use
+  /// a prepared statement after it has been finalized.  Any use of a prepared
+  /// statement after it has been finalized can result in undefined and
+  /// undesirable behavior such as segfaults and heap corruption.
+  int sqlite3_finalize(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    return _sqlite3_finalize(
+      pStmt,
+    );
+  }
+
+  late final _sqlite3_finalizePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_finalize');
+  late final _sqlite3_finalize = _sqlite3_finalizePtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Reset A Prepared Statement Object
+  /// METHOD: sqlite3_stmt
+  ///
+  /// The sqlite3_reset() function is called to reset a [prepared statement]
+  /// object back to its initial state, ready to be re-executed.
+  /// ^Any SQL statement variables that had values bound to them using
+  /// the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
+  /// Use [sqlite3_clear_bindings()] to reset the bindings.
+  ///
+  /// ^The [sqlite3_reset(S)] interface resets the [prepared statement] S
+  /// back to the beginning of its program.
+  ///
+  /// ^If the most recent call to [sqlite3_step(S)] for the
+  /// [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],
+  /// or if [sqlite3_step(S)] has never before been called on S,
+  /// then [sqlite3_reset(S)] returns [SQLITE_OK].
+  ///
+  /// ^If the most recent call to [sqlite3_step(S)] for the
+  /// [prepared statement] S indicated an error, then
+  /// [sqlite3_reset(S)] returns an appropriate [error code].
+  ///
+  /// ^The [sqlite3_reset(S)] interface does not change the values
+  /// of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
+  int sqlite3_reset(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    return _sqlite3_reset(
+      pStmt,
+    );
+  }
+
+  late final _sqlite3_resetPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_reset');
+  late final _sqlite3_reset =
+      _sqlite3_resetPtr.asFunction<int Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Create Or Redefine SQL Functions
+  /// KEYWORDS: {function creation routines}
+  /// METHOD: sqlite3
+  ///
+  /// ^These functions (collectively known as "function creation routines")
+  /// are used to add SQL functions or aggregates or to redefine the behavior
+  /// of existing SQL functions or aggregates. The only differences between
+  /// the three "sqlite3_create_function*" routines are the text encoding
+  /// expected for the second parameter (the name of the function being
+  /// created) and the presence or absence of a destructor callback for
+  /// the application data pointer. Function sqlite3_create_window_function()
+  /// is similar, but allows the user to supply the extra callback functions
+  /// needed by [aggregate window functions].
+  ///
+  /// ^The first parameter is the [database connection] to which the SQL
+  /// function is to be added.  ^If an application uses more than one database
+  /// connection then application-defined SQL functions must be added
+  /// to each database connection separately.
+  ///
+  /// ^The second parameter is the name of the SQL function to be created or
+  /// redefined.  ^The length of the name is limited to 255 bytes in a UTF-8
+  /// representation, exclusive of the zero-terminator.  ^Note that the name
+  /// length limit is in UTF-8 bytes, not characters nor UTF-16 bytes.
+  /// ^Any attempt to create a function with a longer name
+  /// will result in [SQLITE_MISUSE] being returned.
+  ///
+  /// ^The third parameter (nArg)
+  /// is the number of arguments that the SQL function or
+  /// aggregate takes. ^If this parameter is -1, then the SQL function or
+  /// aggregate may take any number of arguments between 0 and the limit
+  /// set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]).  If the third
+  /// parameter is less than -1 or greater than 127 then the behavior is
+  /// undefined.
+  ///
+  /// ^The fourth parameter, eTextRep, specifies what
+  /// [SQLITE_UTF8 | text encoding] this SQL function prefers for
+  /// its parameters.  The application should set this parameter to
+  /// [SQLITE_UTF16LE] if the function implementation invokes
+  /// [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the
+  /// implementation invokes [sqlite3_value_text16be()] on an input, or
+  /// [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8]
+  /// otherwise.  ^The same SQL function may be registered multiple times using
+  /// different preferred text encodings, with different implementations for
+  /// each encoding.
+  /// ^When multiple implementations of the same function are available, SQLite
+  /// will pick the one that involves the least amount of data conversion.
+  ///
+  /// ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC]
+  /// to signal that the function will always return the same result given
+  /// the same inputs within a single SQL statement.  Most SQL functions are
+  /// deterministic.  The built-in [random()] SQL function is an example of a
+  /// function that is not deterministic.  The SQLite query planner is able to
+  /// perform additional optimizations on deterministic functions, so use
+  /// of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
+  ///
+  /// ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY]
+  /// flag, which if present prevents the function from being invoked from
+  /// within VIEWs, TRIGGERs, CHECK constraints, generated column expressions,
+  /// index expressions, or the WHERE clause of partial indexes.
+  ///
+  /// <span style="background-color:#ffff90;">
+  /// For best security, the [SQLITE_DIRECTONLY] flag is recommended for
+  /// all application-defined SQL functions that do not need to be
+  /// used inside of triggers, view, CHECK constraints, or other elements of
+  /// the database schema.  This flags is especially recommended for SQL
+  /// functions that have side effects or reveal internal application state.
+  /// Without this flag, an attacker might be able to modify the schema of
+  /// a database file to include invocations of the function with parameters
+  /// chosen by the attacker, which the application will then execute when
+  /// the database file is opened and read.
+  /// </span>
+  ///
+  /// ^(The fifth parameter is an arbitrary pointer.  The implementation of the
+  /// function can gain access to this pointer using [sqlite3_user_data()].)^
+  ///
+  /// ^The sixth, seventh and eighth parameters passed to the three
+  /// "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
+  /// pointers to C-language functions that implement the SQL function or
+  /// aggregate. ^A scalar SQL function requires an implementation of the xFunc
+  /// callback only; NULL pointers must be passed as the xStep and xFinal
+  /// parameters. ^An aggregate SQL function requires an implementation of xStep
+  /// and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
+  /// SQL function or aggregate, pass NULL pointers for all three function
+  /// callbacks.
+  ///
+  /// ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue
+  /// and xInverse) passed to sqlite3_create_window_function are pointers to
+  /// C-language callbacks that implement the new function. xStep and xFinal
+  /// must both be non-NULL. xValue and xInverse may either both be NULL, in
+  /// which case a regular aggregate function is created, or must both be
+  /// non-NULL, in which case the new function may be used as either an aggregate
+  /// or aggregate window function. More details regarding the implementation
+  /// of aggregate window functions are
+  /// [user-defined window functions|available here].
+  ///
+  /// ^(If the final parameter to sqlite3_create_function_v2() or
+  /// sqlite3_create_window_function() is not NULL, then it is destructor for
+  /// the application data pointer. The destructor is invoked when the function
+  /// is deleted, either by being overloaded or when the database connection
+  /// closes.)^ ^The destructor is also invoked if the call to
+  /// sqlite3_create_function_v2() fails.  ^When the destructor callback is
+  /// invoked, it is passed a single argument which is a copy of the application
+  /// data pointer which was the fifth parameter to sqlite3_create_function_v2().
+  ///
+  /// ^It is permitted to register multiple implementations of the same
+  /// functions with the same name but with either differing numbers of
+  /// arguments or differing preferred text encodings.  ^SQLite will use
+  /// the implementation that most closely matches the way in which the
+  /// SQL function is used.  ^A function implementation with a non-negative
+  /// nArg parameter is a better match than a function implementation with
+  /// a negative nArg.  ^A function where the preferred text encoding
+  /// matches the database encoding is a better
+  /// match than a function where the encoding is different.
+  /// ^A function where the encoding difference is between UTF16le and UTF16be
+  /// is a closer match than a function where the encoding difference is
+  /// between UTF8 and UTF16.
+  ///
+  /// ^Built-in functions may be overloaded by new application-defined functions.
+  ///
+  /// ^An application-defined function is permitted to call other
+  /// SQLite interfaces.  However, such calls must not
+  /// close the database connection nor finalize or reset the prepared
+  /// statement in which the function is running.
+  int sqlite3_create_function(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zFunctionName,
+    int nArg,
+    int eTextRep,
+    ffi.Pointer<ffi.Void> pApp,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                    ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>
+        xFunc,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                    ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>
+        xStep,
+    ffi.Pointer<
+            ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_context>)>>
+        xFinal,
+  ) {
+    return _sqlite3_create_function(
+      db,
+      zFunctionName,
+      nArg,
+      eTextRep,
+      pApp,
+      xFunc,
+      xStep,
+      xFinal,
+    );
+  }
+
+  late final _sqlite3_create_functionPtr =
+      _lookup<
+              ffi.NativeFunction<
+                  ffi.Int Function(
+                      ffi.Pointer<sqlite3>,
+                      ffi.Pointer<ffi.Char>,
+                      ffi.Int,
+                      ffi.Int,
+                      ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(
+                                  ffi.Pointer<sqlite3_context>,
+                                  ffi.Int,
+                                  ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(
+                                  ffi.Pointer<sqlite3_context>,
+                                  ffi.Int,
+                                  ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(
+                                  ffi.Pointer<sqlite3_context>)>>)>>(
+          'sqlite3_create_function');
+  late final _sqlite3_create_function = _sqlite3_create_functionPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Char>,
+          int,
+          int,
+          ffi.Pointer<ffi.Void>,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                      ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                      ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Void Function(ffi.Pointer<sqlite3_context>)>>)>();
+
+  int sqlite3_create_function16(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Void> zFunctionName,
+    int nArg,
+    int eTextRep,
+    ffi.Pointer<ffi.Void> pApp,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                    ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>
+        xFunc,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                    ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>
+        xStep,
+    ffi.Pointer<
+            ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_context>)>>
+        xFinal,
+  ) {
+    return _sqlite3_create_function16(
+      db,
+      zFunctionName,
+      nArg,
+      eTextRep,
+      pApp,
+      xFunc,
+      xStep,
+      xFinal,
+    );
+  }
+
+  late final _sqlite3_create_function16Ptr =
+      _lookup<
+              ffi.NativeFunction<
+                  ffi.Int Function(
+                      ffi.Pointer<sqlite3>,
+                      ffi.Pointer<ffi.Void>,
+                      ffi.Int,
+                      ffi.Int,
+                      ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(
+                                  ffi.Pointer<sqlite3_context>,
+                                  ffi.Int,
+                                  ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(
+                                  ffi.Pointer<sqlite3_context>,
+                                  ffi.Int,
+                                  ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(
+                                  ffi.Pointer<sqlite3_context>)>>)>>(
+          'sqlite3_create_function16');
+  late final _sqlite3_create_function16 =
+      _sqlite3_create_function16Ptr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Void>,
+              int,
+              int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                          ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                          ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<sqlite3_context>)>>)>();
+
+  int sqlite3_create_function_v2(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zFunctionName,
+    int nArg,
+    int eTextRep,
+    ffi.Pointer<ffi.Void> pApp,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                    ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>
+        xFunc,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                    ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>
+        xStep,
+    ffi.Pointer<
+            ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_context>)>>
+        xFinal,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        xDestroy,
+  ) {
+    return _sqlite3_create_function_v2(
+      db,
+      zFunctionName,
+      nArg,
+      eTextRep,
+      pApp,
+      xFunc,
+      xStep,
+      xFinal,
+      xDestroy,
+    );
+  }
+
+  late final _sqlite3_create_function_v2Ptr =
+      _lookup<
+              ffi.NativeFunction<
+                  ffi.Int Function(
+                      ffi.Pointer<sqlite3>,
+                      ffi.Pointer<ffi.Char>,
+                      ffi.Int,
+                      ffi.Int,
+                      ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(
+                                  ffi.Pointer<sqlite3_context>,
+                                  ffi.Int,
+                                  ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(
+                                  ffi.Pointer<sqlite3_context>,
+                                  ffi.Int,
+                                  ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(ffi.Pointer<sqlite3_context>)>>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
+          'sqlite3_create_function_v2');
+  late final _sqlite3_create_function_v2 =
+      _sqlite3_create_function_v2Ptr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              int,
+              int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                          ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                          ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<sqlite3_context>)>>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  int sqlite3_create_window_function(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zFunctionName,
+    int nArg,
+    int eTextRep,
+    ffi.Pointer<ffi.Void> pApp,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                    ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>
+        xStep,
+    ffi.Pointer<
+            ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_context>)>>
+        xFinal,
+    ffi.Pointer<
+            ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_context>)>>
+        xValue,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                    ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>
+        xInverse,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        xDestroy,
+  ) {
+    return _sqlite3_create_window_function(
+      db,
+      zFunctionName,
+      nArg,
+      eTextRep,
+      pApp,
+      xStep,
+      xFinal,
+      xValue,
+      xInverse,
+      xDestroy,
+    );
+  }
+
+  late final _sqlite3_create_window_functionPtr =
+      _lookup<
+              ffi.NativeFunction<
+                  ffi.Int Function(
+                      ffi.Pointer<sqlite3>,
+                      ffi.Pointer<ffi.Char>,
+                      ffi.Int,
+                      ffi.Int,
+                      ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(
+                                  ffi.Pointer<sqlite3_context>,
+                                  ffi.Int,
+                                  ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(ffi.Pointer<sqlite3_context>)>>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(ffi.Pointer<sqlite3_context>)>>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(
+                                  ffi.Pointer<sqlite3_context>,
+                                  ffi.Int,
+                                  ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
+          'sqlite3_create_window_function');
+  late final _sqlite3_create_window_function =
+      _sqlite3_create_window_functionPtr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              int,
+              int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                          ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<sqlite3_context>)>>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<sqlite3_context>)>>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Int,
+                          ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  int sqlite3_aggregate_count(
+    ffi.Pointer<sqlite3_context> arg0,
+  ) {
+    return _sqlite3_aggregate_count(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_aggregate_countPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_context>)>>(
+      'sqlite3_aggregate_count');
+  late final _sqlite3_aggregate_count = _sqlite3_aggregate_countPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_context>)>();
+
+  int sqlite3_expired(
+    ffi.Pointer<sqlite3_stmt> arg0,
+  ) {
+    return _sqlite3_expired(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_expiredPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_expired');
+  late final _sqlite3_expired =
+      _sqlite3_expiredPtr.asFunction<int Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  int sqlite3_transfer_bindings(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    ffi.Pointer<sqlite3_stmt> arg1,
+  ) {
+    return _sqlite3_transfer_bindings(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_transfer_bindingsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_stmt>,
+              ffi.Pointer<sqlite3_stmt>)>>('sqlite3_transfer_bindings');
+  late final _sqlite3_transfer_bindings =
+      _sqlite3_transfer_bindingsPtr.asFunction<
+          int Function(ffi.Pointer<sqlite3_stmt>, ffi.Pointer<sqlite3_stmt>)>();
+
+  int sqlite3_global_recover() {
+    return _sqlite3_global_recover();
+  }
+
+  late final _sqlite3_global_recoverPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function()>>('sqlite3_global_recover');
+  late final _sqlite3_global_recover =
+      _sqlite3_global_recoverPtr.asFunction<int Function()>();
+
+  void sqlite3_thread_cleanup() {
+    return _sqlite3_thread_cleanup();
+  }
+
+  late final _sqlite3_thread_cleanupPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>(
+          'sqlite3_thread_cleanup');
+  late final _sqlite3_thread_cleanup =
+      _sqlite3_thread_cleanupPtr.asFunction<void Function()>();
+
+  int sqlite3_memory_alarm(
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(
+                    ffi.Pointer<ffi.Void>, sqlite3_int64, ffi.Int)>>
+        arg0,
+    ffi.Pointer<ffi.Void> arg1,
+    int arg2,
+  ) {
+    return _sqlite3_memory_alarm(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_memory_alarmPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>, sqlite3_int64, ffi.Int)>>,
+              ffi.Pointer<ffi.Void>,
+              sqlite3_int64)>>('sqlite3_memory_alarm');
+  late final _sqlite3_memory_alarm = _sqlite3_memory_alarmPtr.asFunction<
+      int Function(
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.Void>, sqlite3_int64, ffi.Int)>>,
+          ffi.Pointer<ffi.Void>,
+          int)>();
+
+  /// CAPI3REF: Obtaining SQL Values
+  /// METHOD: sqlite3_value
+  ///
+  /// <b>Summary:</b>
+  /// <blockquote><table border=0 cellpadding=0 cellspacing=0>
+  /// <tr><td><b>sqlite3_value_blob</b><td>&rarr;<td>BLOB value
+  /// <tr><td><b>sqlite3_value_double</b><td>&rarr;<td>REAL value
+  /// <tr><td><b>sqlite3_value_int</b><td>&rarr;<td>32-bit INTEGER value
+  /// <tr><td><b>sqlite3_value_int64</b><td>&rarr;<td>64-bit INTEGER value
+  /// <tr><td><b>sqlite3_value_pointer</b><td>&rarr;<td>Pointer value
+  /// <tr><td><b>sqlite3_value_text</b><td>&rarr;<td>UTF-8 TEXT value
+  /// <tr><td><b>sqlite3_value_text16</b><td>&rarr;<td>UTF-16 TEXT value in
+  /// the native byteorder
+  /// <tr><td><b>sqlite3_value_text16be</b><td>&rarr;<td>UTF-16be TEXT value
+  /// <tr><td><b>sqlite3_value_text16le</b><td>&rarr;<td>UTF-16le TEXT value
+  /// <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
+  /// <tr><td><b>sqlite3_value_bytes</b><td>&rarr;<td>Size of a BLOB
+  /// or a UTF-8 TEXT in bytes
+  /// <tr><td><b>sqlite3_value_bytes16&nbsp;&nbsp;</b>
+  /// <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
+  /// TEXT in bytes
+  /// <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
+  /// datatype of the value
+  /// <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
+  /// <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
+  /// <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
+  /// <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
+  /// against a virtual table.
+  /// <tr><td><b>sqlite3_value_frombind&nbsp;&nbsp;</b>
+  /// <td>&rarr;&nbsp;&nbsp;<td>True if value originated from a [bound parameter]
+  /// </table></blockquote>
+  ///
+  /// <b>Details:</b>
+  ///
+  /// These routines extract type, size, and content information from
+  /// [protected sqlite3_value] objects.  Protected sqlite3_value objects
+  /// are used to pass parameter information into the functions that
+  /// implement [application-defined SQL functions] and [virtual tables].
+  ///
+  /// These routines work only with [protected sqlite3_value] objects.
+  /// Any attempt to use these routines on an [unprotected sqlite3_value]
+  /// is not threadsafe.
+  ///
+  /// ^These routines work just like the corresponding [column access functions]
+  /// except that these routines take a single [protected sqlite3_value] object
+  /// pointer instead of a [sqlite3_stmt*] pointer and an integer column number.
+  ///
+  /// ^The sqlite3_value_text16() interface extracts a UTF-16 string
+  /// in the native byte-order of the host machine.  ^The
+  /// sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
+  /// extract UTF-16 strings as big-endian and little-endian respectively.
+  ///
+  /// ^If [sqlite3_value] object V was initialized
+  /// using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)]
+  /// and if X and Y are strings that compare equal according to strcmp(X,Y),
+  /// then sqlite3_value_pointer(V,Y) will return the pointer P.  ^Otherwise,
+  /// sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer()
+  /// routine is part of the [pointer passing interface] added for SQLite 3.20.0.
+  ///
+  /// ^(The sqlite3_value_type(V) interface returns the
+  /// [SQLITE_INTEGER | datatype code] for the initial datatype of the
+  /// [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER],
+  /// [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^
+  /// Other interfaces might change the datatype for an sqlite3_value object.
+  /// For example, if the datatype is initially SQLITE_INTEGER and
+  /// sqlite3_value_text(V) is called to extract a text value for that
+  /// integer, then subsequent calls to sqlite3_value_type(V) might return
+  /// SQLITE_TEXT.  Whether or not a persistent internal datatype conversion
+  /// occurs is undefined and may change from one release of SQLite to the next.
+  ///
+  /// ^(The sqlite3_value_numeric_type() interface attempts to apply
+  /// numeric affinity to the value.  This means that an attempt is
+  /// made to convert the value to an integer or floating point.  If
+  /// such a conversion is possible without loss of information (in other
+  /// words, if the value is a string that looks like a number)
+  /// then the conversion is performed.  Otherwise no conversion occurs.
+  /// The [SQLITE_INTEGER | datatype] after conversion is returned.)^
+  ///
+  /// ^Within the [xUpdate] method of a [virtual table], the
+  /// sqlite3_value_nochange(X) interface returns true if and only if
+  /// the column corresponding to X is unchanged by the UPDATE operation
+  /// that the xUpdate method call was invoked to implement and if
+  /// and the prior [xColumn] method call that was invoked to extracted
+  /// the value for that column returned without setting a result (probably
+  /// because it queried [sqlite3_vtab_nochange()] and found that the column
+  /// was unchanging).  ^Within an [xUpdate] method, any value for which
+  /// sqlite3_value_nochange(X) is true will in all other respects appear
+  /// to be a NULL value.  If sqlite3_value_nochange(X) is invoked anywhere other
+  /// than within an [xUpdate] method call for an UPDATE statement, then
+  /// the return value is arbitrary and meaningless.
+  ///
+  /// ^The sqlite3_value_frombind(X) interface returns non-zero if the
+  /// value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
+  /// interfaces.  ^If X comes from an SQL literal value, or a table column,
+  /// or an expression, then sqlite3_value_frombind(X) returns zero.
+  ///
+  /// Please pay particular attention to the fact that the pointer returned
+  /// from [sqlite3_value_blob()], [sqlite3_value_text()], or
+  /// [sqlite3_value_text16()] can be invalidated by a subsequent call to
+  /// [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
+  /// or [sqlite3_value_text16()].
+  ///
+  /// These routines must be called from the same thread as
+  /// the SQL function that supplied the [sqlite3_value*] parameters.
+  ///
+  /// As long as the input parameter is correct, these routines can only
+  /// fail if an out-of-memory error occurs during a format conversion.
+  /// Only the following subset of interfaces are subject to out-of-memory
+  /// errors:
+  ///
+  /// <ul>
+  /// <li> sqlite3_value_blob()
+  /// <li> sqlite3_value_text()
+  /// <li> sqlite3_value_text16()
+  /// <li> sqlite3_value_text16le()
+  /// <li> sqlite3_value_text16be()
+  /// <li> sqlite3_value_bytes()
+  /// <li> sqlite3_value_bytes16()
+  /// </ul>
+  ///
+  /// If an out-of-memory error occurs, then the return value from these
+  /// routines is the same as if the column had contained an SQL NULL value.
+  /// Valid SQL NULL returns can be distinguished from out-of-memory errors
+  /// by invoking the [sqlite3_errcode()] immediately after the suspect
+  /// return value is obtained and before any
+  /// other SQLite interface is called on the same [database connection].
+  ffi.Pointer<ffi.Void> sqlite3_value_blob(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_blob(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_blobPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3_value>)>>('sqlite3_value_blob');
+  late final _sqlite3_value_blob = _sqlite3_value_blobPtr
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_value>)>();
+
+  double sqlite3_value_double(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_double(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_doublePtr = _lookup<
+          ffi.NativeFunction<ffi.Double Function(ffi.Pointer<sqlite3_value>)>>(
+      'sqlite3_value_double');
+  late final _sqlite3_value_double = _sqlite3_value_doublePtr
+      .asFunction<double Function(ffi.Pointer<sqlite3_value>)>();
+
+  int sqlite3_value_int(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_int(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_intPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_value>)>>(
+          'sqlite3_value_int');
+  late final _sqlite3_value_int = _sqlite3_value_intPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_value>)>();
+
+  int sqlite3_value_int64(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_int64(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_int64Ptr = _lookup<
+          ffi
+          .NativeFunction<sqlite3_int64 Function(ffi.Pointer<sqlite3_value>)>>(
+      'sqlite3_value_int64');
+  late final _sqlite3_value_int64 = _sqlite3_value_int64Ptr
+      .asFunction<int Function(ffi.Pointer<sqlite3_value>)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_value_pointer(
+    ffi.Pointer<sqlite3_value> arg0,
+    ffi.Pointer<ffi.Char> arg1,
+  ) {
+    return _sqlite3_value_pointer(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_value_pointerPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_value>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_value_pointer');
+  late final _sqlite3_value_pointer = _sqlite3_value_pointerPtr.asFunction<
+      ffi.Pointer<ffi.Void> Function(
+          ffi.Pointer<sqlite3_value>, ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<ffi.UnsignedChar> sqlite3_value_text(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_text(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_textPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.UnsignedChar> Function(
+              ffi.Pointer<sqlite3_value>)>>('sqlite3_value_text');
+  late final _sqlite3_value_text = _sqlite3_value_textPtr.asFunction<
+      ffi.Pointer<ffi.UnsignedChar> Function(ffi.Pointer<sqlite3_value>)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_value_text16(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_text16(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_text16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3_value>)>>('sqlite3_value_text16');
+  late final _sqlite3_value_text16 = _sqlite3_value_text16Ptr
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_value>)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_value_text16le(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_text16le(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_text16lePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3_value>)>>('sqlite3_value_text16le');
+  late final _sqlite3_value_text16le = _sqlite3_value_text16lePtr
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_value>)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_value_text16be(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_text16be(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_text16bePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3_value>)>>('sqlite3_value_text16be');
+  late final _sqlite3_value_text16be = _sqlite3_value_text16bePtr
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_value>)>();
+
+  int sqlite3_value_bytes(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_bytes(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_bytesPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_value>)>>(
+          'sqlite3_value_bytes');
+  late final _sqlite3_value_bytes = _sqlite3_value_bytesPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_value>)>();
+
+  int sqlite3_value_bytes16(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_bytes16(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_bytes16Ptr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_value>)>>(
+          'sqlite3_value_bytes16');
+  late final _sqlite3_value_bytes16 = _sqlite3_value_bytes16Ptr
+      .asFunction<int Function(ffi.Pointer<sqlite3_value>)>();
+
+  int sqlite3_value_type(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_type(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_typePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_value>)>>(
+          'sqlite3_value_type');
+  late final _sqlite3_value_type = _sqlite3_value_typePtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_value>)>();
+
+  int sqlite3_value_numeric_type(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_numeric_type(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_numeric_typePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_value>)>>(
+          'sqlite3_value_numeric_type');
+  late final _sqlite3_value_numeric_type = _sqlite3_value_numeric_typePtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_value>)>();
+
+  int sqlite3_value_nochange(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_nochange(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_nochangePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_value>)>>(
+          'sqlite3_value_nochange');
+  late final _sqlite3_value_nochange = _sqlite3_value_nochangePtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_value>)>();
+
+  int sqlite3_value_frombind(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_frombind(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_frombindPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_value>)>>(
+          'sqlite3_value_frombind');
+  late final _sqlite3_value_frombind = _sqlite3_value_frombindPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_value>)>();
+
+  /// CAPI3REF: Finding The Subtype Of SQL Values
+  /// METHOD: sqlite3_value
+  ///
+  /// The sqlite3_value_subtype(V) function returns the subtype for
+  /// an [application-defined SQL function] argument V.  The subtype
+  /// information can be used to pass a limited amount of context from
+  /// one SQL function to another.  Use the [sqlite3_result_subtype()]
+  /// routine to set the subtype for the return value of an SQL function.
+  int sqlite3_value_subtype(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_subtype(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_subtypePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.UnsignedInt Function(
+              ffi.Pointer<sqlite3_value>)>>('sqlite3_value_subtype');
+  late final _sqlite3_value_subtype = _sqlite3_value_subtypePtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_value>)>();
+
+  /// CAPI3REF: Copy And Free SQL Values
+  /// METHOD: sqlite3_value
+  ///
+  /// ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
+  /// object D and returns a pointer to that copy.  ^The [sqlite3_value] returned
+  /// is a [protected sqlite3_value] object even if the input is not.
+  /// ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
+  /// memory allocation fails.
+  ///
+  /// ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
+  /// previously obtained from [sqlite3_value_dup()].  ^If V is a NULL pointer
+  /// then sqlite3_value_free(V) is a harmless no-op.
+  ffi.Pointer<sqlite3_value> sqlite3_value_dup(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_dup(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_dupPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3_value> Function(
+              ffi.Pointer<sqlite3_value>)>>('sqlite3_value_dup');
+  late final _sqlite3_value_dup = _sqlite3_value_dupPtr.asFunction<
+      ffi.Pointer<sqlite3_value> Function(ffi.Pointer<sqlite3_value>)>();
+
+  void sqlite3_value_free(
+    ffi.Pointer<sqlite3_value> arg0,
+  ) {
+    return _sqlite3_value_free(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_value_freePtr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_value>)>>(
+      'sqlite3_value_free');
+  late final _sqlite3_value_free = _sqlite3_value_freePtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_value>)>();
+
+  /// CAPI3REF: Obtain Aggregate Function Context
+  /// METHOD: sqlite3_context
+  ///
+  /// Implementations of aggregate SQL functions use this
+  /// routine to allocate memory for storing their state.
+  ///
+  /// ^The first time the sqlite3_aggregate_context(C,N) routine is called
+  /// for a particular aggregate function, SQLite allocates
+  /// N bytes of memory, zeroes out that memory, and returns a pointer
+  /// to the new memory. ^On second and subsequent calls to
+  /// sqlite3_aggregate_context() for the same aggregate function instance,
+  /// the same buffer is returned.  Sqlite3_aggregate_context() is normally
+  /// called once for each invocation of the xStep callback and then one
+  /// last time when the xFinal callback is invoked.  ^(When no rows match
+  /// an aggregate query, the xStep() callback of the aggregate function
+  /// implementation is never called and xFinal() is called exactly once.
+  /// In those cases, sqlite3_aggregate_context() might be called for the
+  /// first time from within xFinal().)^
+  ///
+  /// ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer
+  /// when first called if N is less than or equal to zero or if a memory
+  /// allocate error occurs.
+  ///
+  /// ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
+  /// determined by the N parameter on first successful call.  Changing the
+  /// value of N in any subsequent call to sqlite3_aggregate_context() within
+  /// the same aggregate function instance will not resize the memory
+  /// allocation.)^  Within the xFinal callback, it is customary to set
+  /// N=0 in calls to sqlite3_aggregate_context(C,N) so that no
+  /// pointless memory allocations occur.
+  ///
+  /// ^SQLite automatically frees the memory allocated by
+  /// sqlite3_aggregate_context() when the aggregate query concludes.
+  ///
+  /// The first parameter must be a copy of the
+  /// [sqlite3_context | SQL function context] that is the first parameter
+  /// to the xStep or xFinal callback routine that implements the aggregate
+  /// function.
+  ///
+  /// This routine must be called from the same thread in which
+  /// the aggregate SQL function is running.
+  ffi.Pointer<ffi.Void> sqlite3_aggregate_context(
+    ffi.Pointer<sqlite3_context> arg0,
+    int nBytes,
+  ) {
+    return _sqlite3_aggregate_context(
+      arg0,
+      nBytes,
+    );
+  }
+
+  late final _sqlite3_aggregate_contextPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_context>,
+              ffi.Int)>>('sqlite3_aggregate_context');
+  late final _sqlite3_aggregate_context =
+      _sqlite3_aggregate_contextPtr.asFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_context>, int)>();
+
+  /// CAPI3REF: User Data For Functions
+  /// METHOD: sqlite3_context
+  ///
+  /// ^The sqlite3_user_data() interface returns a copy of
+  /// the pointer that was the pUserData parameter (the 5th parameter)
+  /// of the [sqlite3_create_function()]
+  /// and [sqlite3_create_function16()] routines that originally
+  /// registered the application defined function.
+  ///
+  /// This routine must be called from the same thread in which
+  /// the application-defined function is running.
+  ffi.Pointer<ffi.Void> sqlite3_user_data(
+    ffi.Pointer<sqlite3_context> arg0,
+  ) {
+    return _sqlite3_user_data(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_user_dataPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3_context>)>>('sqlite3_user_data');
+  late final _sqlite3_user_data = _sqlite3_user_dataPtr.asFunction<
+      ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_context>)>();
+
+  /// CAPI3REF: Database Connection For Functions
+  /// METHOD: sqlite3_context
+  ///
+  /// ^The sqlite3_context_db_handle() interface returns a copy of
+  /// the pointer to the [database connection] (the 1st parameter)
+  /// of the [sqlite3_create_function()]
+  /// and [sqlite3_create_function16()] routines that originally
+  /// registered the application defined function.
+  ffi.Pointer<sqlite3> sqlite3_context_db_handle(
+    ffi.Pointer<sqlite3_context> arg0,
+  ) {
+    return _sqlite3_context_db_handle(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_context_db_handlePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3> Function(
+              ffi.Pointer<sqlite3_context>)>>('sqlite3_context_db_handle');
+  late final _sqlite3_context_db_handle =
+      _sqlite3_context_db_handlePtr.asFunction<
+          ffi.Pointer<sqlite3> Function(ffi.Pointer<sqlite3_context>)>();
+
+  /// CAPI3REF: Function Auxiliary Data
+  /// METHOD: sqlite3_context
+  ///
+  /// These functions may be used by (non-aggregate) SQL functions to
+  /// associate metadata with argument values. If the same value is passed to
+  /// multiple invocations of the same SQL function during query execution, under
+  /// some circumstances the associated metadata may be preserved.  An example
+  /// of where this might be useful is in a regular-expression matching
+  /// function. The compiled version of the regular expression can be stored as
+  /// metadata associated with the pattern string.
+  /// Then as long as the pattern string remains the same,
+  /// the compiled regular expression can be reused on multiple
+  /// invocations of the same function.
+  ///
+  /// ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
+  /// associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
+  /// value to the application-defined function.  ^N is zero for the left-most
+  /// function argument.  ^If there is no metadata
+  /// associated with the function argument, the sqlite3_get_auxdata(C,N) interface
+  /// returns a NULL pointer.
+  ///
+  /// ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
+  /// argument of the application-defined function.  ^Subsequent
+  /// calls to sqlite3_get_auxdata(C,N) return P from the most recent
+  /// sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
+  /// NULL if the metadata has been discarded.
+  /// ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
+  /// SQLite will invoke the destructor function X with parameter P exactly
+  /// once, when the metadata is discarded.
+  /// SQLite is free to discard the metadata at any time, including: <ul>
+  /// <li> ^(when the corresponding function parameter changes)^, or
+  /// <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+  /// SQL statement)^, or
+  /// <li> ^(when sqlite3_set_auxdata() is invoked again on the same
+  /// parameter)^, or
+  /// <li> ^(during the original sqlite3_set_auxdata() call when a memory
+  /// allocation error occurs.)^ </ul>
+  ///
+  /// Note the last bullet in particular.  The destructor X in
+  /// sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
+  /// sqlite3_set_auxdata() interface even returns.  Hence sqlite3_set_auxdata()
+  /// should be called near the end of the function implementation and the
+  /// function implementation should not make any use of P after
+  /// sqlite3_set_auxdata() has been called.
+  ///
+  /// ^(In practice, metadata is preserved between function calls for
+  /// function parameters that are compile-time constants, including literal
+  /// values and [parameters] and expressions composed from the same.)^
+  ///
+  /// The value of the N parameter to these interfaces should be non-negative.
+  /// Future enhancements may make use of negative N values to define new
+  /// kinds of function caching behavior.
+  ///
+  /// These routines must be called from the same thread in which
+  /// the SQL function is running.
+  ffi.Pointer<ffi.Void> sqlite3_get_auxdata(
+    ffi.Pointer<sqlite3_context> arg0,
+    int N,
+  ) {
+    return _sqlite3_get_auxdata(
+      arg0,
+      N,
+    );
+  }
+
+  late final _sqlite3_get_auxdataPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3_context>, ffi.Int)>>('sqlite3_get_auxdata');
+  late final _sqlite3_get_auxdata = _sqlite3_get_auxdataPtr.asFunction<
+      ffi.Pointer<ffi.Void> Function(ffi.Pointer<sqlite3_context>, int)>();
+
+  void sqlite3_set_auxdata(
+    ffi.Pointer<sqlite3_context> arg0,
+    int N,
+    ffi.Pointer<ffi.Void> arg2,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg3,
+  ) {
+    return _sqlite3_set_auxdata(
+      arg0,
+      N,
+      arg2,
+      arg3,
+    );
+  }
+
+  late final _sqlite3_set_auxdataPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<sqlite3_context>,
+              ffi.Int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>)>>)>>('sqlite3_set_auxdata');
+  late final _sqlite3_set_auxdata = _sqlite3_set_auxdataPtr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>,
+          int,
+          ffi.Pointer<ffi.Void>,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  /// CAPI3REF: Setting The Result Of An SQL Function
+  /// METHOD: sqlite3_context
+  ///
+  /// These routines are used by the xFunc or xFinal callbacks that
+  /// implement SQL functions and aggregates.  See
+  /// [sqlite3_create_function()] and [sqlite3_create_function16()]
+  /// for additional information.
+  ///
+  /// These functions work very much like the [parameter binding] family of
+  /// functions used to bind values to host parameters in prepared statements.
+  /// Refer to the [SQL parameter] documentation for additional information.
+  ///
+  /// ^The sqlite3_result_blob() interface sets the result from
+  /// an application-defined function to be the BLOB whose content is pointed
+  /// to by the second parameter and which is N bytes long where N is the
+  /// third parameter.
+  ///
+  /// ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N)
+  /// interfaces set the result of the application-defined function to be
+  /// a BLOB containing all zero bytes and N bytes in size.
+  ///
+  /// ^The sqlite3_result_double() interface sets the result from
+  /// an application-defined function to be a floating point value specified
+  /// by its 2nd argument.
+  ///
+  /// ^The sqlite3_result_error() and sqlite3_result_error16() functions
+  /// cause the implemented SQL function to throw an exception.
+  /// ^SQLite uses the string pointed to by the
+  /// 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
+  /// as the text of an error message.  ^SQLite interprets the error
+  /// message string from sqlite3_result_error() as UTF-8. ^SQLite
+  /// interprets the string from sqlite3_result_error16() as UTF-16 using
+  /// the same [byte-order determination rules] as [sqlite3_bind_text16()].
+  /// ^If the third parameter to sqlite3_result_error()
+  /// or sqlite3_result_error16() is negative then SQLite takes as the error
+  /// message all text up through the first zero character.
+  /// ^If the third parameter to sqlite3_result_error() or
+  /// sqlite3_result_error16() is non-negative then SQLite takes that many
+  /// bytes (not characters) from the 2nd parameter as the error message.
+  /// ^The sqlite3_result_error() and sqlite3_result_error16()
+  /// routines make a private copy of the error message text before
+  /// they return.  Hence, the calling function can deallocate or
+  /// modify the text after they return without harm.
+  /// ^The sqlite3_result_error_code() function changes the error code
+  /// returned by SQLite as a result of an error in a function.  ^By default,
+  /// the error code is SQLITE_ERROR.  ^A subsequent call to sqlite3_result_error()
+  /// or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
+  ///
+  /// ^The sqlite3_result_error_toobig() interface causes SQLite to throw an
+  /// error indicating that a string or BLOB is too long to represent.
+  ///
+  /// ^The sqlite3_result_error_nomem() interface causes SQLite to throw an
+  /// error indicating that a memory allocation failed.
+  ///
+  /// ^The sqlite3_result_int() interface sets the return value
+  /// of the application-defined function to be the 32-bit signed integer
+  /// value given in the 2nd argument.
+  /// ^The sqlite3_result_int64() interface sets the return value
+  /// of the application-defined function to be the 64-bit signed integer
+  /// value given in the 2nd argument.
+  ///
+  /// ^The sqlite3_result_null() interface sets the return value
+  /// of the application-defined function to be NULL.
+  ///
+  /// ^The sqlite3_result_text(), sqlite3_result_text16(),
+  /// sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
+  /// set the return value of the application-defined function to be
+  /// a text string which is represented as UTF-8, UTF-16 native byte order,
+  /// UTF-16 little endian, or UTF-16 big endian, respectively.
+  /// ^The sqlite3_result_text64() interface sets the return value of an
+  /// application-defined function to be a text string in an encoding
+  /// specified by the fifth (and last) parameter, which must be one
+  /// of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
+  /// ^SQLite takes the text result from the application from
+  /// the 2nd parameter of the sqlite3_result_text* interfaces.
+  /// ^If the 3rd parameter to the sqlite3_result_text* interfaces
+  /// is negative, then SQLite takes result text from the 2nd parameter
+  /// through the first zero character.
+  /// ^If the 3rd parameter to the sqlite3_result_text* interfaces
+  /// is non-negative, then as many bytes (not characters) of the text
+  /// pointed to by the 2nd parameter are taken as the application-defined
+  /// function result.  If the 3rd parameter is non-negative, then it
+  /// must be the byte offset into the string where the NUL terminator would
+  /// appear if the string where NUL terminated.  If any NUL characters occur
+  /// in the string at a byte offset that is less than the value of the 3rd
+  /// parameter, then the resulting string will contain embedded NULs and the
+  /// result of expressions operating on strings with embedded NULs is undefined.
+  /// ^If the 4th parameter to the sqlite3_result_text* interfaces
+  /// or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
+  /// function as the destructor on the text or BLOB result when it has
+  /// finished using that result.
+  /// ^If the 4th parameter to the sqlite3_result_text* interfaces or to
+  /// sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite
+  /// assumes that the text or BLOB result is in constant space and does not
+  /// copy the content of the parameter nor call a destructor on the content
+  /// when it has finished using that result.
+  /// ^If the 4th parameter to the sqlite3_result_text* interfaces
+  /// or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
+  /// then SQLite makes a copy of the result into space obtained
+  /// from [sqlite3_malloc()] before it returns.
+  ///
+  /// ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and
+  /// sqlite3_result_text16be() routines, and for sqlite3_result_text64()
+  /// when the encoding is not UTF8, if the input UTF16 begins with a
+  /// byte-order mark (BOM, U+FEFF) then the BOM is removed from the
+  /// string and the rest of the string is interpreted according to the
+  /// byte-order specified by the BOM.  ^The byte-order specified by
+  /// the BOM at the beginning of the text overrides the byte-order
+  /// specified by the interface procedure.  ^So, for example, if
+  /// sqlite3_result_text16le() is invoked with text that begins
+  /// with bytes 0xfe, 0xff (a big-endian byte-order mark) then the
+  /// first two bytes of input are skipped and the remaining input
+  /// is interpreted as UTF16BE text.
+  ///
+  /// ^For UTF16 input text to the sqlite3_result_text16(),
+  /// sqlite3_result_text16be(), sqlite3_result_text16le(), and
+  /// sqlite3_result_text64() routines, if the text contains invalid
+  /// UTF16 characters, the invalid characters might be converted
+  /// into the unicode replacement character, U+FFFD.
+  ///
+  /// ^The sqlite3_result_value() interface sets the result of
+  /// the application-defined function to be a copy of the
+  /// [unprotected sqlite3_value] object specified by the 2nd parameter.  ^The
+  /// sqlite3_result_value() interface makes a copy of the [sqlite3_value]
+  /// so that the [sqlite3_value] specified in the parameter may change or
+  /// be deallocated after sqlite3_result_value() returns without harm.
+  /// ^A [protected sqlite3_value] object may always be used where an
+  /// [unprotected sqlite3_value] object is required, so either
+  /// kind of [sqlite3_value] object can be used with this interface.
+  ///
+  /// ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an
+  /// SQL NULL value, just like [sqlite3_result_null(C)], except that it
+  /// also associates the host-language pointer P or type T with that
+  /// NULL value such that the pointer can be retrieved within an
+  /// [application-defined SQL function] using [sqlite3_value_pointer()].
+  /// ^If the D parameter is not NULL, then it is a pointer to a destructor
+  /// for the P parameter.  ^SQLite invokes D with P as its only argument
+  /// when SQLite is finished with P.  The T parameter should be a static
+  /// string and preferably a string literal. The sqlite3_result_pointer()
+  /// routine is part of the [pointer passing interface] added for SQLite 3.20.0.
+  ///
+  /// If these routines are called from within the different thread
+  /// than the one containing the application-defined function that received
+  /// the [sqlite3_context] pointer, the results are undefined.
+  void sqlite3_result_blob(
+    ffi.Pointer<sqlite3_context> arg0,
+    ffi.Pointer<ffi.Void> arg1,
+    int arg2,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg3,
+  ) {
+    return _sqlite3_result_blob(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+    );
+  }
+
+  late final _sqlite3_result_blobPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<sqlite3_context>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Int,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>)>>)>>('sqlite3_result_blob');
+  late final _sqlite3_result_blob = _sqlite3_result_blobPtr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>,
+          ffi.Pointer<ffi.Void>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  void sqlite3_result_blob64(
+    ffi.Pointer<sqlite3_context> arg0,
+    ffi.Pointer<ffi.Void> arg1,
+    int arg2,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg3,
+  ) {
+    return _sqlite3_result_blob64(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+    );
+  }
+
+  late final _sqlite3_result_blob64Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<sqlite3_context>,
+              ffi.Pointer<ffi.Void>,
+              sqlite3_uint64,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>)>>)>>('sqlite3_result_blob64');
+  late final _sqlite3_result_blob64 = _sqlite3_result_blob64Ptr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>,
+          ffi.Pointer<ffi.Void>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  void sqlite3_result_double(
+    ffi.Pointer<sqlite3_context> arg0,
+    double arg1,
+  ) {
+    return _sqlite3_result_double(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_result_doublePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_context>,
+              ffi.Double)>>('sqlite3_result_double');
+  late final _sqlite3_result_double = _sqlite3_result_doublePtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_context>, double)>();
+
+  void sqlite3_result_error(
+    ffi.Pointer<sqlite3_context> arg0,
+    ffi.Pointer<ffi.Char> arg1,
+    int arg2,
+  ) {
+    return _sqlite3_result_error(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_result_errorPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Pointer<ffi.Char>,
+              ffi.Int)>>('sqlite3_result_error');
+  late final _sqlite3_result_error = _sqlite3_result_errorPtr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>, ffi.Pointer<ffi.Char>, int)>();
+
+  void sqlite3_result_error16(
+    ffi.Pointer<sqlite3_context> arg0,
+    ffi.Pointer<ffi.Void> arg1,
+    int arg2,
+  ) {
+    return _sqlite3_result_error16(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_result_error16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_context>, ffi.Pointer<ffi.Void>,
+              ffi.Int)>>('sqlite3_result_error16');
+  late final _sqlite3_result_error16 = _sqlite3_result_error16Ptr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>, ffi.Pointer<ffi.Void>, int)>();
+
+  void sqlite3_result_error_toobig(
+    ffi.Pointer<sqlite3_context> arg0,
+  ) {
+    return _sqlite3_result_error_toobig(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_result_error_toobigPtr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_context>)>>(
+      'sqlite3_result_error_toobig');
+  late final _sqlite3_result_error_toobig = _sqlite3_result_error_toobigPtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_context>)>();
+
+  void sqlite3_result_error_nomem(
+    ffi.Pointer<sqlite3_context> arg0,
+  ) {
+    return _sqlite3_result_error_nomem(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_result_error_nomemPtr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_context>)>>(
+      'sqlite3_result_error_nomem');
+  late final _sqlite3_result_error_nomem = _sqlite3_result_error_nomemPtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_context>)>();
+
+  void sqlite3_result_error_code(
+    ffi.Pointer<sqlite3_context> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_result_error_code(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_result_error_codePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_context>,
+              ffi.Int)>>('sqlite3_result_error_code');
+  late final _sqlite3_result_error_code = _sqlite3_result_error_codePtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_context>, int)>();
+
+  void sqlite3_result_int(
+    ffi.Pointer<sqlite3_context> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_result_int(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_result_intPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<sqlite3_context>, ffi.Int)>>('sqlite3_result_int');
+  late final _sqlite3_result_int = _sqlite3_result_intPtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_context>, int)>();
+
+  void sqlite3_result_int64(
+    ffi.Pointer<sqlite3_context> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_result_int64(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_result_int64Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_context>,
+              sqlite3_int64)>>('sqlite3_result_int64');
+  late final _sqlite3_result_int64 = _sqlite3_result_int64Ptr
+      .asFunction<void Function(ffi.Pointer<sqlite3_context>, int)>();
+
+  void sqlite3_result_null(
+    ffi.Pointer<sqlite3_context> arg0,
+  ) {
+    return _sqlite3_result_null(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_result_nullPtr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_context>)>>(
+      'sqlite3_result_null');
+  late final _sqlite3_result_null = _sqlite3_result_nullPtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_context>)>();
+
+  void sqlite3_result_text(
+    ffi.Pointer<sqlite3_context> arg0,
+    ffi.Pointer<ffi.Char> arg1,
+    int arg2,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg3,
+  ) {
+    return _sqlite3_result_text(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+    );
+  }
+
+  late final _sqlite3_result_textPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<sqlite3_context>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Int,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>)>>)>>('sqlite3_result_text');
+  late final _sqlite3_result_text = _sqlite3_result_textPtr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>,
+          ffi.Pointer<ffi.Char>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  void sqlite3_result_text64(
+    ffi.Pointer<sqlite3_context> arg0,
+    ffi.Pointer<ffi.Char> arg1,
+    int arg2,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg3,
+    int encoding,
+  ) {
+    return _sqlite3_result_text64(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+      encoding,
+    );
+  }
+
+  late final _sqlite3_result_text64Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<sqlite3_context>,
+              ffi.Pointer<ffi.Char>,
+              sqlite3_uint64,
+              ffi.Pointer<
+                  ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>,
+              ffi.UnsignedChar)>>('sqlite3_result_text64');
+  late final _sqlite3_result_text64 = _sqlite3_result_text64Ptr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>,
+          ffi.Pointer<ffi.Char>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>,
+          int)>();
+
+  void sqlite3_result_text16(
+    ffi.Pointer<sqlite3_context> arg0,
+    ffi.Pointer<ffi.Void> arg1,
+    int arg2,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg3,
+  ) {
+    return _sqlite3_result_text16(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+    );
+  }
+
+  late final _sqlite3_result_text16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<sqlite3_context>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Int,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>)>>)>>('sqlite3_result_text16');
+  late final _sqlite3_result_text16 = _sqlite3_result_text16Ptr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>,
+          ffi.Pointer<ffi.Void>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  void sqlite3_result_text16le(
+    ffi.Pointer<sqlite3_context> arg0,
+    ffi.Pointer<ffi.Void> arg1,
+    int arg2,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg3,
+  ) {
+    return _sqlite3_result_text16le(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+    );
+  }
+
+  late final _sqlite3_result_text16lePtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Void Function(
+                  ffi.Pointer<sqlite3_context>,
+                  ffi.Pointer<ffi.Void>,
+                  ffi.Int,
+                  ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
+      'sqlite3_result_text16le');
+  late final _sqlite3_result_text16le = _sqlite3_result_text16lePtr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>,
+          ffi.Pointer<ffi.Void>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  void sqlite3_result_text16be(
+    ffi.Pointer<sqlite3_context> arg0,
+    ffi.Pointer<ffi.Void> arg1,
+    int arg2,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg3,
+  ) {
+    return _sqlite3_result_text16be(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+    );
+  }
+
+  late final _sqlite3_result_text16bePtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Void Function(
+                  ffi.Pointer<sqlite3_context>,
+                  ffi.Pointer<ffi.Void>,
+                  ffi.Int,
+                  ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
+      'sqlite3_result_text16be');
+  late final _sqlite3_result_text16be = _sqlite3_result_text16bePtr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>,
+          ffi.Pointer<ffi.Void>,
+          int,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  void sqlite3_result_value(
+    ffi.Pointer<sqlite3_context> arg0,
+    ffi.Pointer<sqlite3_value> arg1,
+  ) {
+    return _sqlite3_result_value(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_result_valuePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_context>,
+              ffi.Pointer<sqlite3_value>)>>('sqlite3_result_value');
+  late final _sqlite3_result_value = _sqlite3_result_valuePtr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>, ffi.Pointer<sqlite3_value>)>();
+
+  void sqlite3_result_pointer(
+    ffi.Pointer<sqlite3_context> arg0,
+    ffi.Pointer<ffi.Void> arg1,
+    ffi.Pointer<ffi.Char> arg2,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg3,
+  ) {
+    return _sqlite3_result_pointer(
+      arg0,
+      arg1,
+      arg2,
+      arg3,
+    );
+  }
+
+  late final _sqlite3_result_pointerPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<sqlite3_context>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>)>>)>>('sqlite3_result_pointer');
+  late final _sqlite3_result_pointer = _sqlite3_result_pointerPtr.asFunction<
+      void Function(
+          ffi.Pointer<sqlite3_context>,
+          ffi.Pointer<ffi.Void>,
+          ffi.Pointer<ffi.Char>,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  void sqlite3_result_zeroblob(
+    ffi.Pointer<sqlite3_context> arg0,
+    int n,
+  ) {
+    return _sqlite3_result_zeroblob(
+      arg0,
+      n,
+    );
+  }
+
+  late final _sqlite3_result_zeroblobPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_context>,
+              ffi.Int)>>('sqlite3_result_zeroblob');
+  late final _sqlite3_result_zeroblob = _sqlite3_result_zeroblobPtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_context>, int)>();
+
+  int sqlite3_result_zeroblob64(
+    ffi.Pointer<sqlite3_context> arg0,
+    int n,
+  ) {
+    return _sqlite3_result_zeroblob64(
+      arg0,
+      n,
+    );
+  }
+
+  late final _sqlite3_result_zeroblob64Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_context>,
+              sqlite3_uint64)>>('sqlite3_result_zeroblob64');
+  late final _sqlite3_result_zeroblob64 = _sqlite3_result_zeroblob64Ptr
+      .asFunction<int Function(ffi.Pointer<sqlite3_context>, int)>();
+
+  /// CAPI3REF: Setting The Subtype Of An SQL Function
+  /// METHOD: sqlite3_context
+  ///
+  /// The sqlite3_result_subtype(C,T) function causes the subtype of
+  /// the result from the [application-defined SQL function] with
+  /// [sqlite3_context] C to be the value T.  Only the lower 8 bits
+  /// of the subtype T are preserved in current versions of SQLite;
+  /// higher order bits are discarded.
+  /// The number of subtype bytes preserved by SQLite might increase
+  /// in future releases of SQLite.
+  void sqlite3_result_subtype(
+    ffi.Pointer<sqlite3_context> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_result_subtype(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_result_subtypePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_context>,
+              ffi.UnsignedInt)>>('sqlite3_result_subtype');
+  late final _sqlite3_result_subtype = _sqlite3_result_subtypePtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_context>, int)>();
+
+  /// CAPI3REF: Define New Collating Sequences
+  /// METHOD: sqlite3
+  ///
+  /// ^These functions add, remove, or modify a [collation] associated
+  /// with the [database connection] specified as the first argument.
+  ///
+  /// ^The name of the collation is a UTF-8 string
+  /// for sqlite3_create_collation() and sqlite3_create_collation_v2()
+  /// and a UTF-16 string in native byte order for sqlite3_create_collation16().
+  /// ^Collation names that compare equal according to [sqlite3_strnicmp()] are
+  /// considered to be the same name.
+  ///
+  /// ^(The third argument (eTextRep) must be one of the constants:
+  /// <ul>
+  /// <li> [SQLITE_UTF8],
+  /// <li> [SQLITE_UTF16LE],
+  /// <li> [SQLITE_UTF16BE],
+  /// <li> [SQLITE_UTF16], or
+  /// <li> [SQLITE_UTF16_ALIGNED].
+  /// </ul>)^
+  /// ^The eTextRep argument determines the encoding of strings passed
+  /// to the collating function callback, xCompare.
+  /// ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
+  /// force strings to be UTF16 with native byte order.
+  /// ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
+  /// on an even byte address.
+  ///
+  /// ^The fourth argument, pArg, is an application data pointer that is passed
+  /// through as the first argument to the collating function callback.
+  ///
+  /// ^The fifth argument, xCompare, is a pointer to the collating function.
+  /// ^Multiple collating functions can be registered using the same name but
+  /// with different eTextRep parameters and SQLite will use whichever
+  /// function requires the least amount of data transformation.
+  /// ^If the xCompare argument is NULL then the collating function is
+  /// deleted.  ^When all collating functions having the same name are deleted,
+  /// that collation is no longer usable.
+  ///
+  /// ^The collating function callback is invoked with a copy of the pArg
+  /// application data pointer and with two strings in the encoding specified
+  /// by the eTextRep argument.  The two integer parameters to the collating
+  /// function callback are the length of the two strings, in bytes. The collating
+  /// function must return an integer that is negative, zero, or positive
+  /// if the first string is less than, equal to, or greater than the second,
+  /// respectively.  A collating function must always return the same answer
+  /// given the same inputs.  If two or more collating functions are registered
+  /// to the same collation name (using different eTextRep values) then all
+  /// must give an equivalent answer when invoked with equivalent strings.
+  /// The collating function must obey the following properties for all
+  /// strings A, B, and C:
+  ///
+  /// <ol>
+  /// <li> If A==B then B==A.
+  /// <li> If A==B and B==C then A==C.
+  /// <li> If A&lt;B THEN B&gt;A.
+  /// <li> If A&lt;B and B&lt;C then A&lt;C.
+  /// </ol>
+  ///
+  /// If a collating function fails any of the above constraints and that
+  /// collating function is registered and used, then the behavior of SQLite
+  /// is undefined.
+  ///
+  /// ^The sqlite3_create_collation_v2() works like sqlite3_create_collation()
+  /// with the addition that the xDestroy callback is invoked on pArg when
+  /// the collating function is deleted.
+  /// ^Collating functions are deleted when they are overridden by later
+  /// calls to the collation creation functions or when the
+  /// [database connection] is closed using [sqlite3_close()].
+  ///
+  /// ^The xDestroy callback is <u>not</u> called if the
+  /// sqlite3_create_collation_v2() function fails.  Applications that invoke
+  /// sqlite3_create_collation_v2() with a non-NULL xDestroy argument should
+  /// check the return code and dispose of the application data pointer
+  /// themselves rather than expecting SQLite to deal with it for them.
+  /// This is different from every other SQLite interface.  The inconsistency
+  /// is unfortunate but cannot be changed without breaking backwards
+  /// compatibility.
+  ///
+  /// See also:  [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
+  int sqlite3_create_collation(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.Char> zName,
+    int eTextRep,
+    ffi.Pointer<ffi.Void> pArg,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int,
+                    ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Void>)>>
+        xCompare,
+  ) {
+    return _sqlite3_create_collation(
+      arg0,
+      zName,
+      eTextRep,
+      pArg,
+      xCompare,
+    );
+  }
+
+  late final _sqlite3_create_collationPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3>,
+                  ffi.Pointer<ffi.Char>,
+                  ffi.Int,
+                  ffi.Pointer<ffi.Void>,
+                  ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Int Function(
+                              ffi.Pointer<ffi.Void>,
+                              ffi.Int,
+                              ffi.Pointer<ffi.Void>,
+                              ffi.Int,
+                              ffi.Pointer<ffi.Void>)>>)>>(
+      'sqlite3_create_collation');
+  late final _sqlite3_create_collation =
+      _sqlite3_create_collationPtr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Void>)>>)>();
+
+  int sqlite3_create_collation_v2(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.Char> zName,
+    int eTextRep,
+    ffi.Pointer<ffi.Void> pArg,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int,
+                    ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Void>)>>
+        xCompare,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        xDestroy,
+  ) {
+    return _sqlite3_create_collation_v2(
+      arg0,
+      zName,
+      eTextRep,
+      pArg,
+      xCompare,
+      xDestroy,
+    );
+  }
+
+  late final _sqlite3_create_collation_v2Ptr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3>,
+                  ffi.Pointer<ffi.Char>,
+                  ffi.Int,
+                  ffi.Pointer<ffi.Void>,
+                  ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Int Function(
+                              ffi.Pointer<ffi.Void>,
+                              ffi.Int,
+                              ffi.Pointer<ffi.Void>,
+                              ffi.Int,
+                              ffi.Pointer<ffi.Void>)>>,
+                  ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
+      'sqlite3_create_collation_v2');
+  late final _sqlite3_create_collation_v2 =
+      _sqlite3_create_collation_v2Ptr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Void>)>>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  int sqlite3_create_collation16(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.Void> zName,
+    int eTextRep,
+    ffi.Pointer<ffi.Void> pArg,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int,
+                    ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Void>)>>
+        xCompare,
+  ) {
+    return _sqlite3_create_collation16(
+      arg0,
+      zName,
+      eTextRep,
+      pArg,
+      xCompare,
+    );
+  }
+
+  late final _sqlite3_create_collation16Ptr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3>,
+                  ffi.Pointer<ffi.Void>,
+                  ffi.Int,
+                  ffi.Pointer<ffi.Void>,
+                  ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Int Function(
+                              ffi.Pointer<ffi.Void>,
+                              ffi.Int,
+                              ffi.Pointer<ffi.Void>,
+                              ffi.Int,
+                              ffi.Pointer<ffi.Void>)>>)>>(
+      'sqlite3_create_collation16');
+  late final _sqlite3_create_collation16 =
+      _sqlite3_create_collation16Ptr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Void>,
+              int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Void>)>>)>();
+
+  /// CAPI3REF: Collation Needed Callbacks
+  /// METHOD: sqlite3
+  ///
+  /// ^To avoid having to register all collation sequences before a database
+  /// can be used, a single callback function may be registered with the
+  /// [database connection] to be invoked whenever an undefined collation
+  /// sequence is required.
+  ///
+  /// ^If the function is registered using the sqlite3_collation_needed() API,
+  /// then it is passed the names of undefined collation sequences as strings
+  /// encoded in UTF-8. ^If sqlite3_collation_needed16() is used,
+  /// the names are passed as UTF-16 in machine native byte order.
+  /// ^A call to either function replaces the existing collation-needed callback.
+  ///
+  /// ^(When the callback is invoked, the first argument passed is a copy
+  /// of the second argument to sqlite3_collation_needed() or
+  /// sqlite3_collation_needed16().  The second argument is the database
+  /// connection.  The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE],
+  /// or [SQLITE_UTF16LE], indicating the most desirable form of the collation
+  /// sequence function required.  The fourth parameter is the name of the
+  /// required collation sequence.)^
+  ///
+  /// The callback function should register the desired collation using
+  /// [sqlite3_create_collation()], [sqlite3_create_collation16()], or
+  /// [sqlite3_create_collation_v2()].
+  int sqlite3_collation_needed(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.Void> arg1,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<sqlite3>,
+                    ffi.Int, ffi.Pointer<ffi.Char>)>>
+        arg2,
+  ) {
+    return _sqlite3_collation_needed(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_collation_neededPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3>,
+                  ffi.Pointer<ffi.Void>,
+                  ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Void Function(
+                              ffi.Pointer<ffi.Void>,
+                              ffi.Pointer<sqlite3>,
+                              ffi.Int,
+                              ffi.Pointer<ffi.Char>)>>)>>(
+      'sqlite3_collation_needed');
+  late final _sqlite3_collation_needed =
+      _sqlite3_collation_neededPtr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Pointer<sqlite3>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Char>)>>)>();
+
+  int sqlite3_collation_needed16(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.Void> arg1,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<sqlite3>,
+                    ffi.Int, ffi.Pointer<ffi.Void>)>>
+        arg2,
+  ) {
+    return _sqlite3_collation_needed16(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_collation_needed16Ptr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3>,
+                  ffi.Pointer<ffi.Void>,
+                  ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Void Function(
+                              ffi.Pointer<ffi.Void>,
+                              ffi.Pointer<sqlite3>,
+                              ffi.Int,
+                              ffi.Pointer<ffi.Void>)>>)>>(
+      'sqlite3_collation_needed16');
+  late final _sqlite3_collation_needed16 =
+      _sqlite3_collation_needed16Ptr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Pointer<sqlite3>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Void>)>>)>();
+
+  /// CAPI3REF: Suspend Execution For A Short Time
+  ///
+  /// The sqlite3_sleep() function causes the current thread to suspend execution
+  /// for at least a number of milliseconds specified in its parameter.
+  ///
+  /// If the operating system does not support sleep requests with
+  /// millisecond time resolution, then the time will be rounded up to
+  /// the nearest second. The number of milliseconds of sleep actually
+  /// requested from the operating system is returned.
+  ///
+  /// ^SQLite implements this interface by calling the xSleep()
+  /// method of the default [sqlite3_vfs] object.  If the xSleep() method
+  /// of the default VFS is not implemented correctly, or not implemented at
+  /// all, then the behavior of sqlite3_sleep() may deviate from the description
+  /// in the previous paragraphs.
+  int sqlite3_sleep(
+    int arg0,
+  ) {
+    return _sqlite3_sleep(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_sleepPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int)>>('sqlite3_sleep');
+  late final _sqlite3_sleep = _sqlite3_sleepPtr.asFunction<int Function(int)>();
+
+  /// CAPI3REF: Name Of The Folder Holding Temporary Files
+  ///
+  /// ^(If this global variable is made to point to a string which is
+  /// the name of a folder (a.k.a. directory), then all temporary files
+  /// created by SQLite when using a built-in [sqlite3_vfs | VFS]
+  /// will be placed in that directory.)^  ^If this variable
+  /// is a NULL pointer, then SQLite performs a search for an appropriate
+  /// temporary file directory.
+  ///
+  /// Applications are strongly discouraged from using this global variable.
+  /// It is required to set a temporary folder on Windows Runtime (WinRT).
+  /// But for all other platforms, it is highly recommended that applications
+  /// neither read nor write this variable.  This global variable is a relic
+  /// that exists for backwards compatibility of legacy applications and should
+  /// be avoided in new projects.
+  ///
+  /// It is not safe to read or modify this variable in more than one
+  /// thread at a time.  It is not safe to read or modify this variable
+  /// if a [database connection] is being used at the same time in a separate
+  /// thread.
+  /// It is intended that this variable be set once
+  /// as part of process initialization and before any SQLite interface
+  /// routines have been called and that this variable remain unchanged
+  /// thereafter.
+  ///
+  /// ^The [temp_store_directory pragma] may modify this variable and cause
+  /// it to point to memory obtained from [sqlite3_malloc].  ^Furthermore,
+  /// the [temp_store_directory pragma] always assumes that any string
+  /// that this variable points to is held in memory obtained from
+  /// [sqlite3_malloc] and the pragma may attempt to free that memory
+  /// using [sqlite3_free].
+  /// Hence, if this variable is modified directly, either it should be
+  /// made NULL or made to point to memory obtained from [sqlite3_malloc]
+  /// or else the use of the [temp_store_directory pragma] should be avoided.
+  /// Except when requested by the [temp_store_directory pragma], SQLite
+  /// does not free the memory that sqlite3_temp_directory points to.  If
+  /// the application wants that memory to be freed, it must do
+  /// so itself, taking care to only do so after all [database connection]
+  /// objects have been destroyed.
+  ///
+  /// <b>Note to Windows Runtime users:</b>  The temporary directory must be set
+  /// prior to calling [sqlite3_open] or [sqlite3_open_v2].  Otherwise, various
+  /// features that require the use of temporary files may fail.  Here is an
+  /// example of how to do this using C++ with the Windows Runtime:
+  ///
+  /// <blockquote><pre>
+  /// LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
+  /// &nbsp;     TemporaryFolder->Path->Data();
+  /// char zPathBuf&#91;MAX_PATH + 1&#93;;
+  /// memset(zPathBuf, 0, sizeof(zPathBuf));
+  /// WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
+  /// &nbsp;     NULL, NULL);
+  /// sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
+  /// </pre></blockquote>
+  late final ffi.Pointer<ffi.Pointer<ffi.Char>> _sqlite3_temp_directory =
+      _lookup<ffi.Pointer<ffi.Char>>('sqlite3_temp_directory');
+
+  ffi.Pointer<ffi.Char> get sqlite3_temp_directory =>
+      _sqlite3_temp_directory.value;
+
+  set sqlite3_temp_directory(ffi.Pointer<ffi.Char> value) =>
+      _sqlite3_temp_directory.value = value;
+
+  /// CAPI3REF: Name Of The Folder Holding Database Files
+  ///
+  /// ^(If this global variable is made to point to a string which is
+  /// the name of a folder (a.k.a. directory), then all database files
+  /// specified with a relative pathname and created or accessed by
+  /// SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed
+  /// to be relative to that directory.)^ ^If this variable is a NULL
+  /// pointer, then SQLite assumes that all database files specified
+  /// with a relative pathname are relative to the current directory
+  /// for the process.  Only the windows VFS makes use of this global
+  /// variable; it is ignored by the unix VFS.
+  ///
+  /// Changing the value of this variable while a database connection is
+  /// open can result in a corrupt database.
+  ///
+  /// It is not safe to read or modify this variable in more than one
+  /// thread at a time.  It is not safe to read or modify this variable
+  /// if a [database connection] is being used at the same time in a separate
+  /// thread.
+  /// It is intended that this variable be set once
+  /// as part of process initialization and before any SQLite interface
+  /// routines have been called and that this variable remain unchanged
+  /// thereafter.
+  ///
+  /// ^The [data_store_directory pragma] may modify this variable and cause
+  /// it to point to memory obtained from [sqlite3_malloc].  ^Furthermore,
+  /// the [data_store_directory pragma] always assumes that any string
+  /// that this variable points to is held in memory obtained from
+  /// [sqlite3_malloc] and the pragma may attempt to free that memory
+  /// using [sqlite3_free].
+  /// Hence, if this variable is modified directly, either it should be
+  /// made NULL or made to point to memory obtained from [sqlite3_malloc]
+  /// or else the use of the [data_store_directory pragma] should be avoided.
+  late final ffi.Pointer<ffi.Pointer<ffi.Char>> _sqlite3_data_directory =
+      _lookup<ffi.Pointer<ffi.Char>>('sqlite3_data_directory');
+
+  ffi.Pointer<ffi.Char> get sqlite3_data_directory =>
+      _sqlite3_data_directory.value;
+
+  set sqlite3_data_directory(ffi.Pointer<ffi.Char> value) =>
+      _sqlite3_data_directory.value = value;
+
+  /// CAPI3REF: Win32 Specific Interface
+  ///
+  /// These interfaces are available only on Windows.  The
+  /// [sqlite3_win32_set_directory] interface is used to set the value associated
+  /// with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to
+  /// zValue, depending on the value of the type parameter.  The zValue parameter
+  /// should be NULL to cause the previous value to be freed via [sqlite3_free];
+  /// a non-NULL value will be copied into memory obtained from [sqlite3_malloc]
+  /// prior to being used.  The [sqlite3_win32_set_directory] interface returns
+  /// [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported,
+  /// or [SQLITE_NOMEM] if memory could not be allocated.  The value of the
+  /// [sqlite3_data_directory] variable is intended to act as a replacement for
+  /// the current directory on the sub-platforms of Win32 where that concept is
+  /// not present, e.g. WinRT and UWP.  The [sqlite3_win32_set_directory8] and
+  /// [sqlite3_win32_set_directory16] interfaces behave exactly the same as the
+  /// sqlite3_win32_set_directory interface except the string parameter must be
+  /// UTF-8 or UTF-16, respectively.
+  int sqlite3_win32_set_directory(
+    int type,
+    ffi.Pointer<ffi.Void> zValue,
+  ) {
+    return _sqlite3_win32_set_directory(
+      type,
+      zValue,
+    );
+  }
+
+  late final _sqlite3_win32_set_directoryPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.UnsignedLong,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_win32_set_directory');
+  late final _sqlite3_win32_set_directory = _sqlite3_win32_set_directoryPtr
+      .asFunction<int Function(int, ffi.Pointer<ffi.Void>)>();
+
+  int sqlite3_win32_set_directory8(
+    int type,
+    ffi.Pointer<ffi.Char> zValue,
+  ) {
+    return _sqlite3_win32_set_directory8(
+      type,
+      zValue,
+    );
+  }
+
+  late final _sqlite3_win32_set_directory8Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.UnsignedLong,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_win32_set_directory8');
+  late final _sqlite3_win32_set_directory8 = _sqlite3_win32_set_directory8Ptr
+      .asFunction<int Function(int, ffi.Pointer<ffi.Char>)>();
+
+  int sqlite3_win32_set_directory16(
+    int type,
+    ffi.Pointer<ffi.Void> zValue,
+  ) {
+    return _sqlite3_win32_set_directory16(
+      type,
+      zValue,
+    );
+  }
+
+  late final _sqlite3_win32_set_directory16Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.UnsignedLong,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_win32_set_directory16');
+  late final _sqlite3_win32_set_directory16 = _sqlite3_win32_set_directory16Ptr
+      .asFunction<int Function(int, ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Test For Auto-Commit Mode
+  /// KEYWORDS: {autocommit mode}
+  /// METHOD: sqlite3
+  ///
+  /// ^The sqlite3_get_autocommit() interface returns non-zero or
+  /// zero if the given database connection is or is not in autocommit mode,
+  /// respectively.  ^Autocommit mode is on by default.
+  /// ^Autocommit mode is disabled by a [BEGIN] statement.
+  /// ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
+  ///
+  /// If certain kinds of errors occur on a statement within a multi-statement
+  /// transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
+  /// [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
+  /// transaction might be rolled back automatically.  The only way to
+  /// find out whether SQLite automatically rolled back the transaction after
+  /// an error is to use this function.
+  ///
+  /// If another thread changes the autocommit status of the database
+  /// connection while this routine is running, then the return value
+  /// is undefined.
+  int sqlite3_get_autocommit(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_get_autocommit(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_get_autocommitPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_get_autocommit');
+  late final _sqlite3_get_autocommit = _sqlite3_get_autocommitPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: Find The Database Handle Of A Prepared Statement
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^The sqlite3_db_handle interface returns the [database connection] handle
+  /// to which a [prepared statement] belongs.  ^The [database connection]
+  /// returned by sqlite3_db_handle is the same [database connection]
+  /// that was the first argument
+  /// to the [sqlite3_prepare_v2()] call (or its variants) that was used to
+  /// create the statement in the first place.
+  ffi.Pointer<sqlite3> sqlite3_db_handle(
+    ffi.Pointer<sqlite3_stmt> arg0,
+  ) {
+    return _sqlite3_db_handle(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_db_handlePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3> Function(
+              ffi.Pointer<sqlite3_stmt>)>>('sqlite3_db_handle');
+  late final _sqlite3_db_handle = _sqlite3_db_handlePtr
+      .asFunction<ffi.Pointer<sqlite3> Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Return The Filename For A Database Connection
+  /// METHOD: sqlite3
+  ///
+  /// ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename
+  /// associated with database N of connection D.
+  /// ^If there is no attached database N on the database
+  /// connection D, or if database N is a temporary or in-memory database, then
+  /// this function will return either a NULL pointer or an empty string.
+  ///
+  /// ^The string value returned by this routine is owned and managed by
+  /// the database connection.  ^The value will be valid until the database N
+  /// is [DETACH]-ed or until the database connection closes.
+  ///
+  /// ^The filename returned by this function is the output of the
+  /// xFullPathname method of the [VFS].  ^In other words, the filename
+  /// will be an absolute pathname, even if the filename used
+  /// to open the database originally was a URI or relative pathname.
+  ///
+  /// If the filename pointer returned by this routine is not NULL, then it
+  /// can be used as the filename input parameter to these routines:
+  /// <ul>
+  /// <li> [sqlite3_uri_parameter()]
+  /// <li> [sqlite3_uri_boolean()]
+  /// <li> [sqlite3_uri_int64()]
+  /// <li> [sqlite3_filename_database()]
+  /// <li> [sqlite3_filename_journal()]
+  /// <li> [sqlite3_filename_wal()]
+  /// </ul>
+  ffi.Pointer<ffi.Char> sqlite3_db_filename(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zDbName,
+  ) {
+    return _sqlite3_db_filename(
+      db,
+      zDbName,
+    );
+  }
+
+  late final _sqlite3_db_filenamePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_db_filename');
+  late final _sqlite3_db_filename = _sqlite3_db_filenamePtr.asFunction<
+      ffi.Pointer<ffi.Char> Function(
+          ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: Determine if a database is read-only
+  /// METHOD: sqlite3
+  ///
+  /// ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
+  /// of connection D is read-only, 0 if it is read/write, or -1 if N is not
+  /// the name of a database on connection D.
+  int sqlite3_db_readonly(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zDbName,
+  ) {
+    return _sqlite3_db_readonly(
+      db,
+      zDbName,
+    );
+  }
+
+  late final _sqlite3_db_readonlyPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_db_readonly');
+  late final _sqlite3_db_readonly = _sqlite3_db_readonlyPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: Find the next prepared statement
+  /// METHOD: sqlite3
+  ///
+  /// ^This interface returns a pointer to the next [prepared statement] after
+  /// pStmt associated with the [database connection] pDb.  ^If pStmt is NULL
+  /// then this interface returns a pointer to the first prepared statement
+  /// associated with the database connection pDb.  ^If no prepared statement
+  /// satisfies the conditions of this routine, it returns NULL.
+  ///
+  /// The [database connection] pointer D in a call to
+  /// [sqlite3_next_stmt(D,S)] must refer to an open database
+  /// connection and in particular must not be a NULL pointer.
+  ffi.Pointer<sqlite3_stmt> sqlite3_next_stmt(
+    ffi.Pointer<sqlite3> pDb,
+    ffi.Pointer<sqlite3_stmt> pStmt,
+  ) {
+    return _sqlite3_next_stmt(
+      pDb,
+      pStmt,
+    );
+  }
+
+  late final _sqlite3_next_stmtPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3_stmt> Function(ffi.Pointer<sqlite3>,
+              ffi.Pointer<sqlite3_stmt>)>>('sqlite3_next_stmt');
+  late final _sqlite3_next_stmt = _sqlite3_next_stmtPtr.asFunction<
+      ffi.Pointer<sqlite3_stmt> Function(
+          ffi.Pointer<sqlite3>, ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Commit And Rollback Notification Callbacks
+  /// METHOD: sqlite3
+  ///
+  /// ^The sqlite3_commit_hook() interface registers a callback
+  /// function to be invoked whenever a transaction is [COMMIT | committed].
+  /// ^Any callback set by a previous call to sqlite3_commit_hook()
+  /// for the same database connection is overridden.
+  /// ^The sqlite3_rollback_hook() interface registers a callback
+  /// function to be invoked whenever a transaction is [ROLLBACK | rolled back].
+  /// ^Any callback set by a previous call to sqlite3_rollback_hook()
+  /// for the same database connection is overridden.
+  /// ^The pArg argument is passed through to the callback.
+  /// ^If the callback on a commit hook function returns non-zero,
+  /// then the commit is converted into a rollback.
+  ///
+  /// ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions
+  /// return the P argument from the previous call of the same function
+  /// on the same [database connection] D, or NULL for
+  /// the first call for each function on D.
+  ///
+  /// The commit and rollback hook callbacks are not reentrant.
+  /// The callback implementation must not do anything that will modify
+  /// the database connection that invoked the callback.  Any actions
+  /// to modify the database connection must be deferred until after the
+  /// completion of the [sqlite3_step()] call that triggered the commit
+  /// or rollback hook in the first place.
+  /// Note that running any other SQL statements, including SELECT statements,
+  /// or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify
+  /// the database connections for the meaning of "modify" in this paragraph.
+  ///
+  /// ^Registering a NULL function disables the callback.
+  ///
+  /// ^When the commit hook callback routine returns zero, the [COMMIT]
+  /// operation is allowed to continue normally.  ^If the commit hook
+  /// returns non-zero, then the [COMMIT] is converted into a [ROLLBACK].
+  /// ^The rollback hook is invoked on a rollback that results from a commit
+  /// hook returning non-zero, just as it would be with any other rollback.
+  ///
+  /// ^For the purposes of this API, a transaction is said to have been
+  /// rolled back if an explicit "ROLLBACK" statement is executed, or
+  /// an error or constraint causes an implicit rollback to occur.
+  /// ^The rollback callback is not invoked if a transaction is
+  /// automatically rolled back because the database connection is closed.
+  ///
+  /// See also the [sqlite3_update_hook()] interface.
+  ffi.Pointer<ffi.Void> sqlite3_commit_hook(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
+        arg1,
+    ffi.Pointer<ffi.Void> arg2,
+  ) {
+    return _sqlite3_commit_hook(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_commit_hookPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<
+                  ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_commit_hook');
+  late final _sqlite3_commit_hook = _sqlite3_commit_hookPtr.asFunction<
+      ffi.Pointer<ffi.Void> Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>,
+          ffi.Pointer<ffi.Void>)>();
+
+  ffi.Pointer<ffi.Void> sqlite3_rollback_hook(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        arg1,
+    ffi.Pointer<ffi.Void> arg2,
+  ) {
+    return _sqlite3_rollback_hook(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_rollback_hookPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<
+                  ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_rollback_hook');
+  late final _sqlite3_rollback_hook = _sqlite3_rollback_hookPtr.asFunction<
+      ffi.Pointer<ffi.Void> Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<
+              ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>,
+          ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Data Change Notification Callbacks
+  /// METHOD: sqlite3
+  ///
+  /// ^The sqlite3_update_hook() interface registers a callback function
+  /// with the [database connection] identified by the first argument
+  /// to be invoked whenever a row is updated, inserted or deleted in
+  /// a [rowid table].
+  /// ^Any callback set by a previous call to this function
+  /// for the same database connection is overridden.
+  ///
+  /// ^The second argument is a pointer to the function to invoke when a
+  /// row is updated, inserted or deleted in a rowid table.
+  /// ^The first argument to the callback is a copy of the third argument
+  /// to sqlite3_update_hook().
+  /// ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
+  /// or [SQLITE_UPDATE], depending on the operation that caused the callback
+  /// to be invoked.
+  /// ^The third and fourth arguments to the callback contain pointers to the
+  /// database and table name containing the affected row.
+  /// ^The final callback parameter is the [rowid] of the row.
+  /// ^In the case of an update, this is the [rowid] after the update takes place.
+  ///
+  /// ^(The update hook is not invoked when internal system tables are
+  /// modified (i.e. sqlite_master and sqlite_sequence).)^
+  /// ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
+  ///
+  /// ^In the current implementation, the update hook
+  /// is not invoked when conflicting rows are deleted because of an
+  /// [ON CONFLICT | ON CONFLICT REPLACE] clause.  ^Nor is the update hook
+  /// invoked when rows are deleted using the [truncate optimization].
+  /// The exceptions defined in this paragraph might change in a future
+  /// release of SQLite.
+  ///
+  /// The update hook implementation must not do anything that will modify
+  /// the database connection that invoked the update hook.  Any actions
+  /// to modify the database connection must be deferred until after the
+  /// completion of the [sqlite3_step()] call that triggered the update hook.
+  /// Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
+  /// database connections for the meaning of "modify" in this paragraph.
+  ///
+  /// ^The sqlite3_update_hook(D,C,P) function
+  /// returns the P argument from the previous call
+  /// on the same [database connection] D, or NULL for
+  /// the first call on D.
+  ///
+  /// See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
+  /// and [sqlite3_preupdate_hook()] interfaces.
+  ffi.Pointer<ffi.Void> sqlite3_update_hook(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(
+                    ffi.Pointer<ffi.Void>,
+                    ffi.Int,
+                    ffi.Pointer<ffi.Char>,
+                    ffi.Pointer<ffi.Char>,
+                    sqlite3_int64)>>
+        arg1,
+    ffi.Pointer<ffi.Void> arg2,
+  ) {
+    return _sqlite3_update_hook(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_update_hookPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Char>,
+                          ffi.Pointer<ffi.Char>,
+                          sqlite3_int64)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_update_hook');
+  late final _sqlite3_update_hook = _sqlite3_update_hookPtr.asFunction<
+      ffi.Pointer<ffi.Void> Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.Void>,
+                      ffi.Int,
+                      ffi.Pointer<ffi.Char>,
+                      ffi.Pointer<ffi.Char>,
+                      sqlite3_int64)>>,
+          ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Enable Or Disable Shared Pager Cache
+  ///
+  /// ^(This routine enables or disables the sharing of the database cache
+  /// and schema data structures between [database connection | connections]
+  /// to the same database. Sharing is enabled if the argument is true
+  /// and disabled if the argument is false.)^
+  ///
+  /// ^Cache sharing is enabled and disabled for an entire process.
+  /// This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]).
+  /// In prior versions of SQLite,
+  /// sharing was enabled or disabled for each thread separately.
+  ///
+  /// ^(The cache sharing mode set by this interface effects all subsequent
+  /// calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()].
+  /// Existing database connections continue to use the sharing mode
+  /// that was in effect at the time they were opened.)^
+  ///
+  /// ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled
+  /// successfully.  An [error code] is returned otherwise.)^
+  ///
+  /// ^Shared cache is disabled by default. It is recommended that it stay
+  /// that way.  In other words, do not use this routine.  This interface
+  /// continues to be provided for historical compatibility, but its use is
+  /// discouraged.  Any use of shared cache is discouraged.  If shared cache
+  /// must be used, it is recommended that shared cache only be enabled for
+  /// individual database connections using the [sqlite3_open_v2()] interface
+  /// with the [SQLITE_OPEN_SHAREDCACHE] flag.
+  ///
+  /// Note: This method is disabled on MacOS X 10.7 and iOS version 5.0
+  /// and will always return SQLITE_MISUSE. On those systems,
+  /// shared cache mode should be enabled per-database connection via
+  /// [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE].
+  ///
+  /// This interface is threadsafe on processors where writing a
+  /// 32-bit integer is atomic.
+  ///
+  /// See Also:  [SQLite Shared-Cache Mode]
+  int sqlite3_enable_shared_cache(
+    int arg0,
+  ) {
+    return _sqlite3_enable_shared_cache(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_enable_shared_cachePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int)>>(
+          'sqlite3_enable_shared_cache');
+  late final _sqlite3_enable_shared_cache =
+      _sqlite3_enable_shared_cachePtr.asFunction<int Function(int)>();
+
+  /// CAPI3REF: Attempt To Free Heap Memory
+  ///
+  /// ^The sqlite3_release_memory() interface attempts to free N bytes
+  /// of heap memory by deallocating non-essential memory allocations
+  /// held by the database library.   Memory used to cache database
+  /// pages to improve performance is an example of non-essential memory.
+  /// ^sqlite3_release_memory() returns the number of bytes actually freed,
+  /// which might be more or less than the amount requested.
+  /// ^The sqlite3_release_memory() routine is a no-op returning zero
+  /// if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT].
+  ///
+  /// See also: [sqlite3_db_release_memory()]
+  int sqlite3_release_memory(
+    int arg0,
+  ) {
+    return _sqlite3_release_memory(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_release_memoryPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int)>>(
+          'sqlite3_release_memory');
+  late final _sqlite3_release_memory =
+      _sqlite3_release_memoryPtr.asFunction<int Function(int)>();
+
+  /// CAPI3REF: Free Memory Used By A Database Connection
+  /// METHOD: sqlite3
+  ///
+  /// ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
+  /// memory as possible from database connection D. Unlike the
+  /// [sqlite3_release_memory()] interface, this interface is in effect even
+  /// when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
+  /// omitted.
+  ///
+  /// See also: [sqlite3_release_memory()]
+  int sqlite3_db_release_memory(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_db_release_memory(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_db_release_memoryPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_db_release_memory');
+  late final _sqlite3_db_release_memory = _sqlite3_db_release_memoryPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: Impose A Limit On Heap Size
+  ///
+  /// These interfaces impose limits on the amount of heap memory that will be
+  /// by all database connections within a single process.
+  ///
+  /// ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
+  /// soft limit on the amount of heap memory that may be allocated by SQLite.
+  /// ^SQLite strives to keep heap memory utilization below the soft heap
+  /// limit by reducing the number of pages held in the page cache
+  /// as heap memory usages approaches the limit.
+  /// ^The soft heap limit is "soft" because even though SQLite strives to stay
+  /// below the limit, it will exceed the limit rather than generate
+  /// an [SQLITE_NOMEM] error.  In other words, the soft heap limit
+  /// is advisory only.
+  ///
+  /// ^The sqlite3_hard_heap_limit64(N) interface sets a hard upper bound of
+  /// N bytes on the amount of memory that will be allocated.  ^The
+  /// sqlite3_hard_heap_limit64(N) interface is similar to
+  /// sqlite3_soft_heap_limit64(N) except that memory allocations will fail
+  /// when the hard heap limit is reached.
+  ///
+  /// ^The return value from both sqlite3_soft_heap_limit64() and
+  /// sqlite3_hard_heap_limit64() is the size of
+  /// the heap limit prior to the call, or negative in the case of an
+  /// error.  ^If the argument N is negative
+  /// then no change is made to the heap limit.  Hence, the current
+  /// size of heap limits can be determined by invoking
+  /// sqlite3_soft_heap_limit64(-1) or sqlite3_hard_heap_limit(-1).
+  ///
+  /// ^Setting the heap limits to zero disables the heap limiter mechanism.
+  ///
+  /// ^The soft heap limit may not be greater than the hard heap limit.
+  /// ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N)
+  /// is invoked with a value of N that is greater than the hard heap limit,
+  /// the the soft heap limit is set to the value of the hard heap limit.
+  /// ^The soft heap limit is automatically enabled whenever the hard heap
+  /// limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and
+  /// the soft heap limit is outside the range of 1..N, then the soft heap
+  /// limit is set to N.  ^Invoking sqlite3_soft_heap_limit64(0) when the
+  /// hard heap limit is enabled makes the soft heap limit equal to the
+  /// hard heap limit.
+  ///
+  /// The memory allocation limits can also be adjusted using
+  /// [PRAGMA soft_heap_limit] and [PRAGMA hard_heap_limit].
+  ///
+  /// ^(The heap limits are not enforced in the current implementation
+  /// if one or more of following conditions are true:
+  ///
+  /// <ul>
+  /// <li> The limit value is set to zero.
+  /// <li> Memory accounting is disabled using a combination of the
+  /// [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
+  /// the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
+  /// <li> An alternative page cache implementation is specified using
+  /// [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...).
+  /// <li> The page cache allocates from its own memory pool supplied
+  /// by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
+  /// from the heap.
+  /// </ul>)^
+  ///
+  /// The circumstances under which SQLite will enforce the heap limits may
+  /// changes in future releases of SQLite.
+  int sqlite3_soft_heap_limit64(
+    int N,
+  ) {
+    return _sqlite3_soft_heap_limit64(
+      N,
+    );
+  }
+
+  late final _sqlite3_soft_heap_limit64Ptr =
+      _lookup<ffi.NativeFunction<sqlite3_int64 Function(sqlite3_int64)>>(
+          'sqlite3_soft_heap_limit64');
+  late final _sqlite3_soft_heap_limit64 =
+      _sqlite3_soft_heap_limit64Ptr.asFunction<int Function(int)>();
+
+  int sqlite3_hard_heap_limit64(
+    int N,
+  ) {
+    return _sqlite3_hard_heap_limit64(
+      N,
+    );
+  }
+
+  late final _sqlite3_hard_heap_limit64Ptr =
+      _lookup<ffi.NativeFunction<sqlite3_int64 Function(sqlite3_int64)>>(
+          'sqlite3_hard_heap_limit64');
+  late final _sqlite3_hard_heap_limit64 =
+      _sqlite3_hard_heap_limit64Ptr.asFunction<int Function(int)>();
+
+  /// CAPI3REF: Deprecated Soft Heap Limit Interface
+  /// DEPRECATED
+  ///
+  /// This is a deprecated version of the [sqlite3_soft_heap_limit64()]
+  /// interface.  This routine is provided for historical compatibility
+  /// only.  All new applications should use the
+  /// [sqlite3_soft_heap_limit64()] interface rather than this one.
+  void sqlite3_soft_heap_limit(
+    int N,
+  ) {
+    return _sqlite3_soft_heap_limit(
+      N,
+    );
+  }
+
+  late final _sqlite3_soft_heap_limitPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int)>>(
+          'sqlite3_soft_heap_limit');
+  late final _sqlite3_soft_heap_limit =
+      _sqlite3_soft_heap_limitPtr.asFunction<void Function(int)>();
+
+  /// CAPI3REF: Extract Metadata About A Column Of A Table
+  /// METHOD: sqlite3
+  ///
+  /// ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
+  /// information about column C of table T in database D
+  /// on [database connection] X.)^  ^The sqlite3_table_column_metadata()
+  /// interface returns SQLITE_OK and fills in the non-NULL pointers in
+  /// the final five arguments with appropriate values if the specified
+  /// column exists.  ^The sqlite3_table_column_metadata() interface returns
+  /// SQLITE_ERROR if the specified column does not exist.
+  /// ^If the column-name parameter to sqlite3_table_column_metadata() is a
+  /// NULL pointer, then this routine simply checks for the existence of the
+  /// table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
+  /// does not.  If the table name parameter T in a call to
+  /// sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is
+  /// undefined behavior.
+  ///
+  /// ^The column is identified by the second, third and fourth parameters to
+  /// this function. ^(The second parameter is either the name of the database
+  /// (i.e. "main", "temp", or an attached database) containing the specified
+  /// table or NULL.)^ ^If it is NULL, then all attached databases are searched
+  /// for the table using the same algorithm used by the database engine to
+  /// resolve unqualified table references.
+  ///
+  /// ^The third and fourth parameters to this function are the table and column
+  /// name of the desired column, respectively.
+  ///
+  /// ^Metadata is returned by writing to the memory locations passed as the 5th
+  /// and subsequent parameters to this function. ^Any of these arguments may be
+  /// NULL, in which case the corresponding element of metadata is omitted.
+  ///
+  /// ^(<blockquote>
+  /// <table border="1">
+  /// <tr><th> Parameter <th> Output<br>Type <th>  Description
+  ///
+  /// <tr><td> 5th <td> const char* <td> Data type
+  /// <tr><td> 6th <td> const char* <td> Name of default collation sequence
+  /// <tr><td> 7th <td> int         <td> True if column has a NOT NULL constraint
+  /// <tr><td> 8th <td> int         <td> True if column is part of the PRIMARY KEY
+  /// <tr><td> 9th <td> int         <td> True if column is [AUTOINCREMENT]
+  /// </table>
+  /// </blockquote>)^
+  ///
+  /// ^The memory pointed to by the character pointers returned for the
+  /// declaration type and collation sequence is valid until the next
+  /// call to any SQLite API function.
+  ///
+  /// ^If the specified table is actually a view, an [error code] is returned.
+  ///
+  /// ^If the specified column is "rowid", "oid" or "_rowid_" and the table
+  /// is not a [WITHOUT ROWID] table and an
+  /// [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
+  /// parameters are set for the explicitly declared column. ^(If there is no
+  /// [INTEGER PRIMARY KEY] column, then the outputs
+  /// for the [rowid] are set as follows:
+  ///
+  /// <pre>
+  /// data type: "INTEGER"
+  /// collation sequence: "BINARY"
+  /// not null: 0
+  /// primary key: 1
+  /// auto increment: 0
+  /// </pre>)^
+  ///
+  /// ^This function causes all database schemas to be read from disk and
+  /// parsed, if that has not already been done, and returns an error if
+  /// any errors are encountered while loading the schema.
+  int sqlite3_table_column_metadata(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zDbName,
+    ffi.Pointer<ffi.Char> zTableName,
+    ffi.Pointer<ffi.Char> zColumnName,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> pzDataType,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> pzCollSeq,
+    ffi.Pointer<ffi.Int> pNotNull,
+    ffi.Pointer<ffi.Int> pPrimaryKey,
+    ffi.Pointer<ffi.Int> pAutoinc,
+  ) {
+    return _sqlite3_table_column_metadata(
+      db,
+      zDbName,
+      zTableName,
+      zColumnName,
+      pzDataType,
+      pzCollSeq,
+      pNotNull,
+      pPrimaryKey,
+      pAutoinc,
+    );
+  }
+
+  late final _sqlite3_table_column_metadataPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Int>)>>('sqlite3_table_column_metadata');
+  late final _sqlite3_table_column_metadata =
+      _sqlite3_table_column_metadataPtr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Int>)>();
+
+  /// CAPI3REF: Load An Extension
+  /// METHOD: sqlite3
+  ///
+  /// ^This interface loads an SQLite extension library from the named file.
+  ///
+  /// ^The sqlite3_load_extension() interface attempts to load an
+  /// [SQLite extension] library contained in the file zFile.  If
+  /// the file cannot be loaded directly, attempts are made to load
+  /// with various operating-system specific extensions added.
+  /// So for example, if "samplelib" cannot be loaded, then names like
+  /// "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might
+  /// be tried also.
+  ///
+  /// ^The entry point is zProc.
+  /// ^(zProc may be 0, in which case SQLite will try to come up with an
+  /// entry point name on its own.  It first tries "sqlite3_extension_init".
+  /// If that does not work, it constructs a name "sqlite3_X_init" where the
+  /// X is consists of the lower-case equivalent of all ASCII alphabetic
+  /// characters in the filename from the last "/" to the first following
+  /// "." and omitting any initial "lib".)^
+  /// ^The sqlite3_load_extension() interface returns
+  /// [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
+  /// ^If an error occurs and pzErrMsg is not 0, then the
+  /// [sqlite3_load_extension()] interface shall attempt to
+  /// fill *pzErrMsg with error message text stored in memory
+  /// obtained from [sqlite3_malloc()]. The calling function
+  /// should free this memory by calling [sqlite3_free()].
+  ///
+  /// ^Extension loading must be enabled using
+  /// [sqlite3_enable_load_extension()] or
+  /// [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
+  /// prior to calling this API,
+  /// otherwise an error will be returned.
+  ///
+  /// <b>Security warning:</b> It is recommended that the
+  /// [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
+  /// interface.  The use of the [sqlite3_enable_load_extension()] interface
+  /// should be avoided.  This will keep the SQL function [load_extension()]
+  /// disabled and prevent SQL injections from giving attackers
+  /// access to extension loading capabilities.
+  ///
+  /// See also the [load_extension() SQL function].
+  int sqlite3_load_extension(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zFile,
+    ffi.Pointer<ffi.Char> zProc,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> pzErrMsg,
+  ) {
+    return _sqlite3_load_extension(
+      db,
+      zFile,
+      zProc,
+      pzErrMsg,
+    );
+  }
+
+  late final _sqlite3_load_extensionPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>)>>('sqlite3_load_extension');
+  late final _sqlite3_load_extension = _sqlite3_load_extensionPtr.asFunction<
+      int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>,
+          ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Pointer<ffi.Char>>)>();
+
+  /// CAPI3REF: Enable Or Disable Extension Loading
+  /// METHOD: sqlite3
+  ///
+  /// ^So as not to open security holes in older applications that are
+  /// unprepared to deal with [extension loading], and as a means of disabling
+  /// [extension loading] while evaluating user-entered SQL, the following API
+  /// is provided to turn the [sqlite3_load_extension()] mechanism on and off.
+  ///
+  /// ^Extension loading is off by default.
+  /// ^Call the sqlite3_enable_load_extension() routine with onoff==1
+  /// to turn extension loading on and call it with onoff==0 to turn
+  /// it back off again.
+  ///
+  /// ^This interface enables or disables both the C-API
+  /// [sqlite3_load_extension()] and the SQL function [load_extension()].
+  /// ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
+  /// to enable or disable only the C-API.)^
+  ///
+  /// <b>Security warning:</b> It is recommended that extension loading
+  /// be enabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
+  /// rather than this interface, so the [load_extension()] SQL function
+  /// remains disabled. This will prevent SQL injections from giving attackers
+  /// access to extension loading capabilities.
+  int sqlite3_enable_load_extension(
+    ffi.Pointer<sqlite3> db,
+    int onoff,
+  ) {
+    return _sqlite3_enable_load_extension(
+      db,
+      onoff,
+    );
+  }
+
+  late final _sqlite3_enable_load_extensionPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>, ffi.Int)>>(
+      'sqlite3_enable_load_extension');
+  late final _sqlite3_enable_load_extension = _sqlite3_enable_load_extensionPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>, int)>();
+
+  /// CAPI3REF: Automatically Load Statically Linked Extensions
+  ///
+  /// ^This interface causes the xEntryPoint() function to be invoked for
+  /// each new [database connection] that is created.  The idea here is that
+  /// xEntryPoint() is the entry point for a statically linked [SQLite extension]
+  /// that is to be automatically loaded into all new database connections.
+  ///
+  /// ^(Even though the function prototype shows that xEntryPoint() takes
+  /// no arguments and returns void, SQLite invokes xEntryPoint() with three
+  /// arguments and expects an integer result as if the signature of the
+  /// entry point where as follows:
+  ///
+  /// <blockquote><pre>
+  /// &nbsp;  int xEntryPoint(
+  /// &nbsp;    sqlite3 *db,
+  /// &nbsp;    const char **pzErrMsg,
+  /// &nbsp;    const struct sqlite3_api_routines *pThunk
+  /// &nbsp;  );
+  /// </pre></blockquote>)^
+  ///
+  /// If the xEntryPoint routine encounters an error, it should make *pzErrMsg
+  /// point to an appropriate error message (obtained from [sqlite3_mprintf()])
+  /// and return an appropriate [error code].  ^SQLite ensures that *pzErrMsg
+  /// is NULL before calling the xEntryPoint().  ^SQLite will invoke
+  /// [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns.  ^If any
+  /// xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()],
+  /// or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail.
+  ///
+  /// ^Calling sqlite3_auto_extension(X) with an entry point X that is already
+  /// on the list of automatic extensions is a harmless no-op. ^No entry point
+  /// will be called more than once for each database connection that is opened.
+  ///
+  /// See also: [sqlite3_reset_auto_extension()]
+  /// and [sqlite3_cancel_auto_extension()]
+  int sqlite3_auto_extension(
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> xEntryPoint,
+  ) {
+    return _sqlite3_auto_extension(
+      xEntryPoint,
+    );
+  }
+
+  late final _sqlite3_auto_extensionPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>>(
+      'sqlite3_auto_extension');
+  late final _sqlite3_auto_extension = _sqlite3_auto_extensionPtr.asFunction<
+      int Function(ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>();
+
+  /// CAPI3REF: Cancel Automatic Extension Loading
+  ///
+  /// ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
+  /// initialization routine X that was registered using a prior call to
+  /// [sqlite3_auto_extension(X)].  ^The [sqlite3_cancel_auto_extension(X)]
+  /// routine returns 1 if initialization routine X was successfully
+  /// unregistered and it returns 0 if X was not on the list of initialization
+  /// routines.
+  int sqlite3_cancel_auto_extension(
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> xEntryPoint,
+  ) {
+    return _sqlite3_cancel_auto_extension(
+      xEntryPoint,
+    );
+  }
+
+  late final _sqlite3_cancel_auto_extensionPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>>(
+      'sqlite3_cancel_auto_extension');
+  late final _sqlite3_cancel_auto_extension =
+      _sqlite3_cancel_auto_extensionPtr.asFunction<
+          int Function(ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>();
+
+  /// CAPI3REF: Reset Automatic Extension Loading
+  ///
+  /// ^This interface disables all automatic extensions previously
+  /// registered using [sqlite3_auto_extension()].
+  void sqlite3_reset_auto_extension() {
+    return _sqlite3_reset_auto_extension();
+  }
+
+  late final _sqlite3_reset_auto_extensionPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function()>>(
+          'sqlite3_reset_auto_extension');
+  late final _sqlite3_reset_auto_extension =
+      _sqlite3_reset_auto_extensionPtr.asFunction<void Function()>();
+
+  /// CAPI3REF: Register A Virtual Table Implementation
+  /// METHOD: sqlite3
+  ///
+  /// ^These routines are used to register a new [virtual table module] name.
+  /// ^Module names must be registered before
+  /// creating a new [virtual table] using the module and before using a
+  /// preexisting [virtual table] for the module.
+  ///
+  /// ^The module name is registered on the [database connection] specified
+  /// by the first parameter.  ^The name of the module is given by the
+  /// second parameter.  ^The third parameter is a pointer to
+  /// the implementation of the [virtual table module].   ^The fourth
+  /// parameter is an arbitrary client data pointer that is passed through
+  /// into the [xCreate] and [xConnect] methods of the virtual table module
+  /// when a new virtual table is be being created or reinitialized.
+  ///
+  /// ^The sqlite3_create_module_v2() interface has a fifth parameter which
+  /// is a pointer to a destructor for the pClientData.  ^SQLite will
+  /// invoke the destructor function (if it is not NULL) when SQLite
+  /// no longer needs the pClientData pointer.  ^The destructor will also
+  /// be invoked if the call to sqlite3_create_module_v2() fails.
+  /// ^The sqlite3_create_module()
+  /// interface is equivalent to sqlite3_create_module_v2() with a NULL
+  /// destructor.
+  ///
+  /// ^If the third parameter (the pointer to the sqlite3_module object) is
+  /// NULL then no new module is create and any existing modules with the
+  /// same name are dropped.
+  ///
+  /// See also: [sqlite3_drop_modules()]
+  int sqlite3_create_module(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zName,
+    ffi.Pointer<sqlite3_module> p,
+    ffi.Pointer<ffi.Void> pClientData,
+  ) {
+    return _sqlite3_create_module(
+      db,
+      zName,
+      p,
+      pClientData,
+    );
+  }
+
+  late final _sqlite3_create_modulePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<sqlite3_module>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_create_module');
+  late final _sqlite3_create_module = _sqlite3_create_modulePtr.asFunction<
+      int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>,
+          ffi.Pointer<sqlite3_module>, ffi.Pointer<ffi.Void>)>();
+
+  int sqlite3_create_module_v2(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zName,
+    ffi.Pointer<sqlite3_module> p,
+    ffi.Pointer<ffi.Void> pClientData,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        xDestroy,
+  ) {
+    return _sqlite3_create_module_v2(
+      db,
+      zName,
+      p,
+      pClientData,
+      xDestroy,
+    );
+  }
+
+  late final _sqlite3_create_module_v2Ptr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3>,
+                  ffi.Pointer<ffi.Char>,
+                  ffi.Pointer<sqlite3_module>,
+                  ffi.Pointer<ffi.Void>,
+                  ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
+      'sqlite3_create_module_v2');
+  late final _sqlite3_create_module_v2 =
+      _sqlite3_create_module_v2Ptr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<sqlite3_module>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+
+  /// CAPI3REF: Remove Unnecessary Virtual Table Implementations
+  /// METHOD: sqlite3
+  ///
+  /// ^The sqlite3_drop_modules(D,L) interface removes all virtual
+  /// table modules from database connection D except those named on list L.
+  /// The L parameter must be either NULL or a pointer to an array of pointers
+  /// to strings where the array is terminated by a single NULL pointer.
+  /// ^If the L parameter is NULL, then all virtual table modules are removed.
+  ///
+  /// See also: [sqlite3_create_module()]
+  int sqlite3_drop_modules(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> azKeep,
+  ) {
+    return _sqlite3_drop_modules(
+      db,
+      azKeep,
+    );
+  }
+
+  late final _sqlite3_drop_modulesPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>)>>('sqlite3_drop_modules');
+  late final _sqlite3_drop_modules = _sqlite3_drop_modulesPtr.asFunction<
+      int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Pointer<ffi.Char>>)>();
+
+  /// CAPI3REF: Declare The Schema Of A Virtual Table
+  ///
+  /// ^The [xCreate] and [xConnect] methods of a
+  /// [virtual table module] call this interface
+  /// to declare the format (the names and datatypes of the columns) of
+  /// the virtual tables they implement.
+  int sqlite3_declare_vtab(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.Char> zSQL,
+  ) {
+    return _sqlite3_declare_vtab(
+      arg0,
+      zSQL,
+    );
+  }
+
+  late final _sqlite3_declare_vtabPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_declare_vtab');
+  late final _sqlite3_declare_vtab = _sqlite3_declare_vtabPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: Overload A Function For A Virtual Table
+  /// METHOD: sqlite3
+  ///
+  /// ^(Virtual tables can provide alternative implementations of functions
+  /// using the [xFindFunction] method of the [virtual table module].
+  /// But global versions of those functions
+  /// must exist in order to be overloaded.)^
+  ///
+  /// ^(This API makes sure a global version of a function with a particular
+  /// name and number of parameters exists.  If no such function exists
+  /// before this API is called, a new function is created.)^  ^The implementation
+  /// of the new function always causes an exception to be thrown.  So
+  /// the new function is not good for anything by itself.  Its only
+  /// purpose is to be a placeholder function that can be overloaded
+  /// by a [virtual table].
+  int sqlite3_overload_function(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.Char> zFuncName,
+    int nArg,
+  ) {
+    return _sqlite3_overload_function(
+      arg0,
+      zFuncName,
+      nArg,
+    );
+  }
+
+  late final _sqlite3_overload_functionPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>,
+              ffi.Int)>>('sqlite3_overload_function');
+  late final _sqlite3_overload_function =
+      _sqlite3_overload_functionPtr.asFunction<
+          int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>, int)>();
+
+  /// CAPI3REF: Open A BLOB For Incremental I/O
+  /// METHOD: sqlite3
+  /// CONSTRUCTOR: sqlite3_blob
+  ///
+  /// ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
+  /// in row iRow, column zColumn, table zTable in database zDb;
+  /// in other words, the same BLOB that would be selected by:
+  ///
+  /// <pre>
+  /// SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
+  /// </pre>)^
+  ///
+  /// ^(Parameter zDb is not the filename that contains the database, but
+  /// rather the symbolic name of the database. For attached databases, this is
+  /// the name that appears after the AS keyword in the [ATTACH] statement.
+  /// For the main database file, the database name is "main". For TEMP
+  /// tables, the database name is "temp".)^
+  ///
+  /// ^If the flags parameter is non-zero, then the BLOB is opened for read
+  /// and write access. ^If the flags parameter is zero, the BLOB is opened for
+  /// read-only access.
+  ///
+  /// ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
+  /// in *ppBlob. Otherwise an [error code] is returned and, unless the error
+  /// code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
+  /// the API is not misused, it is always safe to call [sqlite3_blob_close()]
+  /// on *ppBlob after this function it returns.
+  ///
+  /// This function fails with SQLITE_ERROR if any of the following are true:
+  /// <ul>
+  /// <li> ^(Database zDb does not exist)^,
+  /// <li> ^(Table zTable does not exist within database zDb)^,
+  /// <li> ^(Table zTable is a WITHOUT ROWID table)^,
+  /// <li> ^(Column zColumn does not exist)^,
+  /// <li> ^(Row iRow is not present in the table)^,
+  /// <li> ^(The specified column of row iRow contains a value that is not
+  /// a TEXT or BLOB value)^,
+  /// <li> ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE
+  /// constraint and the blob is being opened for read/write access)^,
+  /// <li> ^([foreign key constraints | Foreign key constraints] are enabled,
+  /// column zColumn is part of a [child key] definition and the blob is
+  /// being opened for read/write access)^.
+  /// </ul>
+  ///
+  /// ^Unless it returns SQLITE_MISUSE, this function sets the
+  /// [database connection] error code and message accessible via
+  /// [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
+  ///
+  /// A BLOB referenced by sqlite3_blob_open() may be read using the
+  /// [sqlite3_blob_read()] interface and modified by using
+  /// [sqlite3_blob_write()].  The [BLOB handle] can be moved to a
+  /// different row of the same table using the [sqlite3_blob_reopen()]
+  /// interface.  However, the column, table, or database of a [BLOB handle]
+  /// cannot be changed after the [BLOB handle] is opened.
+  ///
+  /// ^(If the row that a BLOB handle points to is modified by an
+  /// [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
+  /// then the BLOB handle is marked as "expired".
+  /// This is true if any column of the row is changed, even a column
+  /// other than the one the BLOB handle is open on.)^
+  /// ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
+  /// an expired BLOB handle fail with a return code of [SQLITE_ABORT].
+  /// ^(Changes written into a BLOB prior to the BLOB expiring are not
+  /// rolled back by the expiration of the BLOB.  Such changes will eventually
+  /// commit if the transaction continues to completion.)^
+  ///
+  /// ^Use the [sqlite3_blob_bytes()] interface to determine the size of
+  /// the opened blob.  ^The size of a blob may not be changed by this
+  /// interface.  Use the [UPDATE] SQL command to change the size of a
+  /// blob.
+  ///
+  /// ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
+  /// and the built-in [zeroblob] SQL function may be used to create a
+  /// zero-filled blob to read or write using the incremental-blob interface.
+  ///
+  /// To avoid a resource leak, every open [BLOB handle] should eventually
+  /// be released by a call to [sqlite3_blob_close()].
+  ///
+  /// See also: [sqlite3_blob_close()],
+  /// [sqlite3_blob_reopen()], [sqlite3_blob_read()],
+  /// [sqlite3_blob_bytes()], [sqlite3_blob_write()].
+  int sqlite3_blob_open(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.Char> zDb,
+    ffi.Pointer<ffi.Char> zTable,
+    ffi.Pointer<ffi.Char> zColumn,
+    int iRow,
+    int flags,
+    ffi.Pointer<ffi.Pointer<sqlite3_blob>> ppBlob,
+  ) {
+    return _sqlite3_blob_open(
+      arg0,
+      zDb,
+      zTable,
+      zColumn,
+      iRow,
+      flags,
+      ppBlob,
+    );
+  }
+
+  late final _sqlite3_blob_openPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>,
+              sqlite3_int64,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<sqlite3_blob>>)>>('sqlite3_blob_open');
+  late final _sqlite3_blob_open = _sqlite3_blob_openPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Char>,
+          ffi.Pointer<ffi.Char>,
+          ffi.Pointer<ffi.Char>,
+          int,
+          int,
+          ffi.Pointer<ffi.Pointer<sqlite3_blob>>)>();
+
+  /// CAPI3REF: Move a BLOB Handle to a New Row
+  /// METHOD: sqlite3_blob
+  ///
+  /// ^This function is used to move an existing [BLOB handle] so that it points
+  /// to a different row of the same database table. ^The new row is identified
+  /// by the rowid value passed as the second argument. Only the row can be
+  /// changed. ^The database, table and column on which the blob handle is open
+  /// remain the same. Moving an existing [BLOB handle] to a new row is
+  /// faster than closing the existing handle and opening a new one.
+  ///
+  /// ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
+  /// it must exist and there must be either a blob or text value stored in
+  /// the nominated column.)^ ^If the new row is not present in the table, or if
+  /// it does not contain a blob or text value, or if another error occurs, an
+  /// SQLite error code is returned and the blob handle is considered aborted.
+  /// ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or
+  /// [sqlite3_blob_reopen()] on an aborted blob handle immediately return
+  /// SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
+  /// always returns zero.
+  ///
+  /// ^This function sets the database handle error code and message.
+  int sqlite3_blob_reopen(
+    ffi.Pointer<sqlite3_blob> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_blob_reopen(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_blob_reopenPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_blob>,
+              sqlite3_int64)>>('sqlite3_blob_reopen');
+  late final _sqlite3_blob_reopen = _sqlite3_blob_reopenPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_blob>, int)>();
+
+  /// CAPI3REF: Close A BLOB Handle
+  /// DESTRUCTOR: sqlite3_blob
+  ///
+  /// ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
+  /// unconditionally.  Even if this routine returns an error code, the
+  /// handle is still closed.)^
+  ///
+  /// ^If the blob handle being closed was opened for read-write access, and if
+  /// the database is in auto-commit mode and there are no other open read-write
+  /// blob handles or active write statements, the current transaction is
+  /// committed. ^If an error occurs while committing the transaction, an error
+  /// code is returned and the transaction rolled back.
+  ///
+  /// Calling this function with an argument that is not a NULL pointer or an
+  /// open blob handle results in undefined behaviour. ^Calling this routine
+  /// with a null pointer (such as would be returned by a failed call to
+  /// [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
+  /// is passed a valid open blob handle, the values returned by the
+  /// sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
+  int sqlite3_blob_close(
+    ffi.Pointer<sqlite3_blob> arg0,
+  ) {
+    return _sqlite3_blob_close(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_blob_closePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_blob>)>>(
+          'sqlite3_blob_close');
+  late final _sqlite3_blob_close = _sqlite3_blob_closePtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_blob>)>();
+
+  /// CAPI3REF: Return The Size Of An Open BLOB
+  /// METHOD: sqlite3_blob
+  ///
+  /// ^Returns the size in bytes of the BLOB accessible via the
+  /// successfully opened [BLOB handle] in its only argument.  ^The
+  /// incremental blob I/O routines can only read or overwriting existing
+  /// blob content; they cannot change the size of a blob.
+  ///
+  /// This routine only works on a [BLOB handle] which has been created
+  /// by a prior successful call to [sqlite3_blob_open()] and which has not
+  /// been closed by [sqlite3_blob_close()].  Passing any other pointer in
+  /// to this routine results in undefined and probably undesirable behavior.
+  int sqlite3_blob_bytes(
+    ffi.Pointer<sqlite3_blob> arg0,
+  ) {
+    return _sqlite3_blob_bytes(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_blob_bytesPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_blob>)>>(
+          'sqlite3_blob_bytes');
+  late final _sqlite3_blob_bytes = _sqlite3_blob_bytesPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_blob>)>();
+
+  /// CAPI3REF: Read Data From A BLOB Incrementally
+  /// METHOD: sqlite3_blob
+  ///
+  /// ^(This function is used to read data from an open [BLOB handle] into a
+  /// caller-supplied buffer. N bytes of data are copied into buffer Z
+  /// from the open BLOB, starting at offset iOffset.)^
+  ///
+  /// ^If offset iOffset is less than N bytes from the end of the BLOB,
+  /// [SQLITE_ERROR] is returned and no data is read.  ^If N or iOffset is
+  /// less than zero, [SQLITE_ERROR] is returned and no data is read.
+  /// ^The size of the blob (and hence the maximum value of N+iOffset)
+  /// can be determined using the [sqlite3_blob_bytes()] interface.
+  ///
+  /// ^An attempt to read from an expired [BLOB handle] fails with an
+  /// error code of [SQLITE_ABORT].
+  ///
+  /// ^(On success, sqlite3_blob_read() returns SQLITE_OK.
+  /// Otherwise, an [error code] or an [extended error code] is returned.)^
+  ///
+  /// This routine only works on a [BLOB handle] which has been created
+  /// by a prior successful call to [sqlite3_blob_open()] and which has not
+  /// been closed by [sqlite3_blob_close()].  Passing any other pointer in
+  /// to this routine results in undefined and probably undesirable behavior.
+  ///
+  /// See also: [sqlite3_blob_write()].
+  int sqlite3_blob_read(
+    ffi.Pointer<sqlite3_blob> arg0,
+    ffi.Pointer<ffi.Void> Z,
+    int N,
+    int iOffset,
+  ) {
+    return _sqlite3_blob_read(
+      arg0,
+      Z,
+      N,
+      iOffset,
+    );
+  }
+
+  late final _sqlite3_blob_readPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_blob>, ffi.Pointer<ffi.Void>,
+              ffi.Int, ffi.Int)>>('sqlite3_blob_read');
+  late final _sqlite3_blob_read = _sqlite3_blob_readPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3_blob>, ffi.Pointer<ffi.Void>, int, int)>();
+
+  /// CAPI3REF: Write Data Into A BLOB Incrementally
+  /// METHOD: sqlite3_blob
+  ///
+  /// ^(This function is used to write data into an open [BLOB handle] from a
+  /// caller-supplied buffer. N bytes of data are copied from the buffer Z
+  /// into the open BLOB, starting at offset iOffset.)^
+  ///
+  /// ^(On success, sqlite3_blob_write() returns SQLITE_OK.
+  /// Otherwise, an  [error code] or an [extended error code] is returned.)^
+  /// ^Unless SQLITE_MISUSE is returned, this function sets the
+  /// [database connection] error code and message accessible via
+  /// [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
+  ///
+  /// ^If the [BLOB handle] passed as the first argument was not opened for
+  /// writing (the flags parameter to [sqlite3_blob_open()] was zero),
+  /// this function returns [SQLITE_READONLY].
+  ///
+  /// This function may only modify the contents of the BLOB; it is
+  /// not possible to increase the size of a BLOB using this API.
+  /// ^If offset iOffset is less than N bytes from the end of the BLOB,
+  /// [SQLITE_ERROR] is returned and no data is written. The size of the
+  /// BLOB (and hence the maximum value of N+iOffset) can be determined
+  /// using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less
+  /// than zero [SQLITE_ERROR] is returned and no data is written.
+  ///
+  /// ^An attempt to write to an expired [BLOB handle] fails with an
+  /// error code of [SQLITE_ABORT].  ^Writes to the BLOB that occurred
+  /// before the [BLOB handle] expired are not rolled back by the
+  /// expiration of the handle, though of course those changes might
+  /// have been overwritten by the statement that expired the BLOB handle
+  /// or by other independent statements.
+  ///
+  /// This routine only works on a [BLOB handle] which has been created
+  /// by a prior successful call to [sqlite3_blob_open()] and which has not
+  /// been closed by [sqlite3_blob_close()].  Passing any other pointer in
+  /// to this routine results in undefined and probably undesirable behavior.
+  ///
+  /// See also: [sqlite3_blob_read()].
+  int sqlite3_blob_write(
+    ffi.Pointer<sqlite3_blob> arg0,
+    ffi.Pointer<ffi.Void> z,
+    int n,
+    int iOffset,
+  ) {
+    return _sqlite3_blob_write(
+      arg0,
+      z,
+      n,
+      iOffset,
+    );
+  }
+
+  late final _sqlite3_blob_writePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_blob>, ffi.Pointer<ffi.Void>,
+              ffi.Int, ffi.Int)>>('sqlite3_blob_write');
+  late final _sqlite3_blob_write = _sqlite3_blob_writePtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3_blob>, ffi.Pointer<ffi.Void>, int, int)>();
+
+  /// CAPI3REF: Virtual File System Objects
+  ///
+  /// A virtual filesystem (VFS) is an [sqlite3_vfs] object
+  /// that SQLite uses to interact
+  /// with the underlying operating system.  Most SQLite builds come with a
+  /// single default VFS that is appropriate for the host computer.
+  /// New VFSes can be registered and existing VFSes can be unregistered.
+  /// The following interfaces are provided.
+  ///
+  /// ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name.
+  /// ^Names are case sensitive.
+  /// ^Names are zero-terminated UTF-8 strings.
+  /// ^If there is no match, a NULL pointer is returned.
+  /// ^If zVfsName is NULL then the default VFS is returned.
+  ///
+  /// ^New VFSes are registered with sqlite3_vfs_register().
+  /// ^Each new VFS becomes the default VFS if the makeDflt flag is set.
+  /// ^The same VFS can be registered multiple times without injury.
+  /// ^To make an existing VFS into the default VFS, register it again
+  /// with the makeDflt flag set.  If two different VFSes with the
+  /// same name are registered, the behavior is undefined.  If a
+  /// VFS is registered with a name that is NULL or an empty string,
+  /// then the behavior is undefined.
+  ///
+  /// ^Unregister a VFS with the sqlite3_vfs_unregister() interface.
+  /// ^(If the default VFS is unregistered, another VFS is chosen as
+  /// the default.  The choice for the new VFS is arbitrary.)^
+  ffi.Pointer<sqlite3_vfs> sqlite3_vfs_find(
+    ffi.Pointer<ffi.Char> zVfsName,
+  ) {
+    return _sqlite3_vfs_find(
+      zVfsName,
+    );
+  }
+
+  late final _sqlite3_vfs_findPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3_vfs> Function(
+              ffi.Pointer<ffi.Char>)>>('sqlite3_vfs_find');
+  late final _sqlite3_vfs_find = _sqlite3_vfs_findPtr
+      .asFunction<ffi.Pointer<sqlite3_vfs> Function(ffi.Pointer<ffi.Char>)>();
+
+  int sqlite3_vfs_register(
+    ffi.Pointer<sqlite3_vfs> arg0,
+    int makeDflt,
+  ) {
+    return _sqlite3_vfs_register(
+      arg0,
+      makeDflt,
+    );
+  }
+
+  late final _sqlite3_vfs_registerPtr = _lookup<
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vfs>, ffi.Int)>>(
+      'sqlite3_vfs_register');
+  late final _sqlite3_vfs_register = _sqlite3_vfs_registerPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_vfs>, int)>();
+
+  int sqlite3_vfs_unregister(
+    ffi.Pointer<sqlite3_vfs> arg0,
+  ) {
+    return _sqlite3_vfs_unregister(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_vfs_unregisterPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vfs>)>>(
+          'sqlite3_vfs_unregister');
+  late final _sqlite3_vfs_unregister = _sqlite3_vfs_unregisterPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_vfs>)>();
+
+  /// CAPI3REF: Mutexes
+  ///
+  /// The SQLite core uses these routines for thread
+  /// synchronization. Though they are intended for internal
+  /// use by SQLite, code that links against SQLite is
+  /// permitted to use any of these routines.
+  ///
+  /// The SQLite source code contains multiple implementations
+  /// of these mutex routines.  An appropriate implementation
+  /// is selected automatically at compile-time.  The following
+  /// implementations are available in the SQLite core:
+  ///
+  /// <ul>
+  /// <li>   SQLITE_MUTEX_PTHREADS
+  /// <li>   SQLITE_MUTEX_W32
+  /// <li>   SQLITE_MUTEX_NOOP
+  /// </ul>
+  ///
+  /// The SQLITE_MUTEX_NOOP implementation is a set of routines
+  /// that does no real locking and is appropriate for use in
+  /// a single-threaded application.  The SQLITE_MUTEX_PTHREADS and
+  /// SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
+  /// and Windows.
+  ///
+  /// If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
+  /// macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
+  /// implementation is included with the library. In this case the
+  /// application must supply a custom mutex implementation using the
+  /// [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
+  /// before calling sqlite3_initialize() or any other public sqlite3_
+  /// function that calls sqlite3_initialize().
+  ///
+  /// ^The sqlite3_mutex_alloc() routine allocates a new
+  /// mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
+  /// routine returns NULL if it is unable to allocate the requested
+  /// mutex.  The argument to sqlite3_mutex_alloc() must one of these
+  /// integer constants:
+  ///
+  /// <ul>
+  /// <li>  SQLITE_MUTEX_FAST
+  /// <li>  SQLITE_MUTEX_RECURSIVE
+  /// <li>  SQLITE_MUTEX_STATIC_MASTER
+  /// <li>  SQLITE_MUTEX_STATIC_MEM
+  /// <li>  SQLITE_MUTEX_STATIC_OPEN
+  /// <li>  SQLITE_MUTEX_STATIC_PRNG
+  /// <li>  SQLITE_MUTEX_STATIC_LRU
+  /// <li>  SQLITE_MUTEX_STATIC_PMEM
+  /// <li>  SQLITE_MUTEX_STATIC_APP1
+  /// <li>  SQLITE_MUTEX_STATIC_APP2
+  /// <li>  SQLITE_MUTEX_STATIC_APP3
+  /// <li>  SQLITE_MUTEX_STATIC_VFS1
+  /// <li>  SQLITE_MUTEX_STATIC_VFS2
+  /// <li>  SQLITE_MUTEX_STATIC_VFS3
+  /// </ul>
+  ///
+  /// ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
+  /// cause sqlite3_mutex_alloc() to create
+  /// a new mutex.  ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
+  /// is used but not necessarily so when SQLITE_MUTEX_FAST is used.
+  /// The mutex implementation does not need to make a distinction
+  /// between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
+  /// not want to.  SQLite will only request a recursive mutex in
+  /// cases where it really needs one.  If a faster non-recursive mutex
+  /// implementation is available on the host platform, the mutex subsystem
+  /// might return such a mutex in response to SQLITE_MUTEX_FAST.
+  ///
+  /// ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
+  /// than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
+  /// a pointer to a static preexisting mutex.  ^Nine static mutexes are
+  /// used by the current version of SQLite.  Future versions of SQLite
+  /// may add additional static mutexes.  Static mutexes are for internal
+  /// use by SQLite only.  Applications that use SQLite mutexes should
+  /// use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
+  /// SQLITE_MUTEX_RECURSIVE.
+  ///
+  /// ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
+  /// or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
+  /// returns a different mutex on every call.  ^For the static
+  /// mutex types, the same mutex is returned on every call that has
+  /// the same type number.
+  ///
+  /// ^The sqlite3_mutex_free() routine deallocates a previously
+  /// allocated dynamic mutex.  Attempting to deallocate a static
+  /// mutex results in undefined behavior.
+  ///
+  /// ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
+  /// to enter a mutex.  ^If another thread is already within the mutex,
+  /// sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
+  /// SQLITE_BUSY.  ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
+  /// upon successful entry.  ^(Mutexes created using
+  /// SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
+  /// In such cases, the
+  /// mutex must be exited an equal number of times before another thread
+  /// can enter.)^  If the same thread tries to enter any mutex other
+  /// than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
+  ///
+  /// ^(Some systems (for example, Windows 95) do not support the operation
+  /// implemented by sqlite3_mutex_try().  On those systems, sqlite3_mutex_try()
+  /// will always return SQLITE_BUSY. The SQLite core only ever uses
+  /// sqlite3_mutex_try() as an optimization so this is acceptable
+  /// behavior.)^
+  ///
+  /// ^The sqlite3_mutex_leave() routine exits a mutex that was
+  /// previously entered by the same thread.   The behavior
+  /// is undefined if the mutex is not currently entered by the
+  /// calling thread or is not currently allocated.
+  ///
+  /// ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
+  /// sqlite3_mutex_leave() is a NULL pointer, then all three routines
+  /// behave as no-ops.
+  ///
+  /// See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
+  ffi.Pointer<sqlite3_mutex> sqlite3_mutex_alloc(
+    int arg0,
+  ) {
+    return _sqlite3_mutex_alloc(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_mutex_allocPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<sqlite3_mutex> Function(ffi.Int)>>(
+          'sqlite3_mutex_alloc');
+  late final _sqlite3_mutex_alloc = _sqlite3_mutex_allocPtr
+      .asFunction<ffi.Pointer<sqlite3_mutex> Function(int)>();
+
+  void sqlite3_mutex_free(
+    ffi.Pointer<sqlite3_mutex> arg0,
+  ) {
+    return _sqlite3_mutex_free(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_mutex_freePtr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_mutex>)>>(
+      'sqlite3_mutex_free');
+  late final _sqlite3_mutex_free = _sqlite3_mutex_freePtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_mutex>)>();
+
+  void sqlite3_mutex_enter(
+    ffi.Pointer<sqlite3_mutex> arg0,
+  ) {
+    return _sqlite3_mutex_enter(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_mutex_enterPtr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_mutex>)>>(
+      'sqlite3_mutex_enter');
+  late final _sqlite3_mutex_enter = _sqlite3_mutex_enterPtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_mutex>)>();
+
+  int sqlite3_mutex_try(
+    ffi.Pointer<sqlite3_mutex> arg0,
+  ) {
+    return _sqlite3_mutex_try(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_mutex_tryPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>(
+          'sqlite3_mutex_try');
+  late final _sqlite3_mutex_try = _sqlite3_mutex_tryPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_mutex>)>();
+
+  void sqlite3_mutex_leave(
+    ffi.Pointer<sqlite3_mutex> arg0,
+  ) {
+    return _sqlite3_mutex_leave(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_mutex_leavePtr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_mutex>)>>(
+      'sqlite3_mutex_leave');
+  late final _sqlite3_mutex_leave = _sqlite3_mutex_leavePtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_mutex>)>();
+
+  int sqlite3_mutex_held(
+    ffi.Pointer<sqlite3_mutex> arg0,
+  ) {
+    return _sqlite3_mutex_held(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_mutex_heldPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>(
+          'sqlite3_mutex_held');
+  late final _sqlite3_mutex_held = _sqlite3_mutex_heldPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_mutex>)>();
+
+  int sqlite3_mutex_notheld(
+    ffi.Pointer<sqlite3_mutex> arg0,
+  ) {
+    return _sqlite3_mutex_notheld(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_mutex_notheldPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>(
+          'sqlite3_mutex_notheld');
+  late final _sqlite3_mutex_notheld = _sqlite3_mutex_notheldPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_mutex>)>();
+
+  /// CAPI3REF: Retrieve the mutex for a database connection
+  /// METHOD: sqlite3
+  ///
+  /// ^This interface returns a pointer the [sqlite3_mutex] object that
+  /// serializes access to the [database connection] given in the argument
+  /// when the [threading mode] is Serialized.
+  /// ^If the [threading mode] is Single-thread or Multi-thread then this
+  /// routine returns a NULL pointer.
+  ffi.Pointer<sqlite3_mutex> sqlite3_db_mutex(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_db_mutex(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_db_mutexPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3_mutex> Function(
+              ffi.Pointer<sqlite3>)>>('sqlite3_db_mutex');
+  late final _sqlite3_db_mutex = _sqlite3_db_mutexPtr
+      .asFunction<ffi.Pointer<sqlite3_mutex> Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: Low-Level Control Of Database Files
+  /// METHOD: sqlite3
+  /// KEYWORDS: {file control}
+  ///
+  /// ^The [sqlite3_file_control()] interface makes a direct call to the
+  /// xFileControl method for the [sqlite3_io_methods] object associated
+  /// with a particular database identified by the second argument. ^The
+  /// name of the database is "main" for the main database or "temp" for the
+  /// TEMP database, or the name that appears after the AS keyword for
+  /// databases that are added using the [ATTACH] SQL command.
+  /// ^A NULL pointer can be used in place of "main" to refer to the
+  /// main database file.
+  /// ^The third and fourth parameters to this routine
+  /// are passed directly through to the second and third parameters of
+  /// the xFileControl method.  ^The return value of the xFileControl
+  /// method becomes the return value of this routine.
+  ///
+  /// A few opcodes for [sqlite3_file_control()] are handled directly
+  /// by the SQLite core and never invoke the
+  /// sqlite3_io_methods.xFileControl method.
+  /// ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
+  /// a pointer to the underlying [sqlite3_file] object to be written into
+  /// the space pointed to by the 4th parameter.  The
+  /// [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
+  /// the [sqlite3_file] object associated with the journal file instead of
+  /// the main database.  The [SQLITE_FCNTL_VFS_POINTER] opcode returns
+  /// a pointer to the underlying [sqlite3_vfs] object for the file.
+  /// The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter
+  /// from the pager.
+  ///
+  /// ^If the second parameter (zDbName) does not match the name of any
+  /// open database file, then SQLITE_ERROR is returned.  ^This error
+  /// code is not remembered and will not be recalled by [sqlite3_errcode()]
+  /// or [sqlite3_errmsg()].  The underlying xFileControl method might
+  /// also return SQLITE_ERROR.  There is no way to distinguish between
+  /// an incorrect zDbName and an SQLITE_ERROR return from the underlying
+  /// xFileControl method.
+  ///
+  /// See also: [file control opcodes]
+  int sqlite3_file_control(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<ffi.Char> zDbName,
+    int op,
+    ffi.Pointer<ffi.Void> arg3,
+  ) {
+    return _sqlite3_file_control(
+      arg0,
+      zDbName,
+      op,
+      arg3,
+    );
+  }
+
+  late final _sqlite3_file_controlPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>, ffi.Int,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_file_control');
+  late final _sqlite3_file_control = _sqlite3_file_controlPtr.asFunction<
+      int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>, int,
+          ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Testing Interface
+  ///
+  /// ^The sqlite3_test_control() interface is used to read out internal
+  /// state of SQLite and to inject faults into SQLite for testing
+  /// purposes.  ^The first parameter is an operation code that determines
+  /// the number, meaning, and operation of all subsequent parameters.
+  ///
+  /// This interface is not for use by applications.  It exists solely
+  /// for verifying the correct operation of the SQLite library.  Depending
+  /// on how the SQLite library is compiled, this interface might not exist.
+  ///
+  /// The details of the operation codes, their meanings, the parameters
+  /// they take, and what they do are all subject to change without notice.
+  /// Unlike most of the SQLite API, this function is not guaranteed to
+  /// operate consistently from one release to the next.
+  int sqlite3_test_control(
+    int op,
+  ) {
+    return _sqlite3_test_control(
+      op,
+    );
+  }
+
+  late final _sqlite3_test_controlPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int)>>(
+          'sqlite3_test_control');
+  late final _sqlite3_test_control =
+      _sqlite3_test_controlPtr.asFunction<int Function(int)>();
+
+  /// CAPI3REF: SQL Keyword Checking
+  ///
+  /// These routines provide access to the set of SQL language keywords
+  /// recognized by SQLite.  Applications can uses these routines to determine
+  /// whether or not a specific identifier needs to be escaped (for example,
+  /// by enclosing in double-quotes) so as not to confuse the parser.
+  ///
+  /// The sqlite3_keyword_count() interface returns the number of distinct
+  /// keywords understood by SQLite.
+  ///
+  /// The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
+  /// makes *Z point to that keyword expressed as UTF8 and writes the number
+  /// of bytes in the keyword into *L.  The string that *Z points to is not
+  /// zero-terminated.  The sqlite3_keyword_name(N,Z,L) routine returns
+  /// SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
+  /// or L are NULL or invalid pointers then calls to
+  /// sqlite3_keyword_name(N,Z,L) result in undefined behavior.
+  ///
+  /// The sqlite3_keyword_check(Z,L) interface checks to see whether or not
+  /// the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero
+  /// if it is and zero if not.
+  ///
+  /// The parser used by SQLite is forgiving.  It is often possible to use
+  /// a keyword as an identifier as long as such use does not result in a
+  /// parsing ambiguity.  For example, the statement
+  /// "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and
+  /// creates a new table named "BEGIN" with three columns named
+  /// "REPLACE", "PRAGMA", and "END".  Nevertheless, best practice is to avoid
+  /// using keywords as identifiers.  Common techniques used to avoid keyword
+  /// name collisions include:
+  /// <ul>
+  /// <li> Put all identifier names inside double-quotes.  This is the official
+  /// SQL way to escape identifier names.
+  /// <li> Put identifier names inside &#91;...&#93;.  This is not standard SQL,
+  /// but it is what SQL Server does and so lots of programmers use this
+  /// technique.
+  /// <li> Begin every identifier with the letter "Z" as no SQL keywords start
+  /// with "Z".
+  /// <li> Include a digit somewhere in every identifier name.
+  /// </ul>
+  ///
+  /// Note that the number of keywords understood by SQLite can depend on
+  /// compile-time options.  For example, "VACUUM" is not a keyword if
+  /// SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option.  Also,
+  /// new keywords may be added to future releases of SQLite.
+  int sqlite3_keyword_count() {
+    return _sqlite3_keyword_count();
+  }
+
+  late final _sqlite3_keyword_countPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function()>>('sqlite3_keyword_count');
+  late final _sqlite3_keyword_count =
+      _sqlite3_keyword_countPtr.asFunction<int Function()>();
+
+  int sqlite3_keyword_name(
+    int arg0,
+    ffi.Pointer<ffi.Pointer<ffi.Char>> arg1,
+    ffi.Pointer<ffi.Int> arg2,
+  ) {
+    return _sqlite3_keyword_name(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_keyword_namePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Int, ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.Int>)>>('sqlite3_keyword_name');
+  late final _sqlite3_keyword_name = _sqlite3_keyword_namePtr.asFunction<
+      int Function(
+          int, ffi.Pointer<ffi.Pointer<ffi.Char>>, ffi.Pointer<ffi.Int>)>();
+
+  int sqlite3_keyword_check(
+    ffi.Pointer<ffi.Char> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_keyword_check(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_keyword_checkPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Char>, ffi.Int)>>(
+      'sqlite3_keyword_check');
+  late final _sqlite3_keyword_check = _sqlite3_keyword_checkPtr
+      .asFunction<int Function(ffi.Pointer<ffi.Char>, int)>();
+
+  /// CAPI3REF: Create A New Dynamic String Object
+  /// CONSTRUCTOR: sqlite3_str
+  ///
+  /// ^The [sqlite3_str_new(D)] interface allocates and initializes
+  /// a new [sqlite3_str] object.  To avoid memory leaks, the object returned by
+  /// [sqlite3_str_new()] must be freed by a subsequent call to
+  /// [sqlite3_str_finish(X)].
+  ///
+  /// ^The [sqlite3_str_new(D)] interface always returns a pointer to a
+  /// valid [sqlite3_str] object, though in the event of an out-of-memory
+  /// error the returned object might be a special singleton that will
+  /// silently reject new text, always return SQLITE_NOMEM from
+  /// [sqlite3_str_errcode()], always return 0 for
+  /// [sqlite3_str_length()], and always return NULL from
+  /// [sqlite3_str_finish(X)].  It is always safe to use the value
+  /// returned by [sqlite3_str_new(D)] as the sqlite3_str parameter
+  /// to any of the other [sqlite3_str] methods.
+  ///
+  /// The D parameter to [sqlite3_str_new(D)] may be NULL.  If the
+  /// D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum
+  /// length of the string contained in the [sqlite3_str] object will be
+  /// the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead
+  /// of [SQLITE_MAX_LENGTH].
+  ffi.Pointer<sqlite3_str> sqlite3_str_new(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_str_new(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_str_newPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3_str> Function(
+              ffi.Pointer<sqlite3>)>>('sqlite3_str_new');
+  late final _sqlite3_str_new = _sqlite3_str_newPtr
+      .asFunction<ffi.Pointer<sqlite3_str> Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: Finalize A Dynamic String
+  /// DESTRUCTOR: sqlite3_str
+  ///
+  /// ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
+  /// and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
+  /// that contains the constructed string.  The calling application should
+  /// pass the returned value to [sqlite3_free()] to avoid a memory leak.
+  /// ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
+  /// errors were encountered during construction of the string.  ^The
+  /// [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
+  /// string in [sqlite3_str] object X is zero bytes long.
+  ffi.Pointer<ffi.Char> sqlite3_str_finish(
+    ffi.Pointer<sqlite3_str> arg0,
+  ) {
+    return _sqlite3_str_finish(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_str_finishPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<sqlite3_str>)>>('sqlite3_str_finish');
+  late final _sqlite3_str_finish = _sqlite3_str_finishPtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_str>)>();
+
+  /// CAPI3REF: Add Content To A Dynamic String
+  /// METHOD: sqlite3_str
+  ///
+  /// These interfaces add content to an sqlite3_str object previously obtained
+  /// from [sqlite3_str_new()].
+  ///
+  /// ^The [sqlite3_str_appendf(X,F,...)] and
+  /// [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
+  /// functionality of SQLite to append formatted text onto the end of
+  /// [sqlite3_str] object X.
+  ///
+  /// ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
+  /// onto the end of the [sqlite3_str] object X.  N must be non-negative.
+  /// S must contain at least N non-zero bytes of content.  To append a
+  /// zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
+  /// method instead.
+  ///
+  /// ^The [sqlite3_str_appendall(X,S)] method appends the complete content of
+  /// zero-terminated string S onto the end of [sqlite3_str] object X.
+  ///
+  /// ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
+  /// single-byte character C onto the end of [sqlite3_str] object X.
+  /// ^This method can be used, for example, to add whitespace indentation.
+  ///
+  /// ^The [sqlite3_str_reset(X)] method resets the string under construction
+  /// inside [sqlite3_str] object X back to zero bytes in length.
+  ///
+  /// These methods do not return a result code.  ^If an error occurs, that fact
+  /// is recorded in the [sqlite3_str] object and can be recovered by a
+  /// subsequent call to [sqlite3_str_errcode(X)].
+  void sqlite3_str_appendf(
+    ffi.Pointer<sqlite3_str> arg0,
+    ffi.Pointer<ffi.Char> zFormat,
+  ) {
+    return _sqlite3_str_appendf(
+      arg0,
+      zFormat,
+    );
+  }
+
+  late final _sqlite3_str_appendfPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_str>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_str_appendf');
+  late final _sqlite3_str_appendf = _sqlite3_str_appendfPtr.asFunction<
+      void Function(ffi.Pointer<sqlite3_str>, ffi.Pointer<ffi.Char>)>();
+
+  void sqlite3_str_append(
+    ffi.Pointer<sqlite3_str> arg0,
+    ffi.Pointer<ffi.Char> zIn,
+    int N,
+  ) {
+    return _sqlite3_str_append(
+      arg0,
+      zIn,
+      N,
+    );
+  }
+
+  late final _sqlite3_str_appendPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_str>, ffi.Pointer<ffi.Char>,
+              ffi.Int)>>('sqlite3_str_append');
+  late final _sqlite3_str_append = _sqlite3_str_appendPtr.asFunction<
+      void Function(ffi.Pointer<sqlite3_str>, ffi.Pointer<ffi.Char>, int)>();
+
+  void sqlite3_str_appendall(
+    ffi.Pointer<sqlite3_str> arg0,
+    ffi.Pointer<ffi.Char> zIn,
+  ) {
+    return _sqlite3_str_appendall(
+      arg0,
+      zIn,
+    );
+  }
+
+  late final _sqlite3_str_appendallPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_str>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_str_appendall');
+  late final _sqlite3_str_appendall = _sqlite3_str_appendallPtr.asFunction<
+      void Function(ffi.Pointer<sqlite3_str>, ffi.Pointer<ffi.Char>)>();
+
+  void sqlite3_str_appendchar(
+    ffi.Pointer<sqlite3_str> arg0,
+    int N,
+    int C,
+  ) {
+    return _sqlite3_str_appendchar(
+      arg0,
+      N,
+      C,
+    );
+  }
+
+  late final _sqlite3_str_appendcharPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_str>, ffi.Int,
+              ffi.Char)>>('sqlite3_str_appendchar');
+  late final _sqlite3_str_appendchar = _sqlite3_str_appendcharPtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_str>, int, int)>();
+
+  void sqlite3_str_reset(
+    ffi.Pointer<sqlite3_str> arg0,
+  ) {
+    return _sqlite3_str_reset(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_str_resetPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_str>)>>(
+          'sqlite3_str_reset');
+  late final _sqlite3_str_reset = _sqlite3_str_resetPtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_str>)>();
+
+  /// CAPI3REF: Status Of A Dynamic String
+  /// METHOD: sqlite3_str
+  ///
+  /// These interfaces return the current status of an [sqlite3_str] object.
+  ///
+  /// ^If any prior errors have occurred while constructing the dynamic string
+  /// in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
+  /// an appropriate error code.  ^The [sqlite3_str_errcode(X)] method returns
+  /// [SQLITE_NOMEM] following any out-of-memory error, or
+  /// [SQLITE_TOOBIG] if the size of the dynamic string exceeds
+  /// [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
+  ///
+  /// ^The [sqlite3_str_length(X)] method returns the current length, in bytes,
+  /// of the dynamic string under construction in [sqlite3_str] object X.
+  /// ^The length returned by [sqlite3_str_length(X)] does not include the
+  /// zero-termination byte.
+  ///
+  /// ^The [sqlite3_str_value(X)] method returns a pointer to the current
+  /// content of the dynamic string under construction in X.  The value
+  /// returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
+  /// and might be freed or altered by any subsequent method on the same
+  /// [sqlite3_str] object.  Applications must not used the pointer returned
+  /// [sqlite3_str_value(X)] after any subsequent method call on the same
+  /// object.  ^Applications may change the content of the string returned
+  /// by [sqlite3_str_value(X)] as long as they do not write into any bytes
+  /// outside the range of 0 to [sqlite3_str_length(X)] and do not read or
+  /// write any byte after any subsequent sqlite3_str method call.
+  int sqlite3_str_errcode(
+    ffi.Pointer<sqlite3_str> arg0,
+  ) {
+    return _sqlite3_str_errcode(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_str_errcodePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_str>)>>(
+          'sqlite3_str_errcode');
+  late final _sqlite3_str_errcode = _sqlite3_str_errcodePtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_str>)>();
+
+  int sqlite3_str_length(
+    ffi.Pointer<sqlite3_str> arg0,
+  ) {
+    return _sqlite3_str_length(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_str_lengthPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_str>)>>(
+          'sqlite3_str_length');
+  late final _sqlite3_str_length = _sqlite3_str_lengthPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_str>)>();
+
+  ffi.Pointer<ffi.Char> sqlite3_str_value(
+    ffi.Pointer<sqlite3_str> arg0,
+  ) {
+    return _sqlite3_str_value(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_str_valuePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(
+              ffi.Pointer<sqlite3_str>)>>('sqlite3_str_value');
+  late final _sqlite3_str_value = _sqlite3_str_valuePtr
+      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_str>)>();
+
+  /// CAPI3REF: SQLite Runtime Status
+  ///
+  /// ^These interfaces are used to retrieve runtime status information
+  /// about the performance of SQLite, and optionally to reset various
+  /// highwater marks.  ^The first argument is an integer code for
+  /// the specific parameter to measure.  ^(Recognized integer codes
+  /// are of the form [status parameters | SQLITE_STATUS_...].)^
+  /// ^The current value of the parameter is returned into *pCurrent.
+  /// ^The highest recorded value is returned in *pHighwater.  ^If the
+  /// resetFlag is true, then the highest record value is reset after
+  /// *pHighwater is written.  ^(Some parameters do not record the highest
+  /// value.  For those parameters
+  /// nothing is written into *pHighwater and the resetFlag is ignored.)^
+  /// ^(Other parameters record only the highwater mark and not the current
+  /// value.  For these latter parameters nothing is written into *pCurrent.)^
+  ///
+  /// ^The sqlite3_status() and sqlite3_status64() routines return
+  /// SQLITE_OK on success and a non-zero [error code] on failure.
+  ///
+  /// If either the current value or the highwater mark is too large to
+  /// be represented by a 32-bit integer, then the values returned by
+  /// sqlite3_status() are undefined.
+  ///
+  /// See also: [sqlite3_db_status()]
+  int sqlite3_status(
+    int op,
+    ffi.Pointer<ffi.Int> pCurrent,
+    ffi.Pointer<ffi.Int> pHighwater,
+    int resetFlag,
+  ) {
+    return _sqlite3_status(
+      op,
+      pCurrent,
+      pHighwater,
+      resetFlag,
+    );
+  }
+
+  late final _sqlite3_statusPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Int, ffi.Pointer<ffi.Int>, ffi.Pointer<ffi.Int>,
+              ffi.Int)>>('sqlite3_status');
+  late final _sqlite3_status = _sqlite3_statusPtr.asFunction<
+      int Function(int, ffi.Pointer<ffi.Int>, ffi.Pointer<ffi.Int>, int)>();
+
+  int sqlite3_status64(
+    int op,
+    ffi.Pointer<sqlite3_int64> pCurrent,
+    ffi.Pointer<sqlite3_int64> pHighwater,
+    int resetFlag,
+  ) {
+    return _sqlite3_status64(
+      op,
+      pCurrent,
+      pHighwater,
+      resetFlag,
+    );
+  }
+
+  late final _sqlite3_status64Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Int, ffi.Pointer<sqlite3_int64>,
+              ffi.Pointer<sqlite3_int64>, ffi.Int)>>('sqlite3_status64');
+  late final _sqlite3_status64 = _sqlite3_status64Ptr.asFunction<
+      int Function(
+          int, ffi.Pointer<sqlite3_int64>, ffi.Pointer<sqlite3_int64>, int)>();
+
+  /// CAPI3REF: Database Connection Status
+  /// METHOD: sqlite3
+  ///
+  /// ^This interface is used to retrieve runtime status information
+  /// about a single [database connection].  ^The first argument is the
+  /// database connection object to be interrogated.  ^The second argument
+  /// is an integer constant, taken from the set of
+  /// [SQLITE_DBSTATUS options], that
+  /// determines the parameter to interrogate.  The set of
+  /// [SQLITE_DBSTATUS options] is likely
+  /// to grow in future releases of SQLite.
+  ///
+  /// ^The current value of the requested parameter is written into *pCur
+  /// and the highest instantaneous value is written into *pHiwtr.  ^If
+  /// the resetFlg is true, then the highest instantaneous value is
+  /// reset back down to the current value.
+  ///
+  /// ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
+  /// non-zero [error code] on failure.
+  ///
+  /// See also: [sqlite3_status()] and [sqlite3_stmt_status()].
+  int sqlite3_db_status(
+    ffi.Pointer<sqlite3> arg0,
+    int op,
+    ffi.Pointer<ffi.Int> pCur,
+    ffi.Pointer<ffi.Int> pHiwtr,
+    int resetFlg,
+  ) {
+    return _sqlite3_db_status(
+      arg0,
+      op,
+      pCur,
+      pHiwtr,
+      resetFlg,
+    );
+  }
+
+  late final _sqlite3_db_statusPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3>, ffi.Int, ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Int>, ffi.Int)>>('sqlite3_db_status');
+  late final _sqlite3_db_status = _sqlite3_db_statusPtr.asFunction<
+      int Function(ffi.Pointer<sqlite3>, int, ffi.Pointer<ffi.Int>,
+          ffi.Pointer<ffi.Int>, int)>();
+
+  /// CAPI3REF: Prepared Statement Status
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^(Each prepared statement maintains various
+  /// [SQLITE_STMTSTATUS counters] that measure the number
+  /// of times it has performed specific operations.)^  These counters can
+  /// be used to monitor the performance characteristics of the prepared
+  /// statements.  For example, if the number of table steps greatly exceeds
+  /// the number of table searches or result rows, that would tend to indicate
+  /// that the prepared statement is using a full table scan rather than
+  /// an index.
+  ///
+  /// ^(This interface is used to retrieve and reset counter values from
+  /// a [prepared statement].  The first argument is the prepared statement
+  /// object to be interrogated.  The second argument
+  /// is an integer code for a specific [SQLITE_STMTSTATUS counter]
+  /// to be interrogated.)^
+  /// ^The current value of the requested counter is returned.
+  /// ^If the resetFlg is true, then the counter is reset to zero after this
+  /// interface call returns.
+  ///
+  /// See also: [sqlite3_status()] and [sqlite3_db_status()].
+  int sqlite3_stmt_status(
+    ffi.Pointer<sqlite3_stmt> arg0,
+    int op,
+    int resetFlg,
+  ) {
+    return _sqlite3_stmt_status(
+      arg0,
+      op,
+      resetFlg,
+    );
+  }
+
+  late final _sqlite3_stmt_statusPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_stmt>, ffi.Int,
+              ffi.Int)>>('sqlite3_stmt_status');
+  late final _sqlite3_stmt_status = _sqlite3_stmt_statusPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_stmt>, int, int)>();
+
+  /// CAPI3REF: Online Backup API.
+  ///
+  /// The backup API copies the content of one database into another.
+  /// It is useful either for creating backups of databases or
+  /// for copying in-memory databases to or from persistent files.
+  ///
+  /// See Also: [Using the SQLite Online Backup API]
+  ///
+  /// ^SQLite holds a write transaction open on the destination database file
+  /// for the duration of the backup operation.
+  /// ^The source database is read-locked only while it is being read;
+  /// it is not locked continuously for the entire backup operation.
+  /// ^Thus, the backup may be performed on a live source database without
+  /// preventing other database connections from
+  /// reading or writing to the source database while the backup is underway.
+  ///
+  /// ^(To perform a backup operation:
+  /// <ol>
+  /// <li><b>sqlite3_backup_init()</b> is called once to initialize the
+  /// backup,
+  /// <li><b>sqlite3_backup_step()</b> is called one or more times to transfer
+  /// the data between the two databases, and finally
+  /// <li><b>sqlite3_backup_finish()</b> is called to release all resources
+  /// associated with the backup operation.
+  /// </ol>)^
+  /// There should be exactly one call to sqlite3_backup_finish() for each
+  /// successful call to sqlite3_backup_init().
+  ///
+  /// [[sqlite3_backup_init()]] <b>sqlite3_backup_init()</b>
+  ///
+  /// ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the
+  /// [database connection] associated with the destination database
+  /// and the database name, respectively.
+  /// ^The database name is "main" for the main database, "temp" for the
+  /// temporary database, or the name specified after the AS keyword in
+  /// an [ATTACH] statement for an attached database.
+  /// ^The S and M arguments passed to
+  /// sqlite3_backup_init(D,N,S,M) identify the [database connection]
+  /// and database name of the source database, respectively.
+  /// ^The source and destination [database connections] (parameters S and D)
+  /// must be different or else sqlite3_backup_init(D,N,S,M) will fail with
+  /// an error.
+  ///
+  /// ^A call to sqlite3_backup_init() will fail, returning NULL, if
+  /// there is already a read or read-write transaction open on the
+  /// destination database.
+  ///
+  /// ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
+  /// returned and an error code and error message are stored in the
+  /// destination [database connection] D.
+  /// ^The error code and message for the failed call to sqlite3_backup_init()
+  /// can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
+  /// [sqlite3_errmsg16()] functions.
+  /// ^A successful call to sqlite3_backup_init() returns a pointer to an
+  /// [sqlite3_backup] object.
+  /// ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and
+  /// sqlite3_backup_finish() functions to perform the specified backup
+  /// operation.
+  ///
+  /// [[sqlite3_backup_step()]] <b>sqlite3_backup_step()</b>
+  ///
+  /// ^Function sqlite3_backup_step(B,N) will copy up to N pages between
+  /// the source and destination databases specified by [sqlite3_backup] object B.
+  /// ^If N is negative, all remaining source pages are copied.
+  /// ^If sqlite3_backup_step(B,N) successfully copies N pages and there
+  /// are still more pages to be copied, then the function returns [SQLITE_OK].
+  /// ^If sqlite3_backup_step(B,N) successfully finishes copying all pages
+  /// from source to destination, then it returns [SQLITE_DONE].
+  /// ^If an error occurs while running sqlite3_backup_step(B,N),
+  /// then an [error code] is returned. ^As well as [SQLITE_OK] and
+  /// [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY],
+  /// [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
+  /// [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
+  ///
+  /// ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if
+  /// <ol>
+  /// <li> the destination database was opened read-only, or
+  /// <li> the destination database is using write-ahead-log journaling
+  /// and the destination and source page sizes differ, or
+  /// <li> the destination database is an in-memory database and the
+  /// destination and source page sizes differ.
+  /// </ol>)^
+  ///
+  /// ^If sqlite3_backup_step() cannot obtain a required file-system lock, then
+  /// the [sqlite3_busy_handler | busy-handler function]
+  /// is invoked (if one is specified). ^If the
+  /// busy-handler returns non-zero before the lock is available, then
+  /// [SQLITE_BUSY] is returned to the caller. ^In this case the call to
+  /// sqlite3_backup_step() can be retried later. ^If the source
+  /// [database connection]
+  /// is being used to write to the source database when sqlite3_backup_step()
+  /// is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this
+  /// case the call to sqlite3_backup_step() can be retried later on. ^(If
+  /// [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or
+  /// [SQLITE_READONLY] is returned, then
+  /// there is no point in retrying the call to sqlite3_backup_step(). These
+  /// errors are considered fatal.)^  The application must accept
+  /// that the backup operation has failed and pass the backup operation handle
+  /// to the sqlite3_backup_finish() to release associated resources.
+  ///
+  /// ^The first call to sqlite3_backup_step() obtains an exclusive lock
+  /// on the destination file. ^The exclusive lock is not released until either
+  /// sqlite3_backup_finish() is called or the backup operation is complete
+  /// and sqlite3_backup_step() returns [SQLITE_DONE].  ^Every call to
+  /// sqlite3_backup_step() obtains a [shared lock] on the source database that
+  /// lasts for the duration of the sqlite3_backup_step() call.
+  /// ^Because the source database is not locked between calls to
+  /// sqlite3_backup_step(), the source database may be modified mid-way
+  /// through the backup process.  ^If the source database is modified by an
+  /// external process or via a database connection other than the one being
+  /// used by the backup operation, then the backup will be automatically
+  /// restarted by the next call to sqlite3_backup_step(). ^If the source
+  /// database is modified by the using the same database connection as is used
+  /// by the backup operation, then the backup database is automatically
+  /// updated at the same time.
+  ///
+  /// [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b>
+  ///
+  /// When sqlite3_backup_step() has returned [SQLITE_DONE], or when the
+  /// application wishes to abandon the backup operation, the application
+  /// should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish().
+  /// ^The sqlite3_backup_finish() interfaces releases all
+  /// resources associated with the [sqlite3_backup] object.
+  /// ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any
+  /// active write-transaction on the destination database is rolled back.
+  /// The [sqlite3_backup] object is invalid
+  /// and may not be used following a call to sqlite3_backup_finish().
+  ///
+  /// ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no
+  /// sqlite3_backup_step() errors occurred, regardless or whether or not
+  /// sqlite3_backup_step() completed.
+  /// ^If an out-of-memory condition or IO error occurred during any prior
+  /// sqlite3_backup_step() call on the same [sqlite3_backup] object, then
+  /// sqlite3_backup_finish() returns the corresponding [error code].
+  ///
+  /// ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step()
+  /// is not a permanent error and does not affect the return value of
+  /// sqlite3_backup_finish().
+  ///
+  /// [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]]
+  /// <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
+  ///
+  /// ^The sqlite3_backup_remaining() routine returns the number of pages still
+  /// to be backed up at the conclusion of the most recent sqlite3_backup_step().
+  /// ^The sqlite3_backup_pagecount() routine returns the total number of pages
+  /// in the source database at the conclusion of the most recent
+  /// sqlite3_backup_step().
+  /// ^(The values returned by these functions are only updated by
+  /// sqlite3_backup_step(). If the source database is modified in a way that
+  /// changes the size of the source database or the number of pages remaining,
+  /// those changes are not reflected in the output of sqlite3_backup_pagecount()
+  /// and sqlite3_backup_remaining() until after the next
+  /// sqlite3_backup_step().)^
+  ///
+  /// <b>Concurrent Usage of Database Handles</b>
+  ///
+  /// ^The source [database connection] may be used by the application for other
+  /// purposes while a backup operation is underway or being initialized.
+  /// ^If SQLite is compiled and configured to support threadsafe database
+  /// connections, then the source database connection may be used concurrently
+  /// from within other threads.
+  ///
+  /// However, the application must guarantee that the destination
+  /// [database connection] is not passed to any other API (by any thread) after
+  /// sqlite3_backup_init() is called and before the corresponding call to
+  /// sqlite3_backup_finish().  SQLite does not currently check to see
+  /// if the application incorrectly accesses the destination [database connection]
+  /// and so no error code is reported, but the operations may malfunction
+  /// nevertheless.  Use of the destination database connection while a
+  /// backup is in progress might also also cause a mutex deadlock.
+  ///
+  /// If running in [shared cache mode], the application must
+  /// guarantee that the shared cache used by the destination database
+  /// is not accessed while the backup is running. In practice this means
+  /// that the application must guarantee that the disk file being
+  /// backed up to is not accessed by any connection within the process,
+  /// not just the specific connection that was passed to sqlite3_backup_init().
+  ///
+  /// The [sqlite3_backup] object itself is partially threadsafe. Multiple
+  /// threads may safely make multiple concurrent calls to sqlite3_backup_step().
+  /// However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount()
+  /// APIs are not strictly speaking threadsafe. If they are invoked at the
+  /// same time as another thread is invoking sqlite3_backup_step() it is
+  /// possible that they return invalid values.
+  ffi.Pointer<sqlite3_backup> sqlite3_backup_init(
+    ffi.Pointer<sqlite3> pDest,
+    ffi.Pointer<ffi.Char> zDestName,
+    ffi.Pointer<sqlite3> pSource,
+    ffi.Pointer<ffi.Char> zSourceName,
+  ) {
+    return _sqlite3_backup_init(
+      pDest,
+      zDestName,
+      pSource,
+      zSourceName,
+    );
+  }
+
+  late final _sqlite3_backup_initPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3_backup> Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_backup_init');
+  late final _sqlite3_backup_init = _sqlite3_backup_initPtr.asFunction<
+      ffi.Pointer<sqlite3_backup> Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Char>,
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Char>)>();
+
+  int sqlite3_backup_step(
+    ffi.Pointer<sqlite3_backup> p,
+    int nPage,
+  ) {
+    return _sqlite3_backup_step(
+      p,
+      nPage,
+    );
+  }
+
+  late final _sqlite3_backup_stepPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_backup>, ffi.Int)>>('sqlite3_backup_step');
+  late final _sqlite3_backup_step = _sqlite3_backup_stepPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_backup>, int)>();
+
+  int sqlite3_backup_finish(
+    ffi.Pointer<sqlite3_backup> p,
+  ) {
+    return _sqlite3_backup_finish(
+      p,
+    );
+  }
+
+  late final _sqlite3_backup_finishPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_backup>)>>(
+      'sqlite3_backup_finish');
+  late final _sqlite3_backup_finish = _sqlite3_backup_finishPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_backup>)>();
+
+  int sqlite3_backup_remaining(
+    ffi.Pointer<sqlite3_backup> p,
+  ) {
+    return _sqlite3_backup_remaining(
+      p,
+    );
+  }
+
+  late final _sqlite3_backup_remainingPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_backup>)>>(
+      'sqlite3_backup_remaining');
+  late final _sqlite3_backup_remaining = _sqlite3_backup_remainingPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_backup>)>();
+
+  int sqlite3_backup_pagecount(
+    ffi.Pointer<sqlite3_backup> p,
+  ) {
+    return _sqlite3_backup_pagecount(
+      p,
+    );
+  }
+
+  late final _sqlite3_backup_pagecountPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_backup>)>>(
+      'sqlite3_backup_pagecount');
+  late final _sqlite3_backup_pagecount = _sqlite3_backup_pagecountPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_backup>)>();
+
+  /// CAPI3REF: Unlock Notification
+  /// METHOD: sqlite3
+  ///
+  /// ^When running in shared-cache mode, a database operation may fail with
+  /// an [SQLITE_LOCKED] error if the required locks on the shared-cache or
+  /// individual tables within the shared-cache cannot be obtained. See
+  /// [SQLite Shared-Cache Mode] for a description of shared-cache locking.
+  /// ^This API may be used to register a callback that SQLite will invoke
+  /// when the connection currently holding the required lock relinquishes it.
+  /// ^This API is only available if the library was compiled with the
+  /// [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined.
+  ///
+  /// See Also: [Using the SQLite Unlock Notification Feature].
+  ///
+  /// ^Shared-cache locks are released when a database connection concludes
+  /// its current transaction, either by committing it or rolling it back.
+  ///
+  /// ^When a connection (known as the blocked connection) fails to obtain a
+  /// shared-cache lock and SQLITE_LOCKED is returned to the caller, the
+  /// identity of the database connection (the blocking connection) that
+  /// has locked the required resource is stored internally. ^After an
+  /// application receives an SQLITE_LOCKED error, it may call the
+  /// sqlite3_unlock_notify() method with the blocked connection handle as
+  /// the first argument to register for a callback that will be invoked
+  /// when the blocking connections current transaction is concluded. ^The
+  /// callback is invoked from within the [sqlite3_step] or [sqlite3_close]
+  /// call that concludes the blocking connection's transaction.
+  ///
+  /// ^(If sqlite3_unlock_notify() is called in a multi-threaded application,
+  /// there is a chance that the blocking connection will have already
+  /// concluded its transaction by the time sqlite3_unlock_notify() is invoked.
+  /// If this happens, then the specified callback is invoked immediately,
+  /// from within the call to sqlite3_unlock_notify().)^
+  ///
+  /// ^If the blocked connection is attempting to obtain a write-lock on a
+  /// shared-cache table, and more than one other connection currently holds
+  /// a read-lock on the same table, then SQLite arbitrarily selects one of
+  /// the other connections to use as the blocking connection.
+  ///
+  /// ^(There may be at most one unlock-notify callback registered by a
+  /// blocked connection. If sqlite3_unlock_notify() is called when the
+  /// blocked connection already has a registered unlock-notify callback,
+  /// then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is
+  /// called with a NULL pointer as its second argument, then any existing
+  /// unlock-notify callback is canceled. ^The blocked connections
+  /// unlock-notify callback may also be canceled by closing the blocked
+  /// connection using [sqlite3_close()].
+  ///
+  /// The unlock-notify callback is not reentrant. If an application invokes
+  /// any sqlite3_xxx API functions from within an unlock-notify callback, a
+  /// crash or deadlock may be the result.
+  ///
+  /// ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always
+  /// returns SQLITE_OK.
+  ///
+  /// <b>Callback Invocation Details</b>
+  ///
+  /// When an unlock-notify callback is registered, the application provides a
+  /// single void* pointer that is passed to the callback when it is invoked.
+  /// However, the signature of the callback function allows SQLite to pass
+  /// it an array of void* context pointers. The first argument passed to
+  /// an unlock-notify callback is a pointer to an array of void* pointers,
+  /// and the second is the number of entries in the array.
+  ///
+  /// When a blocking connection's transaction is concluded, there may be
+  /// more than one blocked connection that has registered for an unlock-notify
+  /// callback. ^If two or more such blocked connections have specified the
+  /// same callback function, then instead of invoking the callback function
+  /// multiple times, it is invoked once with the set of void* context pointers
+  /// specified by the blocked connections bundled together into an array.
+  /// This gives the application an opportunity to prioritize any actions
+  /// related to the set of unblocked database connections.
+  ///
+  /// <b>Deadlock Detection</b>
+  ///
+  /// Assuming that after registering for an unlock-notify callback a
+  /// database waits for the callback to be issued before taking any further
+  /// action (a reasonable assumption), then using this API may cause the
+  /// application to deadlock. For example, if connection X is waiting for
+  /// connection Y's transaction to be concluded, and similarly connection
+  /// Y is waiting on connection X's transaction, then neither connection
+  /// will proceed and the system may remain deadlocked indefinitely.
+  ///
+  /// To avoid this scenario, the sqlite3_unlock_notify() performs deadlock
+  /// detection. ^If a given call to sqlite3_unlock_notify() would put the
+  /// system in a deadlocked state, then SQLITE_LOCKED is returned and no
+  /// unlock-notify callback is registered. The system is said to be in
+  /// a deadlocked state if connection A has registered for an unlock-notify
+  /// callback on the conclusion of connection B's transaction, and connection
+  /// B has itself registered for an unlock-notify callback when connection
+  /// A's transaction is concluded. ^Indirect deadlock is also detected, so
+  /// the system is also considered to be deadlocked if connection B has
+  /// registered for an unlock-notify callback on the conclusion of connection
+  /// C's transaction, where connection C is waiting on connection A. ^Any
+  /// number of levels of indirection are allowed.
+  ///
+  /// <b>The "DROP TABLE" Exception</b>
+  ///
+  /// When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost
+  /// always appropriate to call sqlite3_unlock_notify(). There is however,
+  /// one exception. When executing a "DROP TABLE" or "DROP INDEX" statement,
+  /// SQLite checks if there are any currently executing SELECT statements
+  /// that belong to the same connection. If there are, SQLITE_LOCKED is
+  /// returned. In this case there is no "blocking connection", so invoking
+  /// sqlite3_unlock_notify() results in the unlock-notify callback being
+  /// invoked immediately. If the application then re-attempts the "DROP TABLE"
+  /// or "DROP INDEX" query, an infinite loop might be the result.
+  ///
+  /// One way around this problem is to check the extended error code returned
+  /// by an sqlite3_step() call. ^(If there is a blocking connection, then the
+  /// extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in
+  /// the special "DROP TABLE/INDEX" case, the extended error code is just
+  /// SQLITE_LOCKED.)^
+  int sqlite3_unlock_notify(
+    ffi.Pointer<sqlite3> pBlocked,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Void Function(
+                    ffi.Pointer<ffi.Pointer<ffi.Void>> apArg, ffi.Int nArg)>>
+        xNotify,
+    ffi.Pointer<ffi.Void> pNotifyArg,
+  ) {
+    return _sqlite3_unlock_notify(
+      pBlocked,
+      xNotify,
+      pNotifyArg,
+    );
+  }
+
+  late final _sqlite3_unlock_notifyPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(
+                          ffi.Pointer<ffi.Pointer<ffi.Void>> apArg,
+                          ffi.Int nArg)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_unlock_notify');
+  late final _sqlite3_unlock_notify = _sqlite3_unlock_notifyPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.Pointer<ffi.Void>> apArg, ffi.Int nArg)>>,
+          ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: String Comparison
+  ///
+  /// ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications
+  /// and extensions to compare the contents of two buffers containing UTF-8
+  /// strings in a case-independent fashion, using the same definition of "case
+  /// independence" that SQLite uses internally when comparing identifiers.
+  int sqlite3_stricmp(
+    ffi.Pointer<ffi.Char> arg0,
+    ffi.Pointer<ffi.Char> arg1,
+  ) {
+    return _sqlite3_stricmp(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_stricmpPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_stricmp');
+  late final _sqlite3_stricmp = _sqlite3_stricmpPtr
+      .asFunction<int Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
+
+  int sqlite3_strnicmp(
+    ffi.Pointer<ffi.Char> arg0,
+    ffi.Pointer<ffi.Char> arg1,
+    int arg2,
+  ) {
+    return _sqlite3_strnicmp(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_strnicmpPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>,
+              ffi.Int)>>('sqlite3_strnicmp');
+  late final _sqlite3_strnicmp = _sqlite3_strnicmpPtr.asFunction<
+      int Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>, int)>();
+
+  /// CAPI3REF: String Globbing
+  ///
+  /// ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
+  /// string X matches the [GLOB] pattern P.
+  /// ^The definition of [GLOB] pattern matching used in
+  /// [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
+  /// SQL dialect understood by SQLite.  ^The [sqlite3_strglob(P,X)] function
+  /// is case sensitive.
+  ///
+  /// Note that this routine returns zero on a match and non-zero if the strings
+  /// do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
+  ///
+  /// See also: [sqlite3_strlike()].
+  int sqlite3_strglob(
+    ffi.Pointer<ffi.Char> zGlob,
+    ffi.Pointer<ffi.Char> zStr,
+  ) {
+    return _sqlite3_strglob(
+      zGlob,
+      zStr,
+    );
+  }
+
+  late final _sqlite3_strglobPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_strglob');
+  late final _sqlite3_strglob = _sqlite3_strglobPtr
+      .asFunction<int Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: String LIKE Matching
+  ///
+  /// ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
+  /// string X matches the [LIKE] pattern P with escape character E.
+  /// ^The definition of [LIKE] pattern matching used in
+  /// [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
+  /// operator in the SQL dialect understood by SQLite.  ^For "X LIKE P" without
+  /// the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
+  /// ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
+  /// insensitive - equivalent upper and lower case ASCII characters match
+  /// one another.
+  ///
+  /// ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
+  /// only ASCII characters are case folded.
+  ///
+  /// Note that this routine returns zero on a match and non-zero if the strings
+  /// do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
+  ///
+  /// See also: [sqlite3_strglob()].
+  int sqlite3_strlike(
+    ffi.Pointer<ffi.Char> zGlob,
+    ffi.Pointer<ffi.Char> zStr,
+    int cEsc,
+  ) {
+    return _sqlite3_strlike(
+      zGlob,
+      zStr,
+      cEsc,
+    );
+  }
+
+  late final _sqlite3_strlikePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>,
+              ffi.UnsignedInt)>>('sqlite3_strlike');
+  late final _sqlite3_strlike = _sqlite3_strlikePtr.asFunction<
+      int Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>, int)>();
+
+  /// CAPI3REF: Error Logging Interface
+  ///
+  /// ^The [sqlite3_log()] interface writes a message into the [error log]
+  /// established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()].
+  /// ^If logging is enabled, the zFormat string and subsequent arguments are
+  /// used with [sqlite3_snprintf()] to generate the final output string.
+  ///
+  /// The sqlite3_log() interface is intended for use by extensions such as
+  /// virtual tables, collating functions, and SQL functions.  While there is
+  /// nothing to prevent an application from calling sqlite3_log(), doing so
+  /// is considered bad form.
+  ///
+  /// The zFormat string must not be NULL.
+  ///
+  /// To avoid deadlocks and other threading problems, the sqlite3_log() routine
+  /// will not use dynamically allocated memory.  The log message is stored in
+  /// a fixed-length buffer on the stack.  If the log message is longer than
+  /// a few hundred characters, it will be truncated to the length of the
+  /// buffer.
+  void sqlite3_log(
+    int iErrCode,
+    ffi.Pointer<ffi.Char> zFormat,
+  ) {
+    return _sqlite3_log(
+      iErrCode,
+      zFormat,
+    );
+  }
+
+  late final _sqlite3_logPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Int, ffi.Pointer<ffi.Char>)>>('sqlite3_log');
+  late final _sqlite3_log =
+      _sqlite3_logPtr.asFunction<void Function(int, ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: Write-Ahead Log Commit Hook
+  /// METHOD: sqlite3
+  ///
+  /// ^The [sqlite3_wal_hook()] function is used to register a callback that
+  /// is invoked each time data is committed to a database in wal mode.
+  ///
+  /// ^(The callback is invoked by SQLite after the commit has taken place and
+  /// the associated write-lock on the database released)^, so the implementation
+  /// may read, write or [checkpoint] the database as required.
+  ///
+  /// ^The first parameter passed to the callback function when it is invoked
+  /// is a copy of the third parameter passed to sqlite3_wal_hook() when
+  /// registering the callback. ^The second is a copy of the database handle.
+  /// ^The third parameter is the name of the database that was written to -
+  /// either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
+  /// is the number of pages currently in the write-ahead log file,
+  /// including those that were just committed.
+  ///
+  /// The callback function should normally return [SQLITE_OK].  ^If an error
+  /// code is returned, that error will propagate back up through the
+  /// SQLite code base to cause the statement that provoked the callback
+  /// to report an error, though the commit will have still occurred. If the
+  /// callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
+  /// that does not correspond to any valid SQLite error code, the results
+  /// are undefined.
+  ///
+  /// A single database handle may have at most a single write-ahead log callback
+  /// registered at one time. ^Calling [sqlite3_wal_hook()] replaces any
+  /// previously registered write-ahead log callback. ^Note that the
+  /// [sqlite3_wal_autocheckpoint()] interface and the
+  /// [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
+  /// overwrite any prior [sqlite3_wal_hook()] settings.
+  ffi.Pointer<ffi.Void> sqlite3_wal_hook(
+    ffi.Pointer<sqlite3> arg0,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<sqlite3>,
+                    ffi.Pointer<ffi.Char>, ffi.Int)>>
+        arg1,
+    ffi.Pointer<ffi.Void> arg2,
+  ) {
+    return _sqlite3_wal_hook(
+      arg0,
+      arg1,
+      arg2,
+    );
+  }
+
+  late final _sqlite3_wal_hookPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Pointer<sqlite3>,
+                          ffi.Pointer<ffi.Char>,
+                          ffi.Int)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_wal_hook');
+  late final _sqlite3_wal_hook = _sqlite3_wal_hookPtr.asFunction<
+      ffi.Pointer<ffi.Void> Function(
+          ffi.Pointer<sqlite3>,
+          ffi.Pointer<
+              ffi.NativeFunction<
+                  ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<sqlite3>,
+                      ffi.Pointer<ffi.Char>, ffi.Int)>>,
+          ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Configure an auto-checkpoint
+  /// METHOD: sqlite3
+  ///
+  /// ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
+  /// [sqlite3_wal_hook()] that causes any database on [database connection] D
+  /// to automatically [checkpoint]
+  /// after committing a transaction if there are N or
+  /// more frames in the [write-ahead log] file.  ^Passing zero or
+  /// a negative value as the nFrame parameter disables automatic
+  /// checkpoints entirely.
+  ///
+  /// ^The callback registered by this function replaces any existing callback
+  /// registered using [sqlite3_wal_hook()].  ^Likewise, registering a callback
+  /// using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
+  /// configured by this function.
+  ///
+  /// ^The [wal_autocheckpoint pragma] can be used to invoke this interface
+  /// from SQL.
+  ///
+  /// ^Checkpoints initiated by this mechanism are
+  /// [sqlite3_wal_checkpoint_v2|PASSIVE].
+  ///
+  /// ^Every new [database connection] defaults to having the auto-checkpoint
+  /// enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
+  /// pages.  The use of this interface
+  /// is only necessary if the default setting is found to be suboptimal
+  /// for a particular application.
+  int sqlite3_wal_autocheckpoint(
+    ffi.Pointer<sqlite3> db,
+    int N,
+  ) {
+    return _sqlite3_wal_autocheckpoint(
+      db,
+      N,
+    );
+  }
+
+  late final _sqlite3_wal_autocheckpointPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>, ffi.Int)>>(
+      'sqlite3_wal_autocheckpoint');
+  late final _sqlite3_wal_autocheckpoint = _sqlite3_wal_autocheckpointPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>, int)>();
+
+  /// CAPI3REF: Checkpoint a database
+  /// METHOD: sqlite3
+  ///
+  /// ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
+  /// [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
+  ///
+  /// In brief, sqlite3_wal_checkpoint(D,X) causes the content in the
+  /// [write-ahead log] for database X on [database connection] D to be
+  /// transferred into the database file and for the write-ahead log to
+  /// be reset.  See the [checkpointing] documentation for addition
+  /// information.
+  ///
+  /// This interface used to be the only way to cause a checkpoint to
+  /// occur.  But then the newer and more powerful [sqlite3_wal_checkpoint_v2()]
+  /// interface was added.  This interface is retained for backwards
+  /// compatibility and as a convenience for applications that need to manually
+  /// start a callback but which do not need the full power (and corresponding
+  /// complication) of [sqlite3_wal_checkpoint_v2()].
+  int sqlite3_wal_checkpoint(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zDb,
+  ) {
+    return _sqlite3_wal_checkpoint(
+      db,
+      zDb,
+    );
+  }
+
+  late final _sqlite3_wal_checkpointPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_wal_checkpoint');
+  late final _sqlite3_wal_checkpoint = _sqlite3_wal_checkpointPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: Checkpoint a database
+  /// METHOD: sqlite3
+  ///
+  /// ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
+  /// operation on database X of [database connection] D in mode M.  Status
+  /// information is written back into integers pointed to by L and C.)^
+  /// ^(The M parameter must be a valid [checkpoint mode]:)^
+  ///
+  /// <dl>
+  /// <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
+  /// ^Checkpoint as many frames as possible without waiting for any database
+  /// readers or writers to finish, then sync the database file if all frames
+  /// in the log were checkpointed. ^The [busy-handler callback]
+  /// is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode.
+  /// ^On the other hand, passive mode might leave the checkpoint unfinished
+  /// if there are concurrent readers or writers.
+  ///
+  /// <dt>SQLITE_CHECKPOINT_FULL<dd>
+  /// ^This mode blocks (it invokes the
+  /// [sqlite3_busy_handler|busy-handler callback]) until there is no
+  /// database writer and all readers are reading from the most recent database
+  /// snapshot. ^It then checkpoints all frames in the log file and syncs the
+  /// database file. ^This mode blocks new database writers while it is pending,
+  /// but new database readers are allowed to continue unimpeded.
+  ///
+  /// <dt>SQLITE_CHECKPOINT_RESTART<dd>
+  /// ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition
+  /// that after checkpointing the log file it blocks (calls the
+  /// [busy-handler callback])
+  /// until all readers are reading from the database file only. ^This ensures
+  /// that the next writer will restart the log file from the beginning.
+  /// ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new
+  /// database writer attempts while it is pending, but does not impede readers.
+  ///
+  /// <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
+  /// ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
+  /// addition that it also truncates the log file to zero bytes just prior
+  /// to a successful return.
+  /// </dl>
+  ///
+  /// ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
+  /// the log file or to -1 if the checkpoint could not run because
+  /// of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
+  /// NULL,then *pnCkpt is set to the total number of checkpointed frames in the
+  /// log file (including any that were already checkpointed before the function
+  /// was called) or to -1 if the checkpoint could not run due to an error or
+  /// because the database is not in WAL mode. ^Note that upon successful
+  /// completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been
+  /// truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero.
+  ///
+  /// ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If
+  /// any other process is running a checkpoint operation at the same time, the
+  /// lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a
+  /// busy-handler configured, it will not be invoked in this case.
+  ///
+  /// ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the
+  /// exclusive "writer" lock on the database file. ^If the writer lock cannot be
+  /// obtained immediately, and a busy-handler is configured, it is invoked and
+  /// the writer lock retried until either the busy-handler returns 0 or the lock
+  /// is successfully obtained. ^The busy-handler is also invoked while waiting for
+  /// database readers as described above. ^If the busy-handler returns 0 before
+  /// the writer lock is obtained or while waiting for database readers, the
+  /// checkpoint operation proceeds from that point in the same way as
+  /// SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible
+  /// without blocking any further. ^SQLITE_BUSY is returned in this case.
+  ///
+  /// ^If parameter zDb is NULL or points to a zero length string, then the
+  /// specified operation is attempted on all WAL databases [attached] to
+  /// [database connection] db.  In this case the
+  /// values written to output parameters *pnLog and *pnCkpt are undefined. ^If
+  /// an SQLITE_BUSY error is encountered when processing one or more of the
+  /// attached WAL databases, the operation is still attempted on any remaining
+  /// attached databases and SQLITE_BUSY is returned at the end. ^If any other
+  /// error occurs while processing an attached database, processing is abandoned
+  /// and the error code is returned to the caller immediately. ^If no error
+  /// (SQLITE_BUSY or otherwise) is encountered while processing the attached
+  /// databases, SQLITE_OK is returned.
+  ///
+  /// ^If database zDb is the name of an attached database that is not in WAL
+  /// mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If
+  /// zDb is not NULL (or a zero length string) and is not the name of any
+  /// attached database, SQLITE_ERROR is returned to the caller.
+  ///
+  /// ^Unless it returns SQLITE_MISUSE,
+  /// the sqlite3_wal_checkpoint_v2() interface
+  /// sets the error information that is queried by
+  /// [sqlite3_errcode()] and [sqlite3_errmsg()].
+  ///
+  /// ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
+  /// from SQL.
+  int sqlite3_wal_checkpoint_v2(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zDb,
+    int eMode,
+    ffi.Pointer<ffi.Int> pnLog,
+    ffi.Pointer<ffi.Int> pnCkpt,
+  ) {
+    return _sqlite3_wal_checkpoint_v2(
+      db,
+      zDb,
+      eMode,
+      pnLog,
+      pnCkpt,
+    );
+  }
+
+  late final _sqlite3_wal_checkpoint_v2Ptr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Int,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Int>)>>('sqlite3_wal_checkpoint_v2');
+  late final _sqlite3_wal_checkpoint_v2 =
+      _sqlite3_wal_checkpoint_v2Ptr.asFunction<
+          int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>, int,
+              ffi.Pointer<ffi.Int>, ffi.Pointer<ffi.Int>)>();
+
+  /// CAPI3REF: Virtual Table Interface Configuration
+  ///
+  /// This function may be called by either the [xConnect] or [xCreate] method
+  /// of a [virtual table] implementation to configure
+  /// various facets of the virtual table interface.
+  ///
+  /// If this interface is invoked outside the context of an xConnect or
+  /// xCreate virtual table method then the behavior is undefined.
+  ///
+  /// In the call sqlite3_vtab_config(D,C,...) the D parameter is the
+  /// [database connection] in which the virtual table is being created and
+  /// which is passed in as the first argument to the [xConnect] or [xCreate]
+  /// method that is invoking sqlite3_vtab_config().  The C parameter is one
+  /// of the [virtual table configuration options].  The presence and meaning
+  /// of parameters after C depend on which [virtual table configuration option]
+  /// is used.
+  int sqlite3_vtab_config(
+    ffi.Pointer<sqlite3> arg0,
+    int op,
+  ) {
+    return _sqlite3_vtab_config(
+      arg0,
+      op,
+    );
+  }
+
+  late final _sqlite3_vtab_configPtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>, ffi.Int)>>(
+      'sqlite3_vtab_config');
+  late final _sqlite3_vtab_config = _sqlite3_vtab_configPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>, int)>();
+
+  /// CAPI3REF: Determine The Virtual Table Conflict Policy
+  ///
+  /// This function may only be called from within a call to the [xUpdate] method
+  /// of a [virtual table] implementation for an INSERT or UPDATE operation. ^The
+  /// value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL],
+  /// [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode
+  /// of the SQL statement that triggered the call to the [xUpdate] method of the
+  /// [virtual table].
+  int sqlite3_vtab_on_conflict(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_vtab_on_conflict(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_vtab_on_conflictPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_vtab_on_conflict');
+  late final _sqlite3_vtab_on_conflict = _sqlite3_vtab_on_conflictPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
+  ///
+  /// If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
+  /// method of a [virtual table], then it returns true if and only if the
+  /// column is being fetched as part of an UPDATE operation during which the
+  /// column value will not change.  Applications might use this to substitute
+  /// a return value that is less expensive to compute and that the corresponding
+  /// [xUpdate] method understands as a "no-change" value.
+  ///
+  /// If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
+  /// the column is not changed by the UPDATE statement, then the xColumn
+  /// method can optionally return without setting a result, without calling
+  /// any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
+  /// In that case, [sqlite3_value_nochange(X)] will return true for the
+  /// same column in the [xUpdate] method.
+  int sqlite3_vtab_nochange(
+    ffi.Pointer<sqlite3_context> arg0,
+  ) {
+    return _sqlite3_vtab_nochange(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_vtab_nochangePtr = _lookup<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_context>)>>(
+      'sqlite3_vtab_nochange');
+  late final _sqlite3_vtab_nochange = _sqlite3_vtab_nochangePtr
+      .asFunction<int Function(ffi.Pointer<sqlite3_context>)>();
+
+  /// CAPI3REF: Determine The Collation For a Virtual Table Constraint
+  ///
+  /// This function may only be called from within a call to the [xBestIndex]
+  /// method of a [virtual table].
+  ///
+  /// The first argument must be the sqlite3_index_info object that is the
+  /// first parameter to the xBestIndex() method. The second argument must be
+  /// an index into the aConstraint[] array belonging to the sqlite3_index_info
+  /// structure passed to xBestIndex. This function returns a pointer to a buffer
+  /// containing the name of the collation sequence for the corresponding
+  /// constraint.
+  ffi.Pointer<ffi.Char> sqlite3_vtab_collation(
+    ffi.Pointer<sqlite3_index_info> arg0,
+    int arg1,
+  ) {
+    return _sqlite3_vtab_collation(
+      arg0,
+      arg1,
+    );
+  }
+
+  late final _sqlite3_vtab_collationPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_index_info>,
+              ffi.Int)>>('sqlite3_vtab_collation');
+  late final _sqlite3_vtab_collation = _sqlite3_vtab_collationPtr.asFunction<
+      ffi.Pointer<ffi.Char> Function(ffi.Pointer<sqlite3_index_info>, int)>();
+
+  /// CAPI3REF: Prepared Statement Scan Status
+  /// METHOD: sqlite3_stmt
+  ///
+  /// This interface returns information about the predicted and measured
+  /// performance for pStmt.  Advanced applications can use this
+  /// interface to compare the predicted and the measured performance and
+  /// issue warnings and/or rerun [ANALYZE] if discrepancies are found.
+  ///
+  /// Since this interface is expected to be rarely used, it is only
+  /// available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS]
+  /// compile-time option.
+  ///
+  /// The "iScanStatusOp" parameter determines which status information to return.
+  /// The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
+  /// of this interface is undefined.
+  /// ^The requested measurement is written into a variable pointed to by
+  /// the "pOut" parameter.
+  /// Parameter "idx" identifies the specific loop to retrieve statistics for.
+  /// Loops are numbered starting from zero. ^If idx is out of range - less than
+  /// zero or greater than or equal to the total number of loops used to implement
+  /// the statement - a non-zero value is returned and the variable that pOut
+  /// points to is unchanged.
+  ///
+  /// ^Statistics might not be available for all loops in all statements. ^In cases
+  /// where there exist loops with no available statistics, this function behaves
+  /// as if the loop did not exist - it returns non-zero and leave the variable
+  /// that pOut points to unchanged.
+  ///
+  /// See also: [sqlite3_stmt_scanstatus_reset()]
+  int sqlite3_stmt_scanstatus(
+    ffi.Pointer<sqlite3_stmt> pStmt,
+    int idx,
+    int iScanStatusOp,
+    ffi.Pointer<ffi.Void> pOut,
+  ) {
+    return _sqlite3_stmt_scanstatus(
+      pStmt,
+      idx,
+      iScanStatusOp,
+      pOut,
+    );
+  }
+
+  late final _sqlite3_stmt_scanstatusPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_stmt>, ffi.Int, ffi.Int,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_stmt_scanstatus');
+  late final _sqlite3_stmt_scanstatus = _sqlite3_stmt_scanstatusPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3_stmt>, int, int, ffi.Pointer<ffi.Void>)>();
+
+  /// CAPI3REF: Zero Scan-Status Counters
+  /// METHOD: sqlite3_stmt
+  ///
+  /// ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
+  ///
+  /// This API is only available if the library is built with pre-processor
+  /// symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
+  void sqlite3_stmt_scanstatus_reset(
+    ffi.Pointer<sqlite3_stmt> arg0,
+  ) {
+    return _sqlite3_stmt_scanstatus_reset(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_stmt_scanstatus_resetPtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_stmt>)>>(
+          'sqlite3_stmt_scanstatus_reset');
+  late final _sqlite3_stmt_scanstatus_reset = _sqlite3_stmt_scanstatus_resetPtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_stmt>)>();
+
+  /// CAPI3REF: Flush caches to disk mid-transaction
+  ///
+  /// ^If a write-transaction is open on [database connection] D when the
+  /// [sqlite3_db_cacheflush(D)] interface invoked, any dirty
+  /// pages in the pager-cache that are not currently in use are written out
+  /// to disk. A dirty page may be in use if a database cursor created by an
+  /// active SQL statement is reading from it, or if it is page 1 of a database
+  /// file (page 1 is always "in use").  ^The [sqlite3_db_cacheflush(D)]
+  /// interface flushes caches for all schemas - "main", "temp", and
+  /// any [attached] databases.
+  ///
+  /// ^If this function needs to obtain extra database locks before dirty pages
+  /// can be flushed to disk, it does so. ^If those locks cannot be obtained
+  /// immediately and there is a busy-handler callback configured, it is invoked
+  /// in the usual manner. ^If the required lock still cannot be obtained, then
+  /// the database is skipped and an attempt made to flush any dirty pages
+  /// belonging to the next (if any) database. ^If any databases are skipped
+  /// because locks cannot be obtained, but no other error occurs, this
+  /// function returns SQLITE_BUSY.
+  ///
+  /// ^If any other error occurs while flushing dirty pages to disk (for
+  /// example an IO error or out-of-memory condition), then processing is
+  /// abandoned and an SQLite [error code] is returned to the caller immediately.
+  ///
+  /// ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
+  ///
+  /// ^This function does not set the database handle error code or message
+  /// returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
+  int sqlite3_db_cacheflush(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_db_cacheflush(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_db_cacheflushPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_db_cacheflush');
+  late final _sqlite3_db_cacheflush = _sqlite3_db_cacheflushPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: Low-level system error code
+  ///
+  /// ^Attempt to return the underlying operating system error code or error
+  /// number that caused the most recent I/O error or failure to open a file.
+  /// The return value is OS-dependent.  For example, on unix systems, after
+  /// [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
+  /// called to get back the underlying "errno" that caused the problem, such
+  /// as ENOSPC, EAUTH, EISDIR, and so forth.
+  int sqlite3_system_errno(
+    ffi.Pointer<sqlite3> arg0,
+  ) {
+    return _sqlite3_system_errno(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_system_errnoPtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3>)>>(
+          'sqlite3_system_errno');
+  late final _sqlite3_system_errno =
+      _sqlite3_system_errnoPtr.asFunction<int Function(ffi.Pointer<sqlite3>)>();
+
+  /// CAPI3REF: Record A Database Snapshot
+  /// CONSTRUCTOR: sqlite3_snapshot
+  ///
+  /// ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
+  /// new [sqlite3_snapshot] object that records the current state of
+  /// schema S in database connection D.  ^On success, the
+  /// [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
+  /// created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
+  /// If there is not already a read-transaction open on schema S when
+  /// this function is called, one is opened automatically.
+  ///
+  /// The following must be true for this function to succeed. If any of
+  /// the following statements are false when sqlite3_snapshot_get() is
+  /// called, SQLITE_ERROR is returned. The final value of *P is undefined
+  /// in this case.
+  ///
+  /// <ul>
+  /// <li> The database handle must not be in [autocommit mode].
+  ///
+  /// <li> Schema S of [database connection] D must be a [WAL mode] database.
+  ///
+  /// <li> There must not be a write transaction open on schema S of database
+  /// connection D.
+  ///
+  /// <li> One or more transactions must have been written to the current wal
+  /// file since it was created on disk (by any connection). This means
+  /// that a snapshot cannot be taken on a wal mode database with no wal
+  /// file immediately after it is first opened. At least one transaction
+  /// must be written to it first.
+  /// </ul>
+  ///
+  /// This function may also return SQLITE_NOMEM.  If it is called with the
+  /// database handle in autocommit mode but fails for some other reason,
+  /// whether or not a read transaction is opened on schema S is undefined.
+  ///
+  /// The [sqlite3_snapshot] object returned from a successful call to
+  /// [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
+  /// to avoid a memory leak.
+  ///
+  /// The [sqlite3_snapshot_get()] interface is only available when the
+  /// [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+  int sqlite3_snapshot_get(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zSchema,
+    ffi.Pointer<ffi.Pointer<sqlite3_snapshot>> ppSnapshot,
+  ) {
+    return _sqlite3_snapshot_get(
+      db,
+      zSchema,
+      ppSnapshot,
+    );
+  }
+
+  late final _sqlite3_snapshot_getPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>,
+                  ffi.Pointer<ffi.Pointer<sqlite3_snapshot>>)>>(
+      'sqlite3_snapshot_get');
+  late final _sqlite3_snapshot_get = _sqlite3_snapshot_getPtr.asFunction<
+      int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>,
+          ffi.Pointer<ffi.Pointer<sqlite3_snapshot>>)>();
+
+  /// CAPI3REF: Start a read transaction on an historical snapshot
+  /// METHOD: sqlite3_snapshot
+  ///
+  /// ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read
+  /// transaction or upgrades an existing one for schema S of
+  /// [database connection] D such that the read transaction refers to
+  /// historical [snapshot] P, rather than the most recent change to the
+  /// database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK
+  /// on success or an appropriate [error code] if it fails.
+  ///
+  /// ^In order to succeed, the database connection must not be in
+  /// [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
+  /// is already a read transaction open on schema S, then the database handle
+  /// must have no active statements (SELECT statements that have been passed
+  /// to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()).
+  /// SQLITE_ERROR is returned if either of these conditions is violated, or
+  /// if schema S does not exist, or if the snapshot object is invalid.
+  ///
+  /// ^A call to sqlite3_snapshot_open() will fail to open if the specified
+  /// snapshot has been overwritten by a [checkpoint]. In this case
+  /// SQLITE_ERROR_SNAPSHOT is returned.
+  ///
+  /// If there is already a read transaction open when this function is
+  /// invoked, then the same read transaction remains open (on the same
+  /// database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT
+  /// is returned. If another error code - for example SQLITE_PROTOCOL or an
+  /// SQLITE_IOERR error code - is returned, then the final state of the
+  /// read transaction is undefined. If SQLITE_OK is returned, then the
+  /// read transaction is now open on database snapshot P.
+  ///
+  /// ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
+  /// database connection D does not know that the database file for
+  /// schema S is in [WAL mode].  A database connection might not know
+  /// that the database file is in [WAL mode] if there has been no prior
+  /// I/O on that database connection, or if the database entered [WAL mode]
+  /// after the most recent I/O on the database connection.)^
+  /// (Hint: Run "[PRAGMA application_id]" against a newly opened
+  /// database connection in order to make it ready to use snapshots.)
+  ///
+  /// The [sqlite3_snapshot_open()] interface is only available when the
+  /// [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+  int sqlite3_snapshot_open(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zSchema,
+    ffi.Pointer<sqlite3_snapshot> pSnapshot,
+  ) {
+    return _sqlite3_snapshot_open(
+      db,
+      zSchema,
+      pSnapshot,
+    );
+  }
+
+  late final _sqlite3_snapshot_openPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<sqlite3_snapshot>)>>('sqlite3_snapshot_open');
+  late final _sqlite3_snapshot_open = _sqlite3_snapshot_openPtr.asFunction<
+      int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>,
+          ffi.Pointer<sqlite3_snapshot>)>();
+
+  /// CAPI3REF: Destroy a snapshot
+  /// DESTRUCTOR: sqlite3_snapshot
+  ///
+  /// ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
+  /// The application must eventually free every [sqlite3_snapshot] object
+  /// using this routine to avoid a memory leak.
+  ///
+  /// The [sqlite3_snapshot_free()] interface is only available when the
+  /// [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+  void sqlite3_snapshot_free(
+    ffi.Pointer<sqlite3_snapshot> arg0,
+  ) {
+    return _sqlite3_snapshot_free(
+      arg0,
+    );
+  }
+
+  late final _sqlite3_snapshot_freePtr = _lookup<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_snapshot>)>>(
+      'sqlite3_snapshot_free');
+  late final _sqlite3_snapshot_free = _sqlite3_snapshot_freePtr
+      .asFunction<void Function(ffi.Pointer<sqlite3_snapshot>)>();
+
+  /// CAPI3REF: Compare the ages of two snapshot handles.
+  /// METHOD: sqlite3_snapshot
+  ///
+  /// The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
+  /// of two valid snapshot handles.
+  ///
+  /// If the two snapshot handles are not associated with the same database
+  /// file, the result of the comparison is undefined.
+  ///
+  /// Additionally, the result of the comparison is only valid if both of the
+  /// snapshot handles were obtained by calling sqlite3_snapshot_get() since the
+  /// last time the wal file was deleted. The wal file is deleted when the
+  /// database is changed back to rollback mode or when the number of database
+  /// clients drops to zero. If either snapshot handle was obtained before the
+  /// wal file was last deleted, the value returned by this function
+  /// is undefined.
+  ///
+  /// Otherwise, this API returns a negative value if P1 refers to an older
+  /// snapshot than P2, zero if the two handles refer to the same database
+  /// snapshot, and a positive value if P1 is a newer snapshot than P2.
+  ///
+  /// This interface is only available if SQLite is compiled with the
+  /// [SQLITE_ENABLE_SNAPSHOT] option.
+  int sqlite3_snapshot_cmp(
+    ffi.Pointer<sqlite3_snapshot> p1,
+    ffi.Pointer<sqlite3_snapshot> p2,
+  ) {
+    return _sqlite3_snapshot_cmp(
+      p1,
+      p2,
+    );
+  }
+
+  late final _sqlite3_snapshot_cmpPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_snapshot>,
+              ffi.Pointer<sqlite3_snapshot>)>>('sqlite3_snapshot_cmp');
+  late final _sqlite3_snapshot_cmp = _sqlite3_snapshot_cmpPtr.asFunction<
+      int Function(
+          ffi.Pointer<sqlite3_snapshot>, ffi.Pointer<sqlite3_snapshot>)>();
+
+  /// CAPI3REF: Recover snapshots from a wal file
+  /// METHOD: sqlite3_snapshot
+  ///
+  /// If a [WAL file] remains on disk after all database connections close
+  /// (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
+  /// or because the last process to have the database opened exited without
+  /// calling [sqlite3_close()]) and a new connection is subsequently opened
+  /// on that database and [WAL file], the [sqlite3_snapshot_open()] interface
+  /// will only be able to open the last transaction added to the WAL file
+  /// even though the WAL file contains other valid transactions.
+  ///
+  /// This function attempts to scan the WAL file associated with database zDb
+  /// of database handle db and make all valid snapshots available to
+  /// sqlite3_snapshot_open(). It is an error if there is already a read
+  /// transaction open on the database, or if the database is not a WAL mode
+  /// database.
+  ///
+  /// SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+  ///
+  /// This interface is only available if SQLite is compiled with the
+  /// [SQLITE_ENABLE_SNAPSHOT] option.
+  int sqlite3_snapshot_recover(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zDb,
+  ) {
+    return _sqlite3_snapshot_recover(
+      db,
+      zDb,
+    );
+  }
+
+  late final _sqlite3_snapshot_recoverPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>)>>('sqlite3_snapshot_recover');
+  late final _sqlite3_snapshot_recover = _sqlite3_snapshot_recoverPtr
+      .asFunction<int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>)>();
+
+  /// CAPI3REF: Serialize a database
+  ///
+  /// The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
+  /// that is a serialization of the S database on [database connection] D.
+  /// If P is not a NULL pointer, then the size of the database in bytes
+  /// is written into *P.
+  ///
+  /// For an ordinary on-disk database file, the serialization is just a
+  /// copy of the disk file.  For an in-memory database or a "TEMP" database,
+  /// the serialization is the same sequence of bytes which would be written
+  /// to disk if that database where backed up to disk.
+  ///
+  /// The usual case is that sqlite3_serialize() copies the serialization of
+  /// the database into memory obtained from [sqlite3_malloc64()] and returns
+  /// a pointer to that memory.  The caller is responsible for freeing the
+  /// returned value to avoid a memory leak.  However, if the F argument
+  /// contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations
+  /// are made, and the sqlite3_serialize() function will return a pointer
+  /// to the contiguous memory representation of the database that SQLite
+  /// is currently using for that database, or NULL if the no such contiguous
+  /// memory representation of the database exists.  A contiguous memory
+  /// representation of the database will usually only exist if there has
+  /// been a prior call to [sqlite3_deserialize(D,S,...)] with the same
+  /// values of D and S.
+  /// The size of the database is written into *P even if the
+  /// SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy
+  /// of the database exists.
+  ///
+  /// A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
+  /// SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
+  /// allocation error occurs.
+  ///
+  /// This interface is only available if SQLite is compiled with the
+  /// [SQLITE_ENABLE_DESERIALIZE] option.
+  ffi.Pointer<ffi.UnsignedChar> sqlite3_serialize(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zSchema,
+    ffi.Pointer<sqlite3_int64> piSize,
+    int mFlags,
+  ) {
+    return _sqlite3_serialize(
+      db,
+      zSchema,
+      piSize,
+      mFlags,
+    );
+  }
+
+  late final _sqlite3_serializePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.UnsignedChar> Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<sqlite3_int64>,
+              ffi.UnsignedInt)>>('sqlite3_serialize');
+  late final _sqlite3_serialize = _sqlite3_serializePtr.asFunction<
+      ffi.Pointer<ffi.UnsignedChar> Function(ffi.Pointer<sqlite3>,
+          ffi.Pointer<ffi.Char>, ffi.Pointer<sqlite3_int64>, int)>();
+
+  /// CAPI3REF: Deserialize a database
+  ///
+  /// The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
+  /// [database connection] D to disconnect from database S and then
+  /// reopen S as an in-memory database based on the serialization contained
+  /// in P.  The serialized database P is N bytes in size.  M is the size of
+  /// the buffer P, which might be larger than N.  If M is larger than N, and
+  /// the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
+  /// permitted to add content to the in-memory database as long as the total
+  /// size does not exceed M bytes.
+  ///
+  /// If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
+  /// invoke sqlite3_free() on the serialization buffer when the database
+  /// connection closes.  If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
+  /// SQLite will try to increase the buffer size using sqlite3_realloc64()
+  /// if writes on the database cause it to grow larger than M bytes.
+  ///
+  /// The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
+  /// database is currently in a read transaction or is involved in a backup
+  /// operation.
+  ///
+  /// If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the
+  /// SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
+  /// [sqlite3_free()] is invoked on argument P prior to returning.
+  ///
+  /// This interface is only available if SQLite is compiled with the
+  /// [SQLITE_ENABLE_DESERIALIZE] option.
+  int sqlite3_deserialize(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zSchema,
+    ffi.Pointer<ffi.UnsignedChar> pData,
+    int szDb,
+    int szBuf,
+    int mFlags,
+  ) {
+    return _sqlite3_deserialize(
+      db,
+      zSchema,
+      pData,
+      szDb,
+      szBuf,
+      mFlags,
+    );
+  }
+
+  late final _sqlite3_deserializePtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<ffi.UnsignedChar>,
+              sqlite3_int64,
+              sqlite3_int64,
+              ffi.UnsignedInt)>>('sqlite3_deserialize');
+  late final _sqlite3_deserialize = _sqlite3_deserializePtr.asFunction<
+      int Function(ffi.Pointer<sqlite3>, ffi.Pointer<ffi.Char>,
+          ffi.Pointer<ffi.UnsignedChar>, int, int, int)>();
+
+  /// Register a geometry callback named zGeom that can be used as part of an
+  /// R-Tree geometry query as follows:
+  ///
+  /// SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
+  int sqlite3_rtree_geometry_callback(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zGeom,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Int Function(ffi.Pointer<sqlite3_rtree_geometry>, ffi.Int,
+                    ffi.Pointer<sqlite3_rtree_dbl>, ffi.Pointer<ffi.Int>)>>
+        xGeom,
+    ffi.Pointer<ffi.Void> pContext,
+  ) {
+    return _sqlite3_rtree_geometry_callback(
+      db,
+      zGeom,
+      xGeom,
+      pContext,
+    );
+  }
+
+  late final _sqlite3_rtree_geometry_callbackPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(
+                          ffi.Pointer<sqlite3_rtree_geometry>,
+                          ffi.Int,
+                          ffi.Pointer<sqlite3_rtree_dbl>,
+                          ffi.Pointer<ffi.Int>)>>,
+              ffi.Pointer<ffi.Void>)>>('sqlite3_rtree_geometry_callback');
+  late final _sqlite3_rtree_geometry_callback =
+      _sqlite3_rtree_geometry_callbackPtr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(
+                          ffi.Pointer<sqlite3_rtree_geometry>,
+                          ffi.Int,
+                          ffi.Pointer<sqlite3_rtree_dbl>,
+                          ffi.Pointer<ffi.Int>)>>,
+              ffi.Pointer<ffi.Void>)>();
+
+  /// Register a 2nd-generation geometry callback named zScore that can be
+  /// used as part of an R-Tree geometry query as follows:
+  ///
+  /// SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
+  int sqlite3_rtree_query_callback(
+    ffi.Pointer<sqlite3> db,
+    ffi.Pointer<ffi.Char> zQueryFunc,
+    ffi.Pointer<
+            ffi.NativeFunction<
+                ffi.Int Function(ffi.Pointer<sqlite3_rtree_query_info>)>>
+        xQueryFunc,
+    ffi.Pointer<ffi.Void> pContext,
+    ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+        xDestructor,
+  ) {
+    return _sqlite3_rtree_query_callback(
+      db,
+      zQueryFunc,
+      xQueryFunc,
+      pContext,
+      xDestructor,
+    );
+  }
+
+  late final _sqlite3_rtree_query_callbackPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3>,
+                  ffi.Pointer<ffi.Char>,
+                  ffi
+                      .Pointer<
+                          ffi.NativeFunction<
+                              ffi.Int Function(
+                                  ffi.Pointer<sqlite3_rtree_query_info>)>>,
+                  ffi.Pointer<ffi.Void>,
+                  ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
+      'sqlite3_rtree_query_callback');
+  late final _sqlite3_rtree_query_callback =
+      _sqlite3_rtree_query_callbackPtr.asFunction<
+          int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(ffi.Pointer<sqlite3_rtree_query_info>)>>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>();
+}
+
+final class sqlite3 extends ffi.Opaque {}
+
+final class sqlite3_file extends ffi.Struct {
+  /// Methods for an open file
+  external ffi.Pointer<sqlite3_io_methods> pMethods;
+}
+
+final class sqlite3_io_methods extends ffi.Opaque {}
+
+final class sqlite3_mutex extends ffi.Opaque {}
+
+final class sqlite3_api_routines extends ffi.Opaque {}
+
+final class sqlite3_vfs extends ffi.Struct {
+  /// Structure version number (currently 3)
+  @ffi.Int()
+  external int iVersion;
+
+  /// Size of subclassed sqlite3_file
+  @ffi.Int()
+  external int szOsFile;
+
+  /// Maximum file pathname length
+  @ffi.Int()
+  external int mxPathname;
+
+  /// Next registered VFS
+  external ffi.Pointer<sqlite3_vfs> pNext;
+
+  /// Name of this virtual file system
+  external ffi.Pointer<ffi.Char> zName;
+
+  /// Pointer to application-specific data
+  external ffi.Pointer<ffi.Void> pAppData;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_vfs>, ffi.Pointer<ffi.Char>,
+              ffi.Pointer<sqlite3_file>, ffi.Int, ffi.Pointer<ffi.Int>)>> xOpen;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3_vfs>, ffi.Pointer<ffi.Char>, ffi.Int)>>
+      xDelete;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_vfs>, ffi.Pointer<ffi.Char>,
+              ffi.Int, ffi.Pointer<ffi.Int>)>> xAccess;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_vfs>, ffi.Pointer<ffi.Char>,
+              ffi.Int, ffi.Pointer<ffi.Char>)>> xFullPathname;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3_vfs>, ffi.Pointer<ffi.Char>)>> xDlOpen;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Void Function(
+                  ffi.Pointer<sqlite3_vfs>, ffi.Int, ffi.Pointer<ffi.Char>)>>
+      xDlError;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> Function(
+              ffi.Pointer<sqlite3_vfs>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Char>)>> xDlSym;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<sqlite3_vfs>, ffi.Pointer<ffi.Void>)>> xDlClose;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3_vfs>, ffi.Int, ffi.Pointer<ffi.Char>)>>
+      xRandomness;
+
+  external ffi.Pointer<
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vfs>, ffi.Int)>>
+      xSleep;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_vfs>, ffi.Pointer<ffi.Double>)>> xCurrentTime;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3_vfs>, ffi.Int, ffi.Pointer<ffi.Char>)>>
+      xGetLastError;
+
+  /// The methods above are in version 1 of the sqlite_vfs object
+  /// definition.  Those that follow are added in version 2 or later
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3_vfs>, ffi.Pointer<sqlite3_int64>)>>
+      xCurrentTimeInt64;
+
+  /// The methods above are in versions 1 and 2 of the sqlite_vfs object.
+  /// Those below are for version 3 and greater.
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_vfs>, ffi.Pointer<ffi.Char>,
+              sqlite3_syscall_ptr)>> xSetSystemCall;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          sqlite3_syscall_ptr Function(
+              ffi.Pointer<sqlite3_vfs>, ffi.Pointer<ffi.Char>)>> xGetSystemCall;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Pointer<ffi.Char> Function(
+                  ffi.Pointer<sqlite3_vfs>, ffi.Pointer<ffi.Char>)>>
+      xNextSystemCall;
+}
+
+typedef sqlite3_int64 = sqlite_int64;
+typedef sqlite_int64 = ffi.LongLong;
+typedef Dartsqlite_int64 = int;
+typedef sqlite3_syscall_ptr
+    = ffi.Pointer<ffi.NativeFunction<sqlite3_syscall_ptrFunction>>;
+typedef sqlite3_syscall_ptrFunction = ffi.Void Function();
+typedef Dartsqlite3_syscall_ptrFunction = void Function();
+
+final class sqlite3_mem_methods extends ffi.Struct {
+  /// Memory allocation function
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Int)>>
+      xMalloc;
+
+  /// Free a prior allocation
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      xFree;
+
+  /// Resize an allocation
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>, ffi.Int)>>
+      xRealloc;
+
+  /// Return the size of an allocation
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
+      xSize;
+
+  /// Round up request size to allocation size
+  external ffi.Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Int)>> xRoundup;
+
+  /// Initialize the memory allocator
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
+      xInit;
+
+  /// Deinitialize the memory allocator
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      xShutdown;
+
+  /// Argument to xInit() and xShutdown()
+  external ffi.Pointer<ffi.Void> pAppData;
+}
+
+typedef sqlite3_uint64 = sqlite_uint64;
+typedef sqlite_uint64 = ffi.UnsignedLongLong;
+typedef Dartsqlite_uint64 = int;
+
+final class sqlite3_stmt extends ffi.Opaque {}
+
+final class sqlite3_value extends ffi.Opaque {}
+
+final class sqlite3_context extends ffi.Opaque {}
+
+/// CAPI3REF: Virtual Table Instance Object
+/// KEYWORDS: sqlite3_vtab
+///
+/// Every [virtual table module] implementation uses a subclass
+/// of this object to describe a particular instance
+/// of the [virtual table].  Each subclass will
+/// be tailored to the specific needs of the module implementation.
+/// The purpose of this superclass is to define certain fields that are
+/// common to all module implementations.
+///
+/// ^Virtual tables methods can set an error message by assigning a
+/// string obtained from [sqlite3_mprintf()] to zErrMsg.  The method should
+/// take care that any prior string is freed by a call to [sqlite3_free()]
+/// prior to assigning a new string to zErrMsg.  ^After the error message
+/// is delivered up to the client application, the string will be automatically
+/// freed by sqlite3_free() and the zErrMsg field will be zeroed.
+final class sqlite3_vtab extends ffi.Struct {
+  /// The module for this virtual table
+  external ffi.Pointer<sqlite3_module> pModule;
+
+  /// Number of open cursors
+  @ffi.Int()
+  external int nRef;
+
+  /// Error message from sqlite3_mprintf()
+  external ffi.Pointer<ffi.Char> zErrMsg;
+}
+
+/// CAPI3REF: Virtual Table Object
+/// KEYWORDS: sqlite3_module {virtual table module}
+///
+/// This structure, sometimes called a "virtual table module",
+/// defines the implementation of a [virtual table].
+/// This structure consists mostly of methods for the module.
+///
+/// ^A virtual table module is created by filling in a persistent
+/// instance of this structure and passing a pointer to that instance
+/// to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
+/// ^The registration remains valid until it is replaced by a different
+/// module or until the [database connection] closes.  The content
+/// of this structure must not change while it is registered with
+/// any database connection.
+final class sqlite3_module extends ffi.Struct {
+  @ffi.Int()
+  external int iVersion;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.Pointer<sqlite3_vtab>>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>)>> xCreate;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.Pointer<sqlite3_vtab>>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>)>> xConnect;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3_vtab>, ffi.Pointer<sqlite3_index_info>)>>
+      xBestIndex;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab> pVTab)>>
+      xDisconnect;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab> pVTab)>>
+      xDestroy;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_vtab> pVTab,
+              ffi.Pointer<ffi.Pointer<sqlite3_vtab_cursor>> ppCursor)>> xOpen;
+
+  external ffi.Pointer<
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab_cursor>)>>
+      xClose;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_vtab_cursor>,
+              ffi.Int,
+              ffi.Pointer<ffi.Char>,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<sqlite3_value>>)>> xFilter;
+
+  external ffi.Pointer<
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab_cursor>)>>
+      xNext;
+
+  external ffi.Pointer<
+      ffi
+      .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab_cursor>)>> xEof;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_vtab_cursor>,
+              ffi.Pointer<sqlite3_context>, ffi.Int)>> xColumn;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<sqlite3_vtab_cursor>,
+              ffi.Pointer<sqlite3_int64>)>> xRowid;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_vtab>,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<sqlite3_value>>,
+              ffi.Pointer<sqlite3_int64>)>> xUpdate;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab> pVTab)>>
+      xBegin;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab> pVTab)>>
+      xSync;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab> pVTab)>>
+      xCommit;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab> pVTab)>>
+      xRollback;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<sqlite3_vtab> pVtab,
+              ffi.Int nArg,
+              ffi.Pointer<ffi.Char> zName,
+              ffi.Pointer<
+                      ffi.Pointer<
+                          ffi.NativeFunction<
+                              ffi.Void Function(
+                                  ffi.Pointer<sqlite3_context>,
+                                  ffi.Int,
+                                  ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>>
+                  pxFunc,
+              ffi.Pointer<ffi.Pointer<ffi.Void>> ppArg)>> xFindFunction;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3_vtab> pVtab, ffi.Pointer<ffi.Char> zNew)>>
+      xRename;
+
+  /// The methods above are in version 1 of the sqlite_module object. Those
+  /// below are for version 2 and greater.
+  external ffi.Pointer<
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab>, ffi.Int)>>
+      xSavepoint;
+
+  external ffi.Pointer<
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab>, ffi.Int)>>
+      xRelease;
+
+  external ffi.Pointer<
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab>, ffi.Int)>>
+      xRollbackTo;
+
+  /// The methods above are in versions 1 and 2 of the sqlite_module object.
+  /// Those below are for version 3 and greater.
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Char>)>>
+      xShadowName;
+}
+
+/// CAPI3REF: Virtual Table Indexing Information
+/// KEYWORDS: sqlite3_index_info
+///
+/// The sqlite3_index_info structure and its substructures is used as part
+/// of the [virtual table] interface to
+/// pass information into and receive the reply from the [xBestIndex]
+/// method of a [virtual table module].  The fields under **Inputs** are the
+/// inputs to xBestIndex and are read-only.  xBestIndex inserts its
+/// results into the **Outputs** fields.
+///
+/// ^(The aConstraint[] array records WHERE clause constraints of the form:
+///
+/// <blockquote>column OP expr</blockquote>
+///
+/// where OP is =, &lt;, &lt;=, &gt;, or &gt;=.)^  ^(The particular operator is
+/// stored in aConstraint[].op using one of the
+/// [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^
+/// ^(The index of the column is stored in
+/// aConstraint[].iColumn.)^  ^(aConstraint[].usable is TRUE if the
+/// expr on the right-hand side can be evaluated (and thus the constraint
+/// is usable) and false if it cannot.)^
+///
+/// ^The optimizer automatically inverts terms of the form "expr OP column"
+/// and makes other simplifications to the WHERE clause in an attempt to
+/// get as many WHERE clause terms into the form shown above as possible.
+/// ^The aConstraint[] array only reports WHERE clause terms that are
+/// relevant to the particular virtual table being queried.
+///
+/// ^Information about the ORDER BY clause is stored in aOrderBy[].
+/// ^Each term of aOrderBy records a column of the ORDER BY clause.
+///
+/// The colUsed field indicates which columns of the virtual table may be
+/// required by the current scan. Virtual table columns are numbered from
+/// zero in the order in which they appear within the CREATE TABLE statement
+/// passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
+/// the corresponding bit is set within the colUsed mask if the column may be
+/// required by SQLite. If the table has at least 64 columns and any column
+/// to the right of the first 63 is required, then bit 63 of colUsed is also
+/// set. In other words, column iCol may be required if the expression
+/// (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to
+/// non-zero.
+///
+/// The [xBestIndex] method must fill aConstraintUsage[] with information
+/// about what parameters to pass to xFilter.  ^If argvIndex>0 then
+/// the right-hand side of the corresponding aConstraint[] is evaluated
+/// and becomes the argvIndex-th entry in argv.  ^(If aConstraintUsage[].omit
+/// is true, then the constraint is assumed to be fully handled by the
+/// virtual table and might not be checked again by the byte code.)^ ^(The
+/// aConstraintUsage[].omit flag is an optimization hint. When the omit flag
+/// is left in its default setting of false, the constraint will always be
+/// checked separately in byte code.  If the omit flag is change to true, then
+/// the constraint may or may not be checked in byte code.  In other words,
+/// when the omit flag is true there is no guarantee that the constraint will
+/// not be checked again using byte code.)^
+///
+/// ^The idxNum and idxPtr values are recorded and passed into the
+/// [xFilter] method.
+/// ^[sqlite3_free()] is used to free idxPtr if and only if
+/// needToFreeIdxPtr is true.
+///
+/// ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
+/// the correct order to satisfy the ORDER BY clause so that no separate
+/// sorting step is required.
+///
+/// ^The estimatedCost value is an estimate of the cost of a particular
+/// strategy. A cost of N indicates that the cost of the strategy is similar
+/// to a linear scan of an SQLite table with N rows. A cost of log(N)
+/// indicates that the expense of the operation is similar to that of a
+/// binary search on a unique indexed field of an SQLite table with N rows.
+///
+/// ^The estimatedRows value is an estimate of the number of rows that
+/// will be returned by the strategy.
+///
+/// The xBestIndex method may optionally populate the idxFlags field with a
+/// mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
+/// SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
+/// assumes that the strategy may visit at most one row.
+///
+/// Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
+/// SQLite also assumes that if a call to the xUpdate() method is made as
+/// part of the same statement to delete or update a virtual table row and the
+/// implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
+/// any database changes. In other words, if the xUpdate() returns
+/// SQLITE_CONSTRAINT, the database contents must be exactly as they were
+/// before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
+/// set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
+/// the xUpdate method are automatically rolled back by SQLite.
+///
+/// IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+/// structure for SQLite [version 3.8.2] ([dateof:3.8.2]).
+/// If a virtual table extension is
+/// used with an SQLite version earlier than 3.8.2, the results of attempting
+/// to read or write the estimatedRows field are undefined (but are likely
+/// to include crashing the application). The estimatedRows field should
+/// therefore only be used if [sqlite3_libversion_number()] returns a
+/// value greater than or equal to 3008002. Similarly, the idxFlags field
+/// was added for [version 3.9.0] ([dateof:3.9.0]).
+/// It may therefore only be used if
+/// sqlite3_libversion_number() returns a value greater than or equal to
+/// 3009000.
+final class sqlite3_index_info extends ffi.Struct {
+  /// Number of entries in aConstraint
+  @ffi.Int()
+  external int nConstraint;
+
+  /// Table of WHERE clause constraints
+  external ffi.Pointer<sqlite3_index_constraint> aConstraint;
+
+  /// Number of terms in the ORDER BY clause
+  @ffi.Int()
+  external int nOrderBy;
+
+  /// The ORDER BY clause
+  external ffi.Pointer<sqlite3_index_orderby> aOrderBy;
+
+  external ffi.Pointer<sqlite3_index_constraint_usage> aConstraintUsage;
+
+  /// Number used to identify the index
+  @ffi.Int()
+  external int idxNum;
+
+  /// String, possibly obtained from sqlite3_malloc
+  external ffi.Pointer<ffi.Char> idxStr;
+
+  /// Free idxStr using sqlite3_free() if true
+  @ffi.Int()
+  external int needToFreeIdxStr;
+
+  /// True if output is already ordered
+  @ffi.Int()
+  external int orderByConsumed;
+
+  /// Estimated cost of using this index
+  @ffi.Double()
+  external double estimatedCost;
+
+  /// Estimated number of rows returned
+  @sqlite3_int64()
+  external int estimatedRows;
+
+  /// Mask of SQLITE_INDEX_SCAN_* flags
+  @ffi.Int()
+  external int idxFlags;
+
+  /// Input: Mask of columns used by statement
+  @sqlite3_uint64()
+  external int colUsed;
+}
+
+final class sqlite3_index_constraint extends ffi.Struct {
+  /// Column constrained.  -1 for ROWID
+  @ffi.Int()
+  external int iColumn;
+
+  /// Constraint operator
+  @ffi.UnsignedChar()
+  external int op;
+
+  /// True if this constraint is usable
+  @ffi.UnsignedChar()
+  external int usable;
+
+  /// Used internally - xBestIndex should ignore
+  @ffi.Int()
+  external int iTermOffset;
+}
+
+final class sqlite3_index_orderby extends ffi.Struct {
+  /// Column number
+  @ffi.Int()
+  external int iColumn;
+
+  /// True for DESC.  False for ASC.
+  @ffi.UnsignedChar()
+  external int desc;
+}
+
+/// Outputs
+final class sqlite3_index_constraint_usage extends ffi.Struct {
+  /// if >0, constraint is part of argv to xFilter
+  @ffi.Int()
+  external int argvIndex;
+
+  /// Do not code a test for this constraint
+  @ffi.UnsignedChar()
+  external int omit;
+}
+
+/// CAPI3REF: Virtual Table Cursor Object
+/// KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}
+///
+/// Every [virtual table module] implementation uses a subclass of the
+/// following structure to describe cursors that point into the
+/// [virtual table] and are used
+/// to loop through the virtual table.  Cursors are created using the
+/// [sqlite3_module.xOpen | xOpen] method of the module and are destroyed
+/// by the [sqlite3_module.xClose | xClose] method.  Cursors are used
+/// by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods
+/// of the module.  Each module implementation will define
+/// the content of a cursor structure to suit its own needs.
+///
+/// This superclass exists in order to define fields of the cursor that
+/// are common to all implementations.
+final class sqlite3_vtab_cursor extends ffi.Struct {
+  /// Virtual table of this cursor
+  external ffi.Pointer<sqlite3_vtab> pVtab;
+}
+
+final class sqlite3_blob extends ffi.Opaque {}
+
+final class sqlite3_mutex_methods extends ffi.Struct {
+  external ffi.Pointer<ffi.NativeFunction<ffi.Int Function()>> xMutexInit;
+
+  external ffi.Pointer<ffi.NativeFunction<ffi.Int Function()>> xMutexEnd;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Pointer<sqlite3_mutex> Function(ffi.Int)>>
+      xMutexAlloc;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_mutex>)>>
+      xMutexFree;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_mutex>)>>
+      xMutexEnter;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>
+      xMutexTry;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_mutex>)>>
+      xMutexLeave;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>
+      xMutexHeld;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>
+      xMutexNotheld;
+}
+
+final class sqlite3_str extends ffi.Opaque {}
+
+final class sqlite3_pcache extends ffi.Opaque {}
+
+final class sqlite3_pcache_page extends ffi.Struct {
+  /// The content of the page
+  external ffi.Pointer<ffi.Void> pBuf;
+
+  /// Extra information associated with the page
+  external ffi.Pointer<ffi.Void> pExtra;
+}
+
+final class sqlite3_pcache_methods2 extends ffi.Struct {
+  @ffi.Int()
+  external int iVersion;
+
+  external ffi.Pointer<ffi.Void> pArg;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
+      xInit;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      xShutdown;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3_pcache> Function(
+              ffi.Int szPage, ffi.Int szExtra, ffi.Int bPurgeable)>> xCreate;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_pcache>, ffi.Int)>> xCachesize;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_pcache>)>>
+      xPagecount;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3_pcache_page> Function(
+              ffi.Pointer<sqlite3_pcache>, ffi.UnsignedInt, ffi.Int)>> xFetch;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_pcache>,
+              ffi.Pointer<sqlite3_pcache_page>, ffi.Int)>> xUnpin;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<sqlite3_pcache>,
+              ffi.Pointer<sqlite3_pcache_page>,
+              ffi.UnsignedInt,
+              ffi.UnsignedInt)>> xRekey;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Void Function(ffi.Pointer<sqlite3_pcache>, ffi.UnsignedInt)>>
+      xTruncate;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_pcache>)>>
+      xDestroy;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_pcache>)>>
+      xShrink;
+}
+
+final class sqlite3_pcache_methods extends ffi.Struct {
+  external ffi.Pointer<ffi.Void> pArg;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
+      xInit;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      xShutdown;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Pointer<sqlite3_pcache> Function(
+              ffi.Int szPage, ffi.Int bPurgeable)>> xCreate;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_pcache>, ffi.Int)>> xCachesize;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_pcache>)>>
+      xPagecount;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<sqlite3_pcache>, ffi.UnsignedInt, ffi.Int)>> xFetch;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Void Function(
+                  ffi.Pointer<sqlite3_pcache>, ffi.Pointer<ffi.Void>, ffi.Int)>>
+      xUnpin;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Void Function(ffi.Pointer<sqlite3_pcache>, ffi.Pointer<ffi.Void>,
+              ffi.UnsignedInt, ffi.UnsignedInt)>> xRekey;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Void Function(ffi.Pointer<sqlite3_pcache>, ffi.UnsignedInt)>>
+      xTruncate;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_pcache>)>>
+      xDestroy;
+}
+
+final class sqlite3_backup extends ffi.Opaque {}
+
+/// CAPI3REF: Database Snapshot
+/// KEYWORDS: {snapshot} {sqlite3_snapshot}
+///
+/// An instance of the snapshot object records the state of a [WAL mode]
+/// database for some specific point in history.
+///
+/// In [WAL mode], multiple [database connections] that are open on the
+/// same database file can each be reading a different historical version
+/// of the database file.  When a [database connection] begins a read
+/// transaction, that connection sees an unchanging copy of the database
+/// as it existed for the point in time when the transaction first started.
+/// Subsequent changes to the database from other connections are not seen
+/// by the reader until a new read transaction is started.
+///
+/// The sqlite3_snapshot object records state information about an historical
+/// version of the database file so that it is possible to later open a new read
+/// transaction that sees that historical version of the database rather than
+/// the most recent version.
+final class sqlite3_snapshot extends ffi.Struct {
+  @ffi.Array.multi([48])
+  external ffi.Array<ffi.UnsignedChar> hidden;
+}
+
+/// A pointer to a structure of the following type is passed as the first
+/// argument to callbacks registered using rtree_geometry_callback().
+final class sqlite3_rtree_geometry extends ffi.Struct {
+  /// Copy of pContext passed to s_r_g_c()
+  external ffi.Pointer<ffi.Void> pContext;
+
+  /// Size of array aParam[]
+  @ffi.Int()
+  external int nParam;
+
+  /// Parameters passed to SQL geom function
+  external ffi.Pointer<sqlite3_rtree_dbl> aParam;
+
+  /// Callback implementation user data
+  external ffi.Pointer<ffi.Void> pUser;
+
+  /// Called by SQLite to clean up pUser
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      xDelUser;
+}
+
+typedef sqlite3_rtree_dbl = ffi.Double;
+typedef Dartsqlite3_rtree_dbl = double;
+
+/// A pointer to a structure of the following type is passed as the
+/// argument to scored geometry callback registered using
+/// sqlite3_rtree_query_callback().
+///
+/// Note that the first 5 fields of this structure are identical to
+/// sqlite3_rtree_geometry.  This structure is a subclass of
+/// sqlite3_rtree_geometry.
+final class sqlite3_rtree_query_info extends ffi.Struct {
+  /// pContext from when function registered
+  external ffi.Pointer<ffi.Void> pContext;
+
+  /// Number of function parameters
+  @ffi.Int()
+  external int nParam;
+
+  /// value of function parameters
+  external ffi.Pointer<sqlite3_rtree_dbl> aParam;
+
+  /// callback can use this, if desired
+  external ffi.Pointer<ffi.Void> pUser;
+
+  /// function to free pUser
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      xDelUser;
+
+  /// Coordinates of node or entry to check
+  external ffi.Pointer<sqlite3_rtree_dbl> aCoord;
+
+  /// Number of pending entries in the queue
+  external ffi.Pointer<ffi.UnsignedInt> anQueue;
+
+  /// Number of coordinates
+  @ffi.Int()
+  external int nCoord;
+
+  /// Level of current node or entry
+  @ffi.Int()
+  external int iLevel;
+
+  /// The largest iLevel value in the tree
+  @ffi.Int()
+  external int mxLevel;
+
+  /// Rowid for current entry
+  @sqlite3_int64()
+  external int iRowid;
+
+  /// Score of parent node
+  @sqlite3_rtree_dbl()
+  external double rParentScore;
+
+  /// Visibility of parent node
+  @ffi.Int()
+  external int eParentWithin;
+
+  /// OUT: Visibility
+  @ffi.Int()
+  external int eWithin;
+
+  /// OUT: Write the score here
+  @sqlite3_rtree_dbl()
+  external double rScore;
+
+  /// Original SQL values of parameters
+  external ffi.Pointer<ffi.Pointer<sqlite3_value>> apSqlParam;
+}
+
+/// EXTENSION API FUNCTIONS
+///
+/// xUserData(pFts):
+/// Return a copy of the context pointer the extension function was
+/// registered with.
+///
+/// xColumnTotalSize(pFts, iCol, pnToken):
+/// If parameter iCol is less than zero, set output variable *pnToken
+/// to the total number of tokens in the FTS5 table. Or, if iCol is
+/// non-negative but less than the number of columns in the table, return
+/// the total number of tokens in column iCol, considering all rows in
+/// the FTS5 table.
+///
+/// If parameter iCol is greater than or equal to the number of columns
+/// in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+/// an OOM condition or IO error), an appropriate SQLite error code is
+/// returned.
+///
+/// xColumnCount(pFts):
+/// Return the number of columns in the table.
+///
+/// xColumnSize(pFts, iCol, pnToken):
+/// If parameter iCol is less than zero, set output variable *pnToken
+/// to the total number of tokens in the current row. Or, if iCol is
+/// non-negative but less than the number of columns in the table, set
+/// *pnToken to the number of tokens in column iCol of the current row.
+///
+/// If parameter iCol is greater than or equal to the number of columns
+/// in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+/// an OOM condition or IO error), an appropriate SQLite error code is
+/// returned.
+///
+/// This function may be quite inefficient if used with an FTS5 table
+/// created with the "columnsize=0" option.
+///
+/// xColumnText:
+/// This function attempts to retrieve the text of column iCol of the
+/// current document. If successful, (*pz) is set to point to a buffer
+/// containing the text in utf-8 encoding, (*pn) is set to the size in bytes
+/// (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
+/// if an error occurs, an SQLite error code is returned and the final values
+/// of (*pz) and (*pn) are undefined.
+///
+/// xPhraseCount:
+/// Returns the number of phrases in the current query expression.
+///
+/// xPhraseSize:
+/// Returns the number of tokens in phrase iPhrase of the query. Phrases
+/// are numbered starting from zero.
+///
+/// xInstCount:
+/// Set *pnInst to the total number of occurrences of all phrases within
+/// the query within the current row. Return SQLITE_OK if successful, or
+/// an error code (i.e. SQLITE_NOMEM) if an error occurs.
+///
+/// This API can be quite slow if used with an FTS5 table created with the
+/// "detail=none" or "detail=column" option. If the FTS5 table is created
+/// with either "detail=none" or "detail=column" and "content=" option
+/// (i.e. if it is a contentless table), then this API always returns 0.
+///
+/// xInst:
+/// Query for the details of phrase match iIdx within the current row.
+/// Phrase matches are numbered starting from zero, so the iIdx argument
+/// should be greater than or equal to zero and smaller than the value
+/// output by xInstCount().
+///
+/// Usually, output parameter *piPhrase is set to the phrase number, *piCol
+/// to the column in which it occurs and *piOff the token offset of the
+/// first token of the phrase. Returns SQLITE_OK if successful, or an error
+/// code (i.e. SQLITE_NOMEM) if an error occurs.
+///
+/// This API can be quite slow if used with an FTS5 table created with the
+/// "detail=none" or "detail=column" option.
+///
+/// xRowid:
+/// Returns the rowid of the current row.
+///
+/// xTokenize:
+/// Tokenize text using the tokenizer belonging to the FTS5 table.
+///
+/// xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
+/// This API function is used to query the FTS table for phrase iPhrase
+/// of the current query. Specifically, a query equivalent to:
+///
+/// ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
+///
+/// with $p set to a phrase equivalent to the phrase iPhrase of the
+/// current query is executed. Any column filter that applies to
+/// phrase iPhrase of the current query is included in $p. For each
+/// row visited, the callback function passed as the fourth argument
+/// is invoked. The context and API objects passed to the callback
+/// function may be used to access the properties of each matched row.
+/// Invoking Api.xUserData() returns a copy of the pointer passed as
+/// the third argument to pUserData.
+///
+/// If the callback function returns any value other than SQLITE_OK, the
+/// query is abandoned and the xQueryPhrase function returns immediately.
+/// If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
+/// Otherwise, the error code is propagated upwards.
+///
+/// If the query runs to completion without incident, SQLITE_OK is returned.
+/// Or, if some error occurs before the query completes or is aborted by
+/// the callback, an SQLite error code is returned.
+///
+///
+/// xSetAuxdata(pFts5, pAux, xDelete)
+///
+/// Save the pointer passed as the second argument as the extension function's
+/// "auxiliary data". The pointer may then be retrieved by the current or any
+/// future invocation of the same fts5 extension function made as part of
+/// the same MATCH query using the xGetAuxdata() API.
+///
+/// Each extension function is allocated a single auxiliary data slot for
+/// each FTS query (MATCH expression). If the extension function is invoked
+/// more than once for a single FTS query, then all invocations share a
+/// single auxiliary data context.
+///
+/// If there is already an auxiliary data pointer when this function is
+/// invoked, then it is replaced by the new pointer. If an xDelete callback
+/// was specified along with the original pointer, it is invoked at this
+/// point.
+///
+/// The xDelete callback, if one is specified, is also invoked on the
+/// auxiliary data pointer after the FTS5 query has finished.
+///
+/// If an error (e.g. an OOM condition) occurs within this function,
+/// the auxiliary data is set to NULL and an error code returned. If the
+/// xDelete parameter was not NULL, it is invoked on the auxiliary data
+/// pointer before returning.
+///
+///
+/// xGetAuxdata(pFts5, bClear)
+///
+/// Returns the current auxiliary data pointer for the fts5 extension
+/// function. See the xSetAuxdata() method for details.
+///
+/// If the bClear argument is non-zero, then the auxiliary data is cleared
+/// (set to NULL) before this function returns. In this case the xDelete,
+/// if any, is not invoked.
+///
+///
+/// xRowCount(pFts5, pnRow)
+///
+/// This function is used to retrieve the total number of rows in the table.
+/// In other words, the same value that would be returned by:
+///
+/// SELECT count(*) FROM ftstable;
+///
+/// xPhraseFirst()
+/// This function is used, along with type Fts5PhraseIter and the xPhraseNext
+/// method, to iterate through all instances of a single query phrase within
+/// the current row. This is the same information as is accessible via the
+/// xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
+/// to use, this API may be faster under some circumstances. To iterate
+/// through instances of phrase iPhrase, use the following code:
+///
+/// Fts5PhraseIter iter;
+/// int iCol, iOff;
+/// for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
+/// iCol>=0;
+/// pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
+/// ){
+/// // An instance of phrase iPhrase at offset iOff of column iCol
+/// }
+///
+/// The Fts5PhraseIter structure is defined above. Applications should not
+/// modify this structure directly - it should only be used as shown above
+/// with the xPhraseFirst() and xPhraseNext() API methods (and by
+/// xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
+///
+/// This API can be quite slow if used with an FTS5 table created with the
+/// "detail=none" or "detail=column" option. If the FTS5 table is created
+/// with either "detail=none" or "detail=column" and "content=" option
+/// (i.e. if it is a contentless table), then this API always iterates
+/// through an empty set (all calls to xPhraseFirst() set iCol to -1).
+///
+/// xPhraseNext()
+/// See xPhraseFirst above.
+///
+/// xPhraseFirstColumn()
+/// This function and xPhraseNextColumn() are similar to the xPhraseFirst()
+/// and xPhraseNext() APIs described above. The difference is that instead
+/// of iterating through all instances of a phrase in the current row, these
+/// APIs are used to iterate through the set of columns in the current row
+/// that contain one or more instances of a specified phrase. For example:
+///
+/// Fts5PhraseIter iter;
+/// int iCol;
+/// for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
+/// iCol>=0;
+/// pApi->xPhraseNextColumn(pFts, &iter, &iCol)
+/// ){
+/// // Column iCol contains at least one instance of phrase iPhrase
+/// }
+///
+/// This API can be quite slow if used with an FTS5 table created with the
+/// "detail=none" option. If the FTS5 table is created with either
+/// "detail=none" "content=" option (i.e. if it is a contentless table),
+/// then this API always iterates through an empty set (all calls to
+/// xPhraseFirstColumn() set iCol to -1).
+///
+/// The information accessed using this API and its companion
+/// xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
+/// (or xInst/xInstCount). The chief advantage of this API is that it is
+/// significantly more efficient than those alternatives when used with
+/// "detail=column" tables.
+///
+/// xPhraseNextColumn()
+/// See xPhraseFirstColumn above.
+final class Fts5ExtensionApi extends ffi.Struct {
+  /// Currently always set to 3
+  @ffi.Int()
+  external int iVersion;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<Fts5Context>)>> xUserData;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<Fts5Context>)>>
+      xColumnCount;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<Fts5Context>, ffi.Pointer<sqlite3_int64>)>> xRowCount;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(ffi.Pointer<Fts5Context>, ffi.Int,
+              ffi.Pointer<sqlite3_int64>)>> xColumnTotalSize;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<Fts5Context>,
+              ffi.Pointer<ffi.Char>,
+              ffi.Int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Char>,
+                          ffi.Int,
+                          ffi.Int,
+                          ffi.Int)>>)>> xTokenize;
+
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<Fts5Context>)>>
+      xPhraseCount;
+
+  external ffi.Pointer<
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<Fts5Context>, ffi.Int)>>
+      xPhraseSize;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Int Function(ffi.Pointer<Fts5Context>, ffi.Pointer<ffi.Int>)>>
+      xInstCount;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<Fts5Context>,
+              ffi.Int,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Int>)>> xInst;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<sqlite3_int64 Function(ffi.Pointer<Fts5Context>)>>
+      xRowid;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<Fts5Context>,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Pointer<ffi.Int>)>> xColumnText;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<Fts5Context>, ffi.Int, ffi.Pointer<ffi.Int>)>>
+      xColumnSize;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<Fts5Context>,
+              ffi.Int,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(
+                          ffi.Pointer<Fts5ExtensionApi>,
+                          ffi.Pointer<Fts5Context>,
+                          ffi.Pointer<ffi.Void>)>>)>> xQueryPhrase;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<Fts5Context>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>> xSetAuxdata;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<Fts5Context>, ffi.Int)>> xGetAuxdata;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<Fts5Context>,
+              ffi.Int,
+              ffi.Pointer<Fts5PhraseIter>,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Int>)>> xPhraseFirst;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<Fts5Context>,
+              ffi.Pointer<Fts5PhraseIter>,
+              ffi.Pointer<ffi.Int>,
+              ffi.Pointer<ffi.Int>)>> xPhraseNext;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<Fts5Context>,
+              ffi.Int,
+              ffi.Pointer<Fts5PhraseIter>,
+              ffi.Pointer<ffi.Int>)>> xPhraseFirstColumn;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              ffi.Pointer<Fts5Context>,
+              ffi.Pointer<Fts5PhraseIter>,
+              ffi.Pointer<ffi.Int>)>> xPhraseNextColumn;
+}
+
+final class Fts5Context extends ffi.Opaque {}
+
+final class Fts5PhraseIter extends ffi.Struct {
+  external ffi.Pointer<ffi.UnsignedChar> a;
+
+  external ffi.Pointer<ffi.UnsignedChar> b;
+}
+
+final class Fts5Tokenizer extends ffi.Opaque {}
+
+final class fts5_tokenizer extends ffi.Struct {
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Pointer<ffi.Char>>,
+              ffi.Int,
+              ffi.Pointer<ffi.Pointer<Fts5Tokenizer>>)>> xCreate;
+
+  external ffi.Pointer<
+          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<Fts5Tokenizer>)>>
+      xDelete;
+
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<Fts5Tokenizer>,
+              ffi.Pointer<ffi.Void>,
+              ffi.Int,
+              ffi.Pointer<ffi.Char>,
+              ffi.Int,
+              ffi.Pointer<
+                  ffi.NativeFunction<
+                      ffi.Int Function(
+                          ffi.Pointer<ffi.Void>,
+                          ffi.Int,
+                          ffi.Pointer<ffi.Char>,
+                          ffi.Int,
+                          ffi.Int,
+                          ffi.Int)>>)>> xTokenize;
+}
+
+final class fts5_api extends ffi.Struct {
+  /// Currently always set to 2
+  @ffi.Int()
+  external int iVersion;
+
+  /// Create a new tokenizer
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<fts5_api> pApi,
+              ffi.Pointer<ffi.Char> zName,
+              ffi.Pointer<ffi.Void> pContext,
+              ffi.Pointer<fts5_tokenizer> pTokenizer,
+              ffi.Pointer<
+                      ffi
+                      .NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+                  xDestroy)>> xCreateTokenizer;
+
+  /// Find an existing tokenizer
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<fts5_api> pApi,
+              ffi.Pointer<ffi.Char> zName,
+              ffi.Pointer<ffi.Pointer<ffi.Void>> ppContext,
+              ffi.Pointer<fts5_tokenizer> pTokenizer)>> xFindTokenizer;
+
+  /// Create a new auxiliary function
+  external ffi.Pointer<
+      ffi.NativeFunction<
+          ffi.Int Function(
+              ffi.Pointer<fts5_api> pApi,
+              ffi.Pointer<ffi.Char> zName,
+              ffi.Pointer<ffi.Void> pContext,
+              fts5_extension_function xFunction,
+              ffi.Pointer<
+                      ffi
+                      .NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+                  xDestroy)>> xCreateFunction;
+}
+
+typedef fts5_extension_function
+    = ffi.Pointer<ffi.NativeFunction<fts5_extension_functionFunction>>;
+typedef fts5_extension_functionFunction = ffi.Void Function(
+    ffi.Pointer<Fts5ExtensionApi> pApi,
+    ffi.Pointer<Fts5Context> pFts,
+    ffi.Pointer<sqlite3_context> pCtx,
+    ffi.Int nVal,
+    ffi.Pointer<ffi.Pointer<sqlite3_value>> apVal);
+typedef Dartfts5_extension_functionFunction = void Function(
+    ffi.Pointer<Fts5ExtensionApi> pApi,
+    ffi.Pointer<Fts5Context> pFts,
+    ffi.Pointer<sqlite3_context> pCtx,
+    int nVal,
+    ffi.Pointer<ffi.Pointer<sqlite3_value>> apVal);
+
+const String SQLITE_VERSION = '3.32.3';
+
+const int SQLITE_VERSION_NUMBER = 3032003;
+
+const String SQLITE_SOURCE_ID =
+    '2020-06-18 14:00:33 7ebdfa80be8e8e73324b8d66b3460222eb74c7e9dfd655b48d6ca7e1933cc8fd';
+
+const int SQLITE_OK = 0;
+
+const int SQLITE_ERROR = 1;
+
+const int SQLITE_INTERNAL = 2;
+
+const int SQLITE_PERM = 3;
+
+const int SQLITE_ABORT = 4;
+
+const int SQLITE_BUSY = 5;
+
+const int SQLITE_LOCKED = 6;
+
+const int SQLITE_NOMEM = 7;
+
+const int SQLITE_READONLY = 8;
+
+const int SQLITE_INTERRUPT = 9;
+
+const int SQLITE_IOERR = 10;
+
+const int SQLITE_CORRUPT = 11;
+
+const int SQLITE_NOTFOUND = 12;
+
+const int SQLITE_FULL = 13;
+
+const int SQLITE_CANTOPEN = 14;
+
+const int SQLITE_PROTOCOL = 15;
+
+const int SQLITE_EMPTY = 16;
+
+const int SQLITE_SCHEMA = 17;
+
+const int SQLITE_TOOBIG = 18;
+
+const int SQLITE_CONSTRAINT = 19;
+
+const int SQLITE_MISMATCH = 20;
+
+const int SQLITE_MISUSE = 21;
+
+const int SQLITE_NOLFS = 22;
+
+const int SQLITE_AUTH = 23;
+
+const int SQLITE_FORMAT = 24;
+
+const int SQLITE_RANGE = 25;
+
+const int SQLITE_NOTADB = 26;
+
+const int SQLITE_NOTICE = 27;
+
+const int SQLITE_WARNING = 28;
+
+const int SQLITE_ROW = 100;
+
+const int SQLITE_DONE = 101;
+
+const int SQLITE_ERROR_MISSING_COLLSEQ = 257;
+
+const int SQLITE_ERROR_RETRY = 513;
+
+const int SQLITE_ERROR_SNAPSHOT = 769;
+
+const int SQLITE_IOERR_READ = 266;
+
+const int SQLITE_IOERR_SHORT_READ = 522;
+
+const int SQLITE_IOERR_WRITE = 778;
+
+const int SQLITE_IOERR_FSYNC = 1034;
+
+const int SQLITE_IOERR_DIR_FSYNC = 1290;
+
+const int SQLITE_IOERR_TRUNCATE = 1546;
+
+const int SQLITE_IOERR_FSTAT = 1802;
+
+const int SQLITE_IOERR_UNLOCK = 2058;
+
+const int SQLITE_IOERR_RDLOCK = 2314;
+
+const int SQLITE_IOERR_DELETE = 2570;
+
+const int SQLITE_IOERR_BLOCKED = 2826;
+
+const int SQLITE_IOERR_NOMEM = 3082;
+
+const int SQLITE_IOERR_ACCESS = 3338;
+
+const int SQLITE_IOERR_CHECKRESERVEDLOCK = 3594;
+
+const int SQLITE_IOERR_LOCK = 3850;
+
+const int SQLITE_IOERR_CLOSE = 4106;
+
+const int SQLITE_IOERR_DIR_CLOSE = 4362;
+
+const int SQLITE_IOERR_SHMOPEN = 4618;
+
+const int SQLITE_IOERR_SHMSIZE = 4874;
+
+const int SQLITE_IOERR_SHMLOCK = 5130;
+
+const int SQLITE_IOERR_SHMMAP = 5386;
+
+const int SQLITE_IOERR_SEEK = 5642;
+
+const int SQLITE_IOERR_DELETE_NOENT = 5898;
+
+const int SQLITE_IOERR_MMAP = 6154;
+
+const int SQLITE_IOERR_GETTEMPPATH = 6410;
+
+const int SQLITE_IOERR_CONVPATH = 6666;
+
+const int SQLITE_IOERR_VNODE = 6922;
+
+const int SQLITE_IOERR_AUTH = 7178;
+
+const int SQLITE_IOERR_BEGIN_ATOMIC = 7434;
+
+const int SQLITE_IOERR_COMMIT_ATOMIC = 7690;
+
+const int SQLITE_IOERR_ROLLBACK_ATOMIC = 7946;
+
+const int SQLITE_IOERR_DATA = 8202;
+
+const int SQLITE_LOCKED_SHAREDCACHE = 262;
+
+const int SQLITE_LOCKED_VTAB = 518;
+
+const int SQLITE_BUSY_RECOVERY = 261;
+
+const int SQLITE_BUSY_SNAPSHOT = 517;
+
+const int SQLITE_BUSY_TIMEOUT = 773;
+
+const int SQLITE_CANTOPEN_NOTEMPDIR = 270;
+
+const int SQLITE_CANTOPEN_ISDIR = 526;
+
+const int SQLITE_CANTOPEN_FULLPATH = 782;
+
+const int SQLITE_CANTOPEN_CONVPATH = 1038;
+
+const int SQLITE_CANTOPEN_DIRTYWAL = 1294;
+
+const int SQLITE_CANTOPEN_SYMLINK = 1550;
+
+const int SQLITE_CORRUPT_VTAB = 267;
+
+const int SQLITE_CORRUPT_SEQUENCE = 523;
+
+const int SQLITE_CORRUPT_INDEX = 779;
+
+const int SQLITE_READONLY_RECOVERY = 264;
+
+const int SQLITE_READONLY_CANTLOCK = 520;
+
+const int SQLITE_READONLY_ROLLBACK = 776;
+
+const int SQLITE_READONLY_DBMOVED = 1032;
+
+const int SQLITE_READONLY_CANTINIT = 1288;
+
+const int SQLITE_READONLY_DIRECTORY = 1544;
+
+const int SQLITE_ABORT_ROLLBACK = 516;
+
+const int SQLITE_CONSTRAINT_CHECK = 275;
+
+const int SQLITE_CONSTRAINT_COMMITHOOK = 531;
+
+const int SQLITE_CONSTRAINT_FOREIGNKEY = 787;
+
+const int SQLITE_CONSTRAINT_FUNCTION = 1043;
+
+const int SQLITE_CONSTRAINT_NOTNULL = 1299;
+
+const int SQLITE_CONSTRAINT_PRIMARYKEY = 1555;
+
+const int SQLITE_CONSTRAINT_TRIGGER = 1811;
+
+const int SQLITE_CONSTRAINT_UNIQUE = 2067;
+
+const int SQLITE_CONSTRAINT_VTAB = 2323;
+
+const int SQLITE_CONSTRAINT_ROWID = 2579;
+
+const int SQLITE_CONSTRAINT_PINNED = 2835;
+
+const int SQLITE_NOTICE_RECOVER_WAL = 283;
+
+const int SQLITE_NOTICE_RECOVER_ROLLBACK = 539;
+
+const int SQLITE_WARNING_AUTOINDEX = 284;
+
+const int SQLITE_AUTH_USER = 279;
+
+const int SQLITE_OK_LOAD_PERMANENTLY = 256;
+
+const int SQLITE_OK_SYMLINK = 512;
+
+const int SQLITE_OPEN_READONLY = 1;
+
+const int SQLITE_OPEN_READWRITE = 2;
+
+const int SQLITE_OPEN_CREATE = 4;
+
+const int SQLITE_OPEN_DELETEONCLOSE = 8;
+
+const int SQLITE_OPEN_EXCLUSIVE = 16;
+
+const int SQLITE_OPEN_AUTOPROXY = 32;
+
+const int SQLITE_OPEN_URI = 64;
+
+const int SQLITE_OPEN_MEMORY = 128;
+
+const int SQLITE_OPEN_MAIN_DB = 256;
+
+const int SQLITE_OPEN_TEMP_DB = 512;
+
+const int SQLITE_OPEN_TRANSIENT_DB = 1024;
+
+const int SQLITE_OPEN_MAIN_JOURNAL = 2048;
+
+const int SQLITE_OPEN_TEMP_JOURNAL = 4096;
+
+const int SQLITE_OPEN_SUBJOURNAL = 8192;
+
+const int SQLITE_OPEN_MASTER_JOURNAL = 16384;
+
+const int SQLITE_OPEN_NOMUTEX = 32768;
+
+const int SQLITE_OPEN_FULLMUTEX = 65536;
+
+const int SQLITE_OPEN_SHAREDCACHE = 131072;
+
+const int SQLITE_OPEN_PRIVATECACHE = 262144;
+
+const int SQLITE_OPEN_WAL = 524288;
+
+const int SQLITE_OPEN_NOFOLLOW = 16777216;
+
+const int SQLITE_IOCAP_ATOMIC = 1;
+
+const int SQLITE_IOCAP_ATOMIC512 = 2;
+
+const int SQLITE_IOCAP_ATOMIC1K = 4;
+
+const int SQLITE_IOCAP_ATOMIC2K = 8;
+
+const int SQLITE_IOCAP_ATOMIC4K = 16;
+
+const int SQLITE_IOCAP_ATOMIC8K = 32;
+
+const int SQLITE_IOCAP_ATOMIC16K = 64;
+
+const int SQLITE_IOCAP_ATOMIC32K = 128;
+
+const int SQLITE_IOCAP_ATOMIC64K = 256;
+
+const int SQLITE_IOCAP_SAFE_APPEND = 512;
+
+const int SQLITE_IOCAP_SEQUENTIAL = 1024;
+
+const int SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN = 2048;
+
+const int SQLITE_IOCAP_POWERSAFE_OVERWRITE = 4096;
+
+const int SQLITE_IOCAP_IMMUTABLE = 8192;
+
+const int SQLITE_IOCAP_BATCH_ATOMIC = 16384;
+
+const int SQLITE_LOCK_NONE = 0;
+
+const int SQLITE_LOCK_SHARED = 1;
+
+const int SQLITE_LOCK_RESERVED = 2;
+
+const int SQLITE_LOCK_PENDING = 3;
+
+const int SQLITE_LOCK_EXCLUSIVE = 4;
+
+const int SQLITE_SYNC_NORMAL = 2;
+
+const int SQLITE_SYNC_FULL = 3;
+
+const int SQLITE_SYNC_DATAONLY = 16;
+
+const int SQLITE_FCNTL_LOCKSTATE = 1;
+
+const int SQLITE_FCNTL_GET_LOCKPROXYFILE = 2;
+
+const int SQLITE_FCNTL_SET_LOCKPROXYFILE = 3;
+
+const int SQLITE_FCNTL_LAST_ERRNO = 4;
+
+const int SQLITE_FCNTL_SIZE_HINT = 5;
+
+const int SQLITE_FCNTL_CHUNK_SIZE = 6;
+
+const int SQLITE_FCNTL_FILE_POINTER = 7;
+
+const int SQLITE_FCNTL_SYNC_OMITTED = 8;
+
+const int SQLITE_FCNTL_WIN32_AV_RETRY = 9;
+
+const int SQLITE_FCNTL_PERSIST_WAL = 10;
+
+const int SQLITE_FCNTL_OVERWRITE = 11;
+
+const int SQLITE_FCNTL_VFSNAME = 12;
+
+const int SQLITE_FCNTL_POWERSAFE_OVERWRITE = 13;
+
+const int SQLITE_FCNTL_PRAGMA = 14;
+
+const int SQLITE_FCNTL_BUSYHANDLER = 15;
+
+const int SQLITE_FCNTL_TEMPFILENAME = 16;
+
+const int SQLITE_FCNTL_MMAP_SIZE = 18;
+
+const int SQLITE_FCNTL_TRACE = 19;
+
+const int SQLITE_FCNTL_HAS_MOVED = 20;
+
+const int SQLITE_FCNTL_SYNC = 21;
+
+const int SQLITE_FCNTL_COMMIT_PHASETWO = 22;
+
+const int SQLITE_FCNTL_WIN32_SET_HANDLE = 23;
+
+const int SQLITE_FCNTL_WAL_BLOCK = 24;
+
+const int SQLITE_FCNTL_ZIPVFS = 25;
+
+const int SQLITE_FCNTL_RBU = 26;
+
+const int SQLITE_FCNTL_VFS_POINTER = 27;
+
+const int SQLITE_FCNTL_JOURNAL_POINTER = 28;
+
+const int SQLITE_FCNTL_WIN32_GET_HANDLE = 29;
+
+const int SQLITE_FCNTL_PDB = 30;
+
+const int SQLITE_FCNTL_BEGIN_ATOMIC_WRITE = 31;
+
+const int SQLITE_FCNTL_COMMIT_ATOMIC_WRITE = 32;
+
+const int SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE = 33;
+
+const int SQLITE_FCNTL_LOCK_TIMEOUT = 34;
+
+const int SQLITE_FCNTL_DATA_VERSION = 35;
+
+const int SQLITE_FCNTL_SIZE_LIMIT = 36;
+
+const int SQLITE_FCNTL_CKPT_DONE = 37;
+
+const int SQLITE_FCNTL_RESERVE_BYTES = 38;
+
+const int SQLITE_FCNTL_CKPT_START = 39;
+
+const int SQLITE_GET_LOCKPROXYFILE = 2;
+
+const int SQLITE_SET_LOCKPROXYFILE = 3;
+
+const int SQLITE_LAST_ERRNO = 4;
+
+const int SQLITE_ACCESS_EXISTS = 0;
+
+const int SQLITE_ACCESS_READWRITE = 1;
+
+const int SQLITE_ACCESS_READ = 2;
+
+const int SQLITE_SHM_UNLOCK = 1;
+
+const int SQLITE_SHM_LOCK = 2;
+
+const int SQLITE_SHM_SHARED = 4;
+
+const int SQLITE_SHM_EXCLUSIVE = 8;
+
+const int SQLITE_SHM_NLOCK = 8;
+
+const int SQLITE_CONFIG_SINGLETHREAD = 1;
+
+const int SQLITE_CONFIG_MULTITHREAD = 2;
+
+const int SQLITE_CONFIG_SERIALIZED = 3;
+
+const int SQLITE_CONFIG_MALLOC = 4;
+
+const int SQLITE_CONFIG_GETMALLOC = 5;
+
+const int SQLITE_CONFIG_SCRATCH = 6;
+
+const int SQLITE_CONFIG_PAGECACHE = 7;
+
+const int SQLITE_CONFIG_HEAP = 8;
+
+const int SQLITE_CONFIG_MEMSTATUS = 9;
+
+const int SQLITE_CONFIG_MUTEX = 10;
+
+const int SQLITE_CONFIG_GETMUTEX = 11;
+
+const int SQLITE_CONFIG_LOOKASIDE = 13;
+
+const int SQLITE_CONFIG_PCACHE = 14;
+
+const int SQLITE_CONFIG_GETPCACHE = 15;
+
+const int SQLITE_CONFIG_LOG = 16;
+
+const int SQLITE_CONFIG_URI = 17;
+
+const int SQLITE_CONFIG_PCACHE2 = 18;
+
+const int SQLITE_CONFIG_GETPCACHE2 = 19;
+
+const int SQLITE_CONFIG_COVERING_INDEX_SCAN = 20;
+
+const int SQLITE_CONFIG_SQLLOG = 21;
+
+const int SQLITE_CONFIG_MMAP_SIZE = 22;
+
+const int SQLITE_CONFIG_WIN32_HEAPSIZE = 23;
+
+const int SQLITE_CONFIG_PCACHE_HDRSZ = 24;
+
+const int SQLITE_CONFIG_PMASZ = 25;
+
+const int SQLITE_CONFIG_STMTJRNL_SPILL = 26;
+
+const int SQLITE_CONFIG_SMALL_MALLOC = 27;
+
+const int SQLITE_CONFIG_SORTERREF_SIZE = 28;
+
+const int SQLITE_CONFIG_MEMDB_MAXSIZE = 29;
+
+const int SQLITE_DBCONFIG_MAINDBNAME = 1000;
+
+const int SQLITE_DBCONFIG_LOOKASIDE = 1001;
+
+const int SQLITE_DBCONFIG_ENABLE_FKEY = 1002;
+
+const int SQLITE_DBCONFIG_ENABLE_TRIGGER = 1003;
+
+const int SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER = 1004;
+
+const int SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION = 1005;
+
+const int SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE = 1006;
+
+const int SQLITE_DBCONFIG_ENABLE_QPSG = 1007;
+
+const int SQLITE_DBCONFIG_TRIGGER_EQP = 1008;
+
+const int SQLITE_DBCONFIG_RESET_DATABASE = 1009;
+
+const int SQLITE_DBCONFIG_DEFENSIVE = 1010;
+
+const int SQLITE_DBCONFIG_WRITABLE_SCHEMA = 1011;
+
+const int SQLITE_DBCONFIG_LEGACY_ALTER_TABLE = 1012;
+
+const int SQLITE_DBCONFIG_DQS_DML = 1013;
+
+const int SQLITE_DBCONFIG_DQS_DDL = 1014;
+
+const int SQLITE_DBCONFIG_ENABLE_VIEW = 1015;
+
+const int SQLITE_DBCONFIG_LEGACY_FILE_FORMAT = 1016;
+
+const int SQLITE_DBCONFIG_TRUSTED_SCHEMA = 1017;
+
+const int SQLITE_DBCONFIG_MAX = 1017;
+
+const int SQLITE_DENY = 1;
+
+const int SQLITE_IGNORE = 2;
+
+const int SQLITE_CREATE_INDEX = 1;
+
+const int SQLITE_CREATE_TABLE = 2;
+
+const int SQLITE_CREATE_TEMP_INDEX = 3;
+
+const int SQLITE_CREATE_TEMP_TABLE = 4;
+
+const int SQLITE_CREATE_TEMP_TRIGGER = 5;
+
+const int SQLITE_CREATE_TEMP_VIEW = 6;
+
+const int SQLITE_CREATE_TRIGGER = 7;
+
+const int SQLITE_CREATE_VIEW = 8;
+
+const int SQLITE_DELETE = 9;
+
+const int SQLITE_DROP_INDEX = 10;
+
+const int SQLITE_DROP_TABLE = 11;
+
+const int SQLITE_DROP_TEMP_INDEX = 12;
+
+const int SQLITE_DROP_TEMP_TABLE = 13;
+
+const int SQLITE_DROP_TEMP_TRIGGER = 14;
+
+const int SQLITE_DROP_TEMP_VIEW = 15;
+
+const int SQLITE_DROP_TRIGGER = 16;
+
+const int SQLITE_DROP_VIEW = 17;
+
+const int SQLITE_INSERT = 18;
+
+const int SQLITE_PRAGMA = 19;
+
+const int SQLITE_READ = 20;
+
+const int SQLITE_SELECT = 21;
+
+const int SQLITE_TRANSACTION = 22;
+
+const int SQLITE_UPDATE = 23;
+
+const int SQLITE_ATTACH = 24;
+
+const int SQLITE_DETACH = 25;
+
+const int SQLITE_ALTER_TABLE = 26;
+
+const int SQLITE_REINDEX = 27;
+
+const int SQLITE_ANALYZE = 28;
+
+const int SQLITE_CREATE_VTABLE = 29;
+
+const int SQLITE_DROP_VTABLE = 30;
+
+const int SQLITE_FUNCTION = 31;
+
+const int SQLITE_SAVEPOINT = 32;
+
+const int SQLITE_COPY = 0;
+
+const int SQLITE_RECURSIVE = 33;
+
+const int SQLITE_TRACE_STMT = 1;
+
+const int SQLITE_TRACE_PROFILE = 2;
+
+const int SQLITE_TRACE_ROW = 4;
+
+const int SQLITE_TRACE_CLOSE = 8;
+
+const int SQLITE_LIMIT_LENGTH = 0;
+
+const int SQLITE_LIMIT_SQL_LENGTH = 1;
+
+const int SQLITE_LIMIT_COLUMN = 2;
+
+const int SQLITE_LIMIT_EXPR_DEPTH = 3;
+
+const int SQLITE_LIMIT_COMPOUND_SELECT = 4;
+
+const int SQLITE_LIMIT_VDBE_OP = 5;
+
+const int SQLITE_LIMIT_FUNCTION_ARG = 6;
+
+const int SQLITE_LIMIT_ATTACHED = 7;
+
+const int SQLITE_LIMIT_LIKE_PATTERN_LENGTH = 8;
+
+const int SQLITE_LIMIT_VARIABLE_NUMBER = 9;
+
+const int SQLITE_LIMIT_TRIGGER_DEPTH = 10;
+
+const int SQLITE_LIMIT_WORKER_THREADS = 11;
+
+const int SQLITE_PREPARE_PERSISTENT = 1;
+
+const int SQLITE_PREPARE_NORMALIZE = 2;
+
+const int SQLITE_PREPARE_NO_VTAB = 4;
+
+const int SQLITE_INTEGER = 1;
+
+const int SQLITE_FLOAT = 2;
+
+const int SQLITE_BLOB = 4;
+
+const int SQLITE_NULL = 5;
+
+const int SQLITE_TEXT = 3;
+
+const int SQLITE3_TEXT = 3;
+
+const int SQLITE_UTF8 = 1;
+
+const int SQLITE_UTF16LE = 2;
+
+const int SQLITE_UTF16BE = 3;
+
+const int SQLITE_UTF16 = 4;
+
+const int SQLITE_ANY = 5;
+
+const int SQLITE_UTF16_ALIGNED = 8;
+
+const int SQLITE_DETERMINISTIC = 2048;
+
+const int SQLITE_DIRECTONLY = 524288;
+
+const int SQLITE_SUBTYPE = 1048576;
+
+const int SQLITE_INNOCUOUS = 2097152;
+
+const int SQLITE_WIN32_DATA_DIRECTORY_TYPE = 1;
+
+const int SQLITE_WIN32_TEMP_DIRECTORY_TYPE = 2;
+
+const int SQLITE_INDEX_SCAN_UNIQUE = 1;
+
+const int SQLITE_INDEX_CONSTRAINT_EQ = 2;
+
+const int SQLITE_INDEX_CONSTRAINT_GT = 4;
+
+const int SQLITE_INDEX_CONSTRAINT_LE = 8;
+
+const int SQLITE_INDEX_CONSTRAINT_LT = 16;
+
+const int SQLITE_INDEX_CONSTRAINT_GE = 32;
+
+const int SQLITE_INDEX_CONSTRAINT_MATCH = 64;
+
+const int SQLITE_INDEX_CONSTRAINT_LIKE = 65;
+
+const int SQLITE_INDEX_CONSTRAINT_GLOB = 66;
+
+const int SQLITE_INDEX_CONSTRAINT_REGEXP = 67;
+
+const int SQLITE_INDEX_CONSTRAINT_NE = 68;
+
+const int SQLITE_INDEX_CONSTRAINT_ISNOT = 69;
+
+const int SQLITE_INDEX_CONSTRAINT_ISNOTNULL = 70;
+
+const int SQLITE_INDEX_CONSTRAINT_ISNULL = 71;
+
+const int SQLITE_INDEX_CONSTRAINT_IS = 72;
+
+const int SQLITE_INDEX_CONSTRAINT_FUNCTION = 150;
+
+const int SQLITE_MUTEX_FAST = 0;
+
+const int SQLITE_MUTEX_RECURSIVE = 1;
+
+const int SQLITE_MUTEX_STATIC_MASTER = 2;
+
+const int SQLITE_MUTEX_STATIC_MEM = 3;
+
+const int SQLITE_MUTEX_STATIC_MEM2 = 4;
+
+const int SQLITE_MUTEX_STATIC_OPEN = 4;
+
+const int SQLITE_MUTEX_STATIC_PRNG = 5;
+
+const int SQLITE_MUTEX_STATIC_LRU = 6;
+
+const int SQLITE_MUTEX_STATIC_LRU2 = 7;
+
+const int SQLITE_MUTEX_STATIC_PMEM = 7;
+
+const int SQLITE_MUTEX_STATIC_APP1 = 8;
+
+const int SQLITE_MUTEX_STATIC_APP2 = 9;
+
+const int SQLITE_MUTEX_STATIC_APP3 = 10;
+
+const int SQLITE_MUTEX_STATIC_VFS1 = 11;
+
+const int SQLITE_MUTEX_STATIC_VFS2 = 12;
+
+const int SQLITE_MUTEX_STATIC_VFS3 = 13;
+
+const int SQLITE_TESTCTRL_FIRST = 5;
+
+const int SQLITE_TESTCTRL_PRNG_SAVE = 5;
+
+const int SQLITE_TESTCTRL_PRNG_RESTORE = 6;
+
+const int SQLITE_TESTCTRL_PRNG_RESET = 7;
+
+const int SQLITE_TESTCTRL_BITVEC_TEST = 8;
+
+const int SQLITE_TESTCTRL_FAULT_INSTALL = 9;
+
+const int SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS = 10;
+
+const int SQLITE_TESTCTRL_PENDING_BYTE = 11;
+
+const int SQLITE_TESTCTRL_ASSERT = 12;
+
+const int SQLITE_TESTCTRL_ALWAYS = 13;
+
+const int SQLITE_TESTCTRL_RESERVE = 14;
+
+const int SQLITE_TESTCTRL_OPTIMIZATIONS = 15;
+
+const int SQLITE_TESTCTRL_ISKEYWORD = 16;
+
+const int SQLITE_TESTCTRL_SCRATCHMALLOC = 17;
+
+const int SQLITE_TESTCTRL_INTERNAL_FUNCTIONS = 17;
+
+const int SQLITE_TESTCTRL_LOCALTIME_FAULT = 18;
+
+const int SQLITE_TESTCTRL_EXPLAIN_STMT = 19;
+
+const int SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD = 19;
+
+const int SQLITE_TESTCTRL_NEVER_CORRUPT = 20;
+
+const int SQLITE_TESTCTRL_VDBE_COVERAGE = 21;
+
+const int SQLITE_TESTCTRL_BYTEORDER = 22;
+
+const int SQLITE_TESTCTRL_ISINIT = 23;
+
+const int SQLITE_TESTCTRL_SORTER_MMAP = 24;
+
+const int SQLITE_TESTCTRL_IMPOSTER = 25;
+
+const int SQLITE_TESTCTRL_PARSER_COVERAGE = 26;
+
+const int SQLITE_TESTCTRL_RESULT_INTREAL = 27;
+
+const int SQLITE_TESTCTRL_PRNG_SEED = 28;
+
+const int SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS = 29;
+
+const int SQLITE_TESTCTRL_LAST = 29;
+
+const int SQLITE_STATUS_MEMORY_USED = 0;
+
+const int SQLITE_STATUS_PAGECACHE_USED = 1;
+
+const int SQLITE_STATUS_PAGECACHE_OVERFLOW = 2;
+
+const int SQLITE_STATUS_SCRATCH_USED = 3;
+
+const int SQLITE_STATUS_SCRATCH_OVERFLOW = 4;
+
+const int SQLITE_STATUS_MALLOC_SIZE = 5;
+
+const int SQLITE_STATUS_PARSER_STACK = 6;
+
+const int SQLITE_STATUS_PAGECACHE_SIZE = 7;
+
+const int SQLITE_STATUS_SCRATCH_SIZE = 8;
+
+const int SQLITE_STATUS_MALLOC_COUNT = 9;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_USED = 0;
+
+const int SQLITE_DBSTATUS_CACHE_USED = 1;
+
+const int SQLITE_DBSTATUS_SCHEMA_USED = 2;
+
+const int SQLITE_DBSTATUS_STMT_USED = 3;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_HIT = 4;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE = 5;
+
+const int SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL = 6;
+
+const int SQLITE_DBSTATUS_CACHE_HIT = 7;
+
+const int SQLITE_DBSTATUS_CACHE_MISS = 8;
+
+const int SQLITE_DBSTATUS_CACHE_WRITE = 9;
+
+const int SQLITE_DBSTATUS_DEFERRED_FKS = 10;
+
+const int SQLITE_DBSTATUS_CACHE_USED_SHARED = 11;
+
+const int SQLITE_DBSTATUS_CACHE_SPILL = 12;
+
+const int SQLITE_DBSTATUS_MAX = 12;
+
+const int SQLITE_STMTSTATUS_FULLSCAN_STEP = 1;
+
+const int SQLITE_STMTSTATUS_SORT = 2;
+
+const int SQLITE_STMTSTATUS_AUTOINDEX = 3;
+
+const int SQLITE_STMTSTATUS_VM_STEP = 4;
+
+const int SQLITE_STMTSTATUS_REPREPARE = 5;
+
+const int SQLITE_STMTSTATUS_RUN = 6;
+
+const int SQLITE_STMTSTATUS_MEMUSED = 99;
+
+const int SQLITE_CHECKPOINT_PASSIVE = 0;
+
+const int SQLITE_CHECKPOINT_FULL = 1;
+
+const int SQLITE_CHECKPOINT_RESTART = 2;
+
+const int SQLITE_CHECKPOINT_TRUNCATE = 3;
+
+const int SQLITE_VTAB_CONSTRAINT_SUPPORT = 1;
+
+const int SQLITE_VTAB_INNOCUOUS = 2;
+
+const int SQLITE_VTAB_DIRECTONLY = 3;
+
+const int SQLITE_ROLLBACK = 1;
+
+const int SQLITE_FAIL = 3;
+
+const int SQLITE_REPLACE = 5;
+
+const int SQLITE_SCANSTAT_NLOOP = 0;
+
+const int SQLITE_SCANSTAT_NVISIT = 1;
+
+const int SQLITE_SCANSTAT_EST = 2;
+
+const int SQLITE_SCANSTAT_NAME = 3;
+
+const int SQLITE_SCANSTAT_EXPLAIN = 4;
+
+const int SQLITE_SCANSTAT_SELECTID = 5;
+
+const int SQLITE_SERIALIZE_NOCOPY = 1;
+
+const int SQLITE_DESERIALIZE_FREEONCLOSE = 1;
+
+const int SQLITE_DESERIALIZE_RESIZEABLE = 2;
+
+const int SQLITE_DESERIALIZE_READONLY = 4;
+
+const int NOT_WITHIN = 0;
+
+const int PARTLY_WITHIN = 1;
+
+const int FULLY_WITHIN = 2;
+
+const int FTS5_TOKENIZE_QUERY = 1;
+
+const int FTS5_TOKENIZE_PREFIX = 2;
+
+const int FTS5_TOKENIZE_DOCUMENT = 4;
+
+const int FTS5_TOKENIZE_AUX = 8;
+
+const int FTS5_TOKEN_COLOCATED = 1;
diff --git a/pkgs/ffigen/test/large_integration_tests/large_test.dart b/pkgs/ffigen/test/large_integration_tests/large_test.dart
new file mode 100644
index 0000000..257ff26
--- /dev/null
+++ b/pkgs/ffigen/test/large_integration_tests/large_test.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/header_parser.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void main() {
+  group('large_test', () {
+    setUpAll(() {
+      logWarnings(Level.SEVERE);
+    });
+    test('Libclang test', () {
+      final config = testConfig('''
+${strings.name}: LibClang
+${strings.description}: Bindings to LibClang.
+${strings.output}: unused
+${strings.compilerOpts}: -I${path.join('third_party', 'libclang', 'include')}
+${strings.comments}:
+  ${strings.style}: ${strings.doxygen}
+  ${strings.length}: ${strings.brief}
+${strings.headers}:
+  ${strings.entryPoints}:
+    - third_party/libclang/include/clang-c/Index.h
+  ${strings.includeDirectives}:
+    - '**BuildSystem.h'
+    - '**CXCompilationDatabase.h'
+    - '**CXErrorCode.h'
+    - '**CXString.h'
+    - '**Documentation.h'
+    - '**FataErrorHandler.h'
+    - '**Index.h'
+${strings.typeMap}:
+  ${strings.typeMapTypedefs}:
+    'time_t':
+      lib: 'ffi'
+      c-type: 'Int64'
+      dart-type: 'int'
+${strings.preamble}: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names
+      ''');
+      final library = parse(config);
+
+      matchLibraryWithExpected(
+        library,
+        'large_test_libclang.dart',
+        ['test', 'large_integration_tests', '_expected_libclang_bindings.dart'],
+        // Remove comments containing @ to hack around a mismatch in the
+        // documentation generated by different clang versions.
+        codeNormalizer: (code) =>
+            code.replaceAll(RegExp('[^\n]*///[^\n]*@[^\n]*\n'), ''),
+      );
+    });
+
+    test('CJSON test', () {
+      final config = testConfig('''
+${strings.name}: CJson
+${strings.description}: Bindings to Cjson.
+${strings.output}: unused
+${strings.comments}:
+  ${strings.length}: ${strings.full}
+${strings.headers}:
+  ${strings.entryPoints}:
+    - third_party/cjson_library/cJSON.h
+  ${strings.includeDirectives}:
+    - '**cJSON.h'
+${strings.preamble}: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names
+      ''');
+      final library = parse(config);
+
+      matchLibraryWithExpected(
+        library,
+        'large_test_cjson.dart',
+        ['test', 'large_integration_tests', '_expected_cjson_bindings.dart'],
+      );
+    });
+
+    test('SQLite test', () {
+      // Excluding functions that use 'va_list' because it can either be a
+      // Pointer<__va_list_tag> or int depending on the OS.
+      final config = testConfig('''
+${strings.name}: SQLite
+${strings.description}: Bindings to SQLite.
+${strings.output}: unused
+${strings.comments}:
+  ${strings.style}: ${strings.any}
+  ${strings.length}: ${strings.full}
+${strings.headers}:
+  ${strings.entryPoints}:
+    - third_party/sqlite/sqlite3.h
+  ${strings.includeDirectives}:
+    - '**sqlite3.h'
+${strings.functions}:
+  ${strings.exclude}:
+    - sqlite3_vmprintf
+    - sqlite3_vsnprintf
+    - sqlite3_str_vappendf
+${strings.preamble}: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names
+      ''');
+      final library = parse(config);
+
+      matchLibraryWithExpected(
+        library,
+        'large_test_sqlite.dart',
+        ['test', 'large_integration_tests', '_expected_sqlite_bindings.dart'],
+      );
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/.gitignore b/pkgs/ffigen/test/native_objc_test/.gitignore
new file mode 100644
index 0000000..ad4daf6
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/.gitignore
@@ -0,0 +1,2 @@
+*_bindings.dart
+*-Swift.h
diff --git a/pkgs/ffigen/test/native_objc_test/automated_ref_count_config.yaml b/pkgs/ffigen/test/native_objc_test/automated_ref_count_config.yaml
new file mode 100644
index 0000000..600d33d
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/automated_ref_count_config.yaml
@@ -0,0 +1,18 @@
+name: AutomatedRefCountTestObjCLibrary
+description: 'Tests automatic reference counting of Objective-C objects'
+language: objc
+output: 'automated_ref_count_bindings.dart'
+exclude-all-by-default: true
+functions:
+  include:
+    - createAutoreleasePool
+    - destroyAutoreleasePool
+objc-interfaces:
+  include:
+    - ArcTestObject
+    - RefCounted
+headers:
+  entry-points:
+    - 'automated_ref_count_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.dart b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.dart
new file mode 100644
index 0000000..63ed706
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.dart
@@ -0,0 +1,317 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import 'package:ffi/ffi.dart';
+import '../test_utils.dart';
+import 'automated_ref_count_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late AutomatedRefCountTestObjCLibrary lib;
+  late void Function(Pointer<Char>, Pointer<Void>) executeInternalCommand;
+
+  group('Automatic reference counting', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib =
+          File('test/native_objc_test/automated_ref_count_test.dylib');
+      verifySetupFile(dylib);
+      lib = AutomatedRefCountTestObjCLibrary(
+          DynamicLibrary.open(dylib.absolute.path));
+
+      executeInternalCommand = DynamicLibrary.process().lookupFunction<
+          Void Function(Pointer<Char>, Pointer<Void>),
+          void Function(
+              Pointer<Char>, Pointer<Void>)>('Dart_ExecuteInternalCommand');
+
+      generateBindingsForCoverage('automated_ref_count');
+    });
+
+    doGC() {
+      final gcNow = "gc-now".toNativeUtf8();
+      executeInternalCommand(gcNow.cast(), nullptr);
+      calloc.free(gcNow);
+    }
+
+    newMethodsInner(Pointer<Int32> counter) {
+      final obj1 = ArcTestObject.new1(lib);
+      obj1.setCounter_(counter);
+      expect(counter.value, 1);
+      final obj2 = ArcTestObject.newWithCounter_(lib, counter);
+      expect(counter.value, 2);
+    }
+
+    test('new methods ref count correctly', () {
+      // To get the GC to work correctly, the references to the objects all have
+      // to be in a separate function.
+      final counter = calloc<Int32>();
+      counter.value = 0;
+      newMethodsInner(counter);
+      doGC();
+      expect(counter.value, 0);
+      calloc.free(counter);
+    });
+
+    allocMethodsInner(Pointer<Int32> counter) {
+      final obj1 = ArcTestObject.alloc(lib).initWithCounter_(counter);
+      expect(counter.value, 1);
+      final obj2 = ArcTestObject.castFrom(ArcTestObject.alloc(lib).init());
+      obj2.setCounter_(counter);
+      expect(counter.value, 2);
+      final obj3 = ArcTestObject.allocTheThing(lib).initWithCounter_(counter);
+      expect(counter.value, 3);
+    }
+
+    test('alloc and init methods ref count correctly', () {
+      final counter = calloc<Int32>();
+      counter.value = 0;
+      allocMethodsInner(counter);
+      doGC();
+      expect(counter.value, 0);
+      calloc.free(counter);
+    });
+
+    copyMethodsInner(Pointer<Int32> counter) {
+      final obj1 = ArcTestObject.newWithCounter_(lib, counter);
+      expect(counter.value, 1);
+      final obj2 = obj1.copyMe();
+      expect(counter.value, 2);
+      final obj3 = obj1.makeACopy();
+      expect(counter.value, 3);
+      final obj4 = obj1.copyWithZone_(nullptr);
+      expect(counter.value, 4);
+      final obj5 = obj1.copy();
+      expect(counter.value, 5);
+    }
+
+    test('copy methods ref count correctly', () {
+      final counter = calloc<Int32>();
+      counter.value = 0;
+      copyMethodsInner(counter);
+      doGC();
+      expect(counter.value, 0);
+      calloc.free(counter);
+    });
+
+    autoreleaseMethodsInner(Pointer<Int32> counter) {
+      final obj = ArcTestObject.makeAndAutorelease_(lib, counter);
+      expect(counter.value, 1);
+    }
+
+    test('autorelease methods ref count correctly', () {
+      final counter = calloc<Int32>();
+      counter.value = 0;
+
+      final pool1 = lib.createAutoreleasePool();
+      autoreleaseMethodsInner(counter);
+      doGC();
+      // The autorelease pool is still holding a reference to the object.
+      expect(counter.value, 1);
+      lib.destroyAutoreleasePool(pool1);
+      expect(counter.value, 0);
+
+      final pool2 = lib.createAutoreleasePool();
+      final obj = ArcTestObject.makeAndAutorelease_(lib, counter);
+      expect(counter.value, 1);
+      doGC();
+      expect(counter.value, 1);
+      lib.destroyAutoreleasePool(pool2);
+      // The obj variable still holds a reference to the object.
+      expect(counter.value, 1);
+      obj.release();
+      expect(counter.value, 0);
+
+      calloc.free(counter);
+    });
+
+    assignPropertiesInnerInner(Pointer<Int32> counter, ArcTestObject outerObj) {
+      final assignObj = ArcTestObject.newWithCounter_(lib, counter);
+      expect(counter.value, 2);
+      outerObj.assignedProperty = assignObj;
+      expect(counter.value, 2);
+      expect(assignObj, outerObj.assignedProperty);
+      // To test that outerObj isn't holding a reference to assignObj, we let
+      // assignObj go out of scope, but keep outerObj in scope. This is
+      // dangerous because outerObj now has a dangling reference, so don't
+      // access that reference.
+    }
+
+    assignPropertiesInner(Pointer<Int32> counter) {
+      final outerObj = ArcTestObject.newWithCounter_(lib, counter);
+      expect(counter.value, 1);
+      assignPropertiesInnerInner(counter, outerObj);
+      doGC();
+      // assignObj has been cleaned up.
+      expect(counter.value, 1);
+    }
+
+    test('assign properties ref count correctly', () {
+      final counter = calloc<Int32>();
+      counter.value = 0;
+      assignPropertiesInner(counter);
+      doGC();
+      expect(counter.value, 0);
+      calloc.free(counter);
+    });
+
+    retainPropertiesInnerInner(Pointer<Int32> counter, ArcTestObject outerObj) {
+      final retainObj = ArcTestObject.newWithCounter_(lib, counter);
+      expect(counter.value, 2);
+      outerObj.retainedProperty = retainObj;
+      expect(counter.value, 2);
+      expect(retainObj, outerObj.retainedProperty);
+    }
+
+    retainPropertiesInner(Pointer<Int32> counter) {
+      final outerObj = ArcTestObject.newWithCounter_(lib, counter);
+      expect(counter.value, 1);
+      retainPropertiesInnerInner(counter, outerObj);
+      doGC();
+      // retainObj is still around, because outerObj retains a reference to it.
+      expect(counter.value, 2);
+    }
+
+    test('retain properties ref count correctly', () {
+      final counter = calloc<Int32>();
+      counter.value = 0;
+      // The getters of retain properties retain+autorelease the value. So we
+      // need an autorelease pool.
+      final pool = lib.createAutoreleasePool();
+      retainPropertiesInner(counter);
+      doGC();
+      expect(counter.value, 1);
+      lib.destroyAutoreleasePool(pool);
+      expect(counter.value, 0);
+      calloc.free(counter);
+    });
+
+    copyPropertiesInner(Pointer<Int32> counter) {
+      final outerObj = ArcTestObject.newWithCounter_(lib, counter);
+      expect(counter.value, 1);
+
+      final copyObj = ArcTestObject.newWithCounter_(lib, counter);
+      expect(counter.value, 2);
+      outerObj.copiedProperty = copyObj;
+      // Copy properties make a copy of the object, so now we have 3 objects.
+      expect(counter.value, 3);
+      expect(copyObj, isNot(outerObj.copiedProperty));
+
+      final anotherCopy = outerObj.copiedProperty;
+      // The getter doesn't copy the object.
+      expect(counter.value, 3);
+      expect(anotherCopy, outerObj.copiedProperty);
+    }
+
+    test('copy properties ref count correctly', () {
+      final counter = calloc<Int32>();
+      counter.value = 0;
+      // The getters of copy properties retain+autorelease the value. So we need
+      // an autorelease pool.
+      final pool = lib.createAutoreleasePool();
+      copyPropertiesInner(counter);
+      doGC();
+      expect(counter.value, 1);
+      lib.destroyAutoreleasePool(pool);
+      expect(counter.value, 0);
+      calloc.free(counter);
+    });
+
+    castFromPointerInnerReleaseAndRetain(int address) {
+      final fromCast = RefCounted.castFromPointer(
+          lib, Pointer<ObjCObject>.fromAddress(address),
+          release: true, retain: true);
+      expect(fromCast.refCount, 2);
+    }
+
+    test('castFromPointer - release and retain', () {
+      final obj1 = RefCounted.new1(lib);
+      expect(obj1.refCount, 1);
+
+      castFromPointerInnerReleaseAndRetain(obj1.meAsInt());
+      doGC();
+      expect(obj1.refCount, 1);
+    });
+
+    castFromPointerInnerNoReleaseAndRetain(int address) {
+      final fromCast = RefCounted.castFromPointer(
+          lib, Pointer<ObjCObject>.fromAddress(address),
+          release: false, retain: false);
+      expect(fromCast.refCount, 1);
+    }
+
+    test('castFromPointer - no release and retain', () {
+      final obj1 = RefCounted.new1(lib);
+      expect(obj1.refCount, 1);
+
+      castFromPointerInnerNoReleaseAndRetain(obj1.meAsInt());
+      doGC();
+      expect(obj1.refCount, 1);
+    });
+
+    test('Manual release', () {
+      final counter = calloc<Int32>();
+      final obj1 = ArcTestObject.newWithCounter_(lib, counter);
+      expect(counter.value, 1);
+      final obj2 = ArcTestObject.newWithCounter_(lib, counter);
+      expect(counter.value, 2);
+      final obj3 = ArcTestObject.newWithCounter_(lib, counter);
+      expect(counter.value, 3);
+
+      obj1.release();
+      expect(counter.value, 2);
+      obj2.release();
+      expect(counter.value, 1);
+      obj3.release();
+      expect(counter.value, 0);
+
+      expect(() => obj1.release(), throwsStateError);
+      calloc.free(counter);
+    });
+
+    ArcTestObject unownedReferenceInner2(Pointer<Int32> counter) {
+      final obj1 = ArcTestObject.new1(lib);
+      obj1.setCounter_(counter);
+      expect(counter.value, 1);
+      final obj1b = obj1.unownedReference();
+      expect(counter.value, 1);
+
+      // Make a second object so that the counter check in unownedReferenceInner
+      // sees some sort of change. Otherwise this test could pass just by the GC
+      // not working correctly.
+      final obj2 = ArcTestObject.new1(lib);
+      obj2.setCounter_(counter);
+      expect(counter.value, 2);
+
+      return obj1b;
+    }
+
+    unownedReferenceInner(Pointer<Int32> counter) {
+      final obj1b = unownedReferenceInner2(counter);
+      doGC(); // Collect obj1 and obj2.
+      // The underlying object obj1 and obj1b points to still exists, because
+      // obj1b took a reference to it. So we still have 1 object.
+      expect(counter.value, 1);
+    }
+
+    test("Method that returns a reference we don't own", () {
+      // Most ObjC API methods return us a reference without incrementing the
+      // ref count (ie, returns us a reference we don't own). So the wrapper
+      // object has to take ownership by calling retain. This test verifies that
+      // is working correctly by holding a reference to an object returned by a
+      // method, after the original wrapper object is gone.
+      final counter = calloc<Int32>();
+      unownedReferenceInner(counter);
+      doGC();
+      expect(counter.value, 0);
+      calloc.free(counter);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.m b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.m
new file mode 100644
index 0000000..cf8ab3a
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.m
@@ -0,0 +1,127 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+#import <Foundation/NSAutoreleasePool.h>
+
+@interface ArcTestObject : NSObject {
+  int32_t* counter;
+}
+
++ (instancetype)allocTheThing;
++ (instancetype)newWithCounter:(int32_t*) _counter;
+- (instancetype)initWithCounter:(int32_t*) _counter;
++ (ArcTestObject*)makeAndAutorelease:(int32_t*) _counter;
+- (void)setCounter:(int32_t*) _counter;
+- (void)dealloc;
+- (ArcTestObject*)unownedReference;
+- (ArcTestObject*)copyMe;
+- (ArcTestObject*)makeACopy;
+- (id)copyWithZone:(NSZone*) zone;
+- (ArcTestObject*)returnsRetained NS_RETURNS_RETAINED;
+
+@property (assign) ArcTestObject* assignedProperty;
+@property (retain) ArcTestObject* retainedProperty;
+@property (copy) ArcTestObject* copiedProperty;
+
+@end
+
+@interface RefCounted : NSObject
+
+@property(readonly) uint64_t refCount;
+
+- (int64_t) meAsInt;
+
+@end
+
+@implementation ArcTestObject
+
++ (instancetype)allocTheThing {
+  return [ArcTestObject alloc];
+}
+
++ (instancetype)newWithCounter:(int32_t*) _counter {
+  return [[ArcTestObject alloc] initWithCounter: _counter];
+}
+
+- (instancetype)initWithCounter:(int32_t*) _counter {
+  counter = _counter;
+  ++*counter;
+  return [super init];
+}
+
++ (instancetype)makeAndAutorelease:(int32_t*) _counter {
+  return [[[ArcTestObject alloc] initWithCounter: _counter] autorelease];
+}
+
+- (void)setCounter:(int32_t*) _counter {
+  counter = _counter;
+  ++*counter;
+}
+
+- (void)dealloc {
+  --*counter;
+  [_retainedProperty release];
+  [_copiedProperty release];
+  [super dealloc];
+}
+
+- (ArcTestObject*)unownedReference {
+  return self;
+}
+
+- (ArcTestObject*)copyMe {
+  return [[ArcTestObject alloc] initWithCounter: counter];
+}
+
+- (ArcTestObject*)makeACopy {
+  return [[ArcTestObject alloc] initWithCounter: counter];
+}
+
+- (id)copyWithZone:(NSZone*) zone {
+  return [[ArcTestObject alloc] initWithCounter: counter];
+}
+
+- (ArcTestObject*)returnsRetained NS_RETURNS_RETAINED {
+  return [self retain];
+}
+
+@end
+
+// Pass around the NSAutoreleasePool as a void* to bypass the Dart wrappers so
+// that we can precisely control the life cycle.
+void* createAutoreleasePool() {
+  return (void*)[NSAutoreleasePool new];
+}
+
+void destroyAutoreleasePool(void* pool) {
+  [((NSAutoreleasePool*)pool) release];
+}
+
+@implementation RefCounted
+
+- (instancetype)init {
+    if (self = [super init]) {
+      self->_refCount = 1;
+    }
+    return self;
+}
+
+- (instancetype)retain {
+  ++self->_refCount;
+  return self;
+}
+
+- (oneway void)release {
+  --self->_refCount;
+  if (self->_refCount == 0) {
+    [self dealloc];
+  }
+}
+
+- (int64_t) meAsInt {
+  return (int64_t) self;
+}
+
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/bad_method_config.yaml b/pkgs/ffigen/test/native_objc_test/bad_method_config.yaml
new file mode 100644
index 0000000..5ad9c1b
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/bad_method_config.yaml
@@ -0,0 +1,21 @@
+# Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# =================== GENERATING TEST BINDINGS ==================
+#    dart run ffigen --config test/bad_method_test/config.yaml
+# ===============================================================
+
+name: NativeObjCLibrary
+description: 'Native Objective C test'
+language: objc
+output: 'bad_method_test_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - 'BadMethodTestObject'
+headers:
+  entry-points:
+    - 'bad_method_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/bad_method_test.dart b/pkgs/ffigen/test/native_objc_test/bad_method_test.dart
new file mode 100644
index 0000000..3b87c5b
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/bad_method_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'bad_method_test_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late NativeObjCLibrary lib;
+  group('bad_method_test', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/bad_method_test.dylib');
+      verifySetupFile(dylib);
+      lib = NativeObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('bad_method');
+    });
+
+    test("Test incomplete struct methods that weren't skipped", () {
+      final obj = BadMethodTestObject.new1(lib);
+      final structPtr = obj.incompletePointerReturn();
+      expect(structPtr.address, 1234);
+      expect(obj.incompletePointerParam_(structPtr), 1234);
+    });
+
+    test("Test bit field methods that weren't skipped", () {
+      final obj = BadMethodTestObject.new1(lib);
+      final bitFieldPtr = obj.bitFieldPointerReturn();
+      expect(bitFieldPtr.address, 5678);
+      expect(obj.bitFieldPointerParam_(bitFieldPtr), 5678);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/bad_method_test.m b/pkgs/ffigen/test/native_objc_test/bad_method_test.m
new file mode 100644
index 0000000..bef4ede
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/bad_method_test.m
@@ -0,0 +1,49 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+
+struct IncompleteStruct;
+
+struct BitField {
+  int x:3;
+  int y:12;
+};
+
+@interface BadMethodTestObject : NSObject {
+}
+
+- (struct IncompleteStruct)incompleteReturn;  // Skipped.
+- (struct IncompleteStruct*)incompletePointerReturn;  // Not skipped.
+- (int64_t)incompleteParam:(struct IncompleteStruct)x;  // Skipped.
+- (int64_t)incompletePointerParam:(struct IncompleteStruct*)x;  // Not skipped.
+
+- (struct BitField)bitFieldReturn;  // Skipped.
+- (struct BitField*)bitFieldPointerReturn;  // Not skipped.
+- (int64_t)bitFieldParam:(struct BitField)x;  // Skipped.
+- (int64_t)bitFieldPointerParam:(struct BitField*)x;  // Not skipped.
+
+@property struct BitField bitFieldProperty;  // Skipped.
+
+@end
+
+@implementation BadMethodTestObject
+
+- (struct IncompleteStruct*)incompletePointerReturn {
+  return (struct IncompleteStruct*)1234;
+}
+
+- (int64_t)incompletePointerParam:(struct IncompleteStruct*)x {
+  return (int64_t)x;
+}
+
+- (struct BitField*)bitFieldPointerReturn {
+  return (struct BitField*)5678;
+}
+
+- (int64_t)bitFieldPointerParam:(struct BitField*)x {
+  return (int64_t)x;
+}
+
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/block_config.yaml b/pkgs/ffigen/test/native_objc_test/block_config.yaml
new file mode 100644
index 0000000..9f12686
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/block_config.yaml
@@ -0,0 +1,16 @@
+name: BlockTestObjCLibrary
+description: 'Tests calling Objective-C blocks.'
+language: objc
+output: 'block_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - BlockTester
+functions:
+  include:
+    - getBlockRetainCount
+headers:
+  entry-points:
+    - 'block_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.dart b/pkgs/ffigen/test/native_objc_test/block_test.dart
new file mode 100644
index 0000000..d2068ce
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/block_test.dart
@@ -0,0 +1,471 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:async';
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import 'package:ffi/ffi.dart';
+import '../test_utils.dart';
+import 'block_bindings.dart';
+import 'util.dart';
+
+// The generated block names are stable but verbose, so typedef them.
+typedef IntBlock = ObjCBlock_Int32_Int32;
+typedef FloatBlock = ObjCBlock_ffiFloat_ffiFloat;
+typedef DoubleBlock = ObjCBlock_ffiDouble_ffiDouble;
+typedef Vec4Block = ObjCBlock_Vec4_Vec4;
+typedef VoidBlock = ObjCBlock_ffiVoid;
+typedef ObjectBlock = ObjCBlock_DummyObject_DummyObject;
+typedef NullableObjectBlock = ObjCBlock_DummyObject_DummyObject1;
+typedef BlockBlock = ObjCBlock_Int32Int32_Int32Int32;
+
+void main() {
+  late BlockTestObjCLibrary lib;
+  late void Function(Pointer<Char>, Pointer<Void>) executeInternalCommand;
+
+  group('Blocks', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/block_test.dylib');
+      verifySetupFile(dylib);
+      lib = BlockTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+
+      executeInternalCommand = DynamicLibrary.process().lookupFunction<
+          Void Function(Pointer<Char>, Pointer<Void>),
+          void Function(
+              Pointer<Char>, Pointer<Void>)>('Dart_ExecuteInternalCommand');
+
+      generateBindingsForCoverage('block');
+    });
+
+    doGC() {
+      final gcNow = "gc-now".toNativeUtf8();
+      executeInternalCommand(gcNow.cast(), nullptr);
+      calloc.free(gcNow);
+    }
+
+    test('BlockTester is working', () {
+      // This doesn't test any Block functionality, just that the BlockTester
+      // itself is working correctly.
+      final blockTester = BlockTester.makeFromMultiplier_(lib, 10);
+      expect(blockTester.call_(123), 1230);
+      final intBlock = blockTester.getBlock();
+      final blockTester2 = BlockTester.makeFromBlock_(lib, intBlock);
+      blockTester2.pokeBlock();
+      expect(blockTester2.call_(456), 4560);
+    });
+
+    test('Block from function pointer', () {
+      final block =
+          IntBlock.fromFunctionPointer(lib, Pointer.fromFunction(_add100, 999));
+      final blockTester = BlockTester.makeFromBlock_(lib, block);
+      blockTester.pokeBlock();
+      expect(blockTester.call_(123), 223);
+      expect(block(123), 223);
+    });
+
+    int Function(int) makeAdder(int addTo) {
+      return (int x) => addTo + x;
+    }
+
+    test('Block from function', () {
+      final block = IntBlock.fromFunction(lib, makeAdder(4000));
+      final blockTester = BlockTester.makeFromBlock_(lib, block);
+      blockTester.pokeBlock();
+      expect(blockTester.call_(123), 4123);
+      expect(block(123), 4123);
+    });
+
+    test('Listener block same thread', () async {
+      final hasRun = Completer();
+      int value = 0;
+      final block = VoidBlock.listener(lib, () {
+        value = 123;
+        hasRun.complete();
+      });
+
+      BlockTester.callOnSameThread_(lib, block);
+
+      await hasRun.future;
+      expect(value, 123);
+    });
+
+    test('Listener block new thread', () async {
+      final hasRun = Completer();
+      int value = 0;
+      final block = VoidBlock.listener(lib, () {
+        value = 123;
+        hasRun.complete();
+      });
+
+      final thread = BlockTester.callOnNewThread_(lib, block);
+      thread.start();
+
+      await hasRun.future;
+      expect(value, 123);
+    });
+
+    test('Float block', () {
+      final block = FloatBlock.fromFunction(lib, (double x) {
+        return x + 4.56;
+      });
+      expect(block(1.23), closeTo(5.79, 1e-6));
+      expect(BlockTester.callFloatBlock_(lib, block), closeTo(5.79, 1e-6));
+    });
+
+    test('Double block', () {
+      final block = DoubleBlock.fromFunction(lib, (double x) {
+        return x + 4.56;
+      });
+      expect(block(1.23), closeTo(5.79, 1e-6));
+      expect(BlockTester.callDoubleBlock_(lib, block), closeTo(5.79, 1e-6));
+    });
+
+    test('Struct block', () {
+      using((Arena arena) {
+        final inputPtr = arena<Vec4>();
+        final input = inputPtr.ref;
+        input.x = 1.2;
+        input.y = 3.4;
+        input.z = 5.6;
+        input.w = 7.8;
+
+        final tempPtr = arena<Vec4>();
+        final temp = tempPtr.ref;
+        final block = Vec4Block.fromFunction(lib, (Vec4 v) {
+          // Twiddle the Vec4 components.
+          temp.x = v.y;
+          temp.y = v.z;
+          temp.z = v.w;
+          temp.w = v.x;
+          return temp;
+        });
+
+        final result1 = block(input);
+        expect(result1.x, 3.4);
+        expect(result1.y, 5.6);
+        expect(result1.z, 7.8);
+        expect(result1.w, 1.2);
+
+        final result2Ptr = arena<Vec4>();
+        final result2 = result2Ptr.ref;
+        BlockTester.callVec4Block_(lib, result2Ptr, block);
+        expect(result2.x, 3.4);
+        expect(result2.y, 5.6);
+        expect(result2.z, 7.8);
+        expect(result2.w, 1.2);
+      });
+    });
+
+    test('Object block', () {
+      bool isCalled = false;
+      final block = ObjectBlock.fromFunction(lib, (DummyObject x) {
+        isCalled = true;
+        return x;
+      });
+
+      final obj = DummyObject.new1(lib);
+      final result1 = block(obj);
+      expect(result1, obj);
+      expect(isCalled, isTrue);
+
+      isCalled = false;
+      final result2 = BlockTester.callObjectBlock_(lib, block);
+      expect(result2, isNot(obj));
+      expect(result2.pointer, isNot(nullptr));
+      expect(isCalled, isTrue);
+    });
+
+    test('Nullable object block', () {
+      bool isCalled = false;
+      final block = NullableObjectBlock.fromFunction(lib, (DummyObject? x) {
+        isCalled = true;
+        return x;
+      });
+
+      final obj = DummyObject.new1(lib);
+      final result1 = block(obj);
+      expect(result1, obj);
+      expect(isCalled, isTrue);
+
+      isCalled = false;
+      final result2 = block(null);
+      expect(result2, isNull);
+      expect(isCalled, isTrue);
+
+      isCalled = false;
+      final result3 = BlockTester.callNullableObjectBlock_(lib, block);
+      expect(result3, isNull);
+      expect(isCalled, isTrue);
+    });
+
+    test('Block block', () {
+      final blockBlock = BlockBlock.fromFunction(lib, (IntBlock intBlock) {
+        return IntBlock.fromFunction(lib, (int x) {
+          return 3 * intBlock(x);
+        });
+      });
+
+      final intBlock = IntBlock.fromFunction(lib, (int x) {
+        return 5 * x;
+      });
+      final result1 = blockBlock(intBlock);
+      expect(result1(1), 15);
+
+      final result2 = BlockTester.newBlock_withMult_(lib, blockBlock, 2);
+      expect(result2(1), 6);
+    });
+
+    test('Native block block', () {
+      final blockBlock = BlockTester.newBlockBlock_(lib, 7);
+
+      final intBlock = IntBlock.fromFunction(lib, (int x) {
+        return 5 * x;
+      });
+      final result1 = blockBlock(intBlock);
+      expect(result1(1), 35);
+
+      final result2 = BlockTester.newBlock_withMult_(lib, blockBlock, 2);
+      expect(result2(1), 14);
+    });
+
+    Pointer<Void> funcPointerBlockRefCountTest() {
+      final block =
+          IntBlock.fromFunctionPointer(lib, Pointer.fromFunction(_add100, 999));
+      expect(lib.getBlockRetainCount(block.pointer.cast()), 1);
+      return block.pointer.cast();
+    }
+
+    test('Function pointer block ref counting', () {
+      final rawBlock = funcPointerBlockRefCountTest();
+      doGC();
+      expect(lib.getBlockRetainCount(rawBlock), 0);
+    });
+
+    Pointer<Void> funcBlockRefCountTest() {
+      final block = IntBlock.fromFunction(lib, makeAdder(4000));
+      expect(lib.getBlockRetainCount(block.pointer.cast()), 1);
+      return block.pointer.cast();
+    }
+
+    test('Function block ref counting', () {
+      final rawBlock = funcBlockRefCountTest();
+      doGC();
+      expect(lib.getBlockRetainCount(rawBlock), 0);
+    });
+
+    (Pointer<Void>, Pointer<Void>, Pointer<Void>)
+        blockBlockDartCallRefCountTest() {
+      final inputBlock = IntBlock.fromFunction(lib, (int x) {
+        return 5 * x;
+      });
+      final blockBlock = BlockBlock.fromFunction(lib, (IntBlock intBlock) {
+        return IntBlock.fromFunction(lib, (int x) {
+          return 3 * intBlock(x);
+        });
+      });
+      final outputBlock = blockBlock(inputBlock);
+      expect(outputBlock(1), 15);
+      doGC();
+
+      // One reference held by inputBlock object, another bound to the
+      // outputBlock lambda.
+      expect(lib.getBlockRetainCount(inputBlock.pointer.cast()), 2);
+
+      expect(lib.getBlockRetainCount(blockBlock.pointer.cast()), 1);
+      expect(lib.getBlockRetainCount(outputBlock.pointer.cast()), 1);
+      return (
+        inputBlock.pointer.cast(),
+        blockBlock.pointer.cast(),
+        outputBlock.pointer.cast()
+      );
+    }
+
+    test('Calling a block block from Dart has correct ref counting', () {
+      final (inputBlock, blockBlock, outputBlock) =
+          blockBlockDartCallRefCountTest();
+      doGC();
+
+      // This leaks because block functions aren't cleaned up at the moment.
+      // TODO(https://github.com/dart-lang/ffigen/issues/428): Fix this leak.
+      expect(lib.getBlockRetainCount(inputBlock), 1);
+
+      expect(lib.getBlockRetainCount(blockBlock), 0);
+      expect(lib.getBlockRetainCount(outputBlock), 0);
+    });
+
+    (Pointer<Void>, Pointer<Void>, Pointer<Void>)
+        blockBlockObjCCallRefCountTest() {
+      late Pointer<Void> inputBlock;
+      final blockBlock = BlockBlock.fromFunction(lib, (IntBlock intBlock) {
+        inputBlock = intBlock.pointer.cast();
+        return IntBlock.fromFunction(lib, (int x) {
+          return 3 * intBlock(x);
+        });
+      });
+      final outputBlock = BlockTester.newBlock_withMult_(lib, blockBlock, 2);
+      expect(outputBlock(1), 6);
+      doGC();
+
+      expect(lib.getBlockRetainCount(inputBlock), 2);
+      expect(lib.getBlockRetainCount(blockBlock.pointer.cast()), 1);
+      expect(lib.getBlockRetainCount(outputBlock.pointer.cast()), 1);
+      return (
+        inputBlock,
+        blockBlock.pointer.cast(),
+        outputBlock.pointer.cast()
+      );
+    }
+
+    test('Calling a block block from ObjC has correct ref counting', () {
+      final (inputBlock, blockBlock, outputBlock) =
+          blockBlockObjCCallRefCountTest();
+      doGC();
+
+      // This leaks because block functions aren't cleaned up at the moment.
+      // TODO(https://github.com/dart-lang/ffigen/issues/428): Fix this leak.
+      expect(lib.getBlockRetainCount(inputBlock), 2);
+
+      expect(lib.getBlockRetainCount(blockBlock), 0);
+      expect(lib.getBlockRetainCount(outputBlock), 0);
+    });
+
+    (Pointer<Void>, Pointer<Void>, Pointer<Void>)
+        nativeBlockBlockDartCallRefCountTest() {
+      final inputBlock = IntBlock.fromFunction(lib, (int x) {
+        return 5 * x;
+      });
+      final blockBlock = BlockTester.newBlockBlock_(lib, 7);
+      final outputBlock = blockBlock(inputBlock);
+      expect(outputBlock(1), 35);
+      doGC();
+
+      // One reference held by inputBlock object, another held internally by the
+      // ObjC implementation of the blockBlock.
+      expect(lib.getBlockRetainCount(inputBlock.pointer.cast()), 2);
+
+      expect(lib.getBlockRetainCount(blockBlock.pointer.cast()), 1);
+      expect(lib.getBlockRetainCount(outputBlock.pointer.cast()), 1);
+      return (
+        inputBlock.pointer.cast(),
+        blockBlock.pointer.cast(),
+        outputBlock.pointer.cast()
+      );
+    }
+
+    test('Calling a native block block from Dart has correct ref counting', () {
+      final (inputBlock, blockBlock, outputBlock) =
+          nativeBlockBlockDartCallRefCountTest();
+      doGC();
+      expect(lib.getBlockRetainCount(inputBlock), 0);
+      expect(lib.getBlockRetainCount(blockBlock), 0);
+      expect(lib.getBlockRetainCount(outputBlock), 0);
+    });
+
+    (Pointer<Void>, Pointer<Void>) nativeBlockBlockObjCCallRefCountTest() {
+      final blockBlock = BlockTester.newBlockBlock_(lib, 7);
+      final outputBlock = BlockTester.newBlock_withMult_(lib, blockBlock, 2);
+      expect(outputBlock(1), 14);
+      doGC();
+
+      expect(lib.getBlockRetainCount(blockBlock.pointer.cast()), 1);
+      expect(lib.getBlockRetainCount(outputBlock.pointer.cast()), 1);
+      return (blockBlock.pointer.cast(), outputBlock.pointer.cast());
+    }
+
+    test('Calling a native block block from ObjC has correct ref counting', () {
+      final (blockBlock, outputBlock) = nativeBlockBlockObjCCallRefCountTest();
+      doGC();
+      expect(lib.getBlockRetainCount(blockBlock), 0);
+      expect(lib.getBlockRetainCount(outputBlock), 0);
+    });
+
+    (Pointer<Int32>, Pointer<Int32>) objectBlockRefCountTest(Allocator alloc) {
+      final inputCounter = alloc<Int32>();
+      final outputCounter = alloc<Int32>();
+      inputCounter.value = 0;
+      outputCounter.value = 0;
+
+      final block = ObjectBlock.fromFunction(lib, (DummyObject x) {
+        return DummyObject.newWithCounter_(lib, outputCounter);
+      });
+
+      final inputObj = DummyObject.newWithCounter_(lib, inputCounter);
+      final outputObj = block(inputObj);
+      expect(inputCounter.value, 1);
+      expect(outputCounter.value, 1);
+
+      return (inputCounter, outputCounter);
+    }
+
+    test('Objects received and returned by blocks have correct ref counts', () {
+      using((Arena arena) {
+        final (inputCounter, outputCounter) = objectBlockRefCountTest(arena);
+        doGC();
+        expect(inputCounter.value, 0);
+        expect(outputCounter.value, 0);
+      });
+    });
+
+    (Pointer<Int32>, Pointer<Int32>) objectNativeBlockRefCountTest(
+        Allocator alloc) {
+      final inputCounter = alloc<Int32>();
+      final outputCounter = alloc<Int32>();
+      inputCounter.value = 0;
+      outputCounter.value = 0;
+
+      final block = ObjectBlock.fromFunction(lib, (DummyObject x) {
+        x.setCounter_(inputCounter);
+        return DummyObject.newWithCounter_(lib, outputCounter);
+      });
+
+      final outputObj = BlockTester.callObjectBlock_(lib, block);
+      expect(inputCounter.value, 1);
+      expect(outputCounter.value, 1);
+
+      return (inputCounter, outputCounter);
+    }
+
+    test(
+        'Objects received and returned by native blocks have correct ref counts',
+        () {
+      using((Arena arena) {
+        final (inputCounter, outputCounter) =
+            objectNativeBlockRefCountTest(arena);
+        doGC();
+
+        // This leaks because block functions aren't cleaned up at the moment.
+        // TODO(https://github.com/dart-lang/ffigen/issues/428): Fix this leak.
+        expect(inputCounter.value, 1);
+
+        expect(outputCounter.value, 0);
+      });
+    });
+
+    test('Block fields have sensible values', () {
+      final block = IntBlock.fromFunction(lib, makeAdder(4000));
+      final blockPtr = block.pointer;
+      expect(blockPtr.ref.isa, isNot(0));
+      expect(blockPtr.ref.flags, isNot(0)); // Set by Block_copy.
+      expect(blockPtr.ref.reserved, 0);
+      expect(blockPtr.ref.invoke, isNot(0));
+      expect(blockPtr.ref.target, isNot(0));
+      final descPtr = blockPtr.ref.descriptor;
+      expect(descPtr.ref.reserved, 0);
+      expect(descPtr.ref.size, isNot(0));
+      expect(descPtr.ref.copy_helper, nullptr);
+      expect(descPtr.ref.dispose_helper, nullptr);
+      expect(descPtr.ref.signature, nullptr);
+    });
+  });
+}
+
+int _add100(int x) {
+  return x + 100;
+}
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.m b/pkgs/ffigen/test/native_objc_test/block_test.m
new file mode 100644
index 0000000..d27a97c
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/block_test.m
@@ -0,0 +1,156 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+#import <Foundation/NSThread.h>
+
+#include "util.h"
+
+typedef struct {
+  double x;
+  double y;
+  double z;
+  double w;
+} Vec4;
+
+@interface DummyObject : NSObject {
+  int32_t* counter;
+}
++ (instancetype)newWithCounter:(int32_t*) _counter;
+- (instancetype)initWithCounter:(int32_t*) _counter;
+- (void)setCounter:(int32_t*) _counter;
+- (void)dealloc;
+@end
+@implementation DummyObject
+
++ (instancetype)newWithCounter:(int32_t*) _counter {
+  return [[DummyObject alloc] initWithCounter: _counter];
+}
+
+- (instancetype)initWithCounter:(int32_t*) _counter {
+  counter = _counter;
+  ++*counter;
+  return [super init];
+}
+
+- (void)setCounter:(int32_t*) _counter {
+  counter = _counter;
+  ++*counter;
+}
+
+- (void)dealloc {
+  if (counter != nil) --*counter;
+  [super dealloc];
+}
+
+@end
+
+
+typedef int32_t (^IntBlock)(int32_t);
+typedef float (^FloatBlock)(float);
+typedef double (^DoubleBlock)(double);
+typedef Vec4 (^Vec4Block)(Vec4);
+typedef void (^VoidBlock)();
+typedef DummyObject* (^ObjectBlock)(DummyObject*);
+typedef DummyObject* _Nullable (^NullableObjectBlock)(DummyObject* _Nullable);
+typedef IntBlock (^BlockBlock)(IntBlock);
+
+// Wrapper around a block, so that our Dart code can test creating and invoking
+// blocks in Objective C code.
+@interface BlockTester : NSObject {
+  IntBlock myBlock;
+}
++ (BlockTester*)makeFromBlock:(IntBlock)block;
++ (BlockTester*)makeFromMultiplier:(int32_t)mult;
+- (int32_t)call:(int32_t)x;
+- (IntBlock)getBlock;
+- (void)pokeBlock;
++ (void)callOnSameThread:(VoidBlock)block;
++ (NSThread*)callOnNewThread:(VoidBlock)block;
++ (float)callFloatBlock:(FloatBlock)block;
++ (double)callDoubleBlock:(DoubleBlock)block;
++ (Vec4)callVec4Block:(Vec4Block)block;
++ (DummyObject*)callObjectBlock:(ObjectBlock)block NS_RETURNS_RETAINED;
++ (nullable DummyObject*)callNullableObjectBlock:(NullableObjectBlock)block;
++ (IntBlock)newBlock:(BlockBlock)block withMult:(int)mult;
++ (BlockBlock)newBlockBlock:(int)mult;
+@end
+
+@implementation BlockTester
++ (BlockTester*)makeFromBlock:(IntBlock)block {
+  BlockTester* bt = [BlockTester new];
+  bt->myBlock = block;
+  return bt;
+}
+
++ (BlockTester*)makeFromMultiplier:(int32_t)mult {
+  BlockTester* bt = [BlockTester new];
+  bt->myBlock = [^int32_t(int32_t x) {
+    return x * mult;
+  } copy];
+  return bt;
+}
+
+- (int32_t)call:(int32_t)x {
+  return myBlock(x);
+}
+
+- (IntBlock)getBlock {
+  return myBlock;
+}
+
+- (void)pokeBlock {
+  // Used to repro https://github.com/dart-lang/ffigen/issues/376
+  [[myBlock retain] release];
+}
+
++ (void)callOnSameThread:(VoidBlock)block {
+  block();
+}
+
++ (NSThread*)callOnNewThread:(VoidBlock)block {
+  return [[NSThread alloc] initWithBlock: block];
+}
+
++ (float)callFloatBlock:(FloatBlock)block {
+  return block(1.23);
+}
+
++ (double)callDoubleBlock:(DoubleBlock)block {
+  return block(1.23);
+}
+
++ (Vec4)callVec4Block:(Vec4Block)block {
+  Vec4 vec4;
+  vec4.x = 1.2;
+  vec4.y = 3.4;
+  vec4.z = 5.6;
+  vec4.w = 7.8;
+  return block(vec4);
+}
+
++ (DummyObject*)callObjectBlock:(ObjectBlock)block NS_RETURNS_RETAINED {
+  return block([DummyObject new]);
+}
+
++ (nullable DummyObject*)callNullableObjectBlock:(NullableObjectBlock)block {
+  return block(nil);
+}
+
++ (IntBlock)newBlock:(BlockBlock)block withMult:(int)mult {
+  return block([^int(int x) {
+    return mult * x;
+  } copy]);
+  // ^ copy this stack allocated block to the heap.
+}
+
++ (BlockBlock)newBlockBlock:(int)mult {
+  return [^IntBlock(IntBlock block) {
+    return [^int(int x) {
+      return mult * block(x);
+    } copy];
+  } copy];
+}
+
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/cast_config.yaml b/pkgs/ffigen/test/native_objc_test/cast_config.yaml
new file mode 100644
index 0000000..af33941
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/cast_config.yaml
@@ -0,0 +1,13 @@
+name: CastTestObjCLibrary
+description: 'Tests casting objects'
+language: objc
+output: 'cast_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - Castaway
+headers:
+  entry-points:
+    - 'cast_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/cast_test.dart b/pkgs/ffigen/test/native_objc_test/cast_test.dart
new file mode 100644
index 0000000..c63d940
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/cast_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'cast_bindings.dart';
+import 'util.dart';
+
+void main() {
+  Castaway? testInstance;
+  late CastTestObjCLibrary lib;
+
+  group('cast', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/cast_test.dylib');
+      verifySetupFile(dylib);
+      lib = CastTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      testInstance = Castaway.new1(lib);
+      generateBindingsForCoverage('cast');
+    });
+
+    test('castFrom', () {
+      final fromCast = Castaway.castFrom(testInstance!.meAsNSObject());
+      expect(fromCast, testInstance!);
+    });
+
+    test('castFromPointer', () {
+      final meAsInt = testInstance!.meAsInt();
+      final fromCast = Castaway.castFromPointer(
+          lib, Pointer<ObjCObject>.fromAddress(meAsInt));
+      expect(fromCast, testInstance!);
+    });
+
+    test('pointers are equal', () {
+      final meAsInt = testInstance!.meAsInt();
+      expect(testInstance!.pointer.address, meAsInt);
+    });
+
+    test('equality equals', () {
+      final meAsInt = testInstance!.meAsInt();
+      final fromCast = Castaway.castFromPointer(
+          lib, Pointer<ObjCObject>.fromAddress(meAsInt));
+      expect(fromCast, testInstance!);
+    });
+
+    test('equality not equals', () {
+      final meAsInt = testInstance!.meAsInt();
+      final fromCast = Castaway.castFromPointer(
+          lib, Pointer<ObjCObject>.fromAddress(meAsInt));
+      expect(fromCast, isNot(equals(NSObject.new1(lib))));
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/cast_test.m b/pkgs/ffigen/test/native_objc_test/cast_test.m
new file mode 100644
index 0000000..363b3ad
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/cast_test.m
@@ -0,0 +1,25 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+
+@interface Castaway : NSObject {
+}
+
+- (NSObject *) meAsNSObject;
+- (int64_t) meAsInt;
+
+@end
+
+@implementation Castaway
+
+- (NSObject *) meAsNSObject {
+  return self;
+}
+
+- (int64_t) meAsInt {
+  return (int64_t) self;
+}
+
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/category_config.yaml b/pkgs/ffigen/test/native_objc_test/category_config.yaml
new file mode 100644
index 0000000..5c74e1a
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/category_config.yaml
@@ -0,0 +1,15 @@
+name: CategoryTestObjCLibrary
+description: 'Tests handling Objective-C categories'
+language: objc
+output: 'category_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - Thing
+headers:
+  entry-points:
+    - 'category_test.m'
+    # Include it twice, as a regression test for #353
+    - 'category_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/category_test.dart b/pkgs/ffigen/test/native_objc_test/category_test.dart
new file mode 100644
index 0000000..a424c46
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/category_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'category_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late Thing testInstance;
+  late CategoryTestObjCLibrary lib;
+
+  group('categories', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/category_test.dylib');
+      verifySetupFile(dylib);
+      lib = CategoryTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      testInstance = Thing.new1(lib);
+      generateBindingsForCoverage('category');
+    });
+
+    test('Category method', () {
+      expect(testInstance.add_Y_(1000, 234), 1234);
+      expect(testInstance.sub_Y_(1234, 1000), 234);
+      expect(testInstance.mul_Y_(1234, 1000), 1234000);
+      expect(testInstance.someProperty, 456);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/category_test.m b/pkgs/ffigen/test/native_objc_test/category_test.m
new file mode 100644
index 0000000..63cd873
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/category_test.m
@@ -0,0 +1,37 @@
+#import <Foundation/NSObject.h>
+
+@interface Thing : NSObject {}
+-(int32_t)add:(int32_t)x Y:(int32_t) y;
+@end
+
+@implementation Thing
+-(int32_t)add:(int32_t)x Y:(int32_t) y {
+  return x + y;
+}
+@end
+
+@interface Thing (Sub)
+-(int32_t)sub:(int32_t)x Y:(int32_t) y;
+@end
+
+@implementation Thing (Sub)
+-(int32_t)sub:(int32_t)x Y:(int32_t) y {
+  return x - y;
+}
+@end
+
+@interface Thing (Mul)
+-(int32_t)mul:(int32_t)x Y:(int32_t) y;
+
+@property (readonly) int32_t someProperty;
+@end
+
+@implementation Thing (Mul)
+-(int32_t)mul:(int32_t)x Y:(int32_t) y {
+  return x * y;
+}
+
+-(int32_t)someProperty {
+  return 456;
+}
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/failed_to_load_config.yaml b/pkgs/ffigen/test/native_objc_test/failed_to_load_config.yaml
new file mode 100644
index 0000000..c96702d
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/failed_to_load_config.yaml
@@ -0,0 +1,13 @@
+name: FailedToLoadTestObjCLibrary
+description: 'Tests failing to load an Objective-C library'
+language: objc
+output: 'failed_to_load_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - ClassThatWillFailToLoad
+headers:
+  entry-points:
+    - 'failed_to_load_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/failed_to_load_test.dart b/pkgs/ffigen/test/native_objc_test/failed_to_load_test.dart
new file mode 100644
index 0000000..8d1bb70
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/failed_to_load_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'failed_to_load_bindings.dart';
+import 'util.dart';
+
+void main() {
+  group('Failed to load', () {
+    setUpAll(() {
+      logWarnings();
+      generateBindingsForCoverage('failed_to_load');
+    });
+
+    test('Failed to load Objective-C class', () {
+      // Load from the host executable, which is missing all the classes for
+      // this test, but has the core ObjC functions, such as objc_getClass. The
+      // library should load ok, because the classes are lazy loaded.
+      final lib = FailedToLoadTestObjCLibrary(DynamicLibrary.executable());
+
+      // But when we try to instantiate one of the classes, we get an error.
+      expect(
+          () => ClassThatWillFailToLoad.new1(lib),
+          throwsA(predicate(
+              (e) => e.toString().contains('ClassThatWillFailToLoad'))));
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/failed_to_load_test.m b/pkgs/ffigen/test/native_objc_test/failed_to_load_test.m
new file mode 100644
index 0000000..b4d5e68
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/failed_to_load_test.m
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+
+@interface ClassThatWillFailToLoad : NSObject {}
+-(int32_t)get123;
+@end
+
+@implementation ClassThatWillFailToLoad
+-(int32_t)get123 {
+  return 123;
+}
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/forward_decl_config.yaml b/pkgs/ffigen/test/native_objc_test/forward_decl_config.yaml
new file mode 100644
index 0000000..7a5c815
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/forward_decl_config.yaml
@@ -0,0 +1,14 @@
+name: ForwardDeclTestObjCLibrary
+description: 'Test that forward declared ObjC classes are correctly filled'
+language: objc
+output: 'forward_decl_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - ForwardDeclaredClass
+headers:
+  entry-points:
+    - 'forward_decl_test.h'
+    - 'forward_decl_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/forward_decl_test.dart b/pkgs/ffigen/test/native_objc_test/forward_decl_test.dart
new file mode 100644
index 0000000..4a06516
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/forward_decl_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'forward_decl_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late ForwardDeclTestObjCLibrary lib;
+
+  group('forward decl', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/forward_decl_test.dylib');
+      verifySetupFile(dylib);
+      lib =
+          ForwardDeclTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('forward_decl');
+    });
+
+    test('Forward declared class', () {
+      expect(ForwardDeclaredClass.get123(lib), 123);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/forward_decl_test.h b/pkgs/ffigen/test/native_objc_test/forward_decl_test.h
new file mode 100644
index 0000000..4336b35
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/forward_decl_test.h
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+
+@class ForwardDeclaredClass;
+
+@interface OtherClass : NSObject
++ (ForwardDeclaredClass*) getTheThing;
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/forward_decl_test.m b/pkgs/ffigen/test/native_objc_test/forward_decl_test.m
new file mode 100644
index 0000000..69c8f66
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/forward_decl_test.m
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+
+@interface ForwardDeclaredClass : NSObject
++ (int32_t)get123;
+@end
+
+@implementation ForwardDeclaredClass
++ (int32_t)get123 {
+  return 123;
+}
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/inherited_instancetype_config.yaml b/pkgs/ffigen/test/native_objc_test/inherited_instancetype_config.yaml
new file mode 100644
index 0000000..9261979
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/inherited_instancetype_config.yaml
@@ -0,0 +1,13 @@
+name: InheritedInstancetypeTestObjCLibrary
+description: 'Regression tests for https://github.com/dart-lang/ffigen/issues/486'
+language: objc
+output: 'inherited_instancetype_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - ChildClass
+headers:
+  entry-points:
+    - 'inherited_instancetype_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/inherited_instancetype_test.dart b/pkgs/ffigen/test/native_objc_test/inherited_instancetype_test.dart
new file mode 100644
index 0000000..93f9355
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/inherited_instancetype_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+// Regression tests for https://github.com/dart-lang/ffigen/issues/486.
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'inherited_instancetype_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late InheritedInstancetypeTestObjCLibrary lib;
+
+  group('inheritedInstancetype', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib =
+          File('test/native_objc_test/inherited_instancetype_test.dylib');
+      verifySetupFile(dylib);
+      lib = InheritedInstancetypeTestObjCLibrary(
+          DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('inherited_instancetype');
+    });
+
+    test('Ordinary init method', () {
+      final ChildClass child = ChildClass.alloc(lib).init();
+      expect(child.field, 123);
+      final ChildClass sameChild = child.getSelf();
+      sameChild.field = 456;
+      expect(child.field, 456);
+    });
+
+    test('Custom create method', () {
+      final ChildClass child = ChildClass.create(lib);
+      expect(child.field, 123);
+      final ChildClass sameChild = child.getSelf();
+      sameChild.field = 456;
+      expect(child.field, 456);
+    });
+
+    test('Polymorphism', () {
+      final ChildClass child = ChildClass.alloc(lib).init();
+      final BaseClass base = child;
+
+      // Calling base.getSelf() should still go through ChildClass.getSelf, so
+      // the result will have a compile time type of BaseClass, but a runtime
+      // type of ChildClass.
+      final BaseClass sameChild = base.getSelf();
+      expect(sameChild, isA<ChildClass>());
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/inherited_instancetype_test.m b/pkgs/ffigen/test/native_objc_test/inherited_instancetype_test.m
new file mode 100644
index 0000000..8f1b20b
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/inherited_instancetype_test.m
@@ -0,0 +1,33 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+
+@interface BaseClass : NSObject {}
++ (instancetype)create;
+- (instancetype)getSelf;
+@end
+
+@interface ChildClass : BaseClass {}
+@property int32_t field;
+@end
+
+@implementation BaseClass
++ (instancetype)create {
+  return [[[self class] alloc] init];
+}
+
+- (instancetype)getSelf {
+  return self;
+}
+@end
+
+@implementation ChildClass
+- (instancetype)init {
+  if (self = [super init]) {
+    self.field = 123;
+  }
+  return self;
+}
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/is_instance_config.yaml b/pkgs/ffigen/test/native_objc_test/is_instance_config.yaml
new file mode 100644
index 0000000..2673c0b
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/is_instance_config.yaml
@@ -0,0 +1,14 @@
+name: IsInstanceTestObjCLibrary
+description: 'Tests isInstance'
+language: objc
+output: 'is_instance_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - ChildClass
+    - UnrelatedClass
+headers:
+  entry-points:
+    - 'is_instance_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/is_instance_test.dart b/pkgs/ffigen/test/native_objc_test/is_instance_test.dart
new file mode 100644
index 0000000..bbbfee9
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/is_instance_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'is_instance_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late IsInstanceTestObjCLibrary lib;
+
+  group('isInstance', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/is_instance_test.dylib');
+      verifySetupFile(dylib);
+      lib = IsInstanceTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('is_instance');
+    });
+
+    test('Unrelated classes', () {
+      final base = NSObject.castFrom(BaseClass.new1(lib));
+      final unrelated = NSObject.castFrom(UnrelatedClass.new1(lib));
+      expect(BaseClass.isInstance(base), isTrue);
+      expect(BaseClass.isInstance(unrelated), isFalse);
+      expect(UnrelatedClass.isInstance(base), isFalse);
+      expect(UnrelatedClass.isInstance(unrelated), isTrue);
+    });
+
+    test('Base class vs child class', () {
+      final base = NSObject.castFrom(BaseClass.new1(lib));
+      final child = NSObject.castFrom(ChildClass.new1(lib));
+      expect(BaseClass.isInstance(base), isTrue);
+      expect(BaseClass.isInstance(child), isTrue);
+      expect(ChildClass.isInstance(base), isFalse);
+      expect(ChildClass.isInstance(child), isTrue);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/is_instance_test.m b/pkgs/ffigen/test/native_objc_test/is_instance_test.m
new file mode 100644
index 0000000..96b2314
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/is_instance_test.m
@@ -0,0 +1,23 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+
+@interface BaseClass : NSObject {}
+@end
+
+@interface ChildClass : BaseClass {}
+@end
+
+@interface UnrelatedClass : NSObject {}
+@end
+
+@implementation BaseClass
+@end
+
+@implementation ChildClass
+@end
+
+@implementation UnrelatedClass
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/method_config.yaml b/pkgs/ffigen/test/native_objc_test/method_config.yaml
new file mode 100644
index 0000000..969ab7c
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/method_config.yaml
@@ -0,0 +1,13 @@
+name: MethodTestObjCLibrary
+description: 'Tests calling Objective-C methods'
+language: objc
+output: 'method_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - MethodInterface
+headers:
+  entry-points:
+    - 'method_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/method_test.dart b/pkgs/ffigen/test/native_objc_test/method_test.dart
new file mode 100644
index 0000000..21ba7e0
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/method_test.dart
@@ -0,0 +1,97 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:ffi/ffi.dart';
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'method_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late MethodInterface testInstance;
+  late MethodTestObjCLibrary lib;
+
+  group('method calls', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/method_test.dylib');
+      verifySetupFile(dylib);
+      lib = MethodTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      testInstance = MethodInterface.new1(lib);
+      generateBindingsForCoverage('method');
+    });
+
+    group('Instance methods', () {
+      test('No arguments', () {
+        expect(testInstance.add(), 5);
+      });
+
+      test('One argument', () {
+        expect(testInstance.add_(23), 23);
+      });
+
+      test('Two arguments', () {
+        expect(testInstance.add_Y_(23, 17), 40);
+      });
+
+      test('Three arguments', () {
+        expect(testInstance.add_Y_Z_(23, 17, 60), 100);
+      });
+    });
+
+    group('Class methods', () {
+      test('No arguments', () {
+        expect(MethodInterface.sub(lib), -5);
+      });
+
+      test('One argument', () {
+        expect(MethodInterface.sub_(lib, 7), -7);
+      });
+
+      test('Two arguments', () {
+        expect(MethodInterface.sub_Y_(lib, 7, 3), -10);
+      });
+
+      test('Three arguments', () {
+        expect(MethodInterface.sub_Y_Z_(lib, 10, 7, 3), -20);
+      });
+    });
+
+    group('Regress #608', () {
+      test('Structs', () {
+        final inputPtr = calloc<Vec4>();
+        final input = inputPtr.ref;
+        input.x = 1.2;
+        input.y = 3.4;
+        input.z = 5.6;
+        input.w = 7.8;
+
+        final resultPtr = calloc<Vec4>();
+        final result = resultPtr.ref;
+        testInstance.twiddleVec4Components_(resultPtr, input);
+        expect(result.x, 3.4);
+        expect(result.y, 5.6);
+        expect(result.z, 7.8);
+        expect(result.w, 1.2);
+
+        calloc.free(inputPtr);
+        calloc.free(resultPtr);
+      });
+
+      test('Floats', () {
+        expect(testInstance.addFloats_Y_(1.23, 4.56), closeTo(5.79, 1e-6));
+      });
+
+      test('Doubles', () {
+        expect(testInstance.addDoubles_Y_(1.23, 4.56), closeTo(5.79, 1e-6));
+      });
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/method_test.m b/pkgs/ffigen/test/native_objc_test/method_test.m
new file mode 100644
index 0000000..179f4ef
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/method_test.m
@@ -0,0 +1,81 @@
+#import <Foundation/NSObject.h>
+
+typedef struct {
+  double x;
+  double y;
+  double z;
+  double w;
+} Vec4;
+
+@interface MethodInterface : NSObject {
+}
+
+
+-(int32_t)add;
+-(int32_t)add:(int32_t)x;
+-(int32_t)add:(int32_t)x Y:(int32_t) y;
+-(int32_t)add:(int32_t)x Y:(int32_t) y Z:(int32_t) z;
+
++(int32_t)sub;
++(int32_t)sub:(int32_t)x;
++(int32_t)sub:(int32_t)x Y:(int32_t) y;
++(int32_t)sub:(int32_t)x Y:(int32_t) y Z:(int32_t) z;
+
+-(Vec4)twiddleVec4Components:(Vec4)v;
+-(float)addFloats:(float)x Y:(float) y;
+-(double)addDoubles:(double)x Y:(double) y;
+
+@end
+
+@implementation MethodInterface
+
+-(int32_t)add {
+  return 5;
+}
+
+-(int32_t)add:(int32_t)x {
+    return x;
+}
+
+-(int32_t)add:(int32_t)x Y:(int32_t) y {
+    return x + y;
+}
+
+-(int32_t)add:(int32_t)x Y:(int32_t) y Z:(int32_t) z {
+    return x + y + z;
+}
+
++(int32_t)sub {
+  return -5;
+}
+
++(int32_t)sub:(int32_t)x {
+    return -x;
+}
+
++(int32_t)sub:(int32_t)x Y:(int32_t) y {
+    return -x - y;
+}
+
++(int32_t)sub:(int32_t)x Y:(int32_t) y Z:(int32_t) z {
+    return - x - y - z;
+}
+
+-(Vec4)twiddleVec4Components:(Vec4)v {
+    Vec4 u;
+    u.x = v.y;
+    u.y = v.z;
+    u.z = v.w;
+    u.w = v.x;
+    return u;
+}
+
+-(float)addFloats:(float)x Y:(float) y {
+    return x + y;
+}
+
+-(double)addDoubles:(double)x Y:(double) y {
+    return x + y;
+}
+
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/native_objc_config.yaml b/pkgs/ffigen/test/native_objc_test/native_objc_config.yaml
new file mode 100644
index 0000000..58bcf50
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/native_objc_config.yaml
@@ -0,0 +1,21 @@
+# Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# =================== GENERATING TEST BINDINGS ==================
+#    dart run ffigen --config test/native_objc_test/config.yaml
+# ===============================================================
+
+name: NativeObjCLibrary
+description: 'Native Objective C test'
+language: objc
+output: 'native_objc_test_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - Foo
+headers:
+  entry-points:
+    - 'native_objc_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/native_objc_test.dart b/pkgs/ffigen/test/native_objc_test/native_objc_test.dart
new file mode 100644
index 0000000..28c006a
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/native_objc_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'native_objc_test_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late NativeObjCLibrary lib;
+  group('native_objc_test', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/native_objc_test.dylib');
+      verifySetupFile(dylib);
+      lib = NativeObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('native_objc');
+    });
+
+    test('Basic types', () {
+      final foo = Foo.new1(lib);
+      final obj = NSObject.new1(lib);
+
+      foo.intVal = 123;
+      expect(foo.intVal, 123);
+
+      foo.boolVal = true;
+      expect(foo.boolVal, true);
+
+      foo.idVal = obj;
+      expect(foo.idVal, obj);
+
+      foo.selVal = Pointer<ObjCSel>.fromAddress(456);
+      expect(foo.selVal.address, 456);
+
+      foo.classVal = obj;
+      expect(foo.classVal, obj);
+    });
+
+    test('Interface basics, with Foo', () {
+      final foo1 = Foo.makeFoo_(lib, 3.14159);
+      final foo2 = Foo.makeFoo_(lib, 2.71828);
+
+      expect(foo1.intVal, 3);
+      expect(foo2.intVal, 2);
+
+      expect(foo1.multiply_withOtherFoo_(false, foo2), 8);
+      expect(foo1.multiply_withOtherFoo_(true, foo2), 6);
+
+      foo1.intVal = 100;
+      expect(foo1.multiply_withOtherFoo_(false, foo2), 8);
+      expect(foo1.multiply_withOtherFoo_(true, foo2), 200);
+
+      foo2.setDoubleVal_(1.61803);
+      expect(foo1.multiply_withOtherFoo_(false, foo2), 5);
+      expect(foo1.multiply_withOtherFoo_(true, foo2), 200);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/native_objc_test.m b/pkgs/ffigen/test/native_objc_test/native_objc_test.m
new file mode 100644
index 0000000..e510df8
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/native_objc_test.m
@@ -0,0 +1,48 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+#import <Foundation/NSString.h>
+
+@interface Foo : NSObject {
+  double doubleVal;
+}
+
+@property int32_t intVal;
+@property BOOL boolVal;
+@property id idVal;
+@property SEL selVal;
+@property NSObject* objVal;
+@property Class classVal;
+
++ (Foo*)makeFoo:(double)x;
+
+- (int32_t)multiply:(BOOL)useIntVals withOtherFoo:(Foo*)other;
+
+- (void)setDoubleVal:(double)x;
+
+@end
+
+@implementation Foo
+
++ (Foo*)makeFoo:(double)x {
+  Foo* foo = [Foo new];
+  foo->doubleVal = x;
+  [foo setIntVal:((int32_t)x)];
+  return foo;
+}
+
+- (int32_t)multiply:(BOOL)useIntVals withOtherFoo:(Foo*)other {
+  if (useIntVals) {
+    return [self intVal] * [other intVal];
+  } else {
+    return (int32_t)(self->doubleVal * other->doubleVal);
+  }
+}
+
+- (void)setDoubleVal:(double)x {
+  self->doubleVal = x;
+}
+
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/nullable_config.yaml b/pkgs/ffigen/test/native_objc_test/nullable_config.yaml
new file mode 100644
index 0000000..eba9e77
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/nullable_config.yaml
@@ -0,0 +1,13 @@
+name: NullableTestObjCLibrary
+description: 'Tests nullability for Objective-C methods'
+language: objc
+output: 'nullable_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - NullableInterface
+headers:
+  entry-points:
+    - 'nullable_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/nullable_inheritance_config.yaml b/pkgs/ffigen/test/native_objc_test/nullable_inheritance_config.yaml
new file mode 100644
index 0000000..930a531
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/nullable_inheritance_config.yaml
@@ -0,0 +1,14 @@
+name: NullableInheritanceTestObjCLibrary
+description: 'Tests nullability of inherited Objective-C methods'
+language: objc
+output: 'nullable_inheritance_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - NullableBase
+    - NullableChild
+headers:
+  entry-points:
+    - 'nullable_inheritance_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/nullable_inheritance_test.dart b/pkgs/ffigen/test/native_objc_test/nullable_inheritance_test.dart
new file mode 100644
index 0000000..fd3052c
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/nullable_inheritance_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'nullable_inheritance_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late NullableInheritanceTestObjCLibrary lib;
+  late NullableBase nullableBase;
+  late NullableChild nullableChild;
+  late NSObject obj;
+  group('Nullable inheritance', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib =
+          File('test/native_objc_test/nullable_inheritance_test.dylib');
+      verifySetupFile(dylib);
+      lib = NullableInheritanceTestObjCLibrary(
+          DynamicLibrary.open(dylib.absolute.path));
+      nullableBase = NullableBase.new1(lib);
+      nullableChild = NullableChild.new1(lib);
+      obj = NSObject.new1(lib);
+      generateBindingsForCoverage('nullable');
+    });
+
+    group('Base', () {
+      test('Nullable arguments', () {
+        expect(nullableBase.nullableArg_(obj), false);
+        expect(nullableBase.nullableArg_(null), true);
+      });
+
+      test('Non-null arguments', () {
+        expect(nullableBase.nonNullArg_(obj), false);
+      });
+
+      test('Nullable return', () {
+        expect(nullableBase.nullableReturn_(false), isA<NSObject>());
+        expect(nullableBase.nullableReturn_(true), null);
+      });
+
+      test('Non-null return', () {
+        expect(nullableBase.nonNullReturn(), isA<NSObject>());
+      });
+    });
+
+    group('Child', () {
+      test('Nullable arguments, changed to non-null', () {
+        expect(nullableChild.nullableArg_(obj), false);
+      });
+
+      test('Non-null arguments, changed to nullable', () {
+        expect(nullableChild.nonNullArg_(obj), false);
+        expect(nullableChild.nonNullArg_(null), true);
+      });
+
+      test('Nullable return, changed to non-null', () {
+        expect(nullableChild.nullableReturn_(false), isA<NSObject>());
+      });
+
+      test('Non-null return, changed to nullable', () {
+        expect(nullableChild.nonNullReturn(), null);
+      });
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/nullable_inheritance_test.m b/pkgs/ffigen/test/native_objc_test/nullable_inheritance_test.m
new file mode 100644
index 0000000..035692c
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/nullable_inheritance_test.m
@@ -0,0 +1,69 @@
+#import <Foundation/NSObject.h>
+
+@interface NullableBase : NSObject {}
+
+-(BOOL) nullableArg:(nullable NSObject *)x;
+-(BOOL) nonNullArg:(NSObject *)x;
+-(nullable NSObject *) nullableReturn:(BOOL)r;
+-(NSObject*) nonNullReturn;
+
+@end
+
+@implementation NullableBase
+
+-(BOOL) nullableArg:(nullable NSObject *)x {
+  return x == NULL;
+}
+
+-(BOOL) nonNullArg:(NSObject *)x {
+  return x == NULL;
+}
+
+-(nullable NSObject *) nullableReturn:(BOOL)r {
+  if (r) {
+    return nil;
+  } else {
+    return [NSObject new];
+  }
+}
+
+-(NSObject *) nonNullReturn {
+  return [NSObject new];
+}
+
+@end
+
+@interface NullableIntermediate : NullableBase {}
+@end
+@implementation NullableIntermediate
+@end
+
+@interface NullableChild : NullableIntermediate {}
+
+// Redeclare the same methods with different nullability.
+-(BOOL) nullableArg:(NSObject *)x;
+-(BOOL) nonNullArg:(nullable NSObject *)x;
+-(NSObject *) nullableReturn:(BOOL)r;
+-(nullable NSObject *) nonNullReturn;
+
+@end
+
+@implementation NullableChild
+
+-(BOOL) nullableArg:(NSObject *)x {
+  return x == NULL;
+}
+
+-(BOOL) nonNullArg:(nullable NSObject *)x {
+  return x == NULL;
+}
+
+-(NSObject *) nullableReturn:(BOOL)r {
+  return [NSObject new];
+}
+
+-(nullable NSObject *) nonNullReturn {
+  return nil;
+}
+
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/nullable_test.dart b/pkgs/ffigen/test/native_objc_test/nullable_test.dart
new file mode 100644
index 0000000..b264531
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/nullable_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'nullable_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late NullableTestObjCLibrary lib;
+  late NullableInterface nullableInterface;
+  late NSObject obj;
+  group('Nullability', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/nullable_test.dylib');
+      verifySetupFile(dylib);
+      lib = NullableTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      nullableInterface = NullableInterface.new1(lib);
+      obj = NSObject.new1(lib);
+      generateBindingsForCoverage('nullable');
+    });
+
+    group('Nullable property', () {
+      test('Not null', () {
+        nullableInterface.nullableObjectProperty = obj;
+        expect(nullableInterface.nullableObjectProperty, obj);
+      });
+      test('Null', () {
+        nullableInterface.nullableObjectProperty = null;
+        expect(nullableInterface.nullableObjectProperty, null);
+      });
+    });
+
+    group('Nullable return', () {
+      test('Not null', () {
+        expect(NullableInterface.returnNil_(lib, false), isA<NSObject>());
+      });
+      test('Null', () {
+        expect(NullableInterface.returnNil_(lib, true), null);
+      });
+    });
+
+    group('Nullable arguments', () {
+      test('Not null', () {
+        expect(
+            NullableInterface.isNullWithNullableNSObjectArg_(lib, obj), false);
+      });
+      test('Null', () {
+        expect(
+            NullableInterface.isNullWithNullableNSObjectArg_(lib, null), true);
+      });
+    });
+
+    group('Not-nullable arguments', () {
+      test('Not null', () {
+        expect(NullableInterface.isNullWithNotNullableNSObjectPtrArg_(lib, obj),
+            false);
+      });
+
+      test('Explicit non null', () {
+        expect(
+            NullableInterface.isNullWithExplicitNonNullableNSObjectPtrArg_(
+                lib, obj),
+            false);
+      });
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/nullable_test.m b/pkgs/ffigen/test/native_objc_test/nullable_test.m
new file mode 100644
index 0000000..06d257d
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/nullable_test.m
@@ -0,0 +1,37 @@
+#import <Foundation/NSObject.h>
+
+@interface NullableInterface  : NSObject {
+}
+
++(BOOL) isNullWithNullableNSObjectArg:(nullable NSObject *)x;
++(BOOL) isNullWithNotNullableNSObjectPtrArg:(NSObject *)x;
++(BOOL) isNullWithExplicitNonNullableNSObjectPtrArg:(nonnull NSObject *)x;
++(nullable NSObject *) returnNil:(BOOL)r;
+
+@property (nullable, retain) NSObject *nullableObjectProperty;
+
+@end
+
+@implementation NullableInterface
+
++(BOOL) isNullWithNullableNSObjectArg:(nullable NSObject *)x {
+  return x == NULL;
+}
+
++(BOOL) isNullWithNotNullableNSObjectPtrArg:(NSObject *)x {
+  return x == NULL;
+}
+
++(BOOL) isNullWithExplicitNonNullableNSObjectPtrArg:(nonnull NSObject *)x {
+  return x == NULL;
+}
+
++(nullable NSObject *) returnNil:(BOOL)r {
+  if (r) {
+    return nil;
+  } else {
+    return [NSObject new];
+  }
+}
+
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/property_config.yaml b/pkgs/ffigen/test/native_objc_test/property_config.yaml
new file mode 100644
index 0000000..220a83a
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/property_config.yaml
@@ -0,0 +1,13 @@
+name: PropertyTestObjCLibrary
+description: 'Tests calling Objective-C properties i.e. getters and setters'
+language: objc
+output: 'property_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - PropertyInterface
+headers:
+  entry-points:
+    - 'property_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/property_test.dart b/pkgs/ffigen/test/native_objc_test/property_test.dart
new file mode 100644
index 0000000..9bd4f3c
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/property_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:ffi/ffi.dart';
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'property_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late PropertyInterface testInstance;
+  late PropertyTestObjCLibrary lib;
+
+  group('properties', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/property_test.dylib');
+      verifySetupFile(dylib);
+      lib = PropertyTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      testInstance = PropertyInterface.new1(lib);
+      generateBindingsForCoverage('property');
+    });
+
+    group('instance properties', () {
+      test('read-only property', () {
+        expect(testInstance.readOnlyProperty, 7);
+      });
+
+      test('read-write property', () {
+        testInstance.readWriteProperty = 23;
+        expect(testInstance.readWriteProperty, 23);
+      });
+    });
+
+    group('class properties', () {
+      test('read-only property', () {
+        expect(PropertyInterface.getClassReadOnlyProperty(lib), 42);
+      });
+
+      test('read-write property', () {
+        PropertyInterface.setClassReadWriteProperty(lib, 101);
+        expect(PropertyInterface.getClassReadWriteProperty(lib), 101);
+      });
+    });
+
+    group('Regress #608', () {
+      test('Structs', () {
+        final inputPtr = calloc<Vec4>();
+        final input = inputPtr.ref;
+        input.x = 1.2;
+        input.y = 3.4;
+        input.z = 5.6;
+        input.w = 7.8;
+
+        final resultPtr = calloc<Vec4>();
+        final result = resultPtr.ref;
+        testInstance.structProperty = input;
+        testInstance.getStructProperty(resultPtr);
+        expect(result.x, 1.2);
+        expect(result.y, 3.4);
+        expect(result.z, 5.6);
+        expect(result.w, 7.8);
+
+        calloc.free(inputPtr);
+        calloc.free(resultPtr);
+      });
+
+      test('Floats', () {
+        testInstance.floatProperty = 1.23;
+        expect(testInstance.floatProperty, closeTo(1.23, 1e-6));
+      });
+
+      test('Doubles', () {
+        testInstance.doubleProperty = 1.23;
+        expect(testInstance.doubleProperty, 1.23);
+      });
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/property_test.m b/pkgs/ffigen/test/native_objc_test/property_test.m
new file mode 100644
index 0000000..0085034
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/property_test.m
@@ -0,0 +1,46 @@
+#import <Foundation/NSObject.h>
+
+@class UndefinedTemplate<ObjectType>;
+
+typedef struct {
+  double x;
+  double y;
+  double z;
+  double w;
+} Vec4;
+
+@interface PropertyInterface : NSObject {
+}
+
+@property (readonly) int32_t readOnlyProperty;
+@property int32_t readWriteProperty;
+@property (class, readonly, copy) UndefinedTemplate<NSString *> *regressGH436;
+@property (class, readonly) int32_t classReadOnlyProperty;
+@property (class) int32_t classReadWriteProperty;
+@property float floatProperty;
+@property double doubleProperty;
+@property Vec4 structProperty;
+
+@end
+
+@implementation PropertyInterface
+
+static int32_t _classReadWriteProperty = 0;
+
+- (int32_t)readOnlyProperty {
+  return 7;
+}
+
++ (int32_t)classReadOnlyProperty {
+  return 42;
+}
+
++ (int32_t)classReadWriteProperty {
+  return _classReadWriteProperty;
+}
+
++ (void)setClassReadWriteProperty:(int32_t)x {
+  _classReadWriteProperty = x;
+}
+
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/rename_config.yaml b/pkgs/ffigen/test/native_objc_test/rename_config.yaml
new file mode 100644
index 0000000..8dbae03
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/rename_config.yaml
@@ -0,0 +1,23 @@
+# Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# =================== GENERATING TEST BINDINGS ==================
+#    dart run ffigen --config test/rename_test/config.yaml
+# ===============================================================
+
+name: RenameLibrary
+description: 'Rename test'
+language: objc
+output: 'rename_test_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - _Renamed
+  rename:
+    '_(.*)': '$1'
+headers:
+  entry-points:
+    - 'rename_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/rename_test.dart b/pkgs/ffigen/test/native_objc_test/rename_test.dart
new file mode 100644
index 0000000..aa8a23f
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/rename_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'rename_test_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late RenameLibrary lib;
+  group('rename_test', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/rename_test.dylib');
+      verifySetupFile(dylib);
+      lib = RenameLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('rename');
+    });
+
+    test('Renamed class', () {
+      final renamed = Renamed.new1(lib);
+      renamed.property = 123;
+      expect(renamed.property, 123);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/rename_test.m b/pkgs/ffigen/test/native_objc_test/rename_test.m
new file mode 100644
index 0000000..6187bd8
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/rename_test.m
@@ -0,0 +1,12 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+
+@interface _Renamed : NSObject
+@property int32_t property;
+@end
+
+@implementation _Renamed
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/setup.dart b/pkgs/ffigen/test/native_objc_test/setup.dart
new file mode 100644
index 0000000..8e74d87
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/setup.dart
@@ -0,0 +1,133 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+Future<void> _buildLib(String input, String output) async {
+  final args = [
+    '-shared',
+    '-fpic',
+    '-x',
+    'objective-c',
+    input,
+    '-framework',
+    'Foundation',
+    '-o',
+    output,
+  ];
+  final process = await Process.start('clang', args);
+  unawaited(stdout.addStream(process.stdout));
+  unawaited(stderr.addStream(process.stderr));
+  final result = await process.exitCode;
+  if (result != 0) {
+    throw ProcessException('clang', args, 'Build failed', result);
+  }
+  print('Generated file: $output');
+}
+
+Future<void> _buildSwift(
+    String input, String outputHeader, String outputLib) async {
+  final args = [
+    '-c',
+    input,
+    '-emit-objc-header-path',
+    outputHeader,
+    '-emit-library',
+    '-o',
+    outputLib,
+  ];
+  final process = await Process.start('swiftc', args);
+  unawaited(stdout.addStream(process.stdout));
+  unawaited(stderr.addStream(process.stderr));
+  final result = await process.exitCode;
+  if (result != 0) {
+    throw ProcessException('swiftc', args, 'Build failed', result);
+  }
+  print('Generated files: $outputHeader and $outputLib');
+}
+
+Future<void> _generateBindings(String config) async {
+  final args = [
+    'run',
+    'ffigen',
+    '--config',
+    'test/native_objc_test/$config',
+  ];
+  final process =
+      await Process.start(Platform.executable, args, workingDirectory: '../..');
+  unawaited(stdout.addStream(process.stdout));
+  unawaited(stderr.addStream(process.stderr));
+  final result = await process.exitCode;
+  if (result != 0) {
+    throw ProcessException('dart', args, 'Generating bindings', result);
+  }
+  print('Generated bindings for: $config');
+}
+
+List<String> _getTestNames() {
+  const configSuffix = '_config.yaml';
+  final names = <String>[];
+  for (final entity in Directory.current.listSync()) {
+    final filename = entity.uri.pathSegments.last;
+    if (filename.endsWith(configSuffix)) {
+      names.add(filename.substring(0, filename.length - configSuffix.length));
+    }
+  }
+  return names;
+}
+
+Future<void> build(List<String> testNames) async {
+  print('Building Dynamic Library for Objective C Native Tests...');
+  for (final name in testNames) {
+    final mFile = '${name}_test.m';
+    if (await File(mFile).exists()) {
+      await _buildLib(mFile, '${name}_test.dylib');
+    }
+  }
+
+  print('Building Dynamic Library and Header for Swift Tests...');
+  for (final name in testNames) {
+    final swiftFile = '${name}_test.swift';
+    if (await File(swiftFile).exists()) {
+      await _buildSwift(
+          swiftFile, '${name}_test-Swift.h', '${name}_test.dylib');
+    }
+  }
+
+  print('Generating Bindings for Objective C Native Tests...');
+  for (final name in testNames) {
+    await _generateBindings('${name}_config.yaml');
+  }
+}
+
+Future<void> clean(List<String> testNames) async {
+  print('Deleting generated and built files...');
+  final filenames = [
+    for (final name in testNames) ...[
+      '${name}_bindings.dart',
+      '${name}_test_bindings.dart',
+      '${name}_test.dylib'
+    ],
+  ];
+  Future.wait(filenames.map((fileName) async {
+    final file = File(fileName);
+    final exists = await file.exists();
+    if (exists) await file.delete();
+  }));
+}
+
+Future<void> main(List<String> arguments) async {
+  // Allow running this script directly from any path (or an IDE).
+  Directory.current = Platform.script.resolve('.').toFilePath();
+  if (!Platform.isMacOS) {
+    throw OSError('Objective C tests are only supported on MacOS');
+  }
+
+  if (arguments.isNotEmpty && arguments[0] == 'clean') {
+    return await clean(_getTestNames());
+  }
+
+  return await build(arguments.isNotEmpty ? arguments : _getTestNames());
+}
diff --git a/pkgs/ffigen/test/native_objc_test/static_func_config.yaml b/pkgs/ffigen/test/native_objc_test/static_func_config.yaml
new file mode 100644
index 0000000..bbafeaa
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/static_func_config.yaml
@@ -0,0 +1,18 @@
+name: StaticFuncTestObjCLibrary
+description: 'Test ObjC static functions'
+language: objc
+output: 'static_func_bindings.dart'
+exclude-all-by-default: true
+functions:
+  include:
+    - getBlockRetainCount
+    - staticFuncOfObject
+    - staticFuncOfNullableObject
+    - staticFuncOfBlock
+    - staticFuncReturnsRetained
+    - staticFuncReturnsRetainedArg
+headers:
+  entry-points:
+    - 'static_func_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/static_func_native_config.yaml b/pkgs/ffigen/test/native_objc_test/static_func_native_config.yaml
new file mode 100644
index 0000000..2a591c9
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/static_func_native_config.yaml
@@ -0,0 +1,19 @@
+name: StaticFuncTestObjCLibrary
+description: 'Test ObjC static functions using @Native'
+language: objc
+output: 'static_func_native_bindings.dart'
+exclude-all-by-default: true
+ffi-native:
+functions:
+  include:
+    - getBlockRetainCount
+    - staticFuncOfObject
+    - staticFuncOfNullableObject
+    - staticFuncOfBlock
+    - staticFuncReturnsRetained
+    - staticFuncReturnsRetainedArg
+headers:
+  entry-points:
+    - 'static_func_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/static_func_native_test.dart b/pkgs/ffigen/test/native_objc_test/static_func_native_test.dart
new file mode 100644
index 0000000..93cbcad
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/static_func_native_test.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+// Keep in sync with static_func_test.dart. These are the same tests, but using
+// @Native.
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import 'package:ffi/ffi.dart';
+import '../test_utils.dart';
+import 'static_func_native_bindings.dart';
+import 'util.dart';
+
+typedef IntBlock = ObjCBlock_Int32_Int32;
+
+void main() {
+  late StaticFuncTestObjCLibrary lib;
+  late void Function(Pointer<Char>, Pointer<Void>) executeInternalCommand;
+
+  group('static functions', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/static_func_test.dylib');
+      verifySetupFile(dylib);
+      lib = StaticFuncTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+
+      executeInternalCommand = DynamicLibrary.process().lookupFunction<
+          Void Function(Pointer<Char>, Pointer<Void>),
+          void Function(
+              Pointer<Char>, Pointer<Void>)>('Dart_ExecuteInternalCommand');
+
+      generateBindingsForCoverage('static_func');
+    });
+
+    doGC() {
+      final gcNow = "gc-now".toNativeUtf8();
+      executeInternalCommand(gcNow.cast(), nullptr);
+      calloc.free(gcNow);
+    }
+
+    Pointer<Int32> staticFuncOfObjectRefCountTest(Allocator alloc) {
+      final counter = alloc<Int32>();
+      counter.value = 0;
+
+      final obj = StaticFuncTestObj.newWithCounter_(lib, counter);
+      expect(counter.value, 1);
+
+      final outputObj = staticFuncOfObject(lib, obj);
+      expect(obj, outputObj);
+      expect(counter.value, 1);
+
+      return counter;
+    }
+
+    test('Objects passed through static functions have correct ref counts', () {
+      using((Arena arena) {
+        final (counter) = staticFuncOfObjectRefCountTest(arena);
+        doGC();
+        expect(counter.value, 0);
+      });
+    });
+
+    Pointer<Int32> staticFuncOfNullableObjectRefCountTest(Allocator alloc) {
+      final counter = alloc<Int32>();
+      counter.value = 0;
+
+      final obj = StaticFuncTestObj.newWithCounter_(lib, counter);
+      expect(counter.value, 1);
+
+      final outputObj = staticFuncOfNullableObject(lib, obj);
+      expect(obj, outputObj);
+      expect(counter.value, 1);
+
+      return counter;
+    }
+
+    test('Nullables passed through static functions have correct ref counts',
+        () {
+      using((Arena arena) {
+        final (counter) = staticFuncOfNullableObjectRefCountTest(arena);
+        doGC();
+        expect(counter.value, 0);
+
+        expect(staticFuncOfNullableObject(lib, null), isNull);
+      });
+    });
+
+    Pointer<Void> staticFuncOfBlockRefCountTest() {
+      final block = IntBlock.fromFunction(lib, (int x) => 2 * x);
+      expect(getBlockRetainCount(block.pointer.cast()), 1);
+
+      final outputBlock = staticFuncOfBlock(lib, block);
+      expect(block, outputBlock);
+      expect(getBlockRetainCount(block.pointer.cast()), 2);
+
+      return block.pointer.cast();
+    }
+
+    test('Blocks passed through static functions have correct ref counts', () {
+      final (rawBlock) = staticFuncOfBlockRefCountTest();
+      doGC();
+      expect(getBlockRetainCount(rawBlock), 0);
+    });
+
+    Pointer<Int32> staticFuncReturnsRetainedRefCountTest(Allocator alloc) {
+      final counter = alloc<Int32>();
+      counter.value = 0;
+
+      final outputObj = staticFuncReturnsRetained(lib, counter);
+      expect(counter.value, 1);
+
+      return counter;
+    }
+
+    test(
+        'Objects returned from static functions with NS_RETURNS_RETAINED '
+        'have correct ref counts', () {
+      using((Arena arena) {
+        final (counter) = staticFuncReturnsRetainedRefCountTest(arena);
+        doGC();
+        expect(counter.value, 0);
+      });
+    });
+
+    Pointer<Int32> staticFuncOfObjectReturnsRetainedRefCountTest(
+        Allocator alloc) {
+      final counter = alloc<Int32>();
+      counter.value = 0;
+
+      final obj = StaticFuncTestObj.newWithCounter_(lib, counter);
+      expect(counter.value, 1);
+
+      final outputObj = staticFuncReturnsRetainedArg(lib, obj);
+      expect(obj, outputObj);
+      expect(counter.value, 1);
+
+      return counter;
+    }
+
+    test(
+        'Objects passed through static functions with NS_RETURNS_RETAINED '
+        'have correct ref counts', () {
+      using((Arena arena) {
+        final (counter) = staticFuncOfObjectReturnsRetainedRefCountTest(arena);
+        doGC();
+        expect(counter.value, 0);
+      });
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/static_func_test.dart b/pkgs/ffigen/test/native_objc_test/static_func_test.dart
new file mode 100644
index 0000000..f3d9c01
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/static_func_test.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+// Keep in sync with static_func_test.dart. These are the same tests, but
+// without using @Native.
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import 'package:ffi/ffi.dart';
+import '../test_utils.dart';
+import 'static_func_bindings.dart';
+import 'util.dart';
+
+typedef IntBlock = ObjCBlock_Int32_Int32;
+
+void main() {
+  late StaticFuncTestObjCLibrary lib;
+  late void Function(Pointer<Char>, Pointer<Void>) executeInternalCommand;
+
+  group('static functions', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/static_func_test.dylib');
+      verifySetupFile(dylib);
+      lib = StaticFuncTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+
+      executeInternalCommand = DynamicLibrary.process().lookupFunction<
+          Void Function(Pointer<Char>, Pointer<Void>),
+          void Function(
+              Pointer<Char>, Pointer<Void>)>('Dart_ExecuteInternalCommand');
+
+      generateBindingsForCoverage('static_func');
+    });
+
+    doGC() {
+      final gcNow = "gc-now".toNativeUtf8();
+      executeInternalCommand(gcNow.cast(), nullptr);
+      calloc.free(gcNow);
+    }
+
+    Pointer<Int32> staticFuncOfObjectRefCountTest(Allocator alloc) {
+      final counter = alloc<Int32>();
+      counter.value = 0;
+
+      final obj = StaticFuncTestObj.newWithCounter_(lib, counter);
+      expect(counter.value, 1);
+
+      final outputObj = lib.staticFuncOfObject(obj);
+      expect(obj, outputObj);
+      expect(counter.value, 1);
+
+      return counter;
+    }
+
+    test('Objects passed through static functions have correct ref counts', () {
+      using((Arena arena) {
+        final (counter) = staticFuncOfObjectRefCountTest(arena);
+        doGC();
+        expect(counter.value, 0);
+      });
+    });
+
+    Pointer<Int32> staticFuncOfNullableObjectRefCountTest(Allocator alloc) {
+      final counter = alloc<Int32>();
+      counter.value = 0;
+
+      final obj = StaticFuncTestObj.newWithCounter_(lib, counter);
+      expect(counter.value, 1);
+
+      final outputObj = lib.staticFuncOfNullableObject(obj);
+      expect(obj, outputObj);
+      expect(counter.value, 1);
+
+      return counter;
+    }
+
+    test('Nullables passed through static functions have correct ref counts',
+        () {
+      using((Arena arena) {
+        final (counter) = staticFuncOfNullableObjectRefCountTest(arena);
+        doGC();
+        expect(counter.value, 0);
+
+        expect(lib.staticFuncOfNullableObject(null), isNull);
+      });
+    });
+
+    Pointer<Void> staticFuncOfBlockRefCountTest() {
+      final block = IntBlock.fromFunction(lib, (int x) => 2 * x);
+      expect(lib.getBlockRetainCount(block.pointer.cast()), 1);
+
+      final outputBlock = lib.staticFuncOfBlock(block);
+      expect(block, outputBlock);
+      expect(lib.getBlockRetainCount(block.pointer.cast()), 2);
+
+      return block.pointer.cast();
+    }
+
+    test('Blocks passed through static functions have correct ref counts', () {
+      final (rawBlock) = staticFuncOfBlockRefCountTest();
+      doGC();
+      expect(lib.getBlockRetainCount(rawBlock), 0);
+    });
+
+    Pointer<Int32> staticFuncReturnsRetainedRefCountTest(Allocator alloc) {
+      final counter = alloc<Int32>();
+      counter.value = 0;
+
+      final outputObj = lib.staticFuncReturnsRetained(counter);
+      expect(counter.value, 1);
+
+      return counter;
+    }
+
+    test(
+        'Objects returned from static functions with NS_RETURNS_RETAINED '
+        'have correct ref counts', () {
+      using((Arena arena) {
+        final (counter) = staticFuncReturnsRetainedRefCountTest(arena);
+        doGC();
+        expect(counter.value, 0);
+      });
+    });
+
+    Pointer<Int32> staticFuncOfObjectReturnsRetainedRefCountTest(
+        Allocator alloc) {
+      final counter = alloc<Int32>();
+      counter.value = 0;
+
+      final obj = StaticFuncTestObj.newWithCounter_(lib, counter);
+      expect(counter.value, 1);
+
+      final outputObj = lib.staticFuncReturnsRetainedArg(obj);
+      expect(obj, outputObj);
+      expect(counter.value, 1);
+
+      return counter;
+    }
+
+    test(
+        'Objects passed through static functions with NS_RETURNS_RETAINED '
+        'have correct ref counts', () {
+      using((Arena arena) {
+        final (counter) = staticFuncOfObjectReturnsRetainedRefCountTest(arena);
+        doGC();
+        expect(counter.value, 0);
+      });
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/static_func_test.m b/pkgs/ffigen/test/native_objc_test/static_func_test.m
new file mode 100644
index 0000000..5fc3a14
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/static_func_test.m
@@ -0,0 +1,63 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSString.h>
+
+#include "util.h"
+
+@interface StaticFuncTestObj : NSObject {
+  int32_t* counter;
+}
++ (instancetype)newWithCounter:(int32_t*) _counter;
+- (instancetype)initWithCounter:(int32_t*) _counter;
+- (void)setCounter:(int32_t*) _counter;
+- (void)dealloc;
+@end
+
+StaticFuncTestObj* staticFuncOfObject(StaticFuncTestObj* a) {
+  return a;
+}
+
+StaticFuncTestObj* _Nullable staticFuncOfNullableObject(
+    StaticFuncTestObj* _Nullable a) {
+  return a;
+}
+
+typedef int32_t (^IntBlock)(int32_t);
+IntBlock staticFuncOfBlock(IntBlock a) {
+  return a;
+}
+
+NS_RETURNS_RETAINED StaticFuncTestObj* staticFuncReturnsRetained(
+    int32_t* counter) {
+  return [StaticFuncTestObj newWithCounter: counter];
+}
+
+NS_RETURNS_RETAINED StaticFuncTestObj* staticFuncReturnsRetainedArg(
+    StaticFuncTestObj* a) {
+  return [a retain];
+}
+
+
+@implementation StaticFuncTestObj
++ (instancetype)newWithCounter:(int32_t*) _counter {
+  return [[StaticFuncTestObj alloc] initWithCounter: _counter];
+}
+
+- (instancetype)initWithCounter:(int32_t*) _counter {
+  counter = _counter;
+  ++*counter;
+  return [super init];
+}
+
+- (void)setCounter:(int32_t*) _counter {
+  counter = _counter;
+  ++*counter;
+}
+
+- (void)dealloc {
+  if (counter != nil) --*counter;
+  [super dealloc];
+}
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/string_config.yaml b/pkgs/ffigen/test/native_objc_test/string_config.yaml
new file mode 100644
index 0000000..016b2bd
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/string_config.yaml
@@ -0,0 +1,13 @@
+name: StringTestObjCLibrary
+description: 'Tests calling Objective-C string methods'
+language: objc
+output: 'string_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - StringUtil
+headers:
+  entry-points:
+    - 'string_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/string_test.dart b/pkgs/ffigen/test/native_objc_test/string_test.dart
new file mode 100644
index 0000000..068e5ed
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/string_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'string_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late StringTestObjCLibrary lib;
+
+  group('string', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/string_test.dylib');
+      verifySetupFile(dylib);
+      lib = StringTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('string');
+    });
+
+    for (final s in ['Hello', '🇵🇬', 'Embedded\u0000Null']) {
+      test('NSString to/from Dart string [$s]', () {
+        final ns1 = NSString(lib, s);
+        expect(ns1.length, s.length);
+        expect(ns1.toString().length, s.length);
+        expect(ns1.toString(), s);
+
+        final ns2 = s.toNSString(lib);
+        expect(ns2.length, s.length);
+        expect(ns2.toString().length, s.length);
+        expect(ns2.toString(), s);
+      });
+    }
+
+    test('strings usable', () {
+      final str1 = 'Hello'.toNSString(lib);
+      final str2 = 'World!'.toNSString(lib);
+
+      final str3 = StringUtil.strConcat_with_(lib, str1, str2);
+      expect(str3.length, 11);
+      expect(str3.toString(), "HelloWorld!");
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/string_test.m b/pkgs/ffigen/test/native_objc_test/string_test.m
new file mode 100644
index 0000000..4184c14
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/string_test.m
@@ -0,0 +1,15 @@
+#import <Foundation/NSObject.h>
+#import <Foundation/NSString.h>
+
+// TODO(https://github.com/dart-lang/ffigen/issues/309): strConcat should just
+// be a static function.
+@interface StringUtil : NSObject {
+}
++ (NSString *)strConcat:(NSString *)a with:(NSString *)b;
+@end
+
+@implementation StringUtil
++ (NSString *)strConcat:(NSString *)a with:(NSString *)b {
+  return [a stringByAppendingString:b];
+}
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/swift_class_config.yaml b/pkgs/ffigen/test/native_objc_test/swift_class_config.yaml
new file mode 100644
index 0000000..20bd288
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/swift_class_config.yaml
@@ -0,0 +1,15 @@
+name: SwiftClassTestLibrary
+description: 'Tests Swift classes'
+language: objc
+output: 'swift_class_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - MySwiftClass
+  module:
+    'MySwiftClass': 'swift_class_test'
+headers:
+  entry-points:
+    - 'swift_class_test-Swift.h'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/swift_class_test.dart b/pkgs/ffigen/test/native_objc_test/swift_class_test.dart
new file mode 100644
index 0000000..09a2714
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/swift_class_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'swift_class_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late SwiftClassTestLibrary lib;
+  group('swift_class_test', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/swift_class_test.dylib');
+      verifySetupFile(dylib);
+      lib = SwiftClassTestLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('swift_class');
+    });
+
+    test('Renamed class', () {
+      final swiftObject = MySwiftClass.new1(lib);
+      expect(swiftObject.getValue(), 123);
+      swiftObject.setValueWithX_(456);
+      expect(swiftObject.getValue(), 456);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/swift_class_test.swift b/pkgs/ffigen/test/native_objc_test/swift_class_test.swift
new file mode 100644
index 0000000..26ae016
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/swift_class_test.swift
@@ -0,0 +1,11 @@
+import Foundation
+
+@objc public class MySwiftClass: NSObject {
+  var val = 123;
+  @objc public func getValue() -> Int {
+    return val;
+  }
+  @objc public func setValue(x: Int) {
+    val = x;
+  }
+}
diff --git a/pkgs/ffigen/test/native_objc_test/typedef_config.yaml b/pkgs/ffigen/test/native_objc_test/typedef_config.yaml
new file mode 100644
index 0000000..f375bfc
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/typedef_config.yaml
@@ -0,0 +1,17 @@
+name: TypedefTestObjCLibrary
+description: 'Tests typedef'
+language: objc
+output: 'typedef_bindings.dart'
+exclude-all-by-default: true
+objc-interfaces:
+  include:
+    - SomeClass
+    - AnotherClass
+typedefs:
+  include:
+    - SomeClassPtr
+headers:
+  entry-points:
+    - 'typedef_test.m'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field
diff --git a/pkgs/ffigen/test/native_objc_test/typedef_test.dart b/pkgs/ffigen/test/native_objc_test/typedef_test.dart
new file mode 100644
index 0000000..7a47fdb
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/typedef_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Objective C support is only available on mac.
+@TestOn('mac-os')
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import 'typedef_bindings.dart';
+import 'util.dart';
+
+void main() {
+  late TypedefTestObjCLibrary lib;
+
+  group('typedef', () {
+    setUpAll(() {
+      logWarnings();
+      final dylib = File('test/native_objc_test/typedef_test.dylib');
+      verifySetupFile(dylib);
+      lib = TypedefTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+      generateBindingsForCoverage('typedef');
+    });
+
+    test('Regression test for #386', () {
+      // https://github.com/dart-lang/ffigen/issues/386
+      // Make sure that the typedef DartSomeClassPtr is for SomeClass.
+      final DartSomeClassPtr instance = SomeClass.new1(lib);
+      expect(instance.pointer, isNot(nullptr));
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_objc_test/typedef_test.m b/pkgs/ffigen/test/native_objc_test/typedef_test.m
new file mode 100644
index 0000000..c5972ab
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/typedef_test.m
@@ -0,0 +1,20 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#import <Foundation/NSObject.h>
+
+@interface SomeClass : NSObject {}
+@end
+
+@implementation SomeClass
+@end
+
+typedef SomeClass* SomeClassPtr;
+
+@interface AnotherClass : NSObject {}
+@property SomeClassPtr property;
+@end
+
+@implementation AnotherClass
+@end
diff --git a/pkgs/ffigen/test/native_objc_test/util.dart b/pkgs/ffigen/test/native_objc_test/util.dart
new file mode 100644
index 0000000..7ef14bf
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/util.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:ffigen/ffigen.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+void generateBindingsForCoverage(String testName) {
+  // The ObjC test bindings are generated in setup.dart (see #362), which means
+  // that the ObjC related bits of ffigen are missed by test coverage. So this
+  // function just regenerates those bindings. It doesn't test anything except
+  // that the generation succeeded, by asserting the file exists.
+  final config = testConfig(
+      File(path.join('test', 'native_objc_test', '${testName}_config.yaml'))
+          .readAsStringSync());
+  final library = parse(config);
+  final file = File(
+    path.join('test', 'debug_generated', '${testName}_test.dart'),
+  );
+  library.generateFile(file);
+  assert(file.existsSync());
+  file.delete();
+}
diff --git a/pkgs/ffigen/test/native_objc_test/util.h b/pkgs/ffigen/test/native_objc_test/util.h
new file mode 100644
index 0000000..0694aea
--- /dev/null
+++ b/pkgs/ffigen/test/native_objc_test/util.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef _TEST_UTIL_H_
+#define _TEST_UTIL_H_
+
+typedef struct {
+  void* isa;
+  int flags;
+  // There are other fields, but we just need the flags and isa.
+} BlockRefCountExtractor;
+
+static void* valid_block_isa = NULL;
+uint64_t getBlockRetainCount(void* block) {
+  BlockRefCountExtractor* b = (BlockRefCountExtractor*)block;
+  // HACK: The only way I can find to reliably figure out that a block has been
+  // deleted is to check the isa field (the lower bits of the flags field seem
+  // to be randomized, not just set to 0). But we also don't know the value this
+  // field has when it's constructed (copying the block changes it from
+  // _NSConcreteGlobalBlock to an internal value). So we assume that the first
+  // time this function is called, we have a valid block, and on subsequent
+  // calls we check to see if the isa field changed.
+  if (valid_block_isa == NULL) {
+    valid_block_isa = b->isa;
+  }
+  if (b->isa != valid_block_isa) {
+    return 0;
+  }
+  // The ref count is stored in the lower bits of the flags field, but skips the
+  // 0x1 bit.
+  return (b->flags & 0xFFFF) >> 1;
+}
+
+#endif  // _TEST_UTIL_H_
diff --git a/pkgs/ffigen/test/native_test/.gitignore b/pkgs/ffigen/test/native_test/.gitignore
new file mode 100644
index 0000000..d97e2fc
--- /dev/null
+++ b/pkgs/ffigen/test/native_test/.gitignore
@@ -0,0 +1,3 @@
+# Ignore files generated by clang on windows.
+native_test.exp
+native_test.lib
diff --git a/pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart b/pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart
new file mode 100644
index 0000000..58934cf
--- /dev/null
+++ b/pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart
@@ -0,0 +1,264 @@
+// ignore_for_file: camel_case_types, non_constant_identifier_names
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+/// Native tests.
+class NativeLibrary {
+  /// Holds the symbol lookup function.
+  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+      _lookup;
+
+  /// The symbols are looked up in [dynamicLibrary].
+  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
+      : _lookup = dynamicLibrary.lookup;
+
+  /// The symbols are looked up with [lookup].
+  NativeLibrary.fromLookup(
+      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
+          lookup)
+      : _lookup = lookup;
+
+  bool Function1Bool(
+    bool x,
+  ) {
+    return _Function1Bool(
+      x,
+    );
+  }
+
+  late final _Function1BoolPtr =
+      _lookup<ffi.NativeFunction<ffi.Bool Function(ffi.Bool)>>('Function1Bool');
+  late final _Function1Bool =
+      _Function1BoolPtr.asFunction<bool Function(bool)>();
+
+  int Function1Uint8(
+    int x,
+  ) {
+    return _Function1Uint8(
+      x,
+    );
+  }
+
+  late final _Function1Uint8Ptr =
+      _lookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Uint8)>>(
+          'Function1Uint8');
+  late final _Function1Uint8 =
+      _Function1Uint8Ptr.asFunction<int Function(int)>();
+
+  int Function1Uint16(
+    int x,
+  ) {
+    return _Function1Uint16(
+      x,
+    );
+  }
+
+  late final _Function1Uint16Ptr =
+      _lookup<ffi.NativeFunction<ffi.Uint16 Function(ffi.Uint16)>>(
+          'Function1Uint16');
+  late final _Function1Uint16 =
+      _Function1Uint16Ptr.asFunction<int Function(int)>();
+
+  int Function1Uint32(
+    int x,
+  ) {
+    return _Function1Uint32(
+      x,
+    );
+  }
+
+  late final _Function1Uint32Ptr =
+      _lookup<ffi.NativeFunction<ffi.Uint32 Function(ffi.Uint32)>>(
+          'Function1Uint32');
+  late final _Function1Uint32 =
+      _Function1Uint32Ptr.asFunction<int Function(int)>();
+
+  int Function1Uint64(
+    int x,
+  ) {
+    return _Function1Uint64(
+      x,
+    );
+  }
+
+  late final _Function1Uint64Ptr =
+      _lookup<ffi.NativeFunction<ffi.Uint64 Function(ffi.Uint64)>>(
+          'Function1Uint64');
+  late final _Function1Uint64 =
+      _Function1Uint64Ptr.asFunction<int Function(int)>();
+
+  int Function1Int8(
+    int x,
+  ) {
+    return _Function1Int8(
+      x,
+    );
+  }
+
+  late final _Function1Int8Ptr =
+      _lookup<ffi.NativeFunction<ffi.Int8 Function(ffi.Int8)>>('Function1Int8');
+  late final _Function1Int8 = _Function1Int8Ptr.asFunction<int Function(int)>();
+
+  int Function1Int16(
+    int x,
+  ) {
+    return _Function1Int16(
+      x,
+    );
+  }
+
+  late final _Function1Int16Ptr =
+      _lookup<ffi.NativeFunction<ffi.Int16 Function(ffi.Int16)>>(
+          'Function1Int16');
+  late final _Function1Int16 =
+      _Function1Int16Ptr.asFunction<int Function(int)>();
+
+  int Function1Int32(
+    int x,
+  ) {
+    return _Function1Int32(
+      x,
+    );
+  }
+
+  late final _Function1Int32Ptr =
+      _lookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Int32)>>(
+          'Function1Int32');
+  late final _Function1Int32 =
+      _Function1Int32Ptr.asFunction<int Function(int)>();
+
+  int Function1Int64(
+    int x,
+  ) {
+    return _Function1Int64(
+      x,
+    );
+  }
+
+  late final _Function1Int64Ptr =
+      _lookup<ffi.NativeFunction<ffi.Int64 Function(ffi.Int64)>>(
+          'Function1Int64');
+  late final _Function1Int64 =
+      _Function1Int64Ptr.asFunction<int Function(int)>();
+
+  int Function1IntPtr(
+    int x,
+  ) {
+    return _Function1IntPtr(
+      x,
+    );
+  }
+
+  late final _Function1IntPtrPtr =
+      _lookup<ffi.NativeFunction<ffi.IntPtr Function(ffi.IntPtr)>>(
+          'Function1IntPtr');
+  late final _Function1IntPtr =
+      _Function1IntPtrPtr.asFunction<int Function(int)>();
+
+  int Function1UintPtr(
+    int x,
+  ) {
+    return _Function1UintPtr(
+      x,
+    );
+  }
+
+  late final _Function1UintPtrPtr =
+      _lookup<ffi.NativeFunction<ffi.UintPtr Function(ffi.UintPtr)>>(
+          'Function1UintPtr');
+  late final _Function1UintPtr =
+      _Function1UintPtrPtr.asFunction<int Function(int)>();
+
+  double Function1Float(
+    double x,
+  ) {
+    return _Function1Float(
+      x,
+    );
+  }
+
+  late final _Function1FloatPtr =
+      _lookup<ffi.NativeFunction<ffi.Float Function(ffi.Float)>>(
+          'Function1Float');
+  late final _Function1Float =
+      _Function1FloatPtr.asFunction<double Function(double)>();
+
+  double Function1Double(
+    double x,
+  ) {
+    return _Function1Double(
+      x,
+    );
+  }
+
+  late final _Function1DoublePtr =
+      _lookup<ffi.NativeFunction<ffi.Double Function(ffi.Double)>>(
+          'Function1Double');
+  late final _Function1Double =
+      _Function1DoublePtr.asFunction<double Function(double)>();
+
+  ffi.Pointer<Struct1> getStruct1() {
+    return _getStruct1();
+  }
+
+  late final _getStruct1Ptr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<Struct1> Function()>>(
+          'getStruct1');
+  late final _getStruct1 =
+      _getStruct1Ptr.asFunction<ffi.Pointer<Struct1> Function()>();
+
+  Struct3 Function1StructReturnByValue(
+    int a,
+    int b,
+    int c,
+  ) {
+    return _Function1StructReturnByValue(
+      a,
+      b,
+      c,
+    );
+  }
+
+  late final _Function1StructReturnByValuePtr =
+      _lookup<ffi.NativeFunction<Struct3 Function(ffi.Int, ffi.Int, ffi.Int)>>(
+          'Function1StructReturnByValue');
+  late final _Function1StructReturnByValue = _Function1StructReturnByValuePtr
+      .asFunction<Struct3 Function(int, int, int)>();
+
+  int Function1StructPassByValue(
+    Struct3 sum_a_b_c,
+  ) {
+    return _Function1StructPassByValue(
+      sum_a_b_c,
+    );
+  }
+
+  late final _Function1StructPassByValuePtr =
+      _lookup<ffi.NativeFunction<ffi.Int Function(Struct3)>>(
+          'Function1StructPassByValue');
+  late final _Function1StructPassByValue =
+      _Function1StructPassByValuePtr.asFunction<int Function(Struct3)>();
+}
+
+final class Struct1 extends ffi.Struct {
+  @ffi.Int8()
+  external int a;
+
+  @ffi.Array.multi([3, 1, 2])
+  external ffi.Array<ffi.Array<ffi.Array<ffi.Int32>>> data;
+}
+
+final class Struct3 extends ffi.Struct {
+  @ffi.Int()
+  external int a;
+
+  @ffi.Int()
+  external int b;
+
+  @ffi.Int()
+  external int c;
+}
diff --git a/pkgs/ffigen/test/native_test/build_test_dylib.dart b/pkgs/ffigen/test/native_test/build_test_dylib.dart
new file mode 100644
index 0000000..a41f686
--- /dev/null
+++ b/pkgs/ffigen/test/native_test/build_test_dylib.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// =======================================================================
+/// ==== Script to generate dynamic library for native_function_tests =====
+/// =======================================================================
+/// This Script effectively calls the following (but user can provide
+/// command line args which will replace the defaults shown below)-
+///
+/// Linux:
+/// ```
+/// clang -shared -fpic native_test.c -o native_test.so
+/// ```
+/// MacOS:
+/// ```
+/// clang -shared -fpic native_test.c -o native_test.dylib
+/// ```
+/// Windows:
+/// ```
+/// call clang -shared native_test.c -o native_test.dll -Wl,"/DEF:native_test.def"
+/// del native_test.exp
+/// del native_test.lib
+/// ```
+/// =======================================================================
+/// =======================================================================
+/// =======================================================================
+
+import 'dart:io';
+
+const macOS = 'macos';
+const windows = 'windows';
+const linux = 'linux';
+
+Map<String, Options> platformOptions = {
+  linux: Options(
+    outputfilename: 'native_test.so',
+    sharedFlag: '-shared',
+    inputHeader: 'native_test.c',
+    fPIC: '-fpic',
+  ),
+  windows: Options(
+    outputfilename: 'native_test.dll',
+    sharedFlag: '-shared',
+    inputHeader: 'native_test.c',
+    moduleDefPath: '-Wl,/DEF:native_test.def',
+  ),
+  macOS: Options(
+    outputfilename: 'native_test.dylib',
+    sharedFlag: '-shared',
+    inputHeader: 'native_test.c',
+    fPIC: '-fpic',
+  ),
+};
+
+void main(List<String> arguments) {
+  print('Building Dynamic Library for Native Tests... ');
+  final options = getPlatformOptions()!;
+
+  // Run clang compiler to generate the dynamic library.
+  final processResult = runClangProcess(options);
+  printSuccess(processResult, options);
+}
+
+/// Calls the clang compiler.
+ProcessResult runClangProcess(Options options) {
+  final result = Process.runSync(
+    'clang',
+    [
+      options.sharedFlag,
+      options.fPIC,
+      options.inputHeader,
+      '-o',
+      options.outputfilename,
+      options.moduleDefPath,
+      '-Wno-nullability-completeness',
+    ],
+  );
+  return result;
+}
+
+/// Prints success message (or process error if any).
+void printSuccess(ProcessResult result, Options options) {
+  print(result.stdout);
+  if ((result.stderr as String).isEmpty) {
+    print('Generated file: ${options.outputfilename}');
+  } else {
+    print(result.stderr);
+  }
+}
+
+/// Get options based on current platform.
+Options? getPlatformOptions() {
+  if (Platform.isMacOS) {
+    return platformOptions[macOS];
+  } else if (Platform.isWindows) {
+    return platformOptions[windows];
+  } else if (Platform.isLinux) {
+    return platformOptions[linux];
+  } else {
+    throw Exception('Unknown Platform.');
+  }
+}
+
+/// Hold options which would be passed to clang.
+class Options {
+  /// Name of dynamic library to generate.
+  final String outputfilename;
+
+  /// Tells compiler to generate a shared library.
+  final String sharedFlag;
+
+  /// Flag for generating Position Independant Code (Not used on windows).
+  final String fPIC;
+
+  /// Input file.
+  final String inputHeader;
+
+  /// Path to `.def` file containing symbols to export, windows use only.
+  final String moduleDefPath;
+
+  Options({
+    required this.outputfilename,
+    required this.sharedFlag,
+    required this.inputHeader,
+    this.fPIC = '',
+    this.moduleDefPath = '',
+  });
+}
diff --git a/pkgs/ffigen/test/native_test/config.yaml b/pkgs/ffigen/test/native_test/config.yaml
new file mode 100644
index 0000000..3942f6f
--- /dev/null
+++ b/pkgs/ffigen/test/native_test/config.yaml
@@ -0,0 +1,21 @@
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# =================== GENERATING TEST BINDINGS ==================
+#    dart run ffigen --config test/native_test/config.yaml
+# ===============================================================
+
+name: NativeLibrary
+description: 'Native tests.'
+output: '_expected_native_test_bindings.dart'
+headers:
+  entry-points:
+    - 'native_test.c'
+  include-directives:
+    - '**native_test.c'
+
+compiler-opts: '-Wno-nullability-completeness'
+preamble: |
+  // ignore_for_file: camel_case_types, non_constant_identifier_names
+
diff --git a/pkgs/ffigen/test/native_test/native_test.c b/pkgs/ffigen/test/native_test/native_test.c
new file mode 100644
index 0000000..f971ac6
--- /dev/null
+++ b/pkgs/ffigen/test/native_test/native_test.c
@@ -0,0 +1,74 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+#define aloc(T) ((T *)malloc(sizeof(T)))
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+bool Function1Bool(bool x) { return !x; }
+
+uint8_t Function1Uint8(uint8_t x) { return x + 42; }
+
+uint16_t Function1Uint16(uint16_t x) { return x + 42; }
+
+uint32_t Function1Uint32(uint32_t x) { return x + 42; }
+
+uint64_t Function1Uint64(uint64_t x) { return x + 42; }
+
+int8_t Function1Int8(int8_t x) { return x + 42; }
+
+int16_t Function1Int16(int16_t x) { return x + 42; }
+
+int32_t Function1Int32(int32_t x) { return x + 42; }
+
+int64_t Function1Int64(int64_t x) { return x + 42; }
+
+intptr_t Function1IntPtr(intptr_t x) { return x + 42; }
+
+uintptr_t Function1UintPtr(uintptr_t x) { return x + 42; }
+
+float Function1Float(float x) { return x + 42.0f; }
+
+double Function1Double(double x) { return x + 42.0; }
+
+struct Struct1
+{
+    int8_t a;
+    int32_t data[3][1][2];
+};
+
+struct Struct1 *getStruct1()
+{
+    struct Struct1 *s = aloc(struct Struct1);
+    s->a = 0;
+    s->data[0][0][0] = 1;
+    s->data[0][0][1] = 2;
+    s->data[1][0][0] = 3;
+    s->data[1][0][1] = 4;
+    s->data[2][0][0] = 5;
+    s->data[2][0][1] = 6;
+    return s;
+}
+
+struct Struct3
+{
+    int a;
+    int b;
+    int c;
+};
+
+struct Struct3 Function1StructReturnByValue(int a, int b, int c)
+{
+    struct Struct3 s;
+    s.a = a;
+    s.b = b;
+    s.c = c;
+    return s;
+}
+
+int Function1StructPassByValue(struct Struct3 sum_a_b_c)
+{
+    return sum_a_b_c.a + sum_a_b_c.b + sum_a_b_c.c;
+}
diff --git a/pkgs/ffigen/test/native_test/native_test.dart b/pkgs/ffigen/test/native_test/native_test.dart
new file mode 100644
index 0000000..9c734a5
--- /dev/null
+++ b/pkgs/ffigen/test/native_test/native_test.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+import 'dart:io';
+import 'dart:math';
+
+import 'package:ffigen/ffigen.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+import '../test_utils.dart';
+import '_expected_native_test_bindings.dart';
+
+void main() {
+  late NativeLibrary bindings;
+  group('native_test', () {
+    setUpAll(() {
+      logWarnings();
+      var dylibName = 'test/native_test/native_test.so';
+      if (Platform.isMacOS) {
+        dylibName = 'test/native_test/native_test.dylib';
+      } else if (Platform.isWindows) {
+        dylibName = r'test\native_test\native_test.dll';
+      }
+      final dylib = File(dylibName);
+      verifySetupFile(dylib);
+      bindings = NativeLibrary(DynamicLibrary.open(dylib.absolute.path));
+    });
+
+    test('generate_bindings', () {
+      final configFile =
+          File(path.join('test', 'native_test', 'config.yaml')).absolute;
+      final outFile = File(
+        path.join(
+            'test', 'debug_generated', '_expected_native_test_bindings.dart'),
+      ).absolute;
+
+      late Config config;
+      withChDir(configFile.path, () {
+        config = testConfigFromPath(configFile.path);
+      });
+      final library = parse(config);
+
+      library.generateFile(outFile);
+
+      try {
+        final actual = outFile.readAsStringSync().replaceAll('\r', '');
+        final expected = File(path.join(config.output))
+            .readAsStringSync()
+            .replaceAll('\r', '');
+        expect(actual, expected);
+        if (outFile.existsSync()) {
+          outFile.delete();
+        }
+      } catch (e) {
+        print('Failed test: Debug generated file: ${outFile.absolute.path}');
+        rethrow;
+      }
+    });
+
+    test('bool', () {
+      expect(bindings.Function1Bool(true), false);
+      expect(bindings.Function1Bool(false), true);
+    });
+    test('uint8_t', () {
+      expect(bindings.Function1Uint8(pow(2, 8).toInt()), 42);
+    });
+    test('uint16_t', () {
+      expect(bindings.Function1Uint16(pow(2, 16).toInt()), 42);
+    });
+    test('uint32_t', () {
+      expect(bindings.Function1Uint32(pow(2, 32).toInt()), 42);
+    });
+    test('uint64_t', () {
+      expect(bindings.Function1Uint64(pow(2, 64).toInt()), 42);
+    });
+    test('int8_t', () {
+      expect(
+          bindings.Function1Int8(pow(2, 7).toInt()), -pow(2, 7).toInt() + 42);
+    });
+    test('int16_t', () {
+      expect(bindings.Function1Int16(pow(2, 15).toInt()),
+          -pow(2, 15).toInt() + 42);
+    });
+    test('int32_t', () {
+      expect(bindings.Function1Int32(pow(2, 31).toInt()),
+          -pow(2, 31).toInt() + 42);
+    });
+    test('int64_t', () {
+      expect(bindings.Function1Int64(pow(2, 63).toInt()),
+          -pow(2, 63).toInt() + 42);
+    });
+    test('intptr_t', () {
+      expect(bindings.Function1IntPtr(0), 42);
+    });
+    test('float', () {
+      expect(bindings.Function1Float(0), 42.0);
+    });
+    test('double', () {
+      expect(bindings.Function1Double(0), 42.0);
+    });
+    test('Array Test: Order of access', () {
+      final struct1 = bindings.getStruct1();
+      var expectedValue = 1;
+      final dimensions = [3, 1, 2];
+      for (var i = 0; i < dimensions[0]; i++) {
+        for (var j = 0; j < dimensions[1]; j++) {
+          for (var k = 0; k < dimensions[2]; k++) {
+            expect(struct1.ref.data[i][j][k], expectedValue);
+            expectedValue++;
+          }
+        }
+      }
+    });
+
+    test('Array Workaround: Range Errors', () {
+      final struct1 = bindings.getStruct1();
+      // Index (get) above range.
+      expect(
+          () => struct1.ref.data[4][0][0], throwsA(TypeMatcher<RangeError>()));
+      expect(
+          () => struct1.ref.data[0][2][0], throwsA(TypeMatcher<RangeError>()));
+      expect(
+          () => struct1.ref.data[0][0][3], throwsA(TypeMatcher<RangeError>()));
+      // Index (get) below range.
+      expect(
+          () => struct1.ref.data[-1][0][0], throwsA(TypeMatcher<RangeError>()));
+      expect(
+          () => struct1.ref.data[-1][0][0], throwsA(TypeMatcher<RangeError>()));
+      expect(
+          () => struct1.ref.data[0][0][-1], throwsA(TypeMatcher<RangeError>()));
+
+      // Index (set) above range.
+      expect(() => struct1.ref.data[4][0][0] = 0,
+          throwsA(TypeMatcher<RangeError>()));
+      expect(() => struct1.ref.data[0][2][0] = 0,
+          throwsA(TypeMatcher<RangeError>()));
+      expect(() => struct1.ref.data[0][0][3] = 0,
+          throwsA(TypeMatcher<RangeError>()));
+      // Index (get) below range.
+      expect(() => struct1.ref.data[-1][0][0] = 0,
+          throwsA(TypeMatcher<RangeError>()));
+      expect(() => struct1.ref.data[-1][0][0] = 0,
+          throwsA(TypeMatcher<RangeError>()));
+      expect(() => struct1.ref.data[0][0][-1] = 0,
+          throwsA(TypeMatcher<RangeError>()));
+    });
+    test('Struct By Value', () {
+      final r = Random();
+      final a = r.nextInt(100), b = r.nextInt(100), c = r.nextInt(100);
+      final s = bindings.Function1StructReturnByValue(a, b, c);
+      expect(bindings.Function1StructPassByValue(s), a + b + c);
+    });
+  });
+}
diff --git a/pkgs/ffigen/test/native_test/native_test.def b/pkgs/ffigen/test/native_test/native_test.def
new file mode 100644
index 0000000..b6bf2e0
--- /dev/null
+++ b/pkgs/ffigen/test/native_test/native_test.def
@@ -0,0 +1,20 @@
+; Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+; for details. All rights reserved. Use of this source code is governed by a
+; BSD-style license that can be found in the LICENSE file.
+
+EXPORTS
+Function1Bool
+Function1Uint8
+Function1Uint16
+Function1Uint32
+Function1Uint64
+Function1Int8
+Function1Int16
+Function1Int32
+Function1Int64
+Function1IntPtr
+Function1Float
+Function1Double
+getStruct1
+Function1StructReturnByValue
+Function1StructPassByValue
diff --git a/pkgs/ffigen/test/regen.dart b/pkgs/ffigen/test/regen.dart
new file mode 100644
index 0000000..ec52964
--- /dev/null
+++ b/pkgs/ffigen/test/regen.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:ffigen/ffigen.dart';
+import 'package:logging/logging.dart';
+import 'test_utils.dart';
+
+const usage = r'''Regenerates the Dart FFI bindings used in tests and examples.
+
+Use this command when developing features that change the generated bindings
+e.g. with this command:
+
+$ dart run test/setup.dart && dart run test/regen.dart && dart test
+''';
+
+void _regenConfig(String yamlConfigPath, String bindingOutputPath) {
+  final yamlConfig = File(yamlConfigPath).absolute;
+  final bindingOutput = File(bindingOutputPath).absolute;
+  withChDir(yamlConfig.path, () {
+    final config = testConfigFromPath(yamlConfig.path);
+    final library = parse(config);
+    library.generateFile(bindingOutput);
+  });
+}
+
+Future<void> main(List<String> args) async {
+  final parser = ArgParser();
+  parser.addSeparator(usage);
+  parser.addFlag(
+    'help',
+    abbr: 'h',
+    help: 'Prints this usage',
+    negatable: false,
+  );
+
+  final parseArgs = parser.parse(args);
+  if (parseArgs.wasParsed('help')) {
+    print(parser.usage);
+    exit(0);
+  } else if (parseArgs.rest.isNotEmpty) {
+    print(parser.usage);
+    exit(1);
+  }
+
+  Logger.root.level = Level.WARNING;
+  Logger.root.onRecord.listen((record) {
+    print('${record.level.name}: ${record.time}: ${record.message}');
+  });
+
+  _regenConfig('test/native_test/config.yaml',
+      'test/native_test/_expected_native_test_bindings.dart');
+  _regenConfig('example/libclang-example/config.yaml',
+      'example/libclang-example/generated_bindings.dart');
+  _regenConfig(
+      'example/simple/config.yaml', 'example/simple/generated_bindings.dart');
+  _regenConfig('example/c_json/config.yaml',
+      'example/c_json/cjson_generated_bindings.dart');
+}
diff --git a/pkgs/ffigen/test/rename_tests/rename.h b/pkgs/ffigen/test/rename_tests/rename.h
new file mode 100644
index 0000000..71ec5bc
--- /dev/null
+++ b/pkgs/ffigen/test/rename_tests/rename.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#define Macro1 1
+#define Test_Macro2 2
+#define FullMatchMacro3 3
+
+struct Struct1
+{
+};
+struct Test_Struct2
+{
+};
+struct FullMatchStruct3
+{
+};
+struct MemberRenameStruct4
+{
+    int _underscore;
+    float fullMatch;
+};
+
+struct AnyMatchStruct5
+{
+    int _underscore;
+};
+
+typedef struct Struct5{
+    int a;
+} Struct5_Alias;
+
+void func1(struct Struct1 *s);
+void test_func2(struct Test_Struct2 *s);
+void fullMatch_func3(struct FullMatchStruct3 *s);
+void memberRename_func4(int _underscore, float fullMatch, int);
+void typedefRenameFunc(Struct5_Alias s);
+
+enum Enum1
+{
+    a = 0,
+    b = 1,
+    c = 2
+};
+enum Test_Enum2
+{
+    e = 0,
+    f = 1,
+    g = 2
+};
+enum FullMatchEnum3
+{
+    i = 0,
+    j = 1,
+    k = 2
+};
+enum MemberRenameEnum4
+{
+    _underscore = 0,
+    fullMatch = 1
+};
+enum
+{
+    _unnamed_underscore = 0,
+    unnamedFullMatch = 1
+};
diff --git a/pkgs/ffigen/test/rename_tests/rename_test.dart b/pkgs/ffigen/test/rename_tests/rename_test.dart
new file mode 100644
index 0000000..24a136a
--- /dev/null
+++ b/pkgs/ffigen/test/rename_tests/rename_test.dart
@@ -0,0 +1,326 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser.dart' as parser;
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:test/test.dart';
+
+import '../test_utils.dart';
+
+late Library actual, expected;
+final functionPrefix = 'fff';
+final structPrefix = 'sss';
+final enumPrefix = 'eee';
+final macroPrefix = 'mmm';
+
+void main() {
+  group('rename_test', () {
+    setUpAll(() {
+      logWarnings();
+      expected = expectedLibrary();
+      actual = parser.parse(testConfig('''
+${strings.name}: 'NativeLibrary'
+${strings.description}: 'Rename Test'
+${strings.output}: 'unused'
+
+${strings.headers}:
+  ${strings.entryPoints}:
+    - 'test/rename_tests/rename.h'
+
+${strings.functions}:
+  ${strings.rename}:
+    'test_(.*)': '\$1'
+    '.*': '$functionPrefix\$0'
+    'fullMatch_func3': 'func3'
+  ${strings.memberRename}:
+    'memberRename_.*':
+      '_(.*)': '\$1'
+      'fullMatch': 'fullMatchSuccess'
+      '': 'unnamed'
+
+${strings.structs}:
+  ${strings.rename}:
+    'Test_(.*)': '\$1'
+    '.*': '$structPrefix\$0'
+    'FullMatchStruct3': 'Struct3'
+  ${strings.memberRename}:
+    'MemberRenameStruct4':
+      '_(.*)': '\$1'
+      'fullMatch': 'fullMatchSuccess'
+    '.*':
+      '_(.*)': '\$1'
+
+${strings.enums}:
+  ${strings.rename}:
+    'Test_(.*)': '\$1'
+    '.*': '$enumPrefix\$0'
+    'FullMatchEnum3': 'Enum3'
+  ${strings.memberRename}:
+    'MemberRenameEnum4':
+      '_(.*)': '\$1'
+      'fullMatch': 'fullMatchSuccess'
+
+${strings.unnamedEnums}:
+  ${strings.rename}:
+    '_(.*)': '\$1'
+    'unnamedFullMatch': 'unnamedFullMatchSuccess'
+
+${strings.macros}:
+  ${strings.rename}:
+    'Test_(.*)': '\$1'
+    '.*': '$macroPrefix\$0'
+    'FullMatchMacro3': 'Macro3'
+
+${strings.typedefs}:
+  ${strings.rename}:
+    'Struct5_Alias': 'Struct5_Alias_Renamed'
+    '''));
+    });
+
+    test('Function addPrefix', () {
+      expect(actual.getBindingAsString('${functionPrefix}func1'),
+          expected.getBindingAsString('${functionPrefix}func1'));
+    });
+    test('Struct addPrefix', () {
+      expect(actual.getBindingAsString('${structPrefix}Struct1'),
+          expected.getBindingAsString('${structPrefix}Struct1'));
+    });
+    test('Enum addPrefix', () {
+      expect(actual.getBindingAsString('${enumPrefix}Enum1'),
+          expected.getBindingAsString('${enumPrefix}Enum1'));
+    });
+    test('Macro addPrefix', () {
+      expect(actual.getBindingAsString('${macroPrefix}Macro1'),
+          expected.getBindingAsString('${macroPrefix}Macro1'));
+    });
+    test('Function rename with pattern', () {
+      expect(actual.getBindingAsString('func2'),
+          expected.getBindingAsString('func2'));
+    });
+    test('Struct rename with pattern', () {
+      expect(actual.getBindingAsString('Struct2'),
+          expected.getBindingAsString('Struct2'));
+    });
+    test('Enum rename with pattern', () {
+      expect(actual.getBindingAsString('Enum2'),
+          expected.getBindingAsString('Enum2'));
+    });
+    test('Macro rename with pattern', () {
+      expect(actual.getBindingAsString('Macro2'),
+          expected.getBindingAsString('Macro2'));
+    });
+    test('Function full match rename', () {
+      expect(actual.getBindingAsString('func3'),
+          expected.getBindingAsString('func3'));
+    });
+    test('Struct full match rename', () {
+      expect(actual.getBindingAsString('Struct3'),
+          expected.getBindingAsString('Struct3'));
+    });
+    test('Enum full match rename', () {
+      expect(actual.getBindingAsString('Enum3'),
+          expected.getBindingAsString('Enum3'));
+    });
+    test('Macro full match rename', () {
+      expect(actual.getBindingAsString('Macro3'),
+          expected.getBindingAsString('Macro3'));
+    });
+    test('Struct member rename', () {
+      expect(actual.getBindingAsString('${structPrefix}MemberRenameStruct4'),
+          expected.getBindingAsString('${structPrefix}MemberRenameStruct4'));
+    });
+    test('Any Struct member rename', () {
+      expect(actual.getBindingAsString('${structPrefix}AnyMatchStruct5'),
+          expected.getBindingAsString('${structPrefix}AnyMatchStruct5'));
+    });
+    test('Function member rename', () {
+      expect(actual.getBindingAsString('${functionPrefix}memberRename_func4'),
+          expected.getBindingAsString('${functionPrefix}memberRename_func4'));
+    });
+    test('Enum member rename', () {
+      expect(actual.getBindingAsString('${enumPrefix}MemberRenameEnum4'),
+          expected.getBindingAsString('${enumPrefix}MemberRenameEnum4'));
+    });
+    test('unnamed Enum regexp rename', () {
+      expect(actual.getBindingAsString('unnamed_underscore'),
+          expected.getBindingAsString('unnamed_underscore'));
+    });
+    test('unnamed Enum full match rename', () {
+      expect(actual.getBindingAsString('unnamedFullMatchSuccess'),
+          expected.getBindingAsString('unnamedFullMatchSuccess'));
+    });
+    test('typedef rename', () {
+      expect(actual.getBindingAsString('Struct5_Alias_Renamed'),
+          expected.getBindingAsString('Struct5_Alias_Renamed'));
+    });
+  });
+}
+
+Library expectedLibrary() {
+  final struct1 = Struct(name: '${structPrefix}Struct1');
+  final struct2 = Struct(name: 'Struct2');
+  final struct3 = Struct(name: 'Struct3');
+  return Library(
+    name: 'Bindings',
+    bindings: [
+      Func(
+        name: '${functionPrefix}func1',
+        originalName: 'func1',
+        returnType: NativeType(
+          SupportedNativeType.Void,
+        ),
+        parameters: [
+          Parameter(
+            name: 's',
+            type: PointerType(struct1),
+          ),
+        ],
+      ),
+      Func(
+        name: 'func2',
+        originalName: 'test_func2',
+        returnType: NativeType(
+          SupportedNativeType.Void,
+        ),
+        parameters: [
+          Parameter(
+            name: 's',
+            type: PointerType(struct2),
+          ),
+        ],
+      ),
+      Func(
+        name: 'func3',
+        originalName: 'fullMatch_func3',
+        returnType: NativeType(
+          SupportedNativeType.Void,
+        ),
+        parameters: [
+          Parameter(
+            name: 's',
+            type: PointerType(struct3),
+          ),
+        ],
+      ),
+      Func(
+        name: '${functionPrefix}memberRename_func4',
+        originalName: 'memberRename_func4',
+        returnType: NativeType(
+          SupportedNativeType.Void,
+        ),
+        parameters: [
+          Parameter(
+            name: 'underscore',
+            type: intType,
+          ),
+          Parameter(
+            name: 'fullMatchSuccess',
+            type: floatType,
+          ),
+          Parameter(
+            name: 'unnamed',
+            type: intType,
+          ),
+        ],
+      ),
+      Func(
+        name: '${functionPrefix}typedefRenameFunc',
+        originalName: 'typedefRenameFunc',
+        returnType: NativeType(
+          SupportedNativeType.Void,
+        ),
+        parameters: [
+          Parameter(
+            name: 's',
+            type: Typealias(
+                name: 'Struct5_Alias_Renamed',
+                type: Struct(name: '${structPrefix}Struct5')),
+          ),
+        ],
+      ),
+      struct1,
+      struct2,
+      struct3,
+      Struct(
+        name: '${structPrefix}MemberRenameStruct4',
+        members: [
+          Member(
+            name: 'underscore',
+            type: intType,
+          ),
+          Member(
+            name: 'fullMatchSuccess',
+            type: floatType,
+          ),
+        ],
+      ),
+      Struct(
+        name: '${structPrefix}AnyMatchStruct5',
+        members: [
+          Member(
+            name: 'underscore',
+            type: intType,
+          ),
+        ],
+      ),
+      EnumClass(
+        name: '${enumPrefix}Enum1',
+        enumConstants: [
+          EnumConstant(name: 'a', value: 0),
+          EnumConstant(name: 'b', value: 1),
+          EnumConstant(name: 'c', value: 2),
+        ],
+      ),
+      EnumClass(
+        name: 'Enum2',
+        enumConstants: [
+          EnumConstant(name: 'e', value: 0),
+          EnumConstant(name: 'f', value: 1),
+          EnumConstant(name: 'g', value: 2),
+        ],
+      ),
+      EnumClass(
+        name: 'Enum3',
+        enumConstants: [
+          EnumConstant(name: 'i', value: 0),
+          EnumConstant(name: 'j', value: 1),
+          EnumConstant(name: 'k', value: 2),
+        ],
+      ),
+      EnumClass(
+        name: '${enumPrefix}MemberRenameEnum4',
+        enumConstants: [
+          EnumConstant(name: 'underscore', value: 0),
+          EnumConstant(name: 'fullMatchSuccess', value: 1),
+        ],
+      ),
+      Constant(
+        name: '${macroPrefix}Macro1',
+        rawType: 'int',
+        rawValue: '1',
+      ),
+      Constant(
+        name: 'Macro2',
+        rawType: 'int',
+        rawValue: '2',
+      ),
+      Constant(
+        name: 'Macro3',
+        rawType: 'int',
+        rawValue: '3',
+      ),
+      Constant(
+        name: 'unnamed_underscore',
+        rawType: 'int',
+        rawValue: '0',
+      ),
+      Constant(
+        name: 'unnamedFullMatchSuccess',
+        rawType: 'int',
+        rawValue: '1',
+      ),
+    ],
+  );
+}
diff --git a/pkgs/ffigen/test/setup.dart b/pkgs/ffigen/test/setup.dart
new file mode 100644
index 0000000..3439901
--- /dev/null
+++ b/pkgs/ffigen/test/setup.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Runs all the test setup scripts. Usage:
+// dart run test/setup.dart
+
+import 'dart:async';
+import 'dart:io';
+
+Future<void> _run(String subdir, String script) async {
+  final dir = Platform.script.resolve('$subdir/');
+  print('\nRunning $script in ${dir.toFilePath()}');
+  final args = ['run', dir.resolve(script).toFilePath()];
+  final process = await Process.start(
+    Platform.executable,
+    args,
+    workingDirectory: dir.toFilePath(),
+  );
+  unawaited(stdout.addStream(process.stdout));
+  unawaited(stderr.addStream(process.stderr));
+  final result = await process.exitCode;
+  if (result != 0) {
+    throw ProcessException(Platform.executable, args, '$script failed', result);
+  }
+}
+
+Future<void> main() async {
+  await _run('native_test', 'build_test_dylib.dart');
+  if (Platform.isMacOS) {
+    await _run('native_objc_test', 'setup.dart');
+  }
+  print('\nSuccess :)\n');
+}
diff --git a/pkgs/ffigen/test/test_utils.dart b/pkgs/ffigen/test/test_utils.dart
new file mode 100644
index 0000000..9482b9c
--- /dev/null
+++ b/pkgs/ffigen/test/test_utils.dart
@@ -0,0 +1,172 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/config_provider/config.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+import 'package:logging/logging.dart';
+import 'package:package_config/package_config_types.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+import 'package:yaml/yaml.dart' as yaml;
+
+extension LibraryTestExt on Library {
+  /// Get a [Binding]'s generated string with a given name.
+  String getBindingAsString(String name) {
+    try {
+      final b = bindings.firstWhere((element) => element.name == name);
+      return b.toBindingString(writer).string;
+    } catch (e) {
+      throw NotFoundException("Binding '$name' not found.");
+    }
+  }
+
+  /// Get a [Binding] with a given name.
+  Binding getBinding(String name) {
+    try {
+      final b = bindings.firstWhere((element) => element.name == name);
+      return b;
+    } catch (e) {
+      throw NotFoundException("Binding '$name' not found.");
+    }
+  }
+}
+
+/// Check whether a file generated by test/setup.dart exists and throw a helpful
+/// exception if it does not.
+void verifySetupFile(File file) {
+  if (!file.existsSync()) {
+    throw NotFoundException("The file ${file.path} does not exist.\n\n"
+        "You may need to run: dart run test/setup.dart\n");
+  }
+}
+
+// Remove '\r' for Windows compatibility, then apply user's normalizer.
+String _normalizeGeneratedCode(
+    String generated, String Function(String)? codeNormalizer) {
+  final noCR = generated.replaceAll('\r', '');
+  if (codeNormalizer == null) return noCR;
+  return codeNormalizer(noCR);
+}
+
+/// Generates actual file using library and tests using [expect] with expected.
+///
+/// This will not delete the actual debug file incase [expect] throws an error.
+void matchLibraryWithExpected(
+    Library library, String pathForActual, List<String> pathToExpected,
+    {String Function(String)? codeNormalizer, bool format = true}) {
+  _matchFileWithExpected(
+    library: library,
+    pathForActual: pathForActual,
+    pathToExpected: pathToExpected,
+    fileWriter: ({required Library library, required File file}) =>
+        library.generateFile(file, format: format),
+    codeNormalizer: codeNormalizer,
+  );
+}
+
+/// Generates actual file using library and tests using [expect] with expected.
+///
+/// This will not delete the actual debug file incase [expect] throws an error.
+void matchLibrarySymbolFileWithExpected(Library library, String pathForActual,
+    List<String> pathToExpected, String importPath) {
+  _matchFileWithExpected(
+      library: library,
+      pathForActual: pathForActual,
+      pathToExpected: pathToExpected,
+      fileWriter: ({required Library library, required File file}) {
+        if (!library.writer.canGenerateSymbolOutput) library.generate();
+        library.generateSymbolOutputFile(file, importPath);
+      });
+}
+
+/// Generates actual file using library and tests using [expect] with expected.
+///
+/// This will not delete the actual debug file incase [expect] throws an error.
+void _matchFileWithExpected({
+  required Library library,
+  required String pathForActual,
+  required List<String> pathToExpected,
+  required void Function({required Library library, required File file})
+      fileWriter,
+  String Function(String)? codeNormalizer,
+}) {
+  final file = File(
+    path.join(strings.tmpDir, pathForActual),
+  );
+  fileWriter(library: library, file: file);
+  try {
+    final actual =
+        _normalizeGeneratedCode(file.readAsStringSync(), codeNormalizer);
+    final expected = _normalizeGeneratedCode(
+        File(path.joinAll(pathToExpected)).readAsStringSync(), codeNormalizer);
+    expect(actual.split('\n'), expected.split('\n'));
+    if (file.existsSync()) {
+      file.delete();
+    }
+  } catch (e) {
+    print('Failed test: Debug generated file: ${file.absolute.path}');
+    rethrow;
+  }
+}
+
+class NotFoundException implements Exception {
+  final String message;
+  NotFoundException(this.message);
+
+  @override
+  String toString() {
+    return message;
+  }
+}
+
+void logWarnings([Level level = Level.WARNING]) {
+  Logger.root.level = level;
+  Logger.root.onRecord.listen((record) {
+    print('${record.level.name.padRight(8)}: ${record.message}');
+  });
+}
+
+void logWarningsToArray(List<String> logArr, [Level level = Level.WARNING]) {
+  Logger.root.level = level;
+  Logger.root.onRecord.listen((record) {
+    logArr.add('${record.level.name.padRight(8)}: ${record.message}');
+  });
+}
+
+Config testConfig(String yamlBody, {String? filename}) {
+  return Config.fromYaml(
+    yaml.loadYaml(yamlBody) as yaml.YamlMap,
+    filename: filename,
+    packageConfig: PackageConfig([
+      Package(
+        'shared_bindings',
+        Uri.file(path.join(path.current, 'example', 'shared_bindings', 'lib/')),
+      ),
+    ]),
+  );
+}
+
+Config testConfigFromPath(String path) {
+  final file = File(path);
+  final yamlBody = file.readAsStringSync();
+  return testConfig(yamlBody, filename: path);
+}
+
+T withChDir<T>(String path, T Function() inner) {
+  final oldDir = Directory.current;
+  Directory.current = File(path).parent;
+
+  late T result;
+
+  try {
+    result = inner();
+  } finally {
+    Directory.current = oldDir;
+  }
+
+  return result;
+}
diff --git a/pkgs/ffigen/test_flutter/flutter_template_tests/flutter_plugin_ffi_test.dart b/pkgs/ffigen/test_flutter/flutter_template_tests/flutter_plugin_ffi_test.dart
new file mode 100644
index 0000000..aa86731
--- /dev/null
+++ b/pkgs/ffigen/test_flutter/flutter_template_tests/flutter_plugin_ffi_test.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@Timeout(Duration(seconds: 120))
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:test/test.dart';
+
+void main() {
+  Uri? tempDirUri;
+  final projectName = 'test_project';
+
+  setUp(() async {
+    tempDirUri = (await Directory.current.createTemp('.temp_test_')).uri;
+  });
+
+  tearDown(() async {
+    final dir = Directory(tempDirUri!.toFilePath());
+    if (await dir.exists()) {
+      await dir.delete(recursive: true);
+    }
+  });
+
+  test('Run Flutter', () async {
+    final projectDirUri = tempDirUri!.resolve('$projectName/');
+    final libDirUri = projectDirUri.resolve('lib/');
+    final bindingsGeneratedUri =
+        libDirUri.resolve('${projectName}_bindings_generated.dart');
+    final bindingsGeneratedCopyUri =
+        libDirUri.resolve('${projectName}_bindings_generated_copy.dart');
+
+    await runProcess(
+      executable: 'flutter',
+      arguments: [
+        'create',
+        '--template=plugin_ffi',
+        projectName,
+      ],
+      workingDirectory: tempDirUri,
+    );
+    await copyFile(
+      source: bindingsGeneratedUri,
+      target: bindingsGeneratedCopyUri,
+    );
+    await runProcess(
+      executable: 'flutter',
+      arguments: [
+        'pub',
+        'run',
+        'ffigen',
+        '--config',
+        'ffigen.yaml',
+      ],
+      workingDirectory: projectDirUri,
+    );
+
+    final originalBindings = await readFileAsString(bindingsGeneratedCopyUri);
+    final regeneratedBindings = await readFileAsString(bindingsGeneratedUri);
+
+    expect(originalBindings, regeneratedBindings);
+  });
+}
+
+Future<String> readFileAsString(Uri uri) async {
+  final contents = await File(uri.toFilePath()).readAsString();
+  return contents.replaceAll('\r', '');
+}
+
+Future<void> runProcess({
+  required List<String> arguments,
+  required String executable,
+  Uri? workingDirectory,
+  Map<String, String>? environment,
+  bool throwOnFailure = true,
+}) async {
+  // Excluding [workingDirectory].
+  final String commandString = [
+    if (workingDirectory != null) '(cd ${workingDirectory.path};',
+    ...?environment?.entries.map((entry) => '${entry.key}=${entry.value}'),
+    executable,
+    ...arguments.map((a) => a.contains(' ') ? "'$a'" : a),
+    if (workingDirectory != null) ')',
+  ].join(' ');
+
+  final workingDirectoryString = workingDirectory?.toFilePath();
+
+  print('Running `$commandString`.');
+  final process = await Process.start(executable, arguments,
+          runInShell: true,
+          includeParentEnvironment: true,
+          workingDirectory: workingDirectoryString,
+          environment: environment)
+      .then((process) {
+    process.stdout.transform(utf8.decoder).forEach((s) => print('  $s'));
+    process.stderr.transform(utf8.decoder).forEach((s) => print('  $s'));
+    return process;
+  });
+  final exitCode = await process.exitCode;
+  if (exitCode != 0) {
+    final message = 'Command `$commandString` failed with exit code $exitCode.';
+    print(message);
+    if (throwOnFailure) {
+      throw Exception(message);
+    }
+  }
+  print('Command `$commandString` done.');
+}
+
+Future<void> copyFile({
+  required Uri source,
+  required Uri target,
+}) async {
+  final file = File.fromUri(source);
+  if (!await file.exists()) {
+    final message = "File not in expected location: '${source.toFilePath()}'.";
+    print(message);
+    throw Exception(message);
+  }
+  print('Copying ${source.toFilePath()} to ${target.toFilePath()}.');
+  await file.copy(target.toFilePath());
+}
diff --git a/pkgs/ffigen/third_party/cjson_library/.gitignore b/pkgs/ffigen/third_party/cjson_library/.gitignore
new file mode 100644
index 0000000..53d01a3
--- /dev/null
+++ b/pkgs/ffigen/third_party/cjson_library/.gitignore
@@ -0,0 +1,17 @@
+# CMake generated files and directories.
+CMakeCache.txt
+CMakeFiles/
+CmakeScripts/
+Makefile
+cmake_install.cmake
+
+# Xcode tooling generated via `cmake -G Xcode .`.
+cjson_library.xcodeproj/
+
+# Xcode generated build and output directories.
+cjson_library.build/
+
+# Generated shared library files.
+*.dylib
+*.so.*
+*.dll
diff --git a/pkgs/ffigen/third_party/cjson_library/CMakeLists.txt b/pkgs/ffigen/third_party/cjson_library/CMakeLists.txt
new file mode 100644
index 0000000..815ba4f
--- /dev/null
+++ b/pkgs/ffigen/third_party/cjson_library/CMakeLists.txt
@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 3.7 FATAL_ERROR)
+project(cjson_library VERSION 1.0.0 LANGUAGES C)
+add_library(cjson_library SHARED cJSON.c)
+
+set_target_properties(cjson_library PROPERTIES
+    PUBLIC_HEADER cJSON.h
+    VERSION ${PROJECT_VERSION}
+    SOVERSION 1
+    OUTPUT_NAME "cjson"
+    XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Hex_Identity_ID_Goes_Here"
+)
diff --git a/pkgs/ffigen/third_party/cjson_library/cJSON.c b/pkgs/ffigen/third_party/cjson_library/cJSON.c
new file mode 100644
index 0000000..a198d66
--- /dev/null
+++ b/pkgs/ffigen/third_party/cjson_library/cJSON.c
@@ -0,0 +1,2998 @@
+/*
+  Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+*/
+
+/* cJSON */
+/* JSON parser in C. */
+
+/* disable warnings about old C89 functions in MSVC */
+#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+#ifdef __GNUC__
+#pragma GCC visibility push(default)
+#endif
+#if defined(_MSC_VER)
+#pragma warning (push)
+/* disable warning about single line comments in system headers */
+#pragma warning (disable : 4001)
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <ctype.h>
+
+#ifdef ENABLE_LOCALES
+#include <locale.h>
+#endif
+
+#if defined(_MSC_VER)
+#pragma warning (pop)
+#endif
+#ifdef __GNUC__
+#pragma GCC visibility pop
+#endif
+
+#include "cJSON.h"
+
+/* define our own boolean type */
+#ifdef true
+#undef true
+#endif
+#define true ((cJSON_bool)1)
+
+#ifdef false
+#undef false
+#endif
+#define false ((cJSON_bool)0)
+
+typedef struct {
+    const unsigned char *json;
+    size_t position;
+} error;
+static error global_error = { NULL, 0 };
+
+CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
+{
+    return (const char*) (global_error.json + global_error.position);
+}
+
+CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) {
+    if (!cJSON_IsString(item)) {
+        return NULL;
+    }
+
+    return item->valuestring;
+}
+
+/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
+#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 12)
+    #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
+#endif
+
+CJSON_PUBLIC(const char*) cJSON_Version(void)
+{
+    static char version[15];
+    sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
+
+    return version;
+}
+
+/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */
+static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
+{
+    if ((string1 == NULL) || (string2 == NULL))
+    {
+        return 1;
+    }
+
+    if (string1 == string2)
+    {
+        return 0;
+    }
+
+    for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
+    {
+        if (*string1 == '\0')
+        {
+            return 0;
+        }
+    }
+
+    return tolower(*string1) - tolower(*string2);
+}
+
+typedef struct internal_hooks
+{
+    void *(CJSON_CDECL *allocate)(size_t size);
+    void (CJSON_CDECL *deallocate)(void *pointer);
+    void *(CJSON_CDECL *reallocate)(void *pointer, size_t size);
+} internal_hooks;
+
+#if defined(_MSC_VER)
+/* work around MSVC error C2322: '...' address of dllimport '...' is not static */
+static void * CJSON_CDECL internal_malloc(size_t size)
+{
+    return malloc(size);
+}
+static void CJSON_CDECL internal_free(void *pointer)
+{
+    free(pointer);
+}
+static void * CJSON_CDECL internal_realloc(void *pointer, size_t size)
+{
+    return realloc(pointer, size);
+}
+#else
+#define internal_malloc malloc
+#define internal_free free
+#define internal_realloc realloc
+#endif
+
+/* strlen of character literals resolved at compile time */
+#define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
+
+static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
+
+static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
+{
+    size_t length = 0;
+    unsigned char *copy = NULL;
+
+    if (string == NULL)
+    {
+        return NULL;
+    }
+
+    length = strlen((const char*)string) + sizeof("");
+    copy = (unsigned char*)hooks->allocate(length);
+    if (copy == NULL)
+    {
+        return NULL;
+    }
+    memcpy(copy, string, length);
+
+    return copy;
+}
+
+CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
+{
+    if (hooks == NULL)
+    {
+        /* Reset hooks */
+        global_hooks.allocate = malloc;
+        global_hooks.deallocate = free;
+        global_hooks.reallocate = realloc;
+        return;
+    }
+
+    global_hooks.allocate = malloc;
+    if (hooks->malloc_fn != NULL)
+    {
+        global_hooks.allocate = hooks->malloc_fn;
+    }
+
+    global_hooks.deallocate = free;
+    if (hooks->free_fn != NULL)
+    {
+        global_hooks.deallocate = hooks->free_fn;
+    }
+
+    /* use realloc only if both free and malloc are used */
+    global_hooks.reallocate = NULL;
+    if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
+    {
+        global_hooks.reallocate = realloc;
+    }
+}
+
+/* Internal constructor. */
+static cJSON *cJSON_New_Item(const internal_hooks * const hooks)
+{
+    cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));
+    if (node)
+    {
+        memset(node, '\0', sizeof(cJSON));
+    }
+
+    return node;
+}
+
+/* Delete a cJSON structure. */
+CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
+{
+    cJSON *next = NULL;
+    while (item != NULL)
+    {
+        next = item->next;
+        if (!(item->type & cJSON_IsReference) && (item->child != NULL))
+        {
+            cJSON_Delete(item->child);
+        }
+        if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
+        {
+            global_hooks.deallocate(item->valuestring);
+        }
+        if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
+        {
+            global_hooks.deallocate(item->string);
+        }
+        global_hooks.deallocate(item);
+        item = next;
+    }
+}
+
+/* get the decimal point character of the current locale */
+static unsigned char get_decimal_point(void)
+{
+#ifdef ENABLE_LOCALES
+    struct lconv *lconv = localeconv();
+    return (unsigned char) lconv->decimal_point[0];
+#else
+    return '.';
+#endif
+}
+
+typedef struct
+{
+    const unsigned char *content;
+    size_t length;
+    size_t offset;
+    size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */
+    internal_hooks hooks;
+} parse_buffer;
+
+/* check if the given size is left to read in a given parse buffer (starting with 1) */
+#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
+/* check if the buffer can be accessed at the given index (starting with 0) */
+#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
+#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
+/* get a pointer to the buffer at the position */
+#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
+
+/* Parse the input text to generate a number, and populate the result into item. */
+static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
+{
+    double number = 0;
+    unsigned char *after_end = NULL;
+    unsigned char number_c_string[64];
+    unsigned char decimal_point = get_decimal_point();
+    size_t i = 0;
+
+    if ((input_buffer == NULL) || (input_buffer->content == NULL))
+    {
+        return false;
+    }
+
+    /* copy the number into a temporary buffer and replace '.' with the decimal point
+     * of the current locale (for strtod)
+     * This also takes care of '\0' not necessarily being available for marking the end of the input */
+    for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
+    {
+        switch (buffer_at_offset(input_buffer)[i])
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            case '+':
+            case '-':
+            case 'e':
+            case 'E':
+                number_c_string[i] = buffer_at_offset(input_buffer)[i];
+                break;
+
+            case '.':
+                number_c_string[i] = decimal_point;
+                break;
+
+            default:
+                goto loop_end;
+        }
+    }
+loop_end:
+    number_c_string[i] = '\0';
+
+    number = strtod((const char*)number_c_string, (char**)&after_end);
+    if (number_c_string == after_end)
+    {
+        return false; /* parse_error */
+    }
+
+    item->valuedouble = number;
+
+    /* use saturation in case of overflow */
+    if (number >= INT_MAX)
+    {
+        item->valueint = INT_MAX;
+    }
+    else if (number <= (double)INT_MIN)
+    {
+        item->valueint = INT_MIN;
+    }
+    else
+    {
+        item->valueint = (int)number;
+    }
+
+    item->type = cJSON_Number;
+
+    input_buffer->offset += (size_t)(after_end - number_c_string);
+    return true;
+}
+
+/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
+CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
+{
+    if (number >= INT_MAX)
+    {
+        object->valueint = INT_MAX;
+    }
+    else if (number <= (double)INT_MIN)
+    {
+        object->valueint = INT_MIN;
+    }
+    else
+    {
+        object->valueint = (int)number;
+    }
+
+    return object->valuedouble = number;
+}
+
+typedef struct
+{
+    unsigned char *buffer;
+    size_t length;
+    size_t offset;
+    size_t depth; /* current nesting depth (for formatted printing) */
+    cJSON_bool noalloc;
+    cJSON_bool format; /* is this print a formatted print */
+    internal_hooks hooks;
+} printbuffer;
+
+/* realloc printbuffer if necessary to have at least "needed" bytes more */
+static unsigned char* ensure(printbuffer * const p, size_t needed)
+{
+    unsigned char *newbuffer = NULL;
+    size_t newsize = 0;
+
+    if ((p == NULL) || (p->buffer == NULL))
+    {
+        return NULL;
+    }
+
+    if ((p->length > 0) && (p->offset >= p->length))
+    {
+        /* make sure that offset is valid */
+        return NULL;
+    }
+
+    if (needed > INT_MAX)
+    {
+        /* sizes bigger than INT_MAX are currently not supported */
+        return NULL;
+    }
+
+    needed += p->offset + 1;
+    if (needed <= p->length)
+    {
+        return p->buffer + p->offset;
+    }
+
+    if (p->noalloc) {
+        return NULL;
+    }
+
+    /* calculate new buffer size */
+    if (needed > (INT_MAX / 2))
+    {
+        /* overflow of int, use INT_MAX if possible */
+        if (needed <= INT_MAX)
+        {
+            newsize = INT_MAX;
+        }
+        else
+        {
+            return NULL;
+        }
+    }
+    else
+    {
+        newsize = needed * 2;
+    }
+
+    if (p->hooks.reallocate != NULL)
+    {
+        /* reallocate with realloc if available */
+        newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
+        if (newbuffer == NULL)
+        {
+            p->hooks.deallocate(p->buffer);
+            p->length = 0;
+            p->buffer = NULL;
+
+            return NULL;
+        }
+    }
+    else
+    {
+        /* otherwise reallocate manually */
+        newbuffer = (unsigned char*)p->hooks.allocate(newsize);
+        if (!newbuffer)
+        {
+            p->hooks.deallocate(p->buffer);
+            p->length = 0;
+            p->buffer = NULL;
+
+            return NULL;
+        }
+        if (newbuffer)
+        {
+            memcpy(newbuffer, p->buffer, p->offset + 1);
+        }
+        p->hooks.deallocate(p->buffer);
+    }
+    p->length = newsize;
+    p->buffer = newbuffer;
+
+    return newbuffer + p->offset;
+}
+
+/* calculate the new length of the string in a printbuffer and update the offset */
+static void update_offset(printbuffer * const buffer)
+{
+    const unsigned char *buffer_pointer = NULL;
+    if ((buffer == NULL) || (buffer->buffer == NULL))
+    {
+        return;
+    }
+    buffer_pointer = buffer->buffer + buffer->offset;
+
+    buffer->offset += strlen((const char*)buffer_pointer);
+}
+
+/* securely comparison of floating-point variables */
+static cJSON_bool compare_double(double a, double b)
+{
+    return (fabs(a - b) <= CJSON_DOUBLE_PRECISION);
+}
+
+/* Render the number nicely from the given item into a string. */
+static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
+{
+    unsigned char *output_pointer = NULL;
+    double d = item->valuedouble;
+    int length = 0;
+    size_t i = 0;
+    unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */
+    unsigned char decimal_point = get_decimal_point();
+    double test = 0.0;
+
+    if (output_buffer == NULL)
+    {
+        return false;
+    }
+
+    /* This checks for NaN and Infinity */
+    if ((d * 0) != 0)
+    {
+        length = sprintf((char*)number_buffer, "null");
+    }
+    else
+    {
+        /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
+        length = sprintf((char*)number_buffer, "%1.15g", d);
+
+        /* Check whether the original double can be recovered */
+        if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d))
+        {
+            /* If not, print with 17 decimal places of precision */
+            length = sprintf((char*)number_buffer, "%1.17g", d);
+        }
+    }
+
+    /* sprintf failed or buffer overrun occurred */
+    if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
+    {
+        return false;
+    }
+
+    /* reserve appropriate space in the output */
+    output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
+    if (output_pointer == NULL)
+    {
+        return false;
+    }
+
+    /* copy the printed number to the output and replace locale
+     * dependent decimal point with '.' */
+    for (i = 0; i < ((size_t)length); i++)
+    {
+        if (number_buffer[i] == decimal_point)
+        {
+            output_pointer[i] = '.';
+            continue;
+        }
+
+        output_pointer[i] = number_buffer[i];
+    }
+    output_pointer[i] = '\0';
+
+    output_buffer->offset += (size_t)length;
+
+    return true;
+}
+
+/* parse 4 digit hexadecimal number */
+static unsigned parse_hex4(const unsigned char * const input)
+{
+    unsigned int h = 0;
+    size_t i = 0;
+
+    for (i = 0; i < 4; i++)
+    {
+        /* parse digit */
+        if ((input[i] >= '0') && (input[i] <= '9'))
+        {
+            h += (unsigned int) input[i] - '0';
+        }
+        else if ((input[i] >= 'A') && (input[i] <= 'F'))
+        {
+            h += (unsigned int) 10 + input[i] - 'A';
+        }
+        else if ((input[i] >= 'a') && (input[i] <= 'f'))
+        {
+            h += (unsigned int) 10 + input[i] - 'a';
+        }
+        else /* invalid */
+        {
+            return 0;
+        }
+
+        if (i < 3)
+        {
+            /* shift left to make place for the next nibble */
+            h = h << 4;
+        }
+    }
+
+    return h;
+}
+
+/* converts a UTF-16 literal to UTF-8
+ * A literal can be one or two sequences of the form \uXXXX */
+static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer)
+{
+    long unsigned int codepoint = 0;
+    unsigned int first_code = 0;
+    const unsigned char *first_sequence = input_pointer;
+    unsigned char utf8_length = 0;
+    unsigned char utf8_position = 0;
+    unsigned char sequence_length = 0;
+    unsigned char first_byte_mark = 0;
+
+    if ((input_end - first_sequence) < 6)
+    {
+        /* input ends unexpectedly */
+        goto fail;
+    }
+
+    /* get the first utf16 sequence */
+    first_code = parse_hex4(first_sequence + 2);
+
+    /* check that the code is valid */
+    if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
+    {
+        goto fail;
+    }
+
+    /* UTF16 surrogate pair */
+    if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
+    {
+        const unsigned char *second_sequence = first_sequence + 6;
+        unsigned int second_code = 0;
+        sequence_length = 12; /* \uXXXX\uXXXX */
+
+        if ((input_end - second_sequence) < 6)
+        {
+            /* input ends unexpectedly */
+            goto fail;
+        }
+
+        if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u'))
+        {
+            /* missing second half of the surrogate pair */
+            goto fail;
+        }
+
+        /* get the second utf16 sequence */
+        second_code = parse_hex4(second_sequence + 2);
+        /* check that the code is valid */
+        if ((second_code < 0xDC00) || (second_code > 0xDFFF))
+        {
+            /* invalid second half of the surrogate pair */
+            goto fail;
+        }
+
+
+        /* calculate the unicode codepoint from the surrogate pair */
+        codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));
+    }
+    else
+    {
+        sequence_length = 6; /* \uXXXX */
+        codepoint = first_code;
+    }
+
+    /* encode as UTF-8
+     * takes at maximum 4 bytes to encode:
+     * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+    if (codepoint < 0x80)
+    {
+        /* normal ascii, encoding 0xxxxxxx */
+        utf8_length = 1;
+    }
+    else if (codepoint < 0x800)
+    {
+        /* two bytes, encoding 110xxxxx 10xxxxxx */
+        utf8_length = 2;
+        first_byte_mark = 0xC0; /* 11000000 */
+    }
+    else if (codepoint < 0x10000)
+    {
+        /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
+        utf8_length = 3;
+        first_byte_mark = 0xE0; /* 11100000 */
+    }
+    else if (codepoint <= 0x10FFFF)
+    {
+        /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */
+        utf8_length = 4;
+        first_byte_mark = 0xF0; /* 11110000 */
+    }
+    else
+    {
+        /* invalid unicode codepoint */
+        goto fail;
+    }
+
+    /* encode as utf8 */
+    for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)
+    {
+        /* 10xxxxxx */
+        (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF);
+        codepoint >>= 6;
+    }
+    /* encode first byte */
+    if (utf8_length > 1)
+    {
+        (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF);
+    }
+    else
+    {
+        (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F);
+    }
+
+    *output_pointer += utf8_length;
+
+    return sequence_length;
+
+fail:
+    return 0;
+}
+
+/* Parse the input text into an unescaped cinput, and populate item. */
+static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)
+{
+    const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
+    const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
+    unsigned char *output_pointer = NULL;
+    unsigned char *output = NULL;
+
+    /* not a string */
+    if (buffer_at_offset(input_buffer)[0] != '\"')
+    {
+        goto fail;
+    }
+
+    {
+        /* calculate approximate size of the output (overestimate) */
+        size_t allocation_length = 0;
+        size_t skipped_bytes = 0;
+        while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"'))
+        {
+            /* is escape sequence */
+            if (input_end[0] == '\\')
+            {
+                if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
+                {
+                    /* prevent buffer overflow when last input character is a backslash */
+                    goto fail;
+                }
+                skipped_bytes++;
+                input_end++;
+            }
+            input_end++;
+        }
+        if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"'))
+        {
+            goto fail; /* string ended unexpectedly */
+        }
+
+        /* This is at most how much we need for the output */
+        allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
+        output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof(""));
+        if (output == NULL)
+        {
+            goto fail; /* allocation failure */
+        }
+    }
+
+    output_pointer = output;
+    /* loop through the string literal */
+    while (input_pointer < input_end)
+    {
+        if (*input_pointer != '\\')
+        {
+            *output_pointer++ = *input_pointer++;
+        }
+        /* escape sequence */
+        else
+        {
+            unsigned char sequence_length = 2;
+            if ((input_end - input_pointer) < 1)
+            {
+                goto fail;
+            }
+
+            switch (input_pointer[1])
+            {
+                case 'b':
+                    *output_pointer++ = '\b';
+                    break;
+                case 'f':
+                    *output_pointer++ = '\f';
+                    break;
+                case 'n':
+                    *output_pointer++ = '\n';
+                    break;
+                case 'r':
+                    *output_pointer++ = '\r';
+                    break;
+                case 't':
+                    *output_pointer++ = '\t';
+                    break;
+                case '\"':
+                case '\\':
+                case '/':
+                    *output_pointer++ = input_pointer[1];
+                    break;
+
+                /* UTF-16 literal */
+                case 'u':
+                    sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
+                    if (sequence_length == 0)
+                    {
+                        /* failed to convert UTF16-literal to UTF-8 */
+                        goto fail;
+                    }
+                    break;
+
+                default:
+                    goto fail;
+            }
+            input_pointer += sequence_length;
+        }
+    }
+
+    /* zero terminate the output */
+    *output_pointer = '\0';
+
+    item->type = cJSON_String;
+    item->valuestring = (char*)output;
+
+    input_buffer->offset = (size_t) (input_end - input_buffer->content);
+    input_buffer->offset++;
+
+    return true;
+
+fail:
+    if (output != NULL)
+    {
+        input_buffer->hooks.deallocate(output);
+    }
+
+    if (input_pointer != NULL)
+    {
+        input_buffer->offset = (size_t)(input_pointer - input_buffer->content);
+    }
+
+    return false;
+}
+
+/* Render the cstring provided to an escaped version that can be printed. */
+static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer)
+{
+    const unsigned char *input_pointer = NULL;
+    unsigned char *output = NULL;
+    unsigned char *output_pointer = NULL;
+    size_t output_length = 0;
+    /* numbers of additional characters needed for escaping */
+    size_t escape_characters = 0;
+
+    if (output_buffer == NULL)
+    {
+        return false;
+    }
+
+    /* empty string */
+    if (input == NULL)
+    {
+        output = ensure(output_buffer, sizeof("\"\""));
+        if (output == NULL)
+        {
+            return false;
+        }
+        strcpy((char*)output, "\"\"");
+
+        return true;
+    }
+
+    /* set "flag" to 1 if something needs to be escaped */
+    for (input_pointer = input; *input_pointer; input_pointer++)
+    {
+        switch (*input_pointer)
+        {
+            case '\"':
+            case '\\':
+            case '\b':
+            case '\f':
+            case '\n':
+            case '\r':
+            case '\t':
+                /* one character escape sequence */
+                escape_characters++;
+                break;
+            default:
+                if (*input_pointer < 32)
+                {
+                    /* UTF-16 escape sequence uXXXX */
+                    escape_characters += 5;
+                }
+                break;
+        }
+    }
+    output_length = (size_t)(input_pointer - input) + escape_characters;
+
+    output = ensure(output_buffer, output_length + sizeof("\"\""));
+    if (output == NULL)
+    {
+        return false;
+    }
+
+    /* no characters have to be escaped */
+    if (escape_characters == 0)
+    {
+        output[0] = '\"';
+        memcpy(output + 1, input, output_length);
+        output[output_length + 1] = '\"';
+        output[output_length + 2] = '\0';
+
+        return true;
+    }
+
+    output[0] = '\"';
+    output_pointer = output + 1;
+    /* copy the string */
+    for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
+    {
+        if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
+        {
+            /* normal character, copy */
+            *output_pointer = *input_pointer;
+        }
+        else
+        {
+            /* character needs to be escaped */
+            *output_pointer++ = '\\';
+            switch (*input_pointer)
+            {
+                case '\\':
+                    *output_pointer = '\\';
+                    break;
+                case '\"':
+                    *output_pointer = '\"';
+                    break;
+                case '\b':
+                    *output_pointer = 'b';
+                    break;
+                case '\f':
+                    *output_pointer = 'f';
+                    break;
+                case '\n':
+                    *output_pointer = 'n';
+                    break;
+                case '\r':
+                    *output_pointer = 'r';
+                    break;
+                case '\t':
+                    *output_pointer = 't';
+                    break;
+                default:
+                    /* escape and print as unicode codepoint */
+                    sprintf((char*)output_pointer, "u%04x", *input_pointer);
+                    output_pointer += 4;
+                    break;
+            }
+        }
+    }
+    output[output_length + 1] = '\"';
+    output[output_length + 2] = '\0';
+
+    return true;
+}
+
+/* Invoke print_string_ptr (which is useful) on an item. */
+static cJSON_bool print_string(const cJSON * const item, printbuffer * const p)
+{
+    return print_string_ptr((unsigned char*)item->valuestring, p);
+}
+
+/* Predeclare these prototypes. */
+static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer);
+static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer);
+static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer);
+static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer);
+static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer);
+static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer);
+
+/* Utility to jump whitespace and cr/lf */
+static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
+{
+    if ((buffer == NULL) || (buffer->content == NULL))
+    {
+        return NULL;
+    }
+
+    while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
+    {
+       buffer->offset++;
+    }
+
+    if (buffer->offset == buffer->length)
+    {
+        buffer->offset--;
+    }
+
+    return buffer;
+}
+
+/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
+static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
+{
+    if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
+    {
+        return NULL;
+    }
+
+    if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
+    {
+        buffer->offset += 3;
+    }
+
+    return buffer;
+}
+
+/* Parse an object - create a new root, and populate. */
+CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
+{
+    parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
+    cJSON *item = NULL;
+
+    /* reset error position */
+    global_error.json = NULL;
+    global_error.position = 0;
+
+    if (value == NULL)
+    {
+        goto fail;
+    }
+
+    buffer.content = (const unsigned char*)value;
+    buffer.length = strlen((const char*)value) + sizeof("");
+    buffer.offset = 0;
+    buffer.hooks = global_hooks;
+
+    item = cJSON_New_Item(&global_hooks);
+    if (item == NULL) /* memory fail */
+    {
+        goto fail;
+    }
+
+    if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
+    {
+        /* parse failure. ep is set. */
+        goto fail;
+    }
+
+    /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
+    if (require_null_terminated)
+    {
+        buffer_skip_whitespace(&buffer);
+        if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0')
+        {
+            goto fail;
+        }
+    }
+    if (return_parse_end)
+    {
+        *return_parse_end = (const char*)buffer_at_offset(&buffer);
+    }
+
+    return item;
+
+fail:
+    if (item != NULL)
+    {
+        cJSON_Delete(item);
+    }
+
+    if (value != NULL)
+    {
+        error local_error;
+        local_error.json = (const unsigned char*)value;
+        local_error.position = 0;
+
+        if (buffer.offset < buffer.length)
+        {
+            local_error.position = buffer.offset;
+        }
+        else if (buffer.length > 0)
+        {
+            local_error.position = buffer.length - 1;
+        }
+
+        if (return_parse_end != NULL)
+        {
+            *return_parse_end = (const char*)local_error.json + local_error.position;
+        }
+
+        global_error = local_error;
+    }
+
+    return NULL;
+}
+
+/* Default options for cJSON_Parse */
+CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
+{
+    return cJSON_ParseWithOpts(value, 0, 0);
+}
+
+#define cjson_min(a, b) ((a < b) ? a : b)
+
+static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)
+{
+    static const size_t default_buffer_size = 256;
+    printbuffer buffer[1];
+    unsigned char *printed = NULL;
+
+    memset(buffer, 0, sizeof(buffer));
+
+    /* create buffer */
+    buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size);
+    buffer->length = default_buffer_size;
+    buffer->format = format;
+    buffer->hooks = *hooks;
+    if (buffer->buffer == NULL)
+    {
+        goto fail;
+    }
+
+    /* print the value */
+    if (!print_value(item, buffer))
+    {
+        goto fail;
+    }
+    update_offset(buffer);
+
+    /* check if reallocate is available */
+    if (hooks->reallocate != NULL)
+    {
+        printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
+        if (printed == NULL) {
+            goto fail;
+        }
+        buffer->buffer = NULL;
+    }
+    else /* otherwise copy the JSON over to a new buffer */
+    {
+        printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
+        if (printed == NULL)
+        {
+            goto fail;
+        }
+        memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
+        printed[buffer->offset] = '\0'; /* just to be sure */
+
+        /* free the buffer */
+        hooks->deallocate(buffer->buffer);
+    }
+
+    return printed;
+
+fail:
+    if (buffer->buffer != NULL)
+    {
+        hooks->deallocate(buffer->buffer);
+    }
+
+    if (printed != NULL)
+    {
+        hooks->deallocate(printed);
+    }
+
+    return NULL;
+}
+
+/* Render a cJSON item/entity/structure to text. */
+CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item)
+{
+    return (char*)print(item, true, &global_hooks);
+}
+
+CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item)
+{
+    return (char*)print(item, false, &global_hooks);
+}
+
+CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)
+{
+    printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
+
+    if (prebuffer < 0)
+    {
+        return NULL;
+    }
+
+    p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer);
+    if (!p.buffer)
+    {
+        return NULL;
+    }
+
+    p.length = (size_t)prebuffer;
+    p.offset = 0;
+    p.noalloc = false;
+    p.format = fmt;
+    p.hooks = global_hooks;
+
+    if (!print_value(item, &p))
+    {
+        global_hooks.deallocate(p.buffer);
+        return NULL;
+    }
+
+    return (char*)p.buffer;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format)
+{
+    printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
+
+    if ((length < 0) || (buffer == NULL))
+    {
+        return false;
+    }
+
+    p.buffer = (unsigned char*)buffer;
+    p.length = (size_t)length;
+    p.offset = 0;
+    p.noalloc = true;
+    p.format = format;
+    p.hooks = global_hooks;
+
+    return print_value(item, &p);
+}
+
+/* Parser core - when encountering text, process appropriately. */
+static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer)
+{
+    if ((input_buffer == NULL) || (input_buffer->content == NULL))
+    {
+        return false; /* no input */
+    }
+
+    /* parse the different types of values */
+    /* null */
+    if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0))
+    {
+        item->type = cJSON_NULL;
+        input_buffer->offset += 4;
+        return true;
+    }
+    /* false */
+    if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0))
+    {
+        item->type = cJSON_False;
+        input_buffer->offset += 5;
+        return true;
+    }
+    /* true */
+    if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0))
+    {
+        item->type = cJSON_True;
+        item->valueint = 1;
+        input_buffer->offset += 4;
+        return true;
+    }
+    /* string */
+    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
+    {
+        return parse_string(item, input_buffer);
+    }
+    /* number */
+    if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9'))))
+    {
+        return parse_number(item, input_buffer);
+    }
+    /* array */
+    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '['))
+    {
+        return parse_array(item, input_buffer);
+    }
+    /* object */
+    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{'))
+    {
+        return parse_object(item, input_buffer);
+    }
+
+    return false;
+}
+
+/* Render a value to text. */
+static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer)
+{
+    unsigned char *output = NULL;
+
+    if ((item == NULL) || (output_buffer == NULL))
+    {
+        return false;
+    }
+
+    switch ((item->type) & 0xFF)
+    {
+        case cJSON_NULL:
+            output = ensure(output_buffer, 5);
+            if (output == NULL)
+            {
+                return false;
+            }
+            strcpy((char*)output, "null");
+            return true;
+
+        case cJSON_False:
+            output = ensure(output_buffer, 6);
+            if (output == NULL)
+            {
+                return false;
+            }
+            strcpy((char*)output, "false");
+            return true;
+
+        case cJSON_True:
+            output = ensure(output_buffer, 5);
+            if (output == NULL)
+            {
+                return false;
+            }
+            strcpy((char*)output, "true");
+            return true;
+
+        case cJSON_Number:
+            return print_number(item, output_buffer);
+
+        case cJSON_Raw:
+        {
+            size_t raw_length = 0;
+            if (item->valuestring == NULL)
+            {
+                return false;
+            }
+
+            raw_length = strlen(item->valuestring) + sizeof("");
+            output = ensure(output_buffer, raw_length);
+            if (output == NULL)
+            {
+                return false;
+            }
+            memcpy(output, item->valuestring, raw_length);
+            return true;
+        }
+
+        case cJSON_String:
+            return print_string(item, output_buffer);
+
+        case cJSON_Array:
+            return print_array(item, output_buffer);
+
+        case cJSON_Object:
+            return print_object(item, output_buffer);
+
+        default:
+            return false;
+    }
+}
+
+/* Build an array from input text. */
+static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer)
+{
+    cJSON *head = NULL; /* head of the linked list */
+    cJSON *current_item = NULL;
+
+    if (input_buffer->depth >= CJSON_NESTING_LIMIT)
+    {
+        return false; /* to deeply nested */
+    }
+    input_buffer->depth++;
+
+    if (buffer_at_offset(input_buffer)[0] != '[')
+    {
+        /* not an array */
+        goto fail;
+    }
+
+    input_buffer->offset++;
+    buffer_skip_whitespace(input_buffer);
+    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']'))
+    {
+        /* empty array */
+        goto success;
+    }
+
+    /* check if we skipped to the end of the buffer */
+    if (cannot_access_at_index(input_buffer, 0))
+    {
+        input_buffer->offset--;
+        goto fail;
+    }
+
+    /* step back to character in front of the first element */
+    input_buffer->offset--;
+    /* loop through the comma separated array elements */
+    do
+    {
+        /* allocate next item */
+        cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
+        if (new_item == NULL)
+        {
+            goto fail; /* allocation failure */
+        }
+
+        /* attach next item to list */
+        if (head == NULL)
+        {
+            /* start the linked list */
+            current_item = head = new_item;
+        }
+        else
+        {
+            /* add to the end and advance */
+            current_item->next = new_item;
+            new_item->prev = current_item;
+            current_item = new_item;
+        }
+
+        /* parse next value */
+        input_buffer->offset++;
+        buffer_skip_whitespace(input_buffer);
+        if (!parse_value(current_item, input_buffer))
+        {
+            goto fail; /* failed to parse value */
+        }
+        buffer_skip_whitespace(input_buffer);
+    }
+    while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
+
+    if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']')
+    {
+        goto fail; /* expected end of array */
+    }
+
+success:
+    input_buffer->depth--;
+
+    item->type = cJSON_Array;
+    item->child = head;
+
+    input_buffer->offset++;
+
+    return true;
+
+fail:
+    if (head != NULL)
+    {
+        cJSON_Delete(head);
+    }
+
+    return false;
+}
+
+/* Render an array to text */
+static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer)
+{
+    unsigned char *output_pointer = NULL;
+    size_t length = 0;
+    cJSON *current_element = item->child;
+
+    if (output_buffer == NULL)
+    {
+        return false;
+    }
+
+    /* Compose the output array. */
+    /* opening square bracket */
+    output_pointer = ensure(output_buffer, 1);
+    if (output_pointer == NULL)
+    {
+        return false;
+    }
+
+    *output_pointer = '[';
+    output_buffer->offset++;
+    output_buffer->depth++;
+
+    while (current_element != NULL)
+    {
+        if (!print_value(current_element, output_buffer))
+        {
+            return false;
+        }
+        update_offset(output_buffer);
+        if (current_element->next)
+        {
+            length = (size_t) (output_buffer->format ? 2 : 1);
+            output_pointer = ensure(output_buffer, length + 1);
+            if (output_pointer == NULL)
+            {
+                return false;
+            }
+            *output_pointer++ = ',';
+            if(output_buffer->format)
+            {
+                *output_pointer++ = ' ';
+            }
+            *output_pointer = '\0';
+            output_buffer->offset += length;
+        }
+        current_element = current_element->next;
+    }
+
+    output_pointer = ensure(output_buffer, 2);
+    if (output_pointer == NULL)
+    {
+        return false;
+    }
+    *output_pointer++ = ']';
+    *output_pointer = '\0';
+    output_buffer->depth--;
+
+    return true;
+}
+
+/* Build an object from the text. */
+static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer)
+{
+    cJSON *head = NULL; /* linked list head */
+    cJSON *current_item = NULL;
+
+    if (input_buffer->depth >= CJSON_NESTING_LIMIT)
+    {
+        return false; /* to deeply nested */
+    }
+    input_buffer->depth++;
+
+    if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
+    {
+        goto fail; /* not an object */
+    }
+
+    input_buffer->offset++;
+    buffer_skip_whitespace(input_buffer);
+    if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}'))
+    {
+        goto success; /* empty object */
+    }
+
+    /* check if we skipped to the end of the buffer */
+    if (cannot_access_at_index(input_buffer, 0))
+    {
+        input_buffer->offset--;
+        goto fail;
+    }
+
+    /* step back to character in front of the first element */
+    input_buffer->offset--;
+    /* loop through the comma separated array elements */
+    do
+    {
+        /* allocate next item */
+        cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
+        if (new_item == NULL)
+        {
+            goto fail; /* allocation failure */
+        }
+
+        /* attach next item to list */
+        if (head == NULL)
+        {
+            /* start the linked list */
+            current_item = head = new_item;
+        }
+        else
+        {
+            /* add to the end and advance */
+            current_item->next = new_item;
+            new_item->prev = current_item;
+            current_item = new_item;
+        }
+
+        /* parse the name of the child */
+        input_buffer->offset++;
+        buffer_skip_whitespace(input_buffer);
+        if (!parse_string(current_item, input_buffer))
+        {
+            goto fail; /* failed to parse name */
+        }
+        buffer_skip_whitespace(input_buffer);
+
+        /* swap valuestring and string, because we parsed the name */
+        current_item->string = current_item->valuestring;
+        current_item->valuestring = NULL;
+
+        if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':'))
+        {
+            goto fail; /* invalid object */
+        }
+
+        /* parse the value */
+        input_buffer->offset++;
+        buffer_skip_whitespace(input_buffer);
+        if (!parse_value(current_item, input_buffer))
+        {
+            goto fail; /* failed to parse value */
+        }
+        buffer_skip_whitespace(input_buffer);
+    }
+    while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
+
+    if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}'))
+    {
+        goto fail; /* expected end of object */
+    }
+
+success:
+    input_buffer->depth--;
+
+    item->type = cJSON_Object;
+    item->child = head;
+
+    input_buffer->offset++;
+    return true;
+
+fail:
+    if (head != NULL)
+    {
+        cJSON_Delete(head);
+    }
+
+    return false;
+}
+
+/* Render an object to text. */
+static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer)
+{
+    unsigned char *output_pointer = NULL;
+    size_t length = 0;
+    cJSON *current_item = item->child;
+
+    if (output_buffer == NULL)
+    {
+        return false;
+    }
+
+    /* Compose the output: */
+    length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
+    output_pointer = ensure(output_buffer, length + 1);
+    if (output_pointer == NULL)
+    {
+        return false;
+    }
+
+    *output_pointer++ = '{';
+    output_buffer->depth++;
+    if (output_buffer->format)
+    {
+        *output_pointer++ = '\n';
+    }
+    output_buffer->offset += length;
+
+    while (current_item)
+    {
+        if (output_buffer->format)
+        {
+            size_t i;
+            output_pointer = ensure(output_buffer, output_buffer->depth);
+            if (output_pointer == NULL)
+            {
+                return false;
+            }
+            for (i = 0; i < output_buffer->depth; i++)
+            {
+                *output_pointer++ = '\t';
+            }
+            output_buffer->offset += output_buffer->depth;
+        }
+
+        /* print key */
+        if (!print_string_ptr((unsigned char*)current_item->string, output_buffer))
+        {
+            return false;
+        }
+        update_offset(output_buffer);
+
+        length = (size_t) (output_buffer->format ? 2 : 1);
+        output_pointer = ensure(output_buffer, length);
+        if (output_pointer == NULL)
+        {
+            return false;
+        }
+        *output_pointer++ = ':';
+        if (output_buffer->format)
+        {
+            *output_pointer++ = '\t';
+        }
+        output_buffer->offset += length;
+
+        /* print value */
+        if (!print_value(current_item, output_buffer))
+        {
+            return false;
+        }
+        update_offset(output_buffer);
+
+        /* print comma if not last */
+        length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0));
+        output_pointer = ensure(output_buffer, length + 1);
+        if (output_pointer == NULL)
+        {
+            return false;
+        }
+        if (current_item->next)
+        {
+            *output_pointer++ = ',';
+        }
+
+        if (output_buffer->format)
+        {
+            *output_pointer++ = '\n';
+        }
+        *output_pointer = '\0';
+        output_buffer->offset += length;
+
+        current_item = current_item->next;
+    }
+
+    output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
+    if (output_pointer == NULL)
+    {
+        return false;
+    }
+    if (output_buffer->format)
+    {
+        size_t i;
+        for (i = 0; i < (output_buffer->depth - 1); i++)
+        {
+            *output_pointer++ = '\t';
+        }
+    }
+    *output_pointer++ = '}';
+    *output_pointer = '\0';
+    output_buffer->depth--;
+
+    return true;
+}
+
+/* Get Array size/item / object item. */
+CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
+{
+    cJSON *child = NULL;
+    size_t size = 0;
+
+    if (array == NULL)
+    {
+        return 0;
+    }
+
+    child = array->child;
+
+    while(child != NULL)
+    {
+        size++;
+        child = child->next;
+    }
+
+    /* FIXME: Can overflow here. Cannot be fixed without breaking the API */
+
+    return (int)size;
+}
+
+static cJSON* get_array_item(const cJSON *array, size_t index)
+{
+    cJSON *current_child = NULL;
+
+    if (array == NULL)
+    {
+        return NULL;
+    }
+
+    current_child = array->child;
+    while ((current_child != NULL) && (index > 0))
+    {
+        index--;
+        current_child = current_child->next;
+    }
+
+    return current_child;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index)
+{
+    if (index < 0)
+    {
+        return NULL;
+    }
+
+    return get_array_item(array, (size_t)index);
+}
+
+static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)
+{
+    cJSON *current_element = NULL;
+
+    if ((object == NULL) || (name == NULL))
+    {
+        return NULL;
+    }
+
+    current_element = object->child;
+    if (case_sensitive)
+    {
+        while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0))
+        {
+            current_element = current_element->next;
+        }
+    }
+    else
+    {
+        while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0))
+        {
+            current_element = current_element->next;
+        }
+    }
+
+    if ((current_element == NULL) || (current_element->string == NULL)) {
+        return NULL;
+    }
+
+    return current_element;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)
+{
+    return get_object_item(object, string, false);
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string)
+{
+    return get_object_item(object, string, true);
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string)
+{
+    return cJSON_GetObjectItem(object, string) ? 1 : 0;
+}
+
+/* Utility for array list handling. */
+static void suffix_object(cJSON *prev, cJSON *item)
+{
+    prev->next = item;
+    item->prev = prev;
+}
+
+/* Utility for handling references. */
+static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks)
+{
+    cJSON *reference = NULL;
+    if (item == NULL)
+    {
+        return NULL;
+    }
+
+    reference = cJSON_New_Item(hooks);
+    if (reference == NULL)
+    {
+        return NULL;
+    }
+
+    memcpy(reference, item, sizeof(cJSON));
+    reference->string = NULL;
+    reference->type |= cJSON_IsReference;
+    reference->next = reference->prev = NULL;
+    return reference;
+}
+
+static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
+{
+    cJSON *child = NULL;
+
+    if ((item == NULL) || (array == NULL))
+    {
+        return false;
+    }
+
+    child = array->child;
+    /*
+     * To find the last item int array quickly, we use prev in array
+     */
+    if (child == NULL)
+    {
+        /* list is empty, start new one */
+        array->child = item;
+        item->prev = item;
+        item->next = NULL;
+    }
+    else
+    {
+        /* append to the end */
+        if (child->prev)
+        {
+            suffix_object(child->prev, item);
+            array->child->prev = item;
+        }
+        else
+        {
+            while (child->next)
+            {
+                child = child->next;
+            }
+            suffix_object(child, item);
+            array->child->prev = item;
+        }
+    }
+    return true;
+}
+
+/* Add item to array/object. */
+CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item)
+{
+    add_item_to_array(array, item);
+}
+
+#if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
+    #pragma GCC diagnostic push
+#endif
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+/* helper function to cast away const */
+static void* cast_away_const(const void* string)
+{
+    return (void*)string;
+}
+#if defined(__clang__) || (defined(__GNUC__)  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
+    #pragma GCC diagnostic pop
+#endif
+
+
+static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)
+{
+    char *new_key = NULL;
+    int new_type = cJSON_Invalid;
+
+    if ((object == NULL) || (string == NULL) || (item == NULL))
+    {
+        return false;
+    }
+
+    if (constant_key)
+    {
+        new_key = (char*)cast_away_const(string);
+        new_type = item->type | cJSON_StringIsConst;
+    }
+    else
+    {
+        new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
+        if (new_key == NULL)
+        {
+            return false;
+        }
+
+        new_type = item->type & ~cJSON_StringIsConst;
+    }
+
+    if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
+    {
+        hooks->deallocate(item->string);
+    }
+
+    item->string = new_key;
+    item->type = new_type;
+
+    return add_item_to_array(object, item);
+}
+
+CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
+{
+    add_item_to_object(object, string, item, &global_hooks, false);
+}
+
+/* Add an item to an object with constant string as key */
+CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
+{
+    add_item_to_object(object, string, item, &global_hooks, true);
+}
+
+CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
+{
+    if (array == NULL)
+    {
+        return;
+    }
+
+    add_item_to_array(array, create_reference(item, &global_hooks));
+}
+
+CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
+{
+    if ((object == NULL) || (string == NULL))
+    {
+        return;
+    }
+
+    add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
+}
+
+CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
+{
+    cJSON *null = cJSON_CreateNull();
+    if (add_item_to_object(object, name, null, &global_hooks, false))
+    {
+        return null;
+    }
+
+    cJSON_Delete(null);
+    return NULL;
+}
+
+CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name)
+{
+    cJSON *true_item = cJSON_CreateTrue();
+    if (add_item_to_object(object, name, true_item, &global_hooks, false))
+    {
+        return true_item;
+    }
+
+    cJSON_Delete(true_item);
+    return NULL;
+}
+
+CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name)
+{
+    cJSON *false_item = cJSON_CreateFalse();
+    if (add_item_to_object(object, name, false_item, &global_hooks, false))
+    {
+        return false_item;
+    }
+
+    cJSON_Delete(false_item);
+    return NULL;
+}
+
+CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean)
+{
+    cJSON *bool_item = cJSON_CreateBool(boolean);
+    if (add_item_to_object(object, name, bool_item, &global_hooks, false))
+    {
+        return bool_item;
+    }
+
+    cJSON_Delete(bool_item);
+    return NULL;
+}
+
+CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number)
+{
+    cJSON *number_item = cJSON_CreateNumber(number);
+    if (add_item_to_object(object, name, number_item, &global_hooks, false))
+    {
+        return number_item;
+    }
+
+    cJSON_Delete(number_item);
+    return NULL;
+}
+
+CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string)
+{
+    cJSON *string_item = cJSON_CreateString(string);
+    if (add_item_to_object(object, name, string_item, &global_hooks, false))
+    {
+        return string_item;
+    }
+
+    cJSON_Delete(string_item);
+    return NULL;
+}
+
+CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw)
+{
+    cJSON *raw_item = cJSON_CreateRaw(raw);
+    if (add_item_to_object(object, name, raw_item, &global_hooks, false))
+    {
+        return raw_item;
+    }
+
+    cJSON_Delete(raw_item);
+    return NULL;
+}
+
+CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name)
+{
+    cJSON *object_item = cJSON_CreateObject();
+    if (add_item_to_object(object, name, object_item, &global_hooks, false))
+    {
+        return object_item;
+    }
+
+    cJSON_Delete(object_item);
+    return NULL;
+}
+
+CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name)
+{
+    cJSON *array = cJSON_CreateArray();
+    if (add_item_to_object(object, name, array, &global_hooks, false))
+    {
+        return array;
+    }
+
+    cJSON_Delete(array);
+    return NULL;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
+{
+    if ((parent == NULL) || (item == NULL))
+    {
+        return NULL;
+    }
+
+    if (item->prev != NULL)
+    {
+        /* not the first element */
+        item->prev->next = item->next;
+    }
+    if (item->next != NULL)
+    {
+        /* not the last element */
+        item->next->prev = item->prev;
+    }
+
+    if (item == parent->child)
+    {
+        /* first element */
+        parent->child = item->next;
+    }
+    /* make sure the detached item doesn't point anywhere anymore */
+    item->prev = NULL;
+    item->next = NULL;
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
+{
+    if (which < 0)
+    {
+        return NULL;
+    }
+
+    return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which));
+}
+
+CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
+{
+    cJSON_Delete(cJSON_DetachItemFromArray(array, which));
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)
+{
+    cJSON *to_detach = cJSON_GetObjectItem(object, string);
+
+    return cJSON_DetachItemViaPointer(object, to_detach);
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string)
+{
+    cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string);
+
+    return cJSON_DetachItemViaPointer(object, to_detach);
+}
+
+CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
+{
+    cJSON_Delete(cJSON_DetachItemFromObject(object, string));
+}
+
+CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)
+{
+    cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string));
+}
+
+/* Replace array/object items with new ones. */
+CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
+{
+    cJSON *after_inserted = NULL;
+
+    if (which < 0)
+    {
+        return;
+    }
+
+    after_inserted = get_array_item(array, (size_t)which);
+    if (after_inserted == NULL)
+    {
+        add_item_to_array(array, newitem);
+        return;
+    }
+
+    newitem->next = after_inserted;
+    newitem->prev = after_inserted->prev;
+    after_inserted->prev = newitem;
+    if (after_inserted == array->child)
+    {
+        array->child = newitem;
+    }
+    else
+    {
+        newitem->prev->next = newitem;
+    }
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
+{
+    if ((parent == NULL) || (replacement == NULL) || (item == NULL))
+    {
+        return false;
+    }
+
+    if (replacement == item)
+    {
+        return true;
+    }
+
+    replacement->next = item->next;
+    replacement->prev = item->prev;
+
+    if (replacement->next != NULL)
+    {
+        replacement->next->prev = replacement;
+    }
+
+    if (parent->child == item)
+    {
+        parent->child = replacement;
+    }
+    else
+    {   /*
+         * To find the last item int array quickly, we use prev in array.
+         * We can't modify the last item's next pointer where this item was the parent's child
+         */
+        if (replacement->prev != NULL)
+        {
+            replacement->prev->next = replacement;
+        }
+    }
+
+    item->next = NULL;
+    item->prev = NULL;
+    cJSON_Delete(item);
+
+    return true;
+}
+
+CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
+{
+    if (which < 0)
+    {
+        return;
+    }
+
+    cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
+}
+
+static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
+{
+    if ((replacement == NULL) || (string == NULL))
+    {
+        return false;
+    }
+
+    /* replace the name in the replacement */
+    if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))
+    {
+        cJSON_free(replacement->string);
+    }
+    replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
+    replacement->type &= ~cJSON_StringIsConst;
+
+    cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
+
+    return true;
+}
+
+CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
+{
+    replace_item_in_object(object, string, newitem, false);
+}
+
+CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
+{
+    replace_item_in_object(object, string, newitem, true);
+}
+
+/* Create basic types: */
+CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_NULL;
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_True;
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_False;
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = boolean ? cJSON_True : cJSON_False;
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_Number;
+        item->valuedouble = num;
+
+        /* use saturation in case of overflow */
+        if (num >= INT_MAX)
+        {
+            item->valueint = INT_MAX;
+        }
+        else if (num <= (double)INT_MIN)
+        {
+            item->valueint = INT_MIN;
+        }
+        else
+        {
+            item->valueint = (int)num;
+        }
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_String;
+        item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
+        if(!item->valuestring)
+        {
+            cJSON_Delete(item);
+            return NULL;
+        }
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if (item != NULL)
+    {
+        item->type = cJSON_String | cJSON_IsReference;
+        item->valuestring = (char*)cast_away_const(string);
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if (item != NULL) {
+        item->type = cJSON_Object | cJSON_IsReference;
+        item->child = (cJSON*)cast_away_const(child);
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) {
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if (item != NULL) {
+        item->type = cJSON_Array | cJSON_IsReference;
+        item->child = (cJSON*)cast_away_const(child);
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type = cJSON_Raw;
+        item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks);
+        if(!item->valuestring)
+        {
+            cJSON_Delete(item);
+            return NULL;
+        }
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if(item)
+    {
+        item->type=cJSON_Array;
+    }
+
+    return item;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void)
+{
+    cJSON *item = cJSON_New_Item(&global_hooks);
+    if (item)
+    {
+        item->type = cJSON_Object;
+    }
+
+    return item;
+}
+
+/* Create Arrays: */
+CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
+{
+    size_t i = 0;
+    cJSON *n = NULL;
+    cJSON *p = NULL;
+    cJSON *a = NULL;
+
+    if ((count < 0) || (numbers == NULL))
+    {
+        return NULL;
+    }
+
+    a = cJSON_CreateArray();
+    for(i = 0; a && (i < (size_t)count); i++)
+    {
+        n = cJSON_CreateNumber(numbers[i]);
+        if (!n)
+        {
+            cJSON_Delete(a);
+            return NULL;
+        }
+        if(!i)
+        {
+            a->child = n;
+        }
+        else
+        {
+            suffix_object(p, n);
+        }
+        p = n;
+    }
+
+    return a;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
+{
+    size_t i = 0;
+    cJSON *n = NULL;
+    cJSON *p = NULL;
+    cJSON *a = NULL;
+
+    if ((count < 0) || (numbers == NULL))
+    {
+        return NULL;
+    }
+
+    a = cJSON_CreateArray();
+
+    for(i = 0; a && (i < (size_t)count); i++)
+    {
+        n = cJSON_CreateNumber((double)numbers[i]);
+        if(!n)
+        {
+            cJSON_Delete(a);
+            return NULL;
+        }
+        if(!i)
+        {
+            a->child = n;
+        }
+        else
+        {
+            suffix_object(p, n);
+        }
+        p = n;
+    }
+
+    return a;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
+{
+    size_t i = 0;
+    cJSON *n = NULL;
+    cJSON *p = NULL;
+    cJSON *a = NULL;
+
+    if ((count < 0) || (numbers == NULL))
+    {
+        return NULL;
+    }
+
+    a = cJSON_CreateArray();
+
+    for(i = 0;a && (i < (size_t)count); i++)
+    {
+        n = cJSON_CreateNumber(numbers[i]);
+        if(!n)
+        {
+            cJSON_Delete(a);
+            return NULL;
+        }
+        if(!i)
+        {
+            a->child = n;
+        }
+        else
+        {
+            suffix_object(p, n);
+        }
+        p = n;
+    }
+
+    return a;
+}
+
+CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count)
+{
+    size_t i = 0;
+    cJSON *n = NULL;
+    cJSON *p = NULL;
+    cJSON *a = NULL;
+
+    if ((count < 0) || (strings == NULL))
+    {
+        return NULL;
+    }
+
+    a = cJSON_CreateArray();
+
+    for (i = 0; a && (i < (size_t)count); i++)
+    {
+        n = cJSON_CreateString(strings[i]);
+        if(!n)
+        {
+            cJSON_Delete(a);
+            return NULL;
+        }
+        if(!i)
+        {
+            a->child = n;
+        }
+        else
+        {
+            suffix_object(p,n);
+        }
+        p = n;
+    }
+
+    return a;
+}
+
+/* Duplication */
+CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
+{
+    cJSON *newitem = NULL;
+    cJSON *child = NULL;
+    cJSON *next = NULL;
+    cJSON *newchild = NULL;
+
+    /* Bail on bad ptr */
+    if (!item)
+    {
+        goto fail;
+    }
+    /* Create new item */
+    newitem = cJSON_New_Item(&global_hooks);
+    if (!newitem)
+    {
+        goto fail;
+    }
+    /* Copy over all vars */
+    newitem->type = item->type & (~cJSON_IsReference);
+    newitem->valueint = item->valueint;
+    newitem->valuedouble = item->valuedouble;
+    if (item->valuestring)
+    {
+        newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks);
+        if (!newitem->valuestring)
+        {
+            goto fail;
+        }
+    }
+    if (item->string)
+    {
+        newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks);
+        if (!newitem->string)
+        {
+            goto fail;
+        }
+    }
+    /* If non-recursive, then we're done! */
+    if (!recurse)
+    {
+        return newitem;
+    }
+    /* Walk the ->next chain for the child. */
+    child = item->child;
+    while (child != NULL)
+    {
+        newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
+        if (!newchild)
+        {
+            goto fail;
+        }
+        if (next != NULL)
+        {
+            /* If newitem->child already set, then crosswire ->prev and ->next and move on */
+            next->next = newchild;
+            newchild->prev = next;
+            next = newchild;
+        }
+        else
+        {
+            /* Set newitem->child and move to it */
+            newitem->child = newchild;
+            next = newchild;
+        }
+        child = child->next;
+    }
+
+    return newitem;
+
+fail:
+    if (newitem != NULL)
+    {
+        cJSON_Delete(newitem);
+    }
+
+    return NULL;
+}
+
+static void skip_oneline_comment(char **input)
+{
+    *input += static_strlen("//");
+
+    for (; (*input)[0] != '\0'; ++(*input))
+    {
+        if ((*input)[0] == '\n') {
+            *input += static_strlen("\n");
+            return;
+        }
+    }
+}
+
+static void skip_multiline_comment(char **input)
+{
+    *input += static_strlen("/*");
+
+    for (; (*input)[0] != '\0'; ++(*input))
+    {
+        if (((*input)[0] == '*') && ((*input)[1] == '/'))
+        {
+            *input += static_strlen("*/");
+            return;
+        }
+    }
+}
+
+static void minify_string(char **input, char **output) {
+    (*output)[0] = (*input)[0];
+    *input += static_strlen("\"");
+    *output += static_strlen("\"");
+
+
+    for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) {
+        (*output)[0] = (*input)[0];
+
+        if ((*input)[0] == '\"') {
+            (*output)[0] = '\"';
+            *input += static_strlen("\"");
+            *output += static_strlen("\"");
+            return;
+        } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) {
+            (*output)[1] = (*input)[1];
+            *input += static_strlen("\"");
+            *output += static_strlen("\"");
+        }
+    }
+}
+
+CJSON_PUBLIC(void) cJSON_Minify(char *json)
+{
+    char *into = json;
+
+    if (json == NULL)
+    {
+        return;
+    }
+
+    while (json[0] != '\0')
+    {
+        switch (json[0])
+        {
+            case ' ':
+            case '\t':
+            case '\r':
+            case '\n':
+                json++;
+                break;
+
+            case '/':
+                if (json[1] == '/')
+                {
+                    skip_oneline_comment(&json);
+                }
+                else if (json[1] == '*')
+                {
+                    skip_multiline_comment(&json);
+                } else {
+                    json++;
+                }
+                break;
+
+            case '\"':
+                minify_string(&json, (char**)&into);
+                break;
+
+            default:
+                into[0] = json[0];
+                json++;
+                into++;
+        }
+    }
+
+    /* and null-terminate. */
+    *into = '\0';
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_Invalid;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_False;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xff) == cJSON_True;
+}
+
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & (cJSON_True | cJSON_False)) != 0;
+}
+CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_NULL;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_Number;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_String;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_Array;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_Object;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
+{
+    if (item == NULL)
+    {
+        return false;
+    }
+
+    return (item->type & 0xFF) == cJSON_Raw;
+}
+
+CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
+{
+    if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
+    {
+        return false;
+    }
+
+    /* check if type is valid */
+    switch (a->type & 0xFF)
+    {
+        case cJSON_False:
+        case cJSON_True:
+        case cJSON_NULL:
+        case cJSON_Number:
+        case cJSON_String:
+        case cJSON_Raw:
+        case cJSON_Array:
+        case cJSON_Object:
+            break;
+
+        default:
+            return false;
+    }
+
+    /* identical objects are equal */
+    if (a == b)
+    {
+        return true;
+    }
+
+    switch (a->type & 0xFF)
+    {
+        /* in these cases and equal type is enough */
+        case cJSON_False:
+        case cJSON_True:
+        case cJSON_NULL:
+            return true;
+
+        case cJSON_Number:
+            if (compare_double(a->valuedouble, b->valuedouble))
+            {
+                return true;
+            }
+            return false;
+
+        case cJSON_String:
+        case cJSON_Raw:
+            if ((a->valuestring == NULL) || (b->valuestring == NULL))
+            {
+                return false;
+            }
+            if (strcmp(a->valuestring, b->valuestring) == 0)
+            {
+                return true;
+            }
+
+            return false;
+
+        case cJSON_Array:
+        {
+            cJSON *a_element = a->child;
+            cJSON *b_element = b->child;
+
+            for (; (a_element != NULL) && (b_element != NULL);)
+            {
+                if (!cJSON_Compare(a_element, b_element, case_sensitive))
+                {
+                    return false;
+                }
+
+                a_element = a_element->next;
+                b_element = b_element->next;
+            }
+
+            /* one of the arrays is longer than the other */
+            if (a_element != b_element) {
+                return false;
+            }
+
+            return true;
+        }
+
+        case cJSON_Object:
+        {
+            cJSON *a_element = NULL;
+            cJSON *b_element = NULL;
+            cJSON_ArrayForEach(a_element, a)
+            {
+                /* TODO This has O(n^2) runtime, which is horrible! */
+                b_element = get_object_item(b, a_element->string, case_sensitive);
+                if (b_element == NULL)
+                {
+                    return false;
+                }
+
+                if (!cJSON_Compare(a_element, b_element, case_sensitive))
+                {
+                    return false;
+                }
+            }
+
+            /* doing this twice, once on a and b to prevent true comparison if a subset of b
+             * TODO: Do this the proper way, this is just a fix for now */
+            cJSON_ArrayForEach(b_element, b)
+            {
+                a_element = get_object_item(a, b_element->string, case_sensitive);
+                if (a_element == NULL)
+                {
+                    return false;
+                }
+
+                if (!cJSON_Compare(b_element, a_element, case_sensitive))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        default:
+            return false;
+    }
+}
+
+CJSON_PUBLIC(void *) cJSON_malloc(size_t size)
+{
+    return global_hooks.allocate(size);
+}
+
+CJSON_PUBLIC(void) cJSON_free(void *object)
+{
+    global_hooks.deallocate(object);
+}
diff --git a/pkgs/ffigen/third_party/cjson_library/cJSON.h b/pkgs/ffigen/third_party/cjson_library/cJSON.h
new file mode 100644
index 0000000..9d28b24
--- /dev/null
+++ b/pkgs/ffigen/third_party/cjson_library/cJSON.h
@@ -0,0 +1,292 @@
+/*
+  Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+*/
+#ifndef cJSON__h
+#define cJSON__h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
+#define __WINDOWS__
+#endif
+
+#ifdef __WINDOWS__
+
+/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention.  For windows you have 3 define options:
+
+CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
+CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
+CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
+
+For *nix builds that support visibility attribute, you can define similar behavior by
+
+setting default visibility to hidden by adding
+-fvisibility=hidden (for gcc)
+or
+-xldscope=hidden (for sun cc)
+to CFLAGS
+
+then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
+
+*/
+
+#define CJSON_CDECL __cdecl
+#define CJSON_STDCALL __stdcall
+
+/* export symbols by default, this is necessary for copy pasting the C and header file */
+#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
+#define CJSON_EXPORT_SYMBOLS
+#endif
+
+#if defined(CJSON_HIDE_SYMBOLS)
+#define CJSON_PUBLIC(type)   type CJSON_STDCALL
+#elif defined(CJSON_EXPORT_SYMBOLS)
+#define CJSON_PUBLIC(type)   __declspec(dllexport) type CJSON_STDCALL
+#elif defined(CJSON_IMPORT_SYMBOLS)
+#define CJSON_PUBLIC(type)   __declspec(dllimport) type CJSON_STDCALL
+#endif
+#else /* !__WINDOWS__ */
+#define CJSON_CDECL
+#define CJSON_STDCALL
+
+#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
+#define CJSON_PUBLIC(type)   __attribute__((visibility("default"))) type
+#else
+#define CJSON_PUBLIC(type) type
+#endif
+#endif
+
+/* project version */
+#define CJSON_VERSION_MAJOR 1
+#define CJSON_VERSION_MINOR 7
+#define CJSON_VERSION_PATCH 12
+
+#include <stddef.h>
+
+/* cJSON Types: */
+#define cJSON_Invalid (0)
+#define cJSON_False  (1 << 0)
+#define cJSON_True   (1 << 1)
+#define cJSON_NULL   (1 << 2)
+#define cJSON_Number (1 << 3)
+#define cJSON_String (1 << 4)
+#define cJSON_Array  (1 << 5)
+#define cJSON_Object (1 << 6)
+#define cJSON_Raw    (1 << 7) /* raw json */
+
+#define cJSON_IsReference 256
+#define cJSON_StringIsConst 512
+
+/* The cJSON structure: */
+typedef struct cJSON
+{
+    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
+    struct cJSON *next;
+    struct cJSON *prev;
+    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
+    struct cJSON *child;
+
+    /* The type of the item, as above. */
+    int type;
+
+    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
+    char *valuestring;
+    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
+    int valueint;
+    /* The item's number, if type==cJSON_Number */
+    double valuedouble;
+
+    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
+    char *string;
+} cJSON;
+
+typedef struct cJSON_Hooks
+{
+      /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
+      void *(CJSON_CDECL *malloc_fn)(size_t sz);
+      void (CJSON_CDECL *free_fn)(void *ptr);
+} cJSON_Hooks;
+
+typedef int cJSON_bool;
+
+/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
+ * This is to prevent stack overflows. */
+#ifndef CJSON_NESTING_LIMIT
+#define CJSON_NESTING_LIMIT 1000
+#endif
+
+/* Precision of double variables comparison */
+#ifndef CJSON_DOUBLE_PRECISION
+#define CJSON_DOUBLE_PRECISION .0000000000000001
+#endif
+
+/* returns the version of cJSON as a string */
+CJSON_PUBLIC(const char*) cJSON_Version(void);
+
+/* Supply malloc, realloc and free functions to cJSON */
+CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
+
+/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
+/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
+CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
+/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
+/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
+CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
+
+/* Render a cJSON entity to text for transfer/storage. */
+CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
+/* Render a cJSON entity to text for transfer/storage without any formatting. */
+CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
+/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
+CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
+/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
+/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
+CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
+/* Delete a cJSON entity and all subentities. */
+CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
+
+/* Returns the number of items in an array (or object). */
+CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
+/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
+CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
+/* Get item "string" from object. Case insensitive. */
+CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
+CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
+CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
+/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
+CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
+
+/* Check if the item is a string and return its valuestring */
+CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
+
+/* These functions check the type of an item */
+CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
+CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
+
+/* These calls create a cJSON item of the appropriate type. */
+CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
+CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
+CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
+CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
+CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
+CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
+/* raw json */
+CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
+CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
+CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
+
+/* Create a string where valuestring references a string so
+ * it will not be freed by cJSON_Delete */
+CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
+/* Create an object/array that only references it's elements so
+ * they will not be freed by cJSON_Delete */
+CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
+CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
+
+/* These utilities create an Array of count items.
+ * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
+CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
+CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
+CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
+CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
+
+/* Append item to the specified array/object. */
+CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
+CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
+/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
+ * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
+ * writing to `item->string` */
+CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
+/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
+CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
+CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
+
+/* Remove/Detach items from Arrays/Objects. */
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
+CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
+CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
+CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
+
+/* Update array items. */
+CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
+CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
+CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
+CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
+CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
+
+/* Duplicate a cJSON item */
+CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
+/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
+ * need to be released. With recurse!=0, it will duplicate any children connected to the item.
+ * The item->next and ->prev pointers are always zero on return from Duplicate. */
+/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
+ * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
+CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
+
+/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
+ * The input pointer json cannot point to a read-only address area, such as a string constant, 
+ * but should point to a readable and writable adress area. */
+CJSON_PUBLIC(void) cJSON_Minify(char *json);
+
+/* Helper functions for creating and adding items to an object at the same time.
+ * They return the added item or NULL on failure. */
+CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
+CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
+CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
+CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
+CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
+CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
+CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
+CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
+CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
+
+/* When assigning an integer value, it needs to be propagated to valuedouble too. */
+#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
+/* helper for the cJSON_SetNumberValue macro */
+CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
+#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
+
+/* Macro for iterating over an array or object */
+#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
+
+/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
+CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
+CJSON_PUBLIC(void) cJSON_free(void *object);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkgs/ffigen/third_party/cjson_library/license.txt b/pkgs/ffigen/third_party/cjson_library/license.txt
new file mode 100644
index 0000000..287ef35
--- /dev/null
+++ b/pkgs/ffigen/third_party/cjson_library/license.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+
+
+Files generated from cJSON source code are
+- example/c_json/cjson_generated_bindings.dart
+- test/large_integration_tests/_expected_cjson_bindings.dart
diff --git a/pkgs/ffigen/third_party/libclang/include/clang-c/BuildSystem.h b/pkgs/ffigen/third_party/libclang/include/clang-c/BuildSystem.h
new file mode 100644
index 0000000..4e9f6de
--- /dev/null
+++ b/pkgs/ffigen/third_party/libclang/include/clang-c/BuildSystem.h
@@ -0,0 +1,153 @@
+/*==-- clang-c/BuildSystem.h - Utilities for use by build systems -*- C -*-===*\
+|*                                                                            *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
+|* Exceptions.                                                                *|
+|* See https://llvm.org/LICENSE.txt for license information.                  *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides various utilities for use by build systems.           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_BUILDSYSTEM_H
+#define LLVM_CLANG_C_BUILDSYSTEM_H
+
+#include "clang-c/CXErrorCode.h"
+#include "clang-c/CXString.h"
+#include "clang-c/ExternC.h"
+#include "clang-c/Platform.h"
+
+LLVM_CLANG_C_EXTERN_C_BEGIN
+
+/**
+ * \defgroup BUILD_SYSTEM Build system utilities
+ * @{
+ */
+
+/**
+ * Return the timestamp for use with Clang's
+ * \c -fbuild-session-timestamp= option.
+ */
+CINDEX_LINKAGE unsigned long long clang_getBuildSessionTimestamp(void);
+
+/**
+ * Object encapsulating information about overlaying virtual
+ * file/directories over the real file system.
+ */
+typedef struct CXVirtualFileOverlayImpl *CXVirtualFileOverlay;
+
+/**
+ * Create a \c CXVirtualFileOverlay object.
+ * Must be disposed with \c clang_VirtualFileOverlay_dispose().
+ *
+ * \param options is reserved, always pass 0.
+ */
+CINDEX_LINKAGE CXVirtualFileOverlay
+clang_VirtualFileOverlay_create(unsigned options);
+
+/**
+ * Map an absolute virtual file path to an absolute real one.
+ * The virtual path must be canonicalized (not contain "."/"..").
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay,
+                                        const char *virtualPath,
+                                        const char *realPath);
+
+/**
+ * Set the case sensitivity for the \c CXVirtualFileOverlay object.
+ * The \c CXVirtualFileOverlay object is case-sensitive by default, this
+ * option can be used to override the default.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay,
+                                            int caseSensitive);
+
+/**
+ * Write out the \c CXVirtualFileOverlay object to a char buffer.
+ *
+ * \param options is reserved, always pass 0.
+ * \param out_buffer_ptr pointer to receive the buffer pointer, which should be
+ * disposed using \c clang_free().
+ * \param out_buffer_size pointer to receive the buffer size.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay, unsigned options,
+                                       char **out_buffer_ptr,
+                                       unsigned *out_buffer_size);
+
+/**
+ * free memory allocated by libclang, such as the buffer returned by
+ * \c CXVirtualFileOverlay() or \c clang_ModuleMapDescriptor_writeToBuffer().
+ *
+ * \param buffer memory pointer to free.
+ */
+CINDEX_LINKAGE void clang_free(void *buffer);
+
+/**
+ * Dispose a \c CXVirtualFileOverlay object.
+ */
+CINDEX_LINKAGE void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay);
+
+/**
+ * Object encapsulating information about a module.map file.
+ */
+typedef struct CXModuleMapDescriptorImpl *CXModuleMapDescriptor;
+
+/**
+ * Create a \c CXModuleMapDescriptor object.
+ * Must be disposed with \c clang_ModuleMapDescriptor_dispose().
+ *
+ * \param options is reserved, always pass 0.
+ */
+CINDEX_LINKAGE CXModuleMapDescriptor
+clang_ModuleMapDescriptor_create(unsigned options);
+
+/**
+ * Sets the framework module name that the module.map describes.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor,
+                                                 const char *name);
+
+/**
+ * Sets the umbrealla header name that the module.map describes.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor,
+                                            const char *name);
+
+/**
+ * Write out the \c CXModuleMapDescriptor object to a char buffer.
+ *
+ * \param options is reserved, always pass 0.
+ * \param out_buffer_ptr pointer to receive the buffer pointer, which should be
+ * disposed using \c clang_free().
+ * \param out_buffer_size pointer to receive the buffer size.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor, unsigned options,
+                                       char **out_buffer_ptr,
+                                       unsigned *out_buffer_size);
+
+/**
+ * Dispose a \c CXModuleMapDescriptor object.
+ */
+CINDEX_LINKAGE void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor);
+
+/**
+ * @}
+ */
+
+LLVM_CLANG_C_EXTERN_C_END
+
+#endif /* CLANG_C_BUILD_SYSTEM_H */
+
diff --git a/pkgs/ffigen/third_party/libclang/include/clang-c/CXCompilationDatabase.h b/pkgs/ffigen/third_party/libclang/include/clang-c/CXCompilationDatabase.h
new file mode 100644
index 0000000..2b336e5
--- /dev/null
+++ b/pkgs/ffigen/third_party/libclang/include/clang-c/CXCompilationDatabase.h
@@ -0,0 +1,174 @@
+/*===-- clang-c/CXCompilationDatabase.h - Compilation database  ---*- C -*-===*\
+|*                                                                            *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
+|* Exceptions.                                                                *|
+|* See https://llvm.org/LICENSE.txt for license information.                  *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides a public interface to use CompilationDatabase without *|
+|* the full Clang C++ API.                                                    *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_CXCOMPILATIONDATABASE_H
+#define LLVM_CLANG_C_CXCOMPILATIONDATABASE_H
+
+#include "clang-c/CXString.h"
+#include "clang-c/ExternC.h"
+#include "clang-c/Platform.h"
+
+LLVM_CLANG_C_EXTERN_C_BEGIN
+
+/** \defgroup COMPILATIONDB CompilationDatabase functions
+ * \ingroup CINDEX
+ *
+ * @{
+ */
+
+/**
+ * A compilation database holds all information used to compile files in a
+ * project. For each file in the database, it can be queried for the working
+ * directory or the command line used for the compiler invocation.
+ *
+ * Must be freed by \c clang_CompilationDatabase_dispose
+ */
+typedef void * CXCompilationDatabase;
+
+/**
+ * Contains the results of a search in the compilation database
+ *
+ * When searching for the compile command for a file, the compilation db can
+ * return several commands, as the file may have been compiled with
+ * different options in different places of the project. This choice of compile
+ * commands is wrapped in this opaque data structure. It must be freed by
+ * \c clang_CompileCommands_dispose.
+ */
+typedef void * CXCompileCommands;
+
+/**
+ * Represents the command line invocation to compile a specific file.
+ */
+typedef void * CXCompileCommand;
+
+/**
+ * Error codes for Compilation Database
+ */
+typedef enum  {
+  /*
+   * No error occurred
+   */
+  CXCompilationDatabase_NoError = 0,
+
+  /*
+   * Database can not be loaded
+   */
+  CXCompilationDatabase_CanNotLoadDatabase = 1
+
+} CXCompilationDatabase_Error;
+
+/**
+ * Creates a compilation database from the database found in directory
+ * buildDir. For example, CMake can output a compile_commands.json which can
+ * be used to build the database.
+ *
+ * It must be freed by \c clang_CompilationDatabase_dispose.
+ */
+CINDEX_LINKAGE CXCompilationDatabase
+clang_CompilationDatabase_fromDirectory(const char *BuildDir,
+                                        CXCompilationDatabase_Error *ErrorCode);
+
+/**
+ * Free the given compilation database
+ */
+CINDEX_LINKAGE void
+clang_CompilationDatabase_dispose(CXCompilationDatabase);
+
+/**
+ * Find the compile commands used for a file. The compile commands
+ * must be freed by \c clang_CompileCommands_dispose.
+ */
+CINDEX_LINKAGE CXCompileCommands
+clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase,
+                                             const char *CompleteFileName);
+
+/**
+ * Get all the compile commands in the given compilation database.
+ */
+CINDEX_LINKAGE CXCompileCommands
+clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase);
+
+/**
+ * Free the given CompileCommands
+ */
+CINDEX_LINKAGE void clang_CompileCommands_dispose(CXCompileCommands);
+
+/**
+ * Get the number of CompileCommand we have for a file
+ */
+CINDEX_LINKAGE unsigned
+clang_CompileCommands_getSize(CXCompileCommands);
+
+/**
+ * Get the I'th CompileCommand for a file
+ *
+ * Note : 0 <= i < clang_CompileCommands_getSize(CXCompileCommands)
+ */
+CINDEX_LINKAGE CXCompileCommand
+clang_CompileCommands_getCommand(CXCompileCommands, unsigned I);
+
+/**
+ * Get the working directory where the CompileCommand was executed from
+ */
+CINDEX_LINKAGE CXString
+clang_CompileCommand_getDirectory(CXCompileCommand);
+
+/**
+ * Get the filename associated with the CompileCommand.
+ */
+CINDEX_LINKAGE CXString
+clang_CompileCommand_getFilename(CXCompileCommand);
+
+/**
+ * Get the number of arguments in the compiler invocation.
+ *
+ */
+CINDEX_LINKAGE unsigned
+clang_CompileCommand_getNumArgs(CXCompileCommand);
+
+/**
+ * Get the I'th argument value in the compiler invocations
+ *
+ * Invariant :
+ *  - argument 0 is the compiler executable
+ */
+CINDEX_LINKAGE CXString
+clang_CompileCommand_getArg(CXCompileCommand, unsigned I);
+
+/**
+ * Get the number of source mappings for the compiler invocation.
+ */
+CINDEX_LINKAGE unsigned
+clang_CompileCommand_getNumMappedSources(CXCompileCommand);
+
+/**
+ * Get the I'th mapped source path for the compiler invocation.
+ */
+CINDEX_LINKAGE CXString
+clang_CompileCommand_getMappedSourcePath(CXCompileCommand, unsigned I);
+
+/**
+ * Get the I'th mapped source content for the compiler invocation.
+ */
+CINDEX_LINKAGE CXString
+clang_CompileCommand_getMappedSourceContent(CXCompileCommand, unsigned I);
+
+/**
+ * @}
+ */
+
+LLVM_CLANG_C_EXTERN_C_END
+
+#endif
+
diff --git a/pkgs/ffigen/third_party/libclang/include/clang-c/CXErrorCode.h b/pkgs/ffigen/third_party/libclang/include/clang-c/CXErrorCode.h
new file mode 100644
index 0000000..b3a0b9d
--- /dev/null
+++ b/pkgs/ffigen/third_party/libclang/include/clang-c/CXErrorCode.h
@@ -0,0 +1,62 @@
+/*===-- clang-c/CXErrorCode.h - C Index Error Codes  --------------*- C -*-===*\
+|*                                                                            *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
+|* Exceptions.                                                                *|
+|* See https://llvm.org/LICENSE.txt for license information.                  *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides the CXErrorCode enumerators.                          *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_CXERRORCODE_H
+#define LLVM_CLANG_C_CXERRORCODE_H
+
+#include "clang-c/ExternC.h"
+#include "clang-c/Platform.h"
+
+LLVM_CLANG_C_EXTERN_C_BEGIN
+
+/**
+ * Error codes returned by libclang routines.
+ *
+ * Zero (\c CXError_Success) is the only error code indicating success.  Other
+ * error codes, including not yet assigned non-zero values, indicate errors.
+ */
+enum CXErrorCode {
+  /**
+   * No error.
+   */
+  CXError_Success = 0,
+
+  /**
+   * A generic error code, no further details are available.
+   *
+   * Errors of this kind can get their own specific error codes in future
+   * libclang versions.
+   */
+  CXError_Failure = 1,
+
+  /**
+   * libclang crashed while performing the requested operation.
+   */
+  CXError_Crashed = 2,
+
+  /**
+   * The function detected that the arguments violate the function
+   * contract.
+   */
+  CXError_InvalidArguments = 3,
+
+  /**
+   * An AST deserialization error has occurred.
+   */
+  CXError_ASTReadError = 4
+};
+
+LLVM_CLANG_C_EXTERN_C_END
+
+#endif
+
diff --git a/pkgs/ffigen/third_party/libclang/include/clang-c/CXString.h b/pkgs/ffigen/third_party/libclang/include/clang-c/CXString.h
new file mode 100644
index 0000000..f117010
--- /dev/null
+++ b/pkgs/ffigen/third_party/libclang/include/clang-c/CXString.h
@@ -0,0 +1,69 @@
+/*===-- clang-c/CXString.h - C Index strings  --------------------*- C -*-===*\
+|*                                                                            *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
+|* Exceptions.                                                                *|
+|* See https://llvm.org/LICENSE.txt for license information.                  *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides the interface to C Index strings.                     *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_CXSTRING_H
+#define LLVM_CLANG_C_CXSTRING_H
+
+#include "clang-c/ExternC.h"
+#include "clang-c/Platform.h"
+
+LLVM_CLANG_C_EXTERN_C_BEGIN
+
+/**
+ * \defgroup CINDEX_STRING String manipulation routines
+ * \ingroup CINDEX
+ *
+ * @{
+ */
+
+/**
+ * A character string.
+ *
+ * The \c CXString type is used to return strings from the interface when
+ * the ownership of that string might differ from one call to the next.
+ * Use \c clang_getCString() to retrieve the string data and, once finished
+ * with the string data, call \c clang_disposeString() to free the string.
+ */
+typedef struct {
+  const void *data;
+  unsigned private_flags;
+} CXString;
+
+typedef struct {
+  CXString *Strings;
+  unsigned Count;
+} CXStringSet;
+
+/**
+ * Retrieve the character data associated with the given string.
+ */
+CINDEX_LINKAGE const char *clang_getCString(CXString string);
+
+/**
+ * Free the given string.
+ */
+CINDEX_LINKAGE void clang_disposeString(CXString string);
+
+/**
+ * Free the given string set.
+ */
+CINDEX_LINKAGE void clang_disposeStringSet(CXStringSet *set);
+
+/**
+ * @}
+ */
+
+LLVM_CLANG_C_EXTERN_C_END
+
+#endif
+
diff --git a/pkgs/ffigen/third_party/libclang/include/clang-c/Documentation.h b/pkgs/ffigen/third_party/libclang/include/clang-c/Documentation.h
new file mode 100644
index 0000000..5bece2c
--- /dev/null
+++ b/pkgs/ffigen/third_party/libclang/include/clang-c/Documentation.h
@@ -0,0 +1,555 @@
+/*==-- clang-c/Documentation.h - Utilities for comment processing -*- C -*-===*\
+|*                                                                            *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
+|* Exceptions.                                                                *|
+|* See https://llvm.org/LICENSE.txt for license information.                  *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides a supplementary interface for inspecting              *|
+|* documentation comments.                                                    *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_DOCUMENTATION_H
+#define LLVM_CLANG_C_DOCUMENTATION_H
+
+#include "clang-c/ExternC.h"
+#include "clang-c/Index.h"
+
+LLVM_CLANG_C_EXTERN_C_BEGIN
+
+/**
+ * \defgroup CINDEX_COMMENT Comment introspection
+ *
+ * The routines in this group provide access to information in documentation
+ * comments. These facilities are distinct from the core and may be subject to
+ * their own schedule of stability and deprecation.
+ *
+ * @{
+ */
+
+/**
+ * A parsed comment.
+ */
+typedef struct {
+  const void *ASTNode;
+  CXTranslationUnit TranslationUnit;
+} CXComment;
+
+/**
+ * Given a cursor that represents a documentable entity (e.g.,
+ * declaration), return the associated parsed comment as a
+ * \c CXComment_FullComment AST node.
+ */
+CINDEX_LINKAGE CXComment clang_Cursor_getParsedComment(CXCursor C);
+
+/**
+ * Describes the type of the comment AST node (\c CXComment).  A comment
+ * node can be considered block content (e. g., paragraph), inline content
+ * (plain text) or neither (the root AST node).
+ */
+enum CXCommentKind {
+  /**
+   * Null comment.  No AST node is constructed at the requested location
+   * because there is no text or a syntax error.
+   */
+  CXComment_Null = 0,
+
+  /**
+   * Plain text.  Inline content.
+   */
+  CXComment_Text = 1,
+
+  /**
+   * A command with word-like arguments that is considered inline content.
+   *
+   * For example: \\c command.
+   */
+  CXComment_InlineCommand = 2,
+
+  /**
+   * HTML start tag with attributes (name-value pairs).  Considered
+   * inline content.
+   *
+   * For example:
+   * \verbatim
+   * <br> <br /> <a href="http://example.org/">
+   * \endverbatim
+   */
+  CXComment_HTMLStartTag = 3,
+
+  /**
+   * HTML end tag.  Considered inline content.
+   *
+   * For example:
+   * \verbatim
+   * </a>
+   * \endverbatim
+   */
+  CXComment_HTMLEndTag = 4,
+
+  /**
+   * A paragraph, contains inline comment.  The paragraph itself is
+   * block content.
+   */
+  CXComment_Paragraph = 5,
+
+  /**
+   * A command that has zero or more word-like arguments (number of
+   * word-like arguments depends on command name) and a paragraph as an
+   * argument.  Block command is block content.
+   *
+   * Paragraph argument is also a child of the block command.
+   *
+   * For example: \has 0 word-like arguments and a paragraph argument.
+   *
+   * AST nodes of special kinds that parser knows about (e. g., \\param
+   * command) have their own node kinds.
+   */
+  CXComment_BlockCommand = 6,
+
+  /**
+   * A \\param or \\arg command that describes the function parameter
+   * (name, passing direction, description).
+   *
+   * For example: \\param [in] ParamName description.
+   */
+  CXComment_ParamCommand = 7,
+
+  /**
+   * A \\tparam command that describes a template parameter (name and
+   * description).
+   *
+   * For example: \\tparam T description.
+   */
+  CXComment_TParamCommand = 8,
+
+  /**
+   * A verbatim block command (e. g., preformatted code).  Verbatim
+   * block has an opening and a closing command and contains multiple lines of
+   * text (\c CXComment_VerbatimBlockLine child nodes).
+   *
+   * For example:
+   * \\verbatim
+   * aaa
+   * \\endverbatim
+   */
+  CXComment_VerbatimBlockCommand = 9,
+
+  /**
+   * A line of text that is contained within a
+   * CXComment_VerbatimBlockCommand node.
+   */
+  CXComment_VerbatimBlockLine = 10,
+
+  /**
+   * A verbatim line command.  Verbatim line has an opening command,
+   * a single line of text (up to the newline after the opening command) and
+   * has no closing command.
+   */
+  CXComment_VerbatimLine = 11,
+
+  /**
+   * A full comment attached to a declaration, contains block content.
+   */
+  CXComment_FullComment = 12
+};
+
+/**
+ * The most appropriate rendering mode for an inline command, chosen on
+ * command semantics in Doxygen.
+ */
+enum CXCommentInlineCommandRenderKind {
+  /**
+   * Command argument should be rendered in a normal font.
+   */
+  CXCommentInlineCommandRenderKind_Normal,
+
+  /**
+   * Command argument should be rendered in a bold font.
+   */
+  CXCommentInlineCommandRenderKind_Bold,
+
+  /**
+   * Command argument should be rendered in a monospaced font.
+   */
+  CXCommentInlineCommandRenderKind_Monospaced,
+
+  /**
+   * Command argument should be rendered emphasized (typically italic
+   * font).
+   */
+  CXCommentInlineCommandRenderKind_Emphasized,
+
+  /**
+   * Command argument should not be rendered (since it only defines an anchor).
+   */
+  CXCommentInlineCommandRenderKind_Anchor
+};
+
+/**
+ * Describes parameter passing direction for \\param or \\arg command.
+ */
+enum CXCommentParamPassDirection {
+  /**
+   * The parameter is an input parameter.
+   */
+  CXCommentParamPassDirection_In,
+
+  /**
+   * The parameter is an output parameter.
+   */
+  CXCommentParamPassDirection_Out,
+
+  /**
+   * The parameter is an input and output parameter.
+   */
+  CXCommentParamPassDirection_InOut
+};
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \returns the type of the AST node.
+ */
+CINDEX_LINKAGE enum CXCommentKind clang_Comment_getKind(CXComment Comment);
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \returns number of children of the AST node.
+ */
+CINDEX_LINKAGE unsigned clang_Comment_getNumChildren(CXComment Comment);
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \param ChildIdx child index (zero-based).
+ *
+ * \returns the specified child of the AST node.
+ */
+CINDEX_LINKAGE
+CXComment clang_Comment_getChild(CXComment Comment, unsigned ChildIdx);
+
+/**
+ * A \c CXComment_Paragraph node is considered whitespace if it contains
+ * only \c CXComment_Text nodes that are empty or whitespace.
+ *
+ * Other AST nodes (except \c CXComment_Paragraph and \c CXComment_Text) are
+ * never considered whitespace.
+ *
+ * \returns non-zero if \c Comment is whitespace.
+ */
+CINDEX_LINKAGE unsigned clang_Comment_isWhitespace(CXComment Comment);
+
+/**
+ * \returns non-zero if \c Comment is inline content and has a newline
+ * immediately following it in the comment text.  Newlines between paragraphs
+ * do not count.
+ */
+CINDEX_LINKAGE
+unsigned clang_InlineContentComment_hasTrailingNewline(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_Text AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE CXString clang_TextComment_getText(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns name of the inline command.
+ */
+CINDEX_LINKAGE
+CXString clang_InlineCommandComment_getCommandName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns the most appropriate rendering mode, chosen on command
+ * semantics in Doxygen.
+ */
+CINDEX_LINKAGE enum CXCommentInlineCommandRenderKind
+clang_InlineCommandComment_getRenderKind(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns number of command arguments.
+ */
+CINDEX_LINKAGE
+unsigned clang_InlineCommandComment_getNumArgs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \param ArgIdx argument index (zero-based).
+ *
+ * \returns text of the specified argument.
+ */
+CINDEX_LINKAGE
+CXString clang_InlineCommandComment_getArgText(CXComment Comment,
+                                               unsigned ArgIdx);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
+ * node.
+ *
+ * \returns HTML tag name.
+ */
+CINDEX_LINKAGE CXString clang_HTMLTagComment_getTagName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \returns non-zero if tag is self-closing (for example, &lt;br /&gt;).
+ */
+CINDEX_LINKAGE
+unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \returns number of attributes (name-value pairs) attached to the start tag.
+ */
+CINDEX_LINKAGE unsigned clang_HTMLStartTag_getNumAttrs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \param AttrIdx attribute index (zero-based).
+ *
+ * \returns name of the specified attribute.
+ */
+CINDEX_LINKAGE
+CXString clang_HTMLStartTag_getAttrName(CXComment Comment, unsigned AttrIdx);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \param AttrIdx attribute index (zero-based).
+ *
+ * \returns value of the specified attribute.
+ */
+CINDEX_LINKAGE
+CXString clang_HTMLStartTag_getAttrValue(CXComment Comment, unsigned AttrIdx);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \returns name of the block command.
+ */
+CINDEX_LINKAGE
+CXString clang_BlockCommandComment_getCommandName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \returns number of word-like arguments.
+ */
+CINDEX_LINKAGE
+unsigned clang_BlockCommandComment_getNumArgs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \param ArgIdx argument index (zero-based).
+ *
+ * \returns text of the specified word-like argument.
+ */
+CINDEX_LINKAGE
+CXString clang_BlockCommandComment_getArgText(CXComment Comment,
+                                              unsigned ArgIdx);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand or
+ * \c CXComment_VerbatimBlockCommand AST node.
+ *
+ * \returns paragraph argument of the block command.
+ */
+CINDEX_LINKAGE
+CXComment clang_BlockCommandComment_getParagraph(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns parameter name.
+ */
+CINDEX_LINKAGE
+CXString clang_ParamCommandComment_getParamName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns non-zero if the parameter that this AST node represents was found
+ * in the function prototype and \c clang_ParamCommandComment_getParamIndex
+ * function will return a meaningful value.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_isParamIndexValid(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns zero-based parameter index in function prototype.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_getParamIndex(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns non-zero if parameter passing direction was specified explicitly in
+ * the comment.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns parameter passing direction.
+ */
+CINDEX_LINKAGE
+enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
+                                                            CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns template parameter name.
+ */
+CINDEX_LINKAGE
+CXString clang_TParamCommandComment_getParamName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns non-zero if the parameter that this AST node represents was found
+ * in the template parameter list and
+ * \c clang_TParamCommandComment_getDepth and
+ * \c clang_TParamCommandComment_getIndex functions will return a meaningful
+ * value.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_isParamPositionValid(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns zero-based nesting depth of this parameter in the template parameter list.
+ *
+ * For example,
+ * \verbatim
+ *     template<typename C, template<typename T> class TT>
+ *     void test(TT<int> aaa);
+ * \endverbatim
+ * for C and TT nesting depth is 0,
+ * for T nesting depth is 1.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_getDepth(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns zero-based parameter index in the template parameter list at a
+ * given nesting depth.
+ *
+ * For example,
+ * \verbatim
+ *     template<typename C, template<typename T> class TT>
+ *     void test(TT<int> aaa);
+ * \endverbatim
+ * for C and TT nesting depth is 0, so we can ask for index at depth 0:
+ * at depth 0 C's index is 0, TT's index is 1.
+ *
+ * For T nesting depth is 1, so we can ask for index at depth 0 and 1:
+ * at depth 0 T's index is 1 (same as TT's),
+ * at depth 1 T's index is 0.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_getIndex(CXComment Comment, unsigned Depth);
+
+/**
+ * \param Comment a \c CXComment_VerbatimBlockLine AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE
+CXString clang_VerbatimBlockLineComment_getText(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_VerbatimLine AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE CXString clang_VerbatimLineComment_getText(CXComment Comment);
+
+/**
+ * Convert an HTML tag AST node to string.
+ *
+ * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
+ * node.
+ *
+ * \returns string containing an HTML tag.
+ */
+CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment);
+
+/**
+ * Convert a given full parsed comment to an HTML fragment.
+ *
+ * Specific details of HTML layout are subject to change.  Don't try to parse
+ * this HTML back into an AST, use other APIs instead.
+ *
+ * Currently the following CSS classes are used:
+ * \li "para-brief" for \paragraph and equivalent commands;
+ * \li "para-returns" for \\returns paragraph and equivalent commands;
+ * \li "word-returns" for the "Returns" word in \\returns paragraph.
+ *
+ * Function argument documentation is rendered as a \<dl\> list with arguments
+ * sorted in function prototype order.  CSS classes used:
+ * \li "param-name-index-NUMBER" for parameter name (\<dt\>);
+ * \li "param-descr-index-NUMBER" for parameter description (\<dd\>);
+ * \li "param-name-index-invalid" and "param-descr-index-invalid" are used if
+ * parameter index is invalid.
+ *
+ * Template parameter documentation is rendered as a \<dl\> list with
+ * parameters sorted in template parameter list order.  CSS classes used:
+ * \li "tparam-name-index-NUMBER" for parameter name (\<dt\>);
+ * \li "tparam-descr-index-NUMBER" for parameter description (\<dd\>);
+ * \li "tparam-name-index-other" and "tparam-descr-index-other" are used for
+ * names inside template template parameters;
+ * \li "tparam-name-index-invalid" and "tparam-descr-index-invalid" are used if
+ * parameter position is invalid.
+ *
+ * \param Comment a \c CXComment_FullComment AST node.
+ *
+ * \returns string containing an HTML fragment.
+ */
+CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment);
+
+/**
+ * Convert a given full parsed comment to an XML document.
+ *
+ * A Relax NG schema for the XML can be found in comment-xml-schema.rng file
+ * inside clang source tree.
+ *
+ * \param Comment a \c CXComment_FullComment AST node.
+ *
+ * \returns string containing an XML document.
+ */
+CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment);
+
+/**
+ * @}
+ */
+
+LLVM_CLANG_C_EXTERN_C_END
+
+#endif /* CLANG_C_DOCUMENTATION_H */
+
diff --git a/pkgs/ffigen/third_party/libclang/include/clang-c/ExternC.h b/pkgs/ffigen/third_party/libclang/include/clang-c/ExternC.h
new file mode 100644
index 0000000..384f24d
--- /dev/null
+++ b/pkgs/ffigen/third_party/libclang/include/clang-c/ExternC.h
@@ -0,0 +1,39 @@
+/*===- clang-c/ExternC.h - Wrapper for 'extern "C"' ---------------*- C -*-===*\
+|*                                                                            *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
+|* Exceptions.                                                                *|
+|* See https://llvm.org/LICENSE.txt for license information.                  *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file defines an 'extern "C"' wrapper.                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_EXTERN_C_H
+#define LLVM_CLANG_C_EXTERN_C_H
+
+#ifdef __clang__
+#define LLVM_CLANG_C_STRICT_PROTOTYPES_BEGIN                                   \
+  _Pragma("clang diagnostic push")                                             \
+      _Pragma("clang diagnostic error \"-Wstrict-prototypes\"")
+#define LLVM_CLANG_C_STRICT_PROTOTYPES_END _Pragma("clang diagnostic pop")
+#else
+#define LLVM_CLANG_C_STRICT_PROTOTYPES_BEGIN
+#define LLVM_CLANG_C_STRICT_PROTOTYPES_END
+#endif
+
+#ifdef __cplusplus
+#define LLVM_CLANG_C_EXTERN_C_BEGIN                                            \
+  extern "C" {                                                                 \
+  LLVM_CLANG_C_STRICT_PROTOTYPES_BEGIN
+#define LLVM_CLANG_C_EXTERN_C_END                                              \
+  LLVM_CLANG_C_STRICT_PROTOTYPES_END                                           \
+  }
+#else
+#define LLVM_CLANG_C_EXTERN_C_BEGIN LLVM_CLANG_C_STRICT_PROTOTYPES_BEGIN
+#define LLVM_CLANG_C_EXTERN_C_END LLVM_CLANG_C_STRICT_PROTOTYPES_END
+#endif
+
+#endif
diff --git a/pkgs/ffigen/third_party/libclang/include/clang-c/FatalErrorHandler.h b/pkgs/ffigen/third_party/libclang/include/clang-c/FatalErrorHandler.h
new file mode 100644
index 0000000..22f34fa
--- /dev/null
+++ b/pkgs/ffigen/third_party/libclang/include/clang-c/FatalErrorHandler.h
@@ -0,0 +1,32 @@
+/*===-- clang-c/FatalErrorHandler.h - Fatal Error Handling --------*- C -*-===*\
+|*                                                                            *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
+|* Exceptions.                                                                *|
+|* See https://llvm.org/LICENSE.txt for license information.                  *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_FATAL_ERROR_HANDLER_H
+#define LLVM_CLANG_C_FATAL_ERROR_HANDLER_H
+
+#include "clang-c/ExternC.h"
+
+LLVM_CLANG_C_EXTERN_C_BEGIN
+
+/**
+ * Installs error handler that prints error message to stderr and calls abort().
+ * Replaces currently installed error handler (if any).
+ */
+void clang_install_aborting_llvm_fatal_error_handler(void);
+
+/**
+ * Removes currently installed error handler (if any).
+ * If no error handler is intalled, the default strategy is to print error
+ * message to stderr and call exit(1).
+ */
+void clang_uninstall_llvm_fatal_error_handler(void);
+
+LLVM_CLANG_C_EXTERN_C_END
+
+#endif
diff --git a/pkgs/ffigen/third_party/libclang/include/clang-c/Index.h b/pkgs/ffigen/third_party/libclang/include/clang-c/Index.h
new file mode 100644
index 0000000..b653995
--- /dev/null
+++ b/pkgs/ffigen/third_party/libclang/include/clang-c/Index.h
@@ -0,0 +1,6782 @@
+/*===-- clang-c/Index.h - Indexing Public C Interface -------------*- C -*-===*\
+|*                                                                            *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
+|* Exceptions.                                                                *|
+|* See https://llvm.org/LICENSE.txt for license information.                  *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides a public interface to a Clang library for extracting  *|
+|* high-level symbol information from source files without exposing the full  *|
+|* Clang C++ API.                                                             *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_INDEX_H
+#define LLVM_CLANG_C_INDEX_H
+
+#include <time.h>
+
+#include "clang-c/BuildSystem.h"
+#include "clang-c/CXErrorCode.h"
+#include "clang-c/CXString.h"
+#include "clang-c/ExternC.h"
+#include "clang-c/Platform.h"
+
+/**
+ * The version constants for the libclang API.
+ * CINDEX_VERSION_MINOR should increase when there are API additions.
+ * CINDEX_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
+ *
+ * The policy about the libclang API was always to keep it source and ABI
+ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
+ */
+#define CINDEX_VERSION_MAJOR 0
+#define CINDEX_VERSION_MINOR 59
+
+#define CINDEX_VERSION_ENCODE(major, minor) ( \
+      ((major) * 10000)                       \
+    + ((minor) *     1))
+
+#define CINDEX_VERSION CINDEX_VERSION_ENCODE( \
+    CINDEX_VERSION_MAJOR,                     \
+    CINDEX_VERSION_MINOR )
+
+#define CINDEX_VERSION_STRINGIZE_(major, minor)   \
+    #major"."#minor
+#define CINDEX_VERSION_STRINGIZE(major, minor)    \
+    CINDEX_VERSION_STRINGIZE_(major, minor)
+
+#define CINDEX_VERSION_STRING CINDEX_VERSION_STRINGIZE( \
+    CINDEX_VERSION_MAJOR,                               \
+    CINDEX_VERSION_MINOR)
+
+LLVM_CLANG_C_EXTERN_C_BEGIN
+
+/** \defgroup CINDEX libclang: C Interface to Clang
+ *
+ * The C Interface to Clang provides a relatively small API that exposes
+ * facilities for parsing source code into an abstract syntax tree (AST),
+ * loading already-parsed ASTs, traversing the AST, associating
+ * physical source locations with elements within the AST, and other
+ * facilities that support Clang-based development tools.
+ *
+ * This C interface to Clang will never provide all of the information
+ * representation stored in Clang's C++ AST, nor should it: the intent is to
+ * maintain an API that is relatively stable from one release to the next,
+ * providing only the basic functionality needed to support development tools.
+ *
+ * To avoid namespace pollution, data types are prefixed with "CX" and
+ * functions are prefixed with "clang_".
+ *
+ * @{
+ */
+
+/**
+ * An "index" that consists of a set of translation units that would
+ * typically be linked together into an executable or library.
+ */
+typedef void *CXIndex;
+
+/**
+ * An opaque type representing target information for a given translation
+ * unit.
+ */
+typedef struct CXTargetInfoImpl *CXTargetInfo;
+
+/**
+ * A single translation unit, which resides in an index.
+ */
+typedef struct CXTranslationUnitImpl *CXTranslationUnit;
+
+/**
+ * Opaque pointer representing client data that will be passed through
+ * to various callbacks and visitors.
+ */
+typedef void *CXClientData;
+
+/**
+ * Provides the contents of a file that has not yet been saved to disk.
+ *
+ * Each CXUnsavedFile instance provides the name of a file on the
+ * system along with the current contents of that file that have not
+ * yet been saved to disk.
+ */
+struct CXUnsavedFile {
+  /**
+   * The file whose contents have not yet been saved.
+   *
+   * This file must already exist in the file system.
+   */
+  const char *Filename;
+
+  /**
+   * A buffer containing the unsaved contents of this file.
+   */
+  const char *Contents;
+
+  /**
+   * The length of the unsaved contents of this buffer.
+   */
+  unsigned long Length;
+};
+
+/**
+ * Describes the availability of a particular entity, which indicates
+ * whether the use of this entity will result in a warning or error due to
+ * it being deprecated or unavailable.
+ */
+enum CXAvailabilityKind {
+  /**
+   * The entity is available.
+   */
+  CXAvailability_Available,
+  /**
+   * The entity is available, but has been deprecated (and its use is
+   * not recommended).
+   */
+  CXAvailability_Deprecated,
+  /**
+   * The entity is not available; any use of it will be an error.
+   */
+  CXAvailability_NotAvailable,
+  /**
+   * The entity is available, but not accessible; any use of it will be
+   * an error.
+   */
+  CXAvailability_NotAccessible
+};
+
+/**
+ * Describes a version number of the form major.minor.subminor.
+ */
+typedef struct CXVersion {
+  /**
+   * The major version number, e.g., the '10' in '10.7.3'. A negative
+   * value indicates that there is no version number at all.
+   */
+  int Major;
+  /**
+   * The minor version number, e.g., the '7' in '10.7.3'. This value
+   * will be negative if no minor version number was provided, e.g., for
+   * version '10'.
+   */
+  int Minor;
+  /**
+   * The subminor version number, e.g., the '3' in '10.7.3'. This value
+   * will be negative if no minor or subminor version number was provided,
+   * e.g., in version '10' or '10.7'.
+   */
+  int Subminor;
+} CXVersion;
+
+/**
+ * Describes the exception specification of a cursor.
+ *
+ * A negative value indicates that the cursor is not a function declaration.
+ */
+enum CXCursor_ExceptionSpecificationKind {
+  /**
+   * The cursor has no exception specification.
+   */
+  CXCursor_ExceptionSpecificationKind_None,
+
+  /**
+   * The cursor has exception specification throw()
+   */
+  CXCursor_ExceptionSpecificationKind_DynamicNone,
+
+  /**
+   * The cursor has exception specification throw(T1, T2)
+   */
+  CXCursor_ExceptionSpecificationKind_Dynamic,
+
+  /**
+   * The cursor has exception specification throw(...).
+   */
+  CXCursor_ExceptionSpecificationKind_MSAny,
+
+  /**
+   * The cursor has exception specification basic noexcept.
+   */
+  CXCursor_ExceptionSpecificationKind_BasicNoexcept,
+
+  /**
+   * The cursor has exception specification computed noexcept.
+   */
+  CXCursor_ExceptionSpecificationKind_ComputedNoexcept,
+
+  /**
+   * The exception specification has not yet been evaluated.
+   */
+  CXCursor_ExceptionSpecificationKind_Unevaluated,
+
+  /**
+   * The exception specification has not yet been instantiated.
+   */
+  CXCursor_ExceptionSpecificationKind_Uninstantiated,
+
+  /**
+   * The exception specification has not been parsed yet.
+   */
+  CXCursor_ExceptionSpecificationKind_Unparsed,
+
+  /**
+   * The cursor has a __declspec(nothrow) exception specification.
+   */
+  CXCursor_ExceptionSpecificationKind_NoThrow
+};
+
+/**
+ * Provides a shared context for creating translation units.
+ *
+ * It provides two options:
+ *
+ * - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local"
+ * declarations (when loading any new translation units). A "local" declaration
+ * is one that belongs in the translation unit itself and not in a precompiled
+ * header that was used by the translation unit. If zero, all declarations
+ * will be enumerated.
+ *
+ * Here is an example:
+ *
+ * \code
+ *   // excludeDeclsFromPCH = 1, displayDiagnostics=1
+ *   Idx = clang_createIndex(1, 1);
+ *
+ *   // IndexTest.pch was produced with the following command:
+ *   // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
+ *   TU = clang_createTranslationUnit(Idx, "IndexTest.pch");
+ *
+ *   // This will load all the symbols from 'IndexTest.pch'
+ *   clang_visitChildren(clang_getTranslationUnitCursor(TU),
+ *                       TranslationUnitVisitor, 0);
+ *   clang_disposeTranslationUnit(TU);
+ *
+ *   // This will load all the symbols from 'IndexTest.c', excluding symbols
+ *   // from 'IndexTest.pch'.
+ *   char *args[] = { "-Xclang", "-include-pch=IndexTest.pch" };
+ *   TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args,
+ *                                                  0, 0);
+ *   clang_visitChildren(clang_getTranslationUnitCursor(TU),
+ *                       TranslationUnitVisitor, 0);
+ *   clang_disposeTranslationUnit(TU);
+ * \endcode
+ *
+ * This process of creating the 'pch', loading it separately, and using it (via
+ * -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
+ * (which gives the indexer the same performance benefit as the compiler).
+ */
+CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+                                         int displayDiagnostics);
+
+/**
+ * Destroy the given index.
+ *
+ * The index must not be destroyed until all of the translation units created
+ * within that index have been destroyed.
+ */
+CINDEX_LINKAGE void clang_disposeIndex(CXIndex index);
+
+typedef enum {
+  /**
+   * Used to indicate that no special CXIndex options are needed.
+   */
+  CXGlobalOpt_None = 0x0,
+
+  /**
+   * Used to indicate that threads that libclang creates for indexing
+   * purposes should use background priority.
+   *
+   * Affects #clang_indexSourceFile, #clang_indexTranslationUnit,
+   * #clang_parseTranslationUnit, #clang_saveTranslationUnit.
+   */
+  CXGlobalOpt_ThreadBackgroundPriorityForIndexing = 0x1,
+
+  /**
+   * Used to indicate that threads that libclang creates for editing
+   * purposes should use background priority.
+   *
+   * Affects #clang_reparseTranslationUnit, #clang_codeCompleteAt,
+   * #clang_annotateTokens
+   */
+  CXGlobalOpt_ThreadBackgroundPriorityForEditing = 0x2,
+
+  /**
+   * Used to indicate that all threads that libclang creates should use
+   * background priority.
+   */
+  CXGlobalOpt_ThreadBackgroundPriorityForAll =
+      CXGlobalOpt_ThreadBackgroundPriorityForIndexing |
+      CXGlobalOpt_ThreadBackgroundPriorityForEditing
+
+} CXGlobalOptFlags;
+
+/**
+ * Sets general options associated with a CXIndex.
+ *
+ * For example:
+ * \code
+ * CXIndex idx = ...;
+ * clang_CXIndex_setGlobalOptions(idx,
+ *     clang_CXIndex_getGlobalOptions(idx) |
+ *     CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
+ * \endcode
+ *
+ * \param options A bitmask of options, a bitwise OR of CXGlobalOpt_XXX flags.
+ */
+CINDEX_LINKAGE void clang_CXIndex_setGlobalOptions(CXIndex, unsigned options);
+
+/**
+ * Gets the general options associated with a CXIndex.
+ *
+ * \returns A bitmask of options, a bitwise OR of CXGlobalOpt_XXX flags that
+ * are associated with the given CXIndex object.
+ */
+CINDEX_LINKAGE unsigned clang_CXIndex_getGlobalOptions(CXIndex);
+
+/**
+ * Sets the invocation emission path option in a CXIndex.
+ *
+ * The invocation emission path specifies a path which will contain log
+ * files for certain libclang invocations. A null value (default) implies that
+ * libclang invocations are not logged..
+ */
+CINDEX_LINKAGE void
+clang_CXIndex_setInvocationEmissionPathOption(CXIndex, const char *Path);
+
+/**
+ * \defgroup CINDEX_FILES File manipulation routines
+ *
+ * @{
+ */
+
+/**
+ * A particular source file that is part of a translation unit.
+ */
+typedef void *CXFile;
+
+/**
+ * Retrieve the complete file and path name of the given file.
+ */
+CINDEX_LINKAGE CXString clang_getFileName(CXFile SFile);
+
+/**
+ * Retrieve the last modification time of the given file.
+ */
+CINDEX_LINKAGE time_t clang_getFileTime(CXFile SFile);
+
+/**
+ * Uniquely identifies a CXFile, that refers to the same underlying file,
+ * across an indexing session.
+ */
+typedef struct {
+  unsigned long long data[3];
+} CXFileUniqueID;
+
+/**
+ * Retrieve the unique ID for the given \c file.
+ *
+ * \param file the file to get the ID for.
+ * \param outID stores the returned CXFileUniqueID.
+ * \returns If there was a failure getting the unique ID, returns non-zero,
+ * otherwise returns 0.
+*/
+CINDEX_LINKAGE int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID);
+
+/**
+ * Determine whether the given header is guarded against
+ * multiple inclusions, either with the conventional
+ * \#ifndef/\#define/\#endif macro guards or with \#pragma once.
+ */
+CINDEX_LINKAGE unsigned
+clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file);
+
+/**
+ * Retrieve a file handle within the given translation unit.
+ *
+ * \param tu the translation unit
+ *
+ * \param file_name the name of the file.
+ *
+ * \returns the file handle for the named file in the translation unit \p tu,
+ * or a NULL file handle if the file was not a part of this translation unit.
+ */
+CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu,
+                                    const char *file_name);
+
+/**
+ * Retrieve the buffer associated with the given file.
+ *
+ * \param tu the translation unit
+ *
+ * \param file the file for which to retrieve the buffer.
+ *
+ * \param size [out] if non-NULL, will be set to the size of the buffer.
+ *
+ * \returns a pointer to the buffer in memory that holds the contents of
+ * \p file, or a NULL pointer when the file is not loaded.
+ */
+CINDEX_LINKAGE const char *clang_getFileContents(CXTranslationUnit tu,
+                                                 CXFile file, size_t *size);
+
+/**
+ * Returns non-zero if the \c file1 and \c file2 point to the same file,
+ * or they are both NULL.
+ */
+CINDEX_LINKAGE int clang_File_isEqual(CXFile file1, CXFile file2);
+
+/**
+ * Returns the real path name of \c file.
+ *
+ * An empty string may be returned. Use \c clang_getFileName() in that case.
+ */
+CINDEX_LINKAGE CXString clang_File_tryGetRealPathName(CXFile file);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_LOCATIONS Physical source locations
+ *
+ * Clang represents physical source locations in its abstract syntax tree in
+ * great detail, with file, line, and column information for the majority of
+ * the tokens parsed in the source code. These data types and functions are
+ * used to represent source location information, either for a particular
+ * point in the program or for a range of points in the program, and extract
+ * specific location information from those data types.
+ *
+ * @{
+ */
+
+/**
+ * Identifies a specific source location within a translation
+ * unit.
+ *
+ * Use clang_getExpansionLocation() or clang_getSpellingLocation()
+ * to map a source location to a particular file, line, and column.
+ */
+typedef struct {
+  const void *ptr_data[2];
+  unsigned int_data;
+} CXSourceLocation;
+
+/**
+ * Identifies a half-open character range in the source code.
+ *
+ * Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
+ * starting and end locations from a source range, respectively.
+ */
+typedef struct {
+  const void *ptr_data[2];
+  unsigned begin_int_data;
+  unsigned end_int_data;
+} CXSourceRange;
+
+/**
+ * Retrieve a NULL (invalid) source location.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getNullLocation(void);
+
+/**
+ * Determine whether two source locations, which must refer into
+ * the same translation unit, refer to exactly the same point in the source
+ * code.
+ *
+ * \returns non-zero if the source locations refer to the same location, zero
+ * if they refer to different locations.
+ */
+CINDEX_LINKAGE unsigned clang_equalLocations(CXSourceLocation loc1,
+                                             CXSourceLocation loc2);
+
+/**
+ * Retrieves the source location associated with a given file/line/column
+ * in a particular translation unit.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getLocation(CXTranslationUnit tu,
+                                                  CXFile file,
+                                                  unsigned line,
+                                                  unsigned column);
+/**
+ * Retrieves the source location associated with a given character offset
+ * in a particular translation unit.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
+                                                           CXFile file,
+                                                           unsigned offset);
+
+/**
+ * Returns non-zero if the given source location is in a system header.
+ */
+CINDEX_LINKAGE int clang_Location_isInSystemHeader(CXSourceLocation location);
+
+/**
+ * Returns non-zero if the given source location is in the main file of
+ * the corresponding translation unit.
+ */
+CINDEX_LINKAGE int clang_Location_isFromMainFile(CXSourceLocation location);
+
+/**
+ * Retrieve a NULL (invalid) source range.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getNullRange(void);
+
+/**
+ * Retrieve a source range given the beginning and ending source
+ * locations.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getRange(CXSourceLocation begin,
+                                            CXSourceLocation end);
+
+/**
+ * Determine whether two ranges are equivalent.
+ *
+ * \returns non-zero if the ranges are the same, zero if they differ.
+ */
+CINDEX_LINKAGE unsigned clang_equalRanges(CXSourceRange range1,
+                                          CXSourceRange range2);
+
+/**
+ * Returns non-zero if \p range is null.
+ */
+CINDEX_LINKAGE int clang_Range_isNull(CXSourceRange range);
+
+/**
+ * Retrieve the file, line, column, and offset represented by
+ * the given source location.
+ *
+ * If the location refers into a macro expansion, retrieves the
+ * location of the macro expansion.
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param file [out] if non-NULL, will be set to the file to which the given
+ * source location points.
+ *
+ * \param line [out] if non-NULL, will be set to the line to which the given
+ * source location points.
+ *
+ * \param column [out] if non-NULL, will be set to the column to which the given
+ * source location points.
+ *
+ * \param offset [out] if non-NULL, will be set to the offset into the
+ * buffer to which the given source location points.
+ */
+CINDEX_LINKAGE void clang_getExpansionLocation(CXSourceLocation location,
+                                               CXFile *file,
+                                               unsigned *line,
+                                               unsigned *column,
+                                               unsigned *offset);
+
+/**
+ * Retrieve the file, line and column represented by the given source
+ * location, as specified in a # line directive.
+ *
+ * Example: given the following source code in a file somefile.c
+ *
+ * \code
+ * #123 "dummy.c" 1
+ *
+ * static int func(void)
+ * {
+ *     return 0;
+ * }
+ * \endcode
+ *
+ * the location information returned by this function would be
+ *
+ * File: dummy.c Line: 124 Column: 12
+ *
+ * whereas clang_getExpansionLocation would have returned
+ *
+ * File: somefile.c Line: 3 Column: 12
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param filename [out] if non-NULL, will be set to the filename of the
+ * source location. Note that filenames returned will be for "virtual" files,
+ * which don't necessarily exist on the machine running clang - e.g. when
+ * parsing preprocessed output obtained from a different environment. If
+ * a non-NULL value is passed in, remember to dispose of the returned value
+ * using \c clang_disposeString() once you've finished with it. For an invalid
+ * source location, an empty string is returned.
+ *
+ * \param line [out] if non-NULL, will be set to the line number of the
+ * source location. For an invalid source location, zero is returned.
+ *
+ * \param column [out] if non-NULL, will be set to the column number of the
+ * source location. For an invalid source location, zero is returned.
+ */
+CINDEX_LINKAGE void clang_getPresumedLocation(CXSourceLocation location,
+                                              CXString *filename,
+                                              unsigned *line,
+                                              unsigned *column);
+
+/**
+ * Legacy API to retrieve the file, line, column, and offset represented
+ * by the given source location.
+ *
+ * This interface has been replaced by the newer interface
+ * #clang_getExpansionLocation(). See that interface's documentation for
+ * details.
+ */
+CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location,
+                                                   CXFile *file,
+                                                   unsigned *line,
+                                                   unsigned *column,
+                                                   unsigned *offset);
+
+/**
+ * Retrieve the file, line, column, and offset represented by
+ * the given source location.
+ *
+ * If the location refers into a macro instantiation, return where the
+ * location was originally spelled in the source file.
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param file [out] if non-NULL, will be set to the file to which the given
+ * source location points.
+ *
+ * \param line [out] if non-NULL, will be set to the line to which the given
+ * source location points.
+ *
+ * \param column [out] if non-NULL, will be set to the column to which the given
+ * source location points.
+ *
+ * \param offset [out] if non-NULL, will be set to the offset into the
+ * buffer to which the given source location points.
+ */
+CINDEX_LINKAGE void clang_getSpellingLocation(CXSourceLocation location,
+                                              CXFile *file,
+                                              unsigned *line,
+                                              unsigned *column,
+                                              unsigned *offset);
+
+/**
+ * Retrieve the file, line, column, and offset represented by
+ * the given source location.
+ *
+ * If the location refers into a macro expansion, return where the macro was
+ * expanded or where the macro argument was written, if the location points at
+ * a macro argument.
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param file [out] if non-NULL, will be set to the file to which the given
+ * source location points.
+ *
+ * \param line [out] if non-NULL, will be set to the line to which the given
+ * source location points.
+ *
+ * \param column [out] if non-NULL, will be set to the column to which the given
+ * source location points.
+ *
+ * \param offset [out] if non-NULL, will be set to the offset into the
+ * buffer to which the given source location points.
+ */
+CINDEX_LINKAGE void clang_getFileLocation(CXSourceLocation location,
+                                          CXFile *file,
+                                          unsigned *line,
+                                          unsigned *column,
+                                          unsigned *offset);
+
+/**
+ * Retrieve a source location representing the first character within a
+ * source range.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getRangeStart(CXSourceRange range);
+
+/**
+ * Retrieve a source location representing the last character within a
+ * source range.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getRangeEnd(CXSourceRange range);
+
+/**
+ * Identifies an array of ranges.
+ */
+typedef struct {
+  /** The number of ranges in the \c ranges array. */
+  unsigned count;
+  /**
+   * An array of \c CXSourceRanges.
+   */
+  CXSourceRange *ranges;
+} CXSourceRangeList;
+
+/**
+ * Retrieve all ranges that were skipped by the preprocessor.
+ *
+ * The preprocessor will skip lines when they are surrounded by an
+ * if/ifdef/ifndef directive whose condition does not evaluate to true.
+ */
+CINDEX_LINKAGE CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit tu,
+                                                         CXFile file);
+
+/**
+ * Retrieve all ranges from all files that were skipped by the
+ * preprocessor.
+ *
+ * The preprocessor will skip lines when they are surrounded by an
+ * if/ifdef/ifndef directive whose condition does not evaluate to true.
+ */
+CINDEX_LINKAGE CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit tu);
+
+/**
+ * Destroy the given \c CXSourceRangeList.
+ */
+CINDEX_LINKAGE void clang_disposeSourceRangeList(CXSourceRangeList *ranges);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_DIAG Diagnostic reporting
+ *
+ * @{
+ */
+
+/**
+ * Describes the severity of a particular diagnostic.
+ */
+enum CXDiagnosticSeverity {
+  /**
+   * A diagnostic that has been suppressed, e.g., by a command-line
+   * option.
+   */
+  CXDiagnostic_Ignored = 0,
+
+  /**
+   * This diagnostic is a note that should be attached to the
+   * previous (non-note) diagnostic.
+   */
+  CXDiagnostic_Note    = 1,
+
+  /**
+   * This diagnostic indicates suspicious code that may not be
+   * wrong.
+   */
+  CXDiagnostic_Warning = 2,
+
+  /**
+   * This diagnostic indicates that the code is ill-formed.
+   */
+  CXDiagnostic_Error   = 3,
+
+  /**
+   * This diagnostic indicates that the code is ill-formed such
+   * that future parser recovery is unlikely to produce useful
+   * results.
+   */
+  CXDiagnostic_Fatal   = 4
+};
+
+/**
+ * A single diagnostic, containing the diagnostic's severity,
+ * location, text, source ranges, and fix-it hints.
+ */
+typedef void *CXDiagnostic;
+
+/**
+ * A group of CXDiagnostics.
+ */
+typedef void *CXDiagnosticSet;
+
+/**
+ * Determine the number of diagnostics in a CXDiagnosticSet.
+ */
+CINDEX_LINKAGE unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags);
+
+/**
+ * Retrieve a diagnostic associated with the given CXDiagnosticSet.
+ *
+ * \param Diags the CXDiagnosticSet to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
+                                                     unsigned Index);
+
+/**
+ * Describes the kind of error that occurred (if any) in a call to
+ * \c clang_loadDiagnostics.
+ */
+enum CXLoadDiag_Error {
+  /**
+   * Indicates that no error occurred.
+   */
+  CXLoadDiag_None = 0,
+
+  /**
+   * Indicates that an unknown error occurred while attempting to
+   * deserialize diagnostics.
+   */
+  CXLoadDiag_Unknown = 1,
+
+  /**
+   * Indicates that the file containing the serialized diagnostics
+   * could not be opened.
+   */
+  CXLoadDiag_CannotLoad = 2,
+
+  /**
+   * Indicates that the serialized diagnostics file is invalid or
+   * corrupt.
+   */
+  CXLoadDiag_InvalidFile = 3
+};
+
+/**
+ * Deserialize a set of diagnostics from a Clang diagnostics bitcode
+ * file.
+ *
+ * \param file The name of the file to deserialize.
+ * \param error A pointer to a enum value recording if there was a problem
+ *        deserializing the diagnostics.
+ * \param errorString A pointer to a CXString for recording the error string
+ *        if the file was not successfully loaded.
+ *
+ * \returns A loaded CXDiagnosticSet if successful, and NULL otherwise.  These
+ * diagnostics should be released using clang_disposeDiagnosticSet().
+ */
+CINDEX_LINKAGE CXDiagnosticSet clang_loadDiagnostics(const char *file,
+                                                  enum CXLoadDiag_Error *error,
+                                                  CXString *errorString);
+
+/**
+ * Release a CXDiagnosticSet and all of its contained diagnostics.
+ */
+CINDEX_LINKAGE void clang_disposeDiagnosticSet(CXDiagnosticSet Diags);
+
+/**
+ * Retrieve the child diagnostics of a CXDiagnostic.
+ *
+ * This CXDiagnosticSet does not need to be released by
+ * clang_disposeDiagnosticSet.
+ */
+CINDEX_LINKAGE CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic D);
+
+/**
+ * Determine the number of diagnostics produced for the given
+ * translation unit.
+ */
+CINDEX_LINKAGE unsigned clang_getNumDiagnostics(CXTranslationUnit Unit);
+
+/**
+ * Retrieve a diagnostic associated with the given translation unit.
+ *
+ * \param Unit the translation unit to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit,
+                                                unsigned Index);
+
+/**
+ * Retrieve the complete set of diagnostics associated with a
+ *        translation unit.
+ *
+ * \param Unit the translation unit to query.
+ */
+CINDEX_LINKAGE CXDiagnosticSet
+  clang_getDiagnosticSetFromTU(CXTranslationUnit Unit);
+
+/**
+ * Destroy a diagnostic.
+ */
+CINDEX_LINKAGE void clang_disposeDiagnostic(CXDiagnostic Diagnostic);
+
+/**
+ * Options to control the display of diagnostics.
+ *
+ * The values in this enum are meant to be combined to customize the
+ * behavior of \c clang_formatDiagnostic().
+ */
+enum CXDiagnosticDisplayOptions {
+  /**
+   * Display the source-location information where the
+   * diagnostic was located.
+   *
+   * When set, diagnostics will be prefixed by the file, line, and
+   * (optionally) column to which the diagnostic refers. For example,
+   *
+   * \code
+   * test.c:28: warning: extra tokens at end of #endif directive
+   * \endcode
+   *
+   * This option corresponds to the clang flag \c -fshow-source-location.
+   */
+  CXDiagnostic_DisplaySourceLocation = 0x01,
+
+  /**
+   * If displaying the source-location information of the
+   * diagnostic, also include the column number.
+   *
+   * This option corresponds to the clang flag \c -fshow-column.
+   */
+  CXDiagnostic_DisplayColumn = 0x02,
+
+  /**
+   * If displaying the source-location information of the
+   * diagnostic, also include information about source ranges in a
+   * machine-parsable format.
+   *
+   * This option corresponds to the clang flag
+   * \c -fdiagnostics-print-source-range-info.
+   */
+  CXDiagnostic_DisplaySourceRanges = 0x04,
+
+  /**
+   * Display the option name associated with this diagnostic, if any.
+   *
+   * The option name displayed (e.g., -Wconversion) will be placed in brackets
+   * after the diagnostic text. This option corresponds to the clang flag
+   * \c -fdiagnostics-show-option.
+   */
+  CXDiagnostic_DisplayOption = 0x08,
+
+  /**
+   * Display the category number associated with this diagnostic, if any.
+   *
+   * The category number is displayed within brackets after the diagnostic text.
+   * This option corresponds to the clang flag
+   * \c -fdiagnostics-show-category=id.
+   */
+  CXDiagnostic_DisplayCategoryId = 0x10,
+
+  /**
+   * Display the category name associated with this diagnostic, if any.
+   *
+   * The category name is displayed within brackets after the diagnostic text.
+   * This option corresponds to the clang flag
+   * \c -fdiagnostics-show-category=name.
+   */
+  CXDiagnostic_DisplayCategoryName = 0x20
+};
+
+/**
+ * Format the given diagnostic in a manner that is suitable for display.
+ *
+ * This routine will format the given diagnostic to a string, rendering
+ * the diagnostic according to the various options given. The
+ * \c clang_defaultDiagnosticDisplayOptions() function returns the set of
+ * options that most closely mimics the behavior of the clang compiler.
+ *
+ * \param Diagnostic The diagnostic to print.
+ *
+ * \param Options A set of options that control the diagnostic display,
+ * created by combining \c CXDiagnosticDisplayOptions values.
+ *
+ * \returns A new string containing for formatted diagnostic.
+ */
+CINDEX_LINKAGE CXString clang_formatDiagnostic(CXDiagnostic Diagnostic,
+                                               unsigned Options);
+
+/**
+ * Retrieve the set of display options most similar to the
+ * default behavior of the clang compiler.
+ *
+ * \returns A set of display options suitable for use with \c
+ * clang_formatDiagnostic().
+ */
+CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions(void);
+
+/**
+ * Determine the severity of the given diagnostic.
+ */
+CINDEX_LINKAGE enum CXDiagnosticSeverity
+clang_getDiagnosticSeverity(CXDiagnostic);
+
+/**
+ * Retrieve the source location of the given diagnostic.
+ *
+ * This location is where Clang would print the caret ('^') when
+ * displaying the diagnostic on the command line.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic);
+
+/**
+ * Retrieve the text of the given diagnostic.
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticSpelling(CXDiagnostic);
+
+/**
+ * Retrieve the name of the command-line option that enabled this
+ * diagnostic.
+ *
+ * \param Diag The diagnostic to be queried.
+ *
+ * \param Disable If non-NULL, will be set to the option that disables this
+ * diagnostic (if any).
+ *
+ * \returns A string that contains the command-line option used to enable this
+ * warning, such as "-Wconversion" or "-pedantic".
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticOption(CXDiagnostic Diag,
+                                                  CXString *Disable);
+
+/**
+ * Retrieve the category number for this diagnostic.
+ *
+ * Diagnostics can be categorized into groups along with other, related
+ * diagnostics (e.g., diagnostics under the same warning flag). This routine
+ * retrieves the category number for the given diagnostic.
+ *
+ * \returns The number of the category that contains this diagnostic, or zero
+ * if this diagnostic is uncategorized.
+ */
+CINDEX_LINKAGE unsigned clang_getDiagnosticCategory(CXDiagnostic);
+
+/**
+ * Retrieve the name of a particular diagnostic category.  This
+ *  is now deprecated.  Use clang_getDiagnosticCategoryText()
+ *  instead.
+ *
+ * \param Category A diagnostic category number, as returned by
+ * \c clang_getDiagnosticCategory().
+ *
+ * \returns The name of the given diagnostic category.
+ */
+CINDEX_DEPRECATED CINDEX_LINKAGE
+CXString clang_getDiagnosticCategoryName(unsigned Category);
+
+/**
+ * Retrieve the diagnostic category text for a given diagnostic.
+ *
+ * \returns The text of the given diagnostic category.
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticCategoryText(CXDiagnostic);
+
+/**
+ * Determine the number of source ranges associated with the given
+ * diagnostic.
+ */
+CINDEX_LINKAGE unsigned clang_getDiagnosticNumRanges(CXDiagnostic);
+
+/**
+ * Retrieve a source range associated with the diagnostic.
+ *
+ * A diagnostic's source ranges highlight important elements in the source
+ * code. On the command line, Clang displays source ranges by
+ * underlining them with '~' characters.
+ *
+ * \param Diagnostic the diagnostic whose range is being extracted.
+ *
+ * \param Range the zero-based index specifying which range to
+ *
+ * \returns the requested source range.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diagnostic,
+                                                      unsigned Range);
+
+/**
+ * Determine the number of fix-it hints associated with the
+ * given diagnostic.
+ */
+CINDEX_LINKAGE unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diagnostic);
+
+/**
+ * Retrieve the replacement information for a given fix-it.
+ *
+ * Fix-its are described in terms of a source range whose contents
+ * should be replaced by a string. This approach generalizes over
+ * three kinds of operations: removal of source code (the range covers
+ * the code to be removed and the replacement string is empty),
+ * replacement of source code (the range covers the code to be
+ * replaced and the replacement string provides the new code), and
+ * insertion (both the start and end of the range point at the
+ * insertion location, and the replacement string provides the text to
+ * insert).
+ *
+ * \param Diagnostic The diagnostic whose fix-its are being queried.
+ *
+ * \param FixIt The zero-based index of the fix-it.
+ *
+ * \param ReplacementRange The source range whose contents will be
+ * replaced with the returned replacement string. Note that source
+ * ranges are half-open ranges [a, b), so the source code should be
+ * replaced from a and up to (but not including) b.
+ *
+ * \returns A string containing text that should be replace the source
+ * code indicated by the \c ReplacementRange.
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic,
+                                                 unsigned FixIt,
+                                               CXSourceRange *ReplacementRange);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_TRANSLATION_UNIT Translation unit manipulation
+ *
+ * The routines in this group provide the ability to create and destroy
+ * translation units from files, either by parsing the contents of the files or
+ * by reading in a serialized representation of a translation unit.
+ *
+ * @{
+ */
+
+/**
+ * Get the original translation unit source file name.
+ */
+CINDEX_LINKAGE CXString
+clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
+
+/**
+ * Return the CXTranslationUnit for a given source file and the provided
+ * command line arguments one would pass to the compiler.
+ *
+ * Note: The 'source_filename' argument is optional.  If the caller provides a
+ * NULL pointer, the name of the source file is expected to reside in the
+ * specified command line arguments.
+ *
+ * Note: When encountered in 'clang_command_line_args', the following options
+ * are ignored:
+ *
+ *   '-c'
+ *   '-emit-ast'
+ *   '-fsyntax-only'
+ *   '-o \<output file>'  (both '-o' and '\<output file>' are ignored)
+ *
+ * \param CIdx The index object with which the translation unit will be
+ * associated.
+ *
+ * \param source_filename The name of the source file to load, or NULL if the
+ * source file is included in \p clang_command_line_args.
+ *
+ * \param num_clang_command_line_args The number of command-line arguments in
+ * \p clang_command_line_args.
+ *
+ * \param clang_command_line_args The command-line arguments that would be
+ * passed to the \c clang executable if it were being invoked out-of-process.
+ * These command-line options will be parsed and will affect how the translation
+ * unit is parsed. Note that the following options are ignored: '-c',
+ * '-emit-ast', '-fsyntax-only' (which is the default), and '-o \<output file>'.
+ *
+ * \param num_unsaved_files the number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param unsaved_files the files that have not yet been saved to disk
+ * but may be required for code completion, including the contents of
+ * those files.  The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ */
+CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile(
+                                         CXIndex CIdx,
+                                         const char *source_filename,
+                                         int num_clang_command_line_args,
+                                   const char * const *clang_command_line_args,
+                                         unsigned num_unsaved_files,
+                                         struct CXUnsavedFile *unsaved_files);
+
+/**
+ * Same as \c clang_createTranslationUnit2, but returns
+ * the \c CXTranslationUnit instead of an error code.  In case of an error this
+ * routine returns a \c NULL \c CXTranslationUnit, without further detailed
+ * error codes.
+ */
+CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(
+    CXIndex CIdx,
+    const char *ast_filename);
+
+/**
+ * Create a translation unit from an AST file (\c -emit-ast).
+ *
+ * \param[out] out_TU A non-NULL pointer to store the created
+ * \c CXTranslationUnit.
+ *
+ * \returns Zero on success, otherwise returns an error code.
+ */
+CINDEX_LINKAGE enum CXErrorCode clang_createTranslationUnit2(
+    CXIndex CIdx,
+    const char *ast_filename,
+    CXTranslationUnit *out_TU);
+
+/**
+ * Flags that control the creation of translation units.
+ *
+ * The enumerators in this enumeration type are meant to be bitwise
+ * ORed together to specify which options should be used when
+ * constructing the translation unit.
+ */
+enum CXTranslationUnit_Flags {
+  /**
+   * Used to indicate that no special translation-unit options are
+   * needed.
+   */
+  CXTranslationUnit_None = 0x0,
+
+  /**
+   * Used to indicate that the parser should construct a "detailed"
+   * preprocessing record, including all macro definitions and instantiations.
+   *
+   * Constructing a detailed preprocessing record requires more memory
+   * and time to parse, since the information contained in the record
+   * is usually not retained. However, it can be useful for
+   * applications that require more detailed information about the
+   * behavior of the preprocessor.
+   */
+  CXTranslationUnit_DetailedPreprocessingRecord = 0x01,
+
+  /**
+   * Used to indicate that the translation unit is incomplete.
+   *
+   * When a translation unit is considered "incomplete", semantic
+   * analysis that is typically performed at the end of the
+   * translation unit will be suppressed. For example, this suppresses
+   * the completion of tentative declarations in C and of
+   * instantiation of implicitly-instantiation function templates in
+   * C++. This option is typically used when parsing a header with the
+   * intent of producing a precompiled header.
+   */
+  CXTranslationUnit_Incomplete = 0x02,
+
+  /**
+   * Used to indicate that the translation unit should be built with an
+   * implicit precompiled header for the preamble.
+   *
+   * An implicit precompiled header is used as an optimization when a
+   * particular translation unit is likely to be reparsed many times
+   * when the sources aren't changing that often. In this case, an
+   * implicit precompiled header will be built containing all of the
+   * initial includes at the top of the main file (what we refer to as
+   * the "preamble" of the file). In subsequent parses, if the
+   * preamble or the files in it have not changed, \c
+   * clang_reparseTranslationUnit() will re-use the implicit
+   * precompiled header to improve parsing performance.
+   */
+  CXTranslationUnit_PrecompiledPreamble = 0x04,
+
+  /**
+   * Used to indicate that the translation unit should cache some
+   * code-completion results with each reparse of the source file.
+   *
+   * Caching of code-completion results is a performance optimization that
+   * introduces some overhead to reparsing but improves the performance of
+   * code-completion operations.
+   */
+  CXTranslationUnit_CacheCompletionResults = 0x08,
+
+  /**
+   * Used to indicate that the translation unit will be serialized with
+   * \c clang_saveTranslationUnit.
+   *
+   * This option is typically used when parsing a header with the intent of
+   * producing a precompiled header.
+   */
+  CXTranslationUnit_ForSerialization = 0x10,
+
+  /**
+   * DEPRECATED: Enabled chained precompiled preambles in C++.
+   *
+   * Note: this is a *temporary* option that is available only while
+   * we are testing C++ precompiled preamble support. It is deprecated.
+   */
+  CXTranslationUnit_CXXChainedPCH = 0x20,
+
+  /**
+   * Used to indicate that function/method bodies should be skipped while
+   * parsing.
+   *
+   * This option can be used to search for declarations/definitions while
+   * ignoring the usages.
+   */
+  CXTranslationUnit_SkipFunctionBodies = 0x40,
+
+  /**
+   * Used to indicate that brief documentation comments should be
+   * included into the set of code completions returned from this translation
+   * unit.
+   */
+  CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80,
+
+  /**
+   * Used to indicate that the precompiled preamble should be created on
+   * the first parse. Otherwise it will be created on the first reparse. This
+   * trades runtime on the first parse (serializing the preamble takes time) for
+   * reduced runtime on the second parse (can now reuse the preamble).
+   */
+  CXTranslationUnit_CreatePreambleOnFirstParse = 0x100,
+
+  /**
+   * Do not stop processing when fatal errors are encountered.
+   *
+   * When fatal errors are encountered while parsing a translation unit,
+   * semantic analysis is typically stopped early when compiling code. A common
+   * source for fatal errors are unresolvable include files. For the
+   * purposes of an IDE, this is undesirable behavior and as much information
+   * as possible should be reported. Use this flag to enable this behavior.
+   */
+  CXTranslationUnit_KeepGoing = 0x200,
+
+  /**
+   * Sets the preprocessor in a mode for parsing a single file only.
+   */
+  CXTranslationUnit_SingleFileParse = 0x400,
+
+  /**
+   * Used in combination with CXTranslationUnit_SkipFunctionBodies to
+   * constrain the skipping of function bodies to the preamble.
+   *
+   * The function bodies of the main file are not skipped.
+   */
+  CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 0x800,
+
+  /**
+   * Used to indicate that attributed types should be included in CXType.
+   */
+  CXTranslationUnit_IncludeAttributedTypes = 0x1000,
+
+  /**
+   * Used to indicate that implicit attributes should be visited.
+   */
+  CXTranslationUnit_VisitImplicitAttributes = 0x2000,
+
+  /**
+   * Used to indicate that non-errors from included files should be ignored.
+   *
+   * If set, clang_getDiagnosticSetFromTU() will not report e.g. warnings from
+   * included files anymore. This speeds up clang_getDiagnosticSetFromTU() for
+   * the case where these warnings are not of interest, as for an IDE for
+   * example, which typically shows only the diagnostics in the main file.
+   */
+  CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles = 0x4000,
+
+  /**
+   * Tells the preprocessor not to skip excluded conditional blocks.
+   */
+  CXTranslationUnit_RetainExcludedConditionalBlocks = 0x8000
+};
+
+/**
+ * Returns the set of flags that is suitable for parsing a translation
+ * unit that is being edited.
+ *
+ * The set of flags returned provide options for \c clang_parseTranslationUnit()
+ * to indicate that the translation unit is likely to be reparsed many times,
+ * either explicitly (via \c clang_reparseTranslationUnit()) or implicitly
+ * (e.g., by code completion (\c clang_codeCompletionAt())). The returned flag
+ * set contains an unspecified set of optimizations (e.g., the precompiled
+ * preamble) geared toward improving the performance of these routines. The
+ * set of optimizations enabled may change from one version to the next.
+ */
+CINDEX_LINKAGE unsigned clang_defaultEditingTranslationUnitOptions(void);
+
+/**
+ * Same as \c clang_parseTranslationUnit2, but returns
+ * the \c CXTranslationUnit instead of an error code.  In case of an error this
+ * routine returns a \c NULL \c CXTranslationUnit, without further detailed
+ * error codes.
+ */
+CINDEX_LINKAGE CXTranslationUnit
+clang_parseTranslationUnit(CXIndex CIdx,
+                           const char *source_filename,
+                           const char *const *command_line_args,
+                           int num_command_line_args,
+                           struct CXUnsavedFile *unsaved_files,
+                           unsigned num_unsaved_files,
+                           unsigned options);
+
+/**
+ * Parse the given source file and the translation unit corresponding
+ * to that file.
+ *
+ * This routine is the main entry point for the Clang C API, providing the
+ * ability to parse a source file into a translation unit that can then be
+ * queried by other functions in the API. This routine accepts a set of
+ * command-line arguments so that the compilation can be configured in the same
+ * way that the compiler is configured on the command line.
+ *
+ * \param CIdx The index object with which the translation unit will be
+ * associated.
+ *
+ * \param source_filename The name of the source file to load, or NULL if the
+ * source file is included in \c command_line_args.
+ *
+ * \param command_line_args The command-line arguments that would be
+ * passed to the \c clang executable if it were being invoked out-of-process.
+ * These command-line options will be parsed and will affect how the translation
+ * unit is parsed. Note that the following options are ignored: '-c',
+ * '-emit-ast', '-fsyntax-only' (which is the default), and '-o \<output file>'.
+ *
+ * \param num_command_line_args The number of command-line arguments in
+ * \c command_line_args.
+ *
+ * \param unsaved_files the files that have not yet been saved to disk
+ * but may be required for parsing, including the contents of
+ * those files.  The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ *
+ * \param num_unsaved_files the number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param options A bitmask of options that affects how the translation unit
+ * is managed but not its compilation. This should be a bitwise OR of the
+ * CXTranslationUnit_XXX flags.
+ *
+ * \param[out] out_TU A non-NULL pointer to store the created
+ * \c CXTranslationUnit, describing the parsed code and containing any
+ * diagnostics produced by the compiler.
+ *
+ * \returns Zero on success, otherwise returns an error code.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_parseTranslationUnit2(CXIndex CIdx,
+                            const char *source_filename,
+                            const char *const *command_line_args,
+                            int num_command_line_args,
+                            struct CXUnsavedFile *unsaved_files,
+                            unsigned num_unsaved_files,
+                            unsigned options,
+                            CXTranslationUnit *out_TU);
+
+/**
+ * Same as clang_parseTranslationUnit2 but requires a full command line
+ * for \c command_line_args including argv[0]. This is useful if the standard
+ * library paths are relative to the binary.
+ */
+CINDEX_LINKAGE enum CXErrorCode clang_parseTranslationUnit2FullArgv(
+    CXIndex CIdx, const char *source_filename,
+    const char *const *command_line_args, int num_command_line_args,
+    struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
+    unsigned options, CXTranslationUnit *out_TU);
+
+/**
+ * Flags that control how translation units are saved.
+ *
+ * The enumerators in this enumeration type are meant to be bitwise
+ * ORed together to specify which options should be used when
+ * saving the translation unit.
+ */
+enum CXSaveTranslationUnit_Flags {
+  /**
+   * Used to indicate that no special saving options are needed.
+   */
+  CXSaveTranslationUnit_None = 0x0
+};
+
+/**
+ * Returns the set of flags that is suitable for saving a translation
+ * unit.
+ *
+ * The set of flags returned provide options for
+ * \c clang_saveTranslationUnit() by default. The returned flag
+ * set contains an unspecified set of options that save translation units with
+ * the most commonly-requested data.
+ */
+CINDEX_LINKAGE unsigned clang_defaultSaveOptions(CXTranslationUnit TU);
+
+/**
+ * Describes the kind of error that occurred (if any) in a call to
+ * \c clang_saveTranslationUnit().
+ */
+enum CXSaveError {
+  /**
+   * Indicates that no error occurred while saving a translation unit.
+   */
+  CXSaveError_None = 0,
+
+  /**
+   * Indicates that an unknown error occurred while attempting to save
+   * the file.
+   *
+   * This error typically indicates that file I/O failed when attempting to
+   * write the file.
+   */
+  CXSaveError_Unknown = 1,
+
+  /**
+   * Indicates that errors during translation prevented this attempt
+   * to save the translation unit.
+   *
+   * Errors that prevent the translation unit from being saved can be
+   * extracted using \c clang_getNumDiagnostics() and \c clang_getDiagnostic().
+   */
+  CXSaveError_TranslationErrors = 2,
+
+  /**
+   * Indicates that the translation unit to be saved was somehow
+   * invalid (e.g., NULL).
+   */
+  CXSaveError_InvalidTU = 3
+};
+
+/**
+ * Saves a translation unit into a serialized representation of
+ * that translation unit on disk.
+ *
+ * Any translation unit that was parsed without error can be saved
+ * into a file. The translation unit can then be deserialized into a
+ * new \c CXTranslationUnit with \c clang_createTranslationUnit() or,
+ * if it is an incomplete translation unit that corresponds to a
+ * header, used as a precompiled header when parsing other translation
+ * units.
+ *
+ * \param TU The translation unit to save.
+ *
+ * \param FileName The file to which the translation unit will be saved.
+ *
+ * \param options A bitmask of options that affects how the translation unit
+ * is saved. This should be a bitwise OR of the
+ * CXSaveTranslationUnit_XXX flags.
+ *
+ * \returns A value that will match one of the enumerators of the CXSaveError
+ * enumeration. Zero (CXSaveError_None) indicates that the translation unit was
+ * saved successfully, while a non-zero value indicates that a problem occurred.
+ */
+CINDEX_LINKAGE int clang_saveTranslationUnit(CXTranslationUnit TU,
+                                             const char *FileName,
+                                             unsigned options);
+
+/**
+ * Suspend a translation unit in order to free memory associated with it.
+ *
+ * A suspended translation unit uses significantly less memory but on the other
+ * side does not support any other calls than \c clang_reparseTranslationUnit
+ * to resume it or \c clang_disposeTranslationUnit to dispose it completely.
+ */
+CINDEX_LINKAGE unsigned clang_suspendTranslationUnit(CXTranslationUnit);
+
+/**
+ * Destroy the specified CXTranslationUnit object.
+ */
+CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit);
+
+/**
+ * Flags that control the reparsing of translation units.
+ *
+ * The enumerators in this enumeration type are meant to be bitwise
+ * ORed together to specify which options should be used when
+ * reparsing the translation unit.
+ */
+enum CXReparse_Flags {
+  /**
+   * Used to indicate that no special reparsing options are needed.
+   */
+  CXReparse_None = 0x0
+};
+
+/**
+ * Returns the set of flags that is suitable for reparsing a translation
+ * unit.
+ *
+ * The set of flags returned provide options for
+ * \c clang_reparseTranslationUnit() by default. The returned flag
+ * set contains an unspecified set of optimizations geared toward common uses
+ * of reparsing. The set of optimizations enabled may change from one version
+ * to the next.
+ */
+CINDEX_LINKAGE unsigned clang_defaultReparseOptions(CXTranslationUnit TU);
+
+/**
+ * Reparse the source files that produced this translation unit.
+ *
+ * This routine can be used to re-parse the source files that originally
+ * created the given translation unit, for example because those source files
+ * have changed (either on disk or as passed via \p unsaved_files). The
+ * source code will be reparsed with the same command-line options as it
+ * was originally parsed.
+ *
+ * Reparsing a translation unit invalidates all cursors and source locations
+ * that refer into that translation unit. This makes reparsing a translation
+ * unit semantically equivalent to destroying the translation unit and then
+ * creating a new translation unit with the same command-line arguments.
+ * However, it may be more efficient to reparse a translation
+ * unit using this routine.
+ *
+ * \param TU The translation unit whose contents will be re-parsed. The
+ * translation unit must originally have been built with
+ * \c clang_createTranslationUnitFromSourceFile().
+ *
+ * \param num_unsaved_files The number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param unsaved_files The files that have not yet been saved to disk
+ * but may be required for parsing, including the contents of
+ * those files.  The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ *
+ * \param options A bitset of options composed of the flags in CXReparse_Flags.
+ * The function \c clang_defaultReparseOptions() produces a default set of
+ * options recommended for most uses, based on the translation unit.
+ *
+ * \returns 0 if the sources could be reparsed.  A non-zero error code will be
+ * returned if reparsing was impossible, such that the translation unit is
+ * invalid. In such cases, the only valid call for \c TU is
+ * \c clang_disposeTranslationUnit(TU).  The error codes returned by this
+ * routine are described by the \c CXErrorCode enum.
+ */
+CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU,
+                                                unsigned num_unsaved_files,
+                                          struct CXUnsavedFile *unsaved_files,
+                                                unsigned options);
+
+/**
+  * Categorizes how memory is being used by a translation unit.
+  */
+enum CXTUResourceUsageKind {
+  CXTUResourceUsage_AST = 1,
+  CXTUResourceUsage_Identifiers = 2,
+  CXTUResourceUsage_Selectors = 3,
+  CXTUResourceUsage_GlobalCompletionResults = 4,
+  CXTUResourceUsage_SourceManagerContentCache = 5,
+  CXTUResourceUsage_AST_SideTables = 6,
+  CXTUResourceUsage_SourceManager_Membuffer_Malloc = 7,
+  CXTUResourceUsage_SourceManager_Membuffer_MMap = 8,
+  CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9,
+  CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10,
+  CXTUResourceUsage_Preprocessor = 11,
+  CXTUResourceUsage_PreprocessingRecord = 12,
+  CXTUResourceUsage_SourceManager_DataStructures = 13,
+  CXTUResourceUsage_Preprocessor_HeaderSearch = 14,
+  CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = CXTUResourceUsage_AST,
+  CXTUResourceUsage_MEMORY_IN_BYTES_END =
+    CXTUResourceUsage_Preprocessor_HeaderSearch,
+
+  CXTUResourceUsage_First = CXTUResourceUsage_AST,
+  CXTUResourceUsage_Last = CXTUResourceUsage_Preprocessor_HeaderSearch
+};
+
+/**
+  * Returns the human-readable null-terminated C string that represents
+  *  the name of the memory category.  This string should never be freed.
+  */
+CINDEX_LINKAGE
+const char *clang_getTUResourceUsageName(enum CXTUResourceUsageKind kind);
+
+typedef struct CXTUResourceUsageEntry {
+  /* The memory usage category. */
+  enum CXTUResourceUsageKind kind;
+  /* Amount of resources used.
+      The units will depend on the resource kind. */
+  unsigned long amount;
+} CXTUResourceUsageEntry;
+
+/**
+  * The memory usage of a CXTranslationUnit, broken into categories.
+  */
+typedef struct CXTUResourceUsage {
+  /* Private data member, used for queries. */
+  void *data;
+
+  /* The number of entries in the 'entries' array. */
+  unsigned numEntries;
+
+  /* An array of key-value pairs, representing the breakdown of memory
+            usage. */
+  CXTUResourceUsageEntry *entries;
+
+} CXTUResourceUsage;
+
+/**
+  * Return the memory usage of a translation unit.  This object
+  *  should be released with clang_disposeCXTUResourceUsage().
+  */
+CINDEX_LINKAGE CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU);
+
+CINDEX_LINKAGE void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage);
+
+/**
+ * Get target information for this translation unit.
+ *
+ * The CXTargetInfo object cannot outlive the CXTranslationUnit object.
+ */
+CINDEX_LINKAGE CXTargetInfo
+clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit);
+
+/**
+ * Destroy the CXTargetInfo object.
+ */
+CINDEX_LINKAGE void
+clang_TargetInfo_dispose(CXTargetInfo Info);
+
+/**
+ * Get the normalized target triple as a string.
+ *
+ * Returns the empty string in case of any error.
+ */
+CINDEX_LINKAGE CXString
+clang_TargetInfo_getTriple(CXTargetInfo Info);
+
+/**
+ * Get the pointer width of the target in bits.
+ *
+ * Returns -1 in case of error.
+ */
+CINDEX_LINKAGE int
+clang_TargetInfo_getPointerWidth(CXTargetInfo Info);
+
+/**
+ * @}
+ */
+
+/**
+ * Describes the kind of entity that a cursor refers to.
+ */
+enum CXCursorKind {
+  /* Declarations */
+  /**
+   * A declaration whose specific kind is not exposed via this
+   * interface.
+   *
+   * Unexposed declarations have the same operations as any other kind
+   * of declaration; one can extract their location information,
+   * spelling, find their definitions, etc. However, the specific kind
+   * of the declaration is not reported.
+   */
+  CXCursor_UnexposedDecl                 = 1,
+  /** A C or C++ struct. */
+  CXCursor_StructDecl                    = 2,
+  /** A C or C++ union. */
+  CXCursor_UnionDecl                     = 3,
+  /** A C++ class. */
+  CXCursor_ClassDecl                     = 4,
+  /** An enumeration. */
+  CXCursor_EnumDecl                      = 5,
+  /**
+   * A field (in C) or non-static data member (in C++) in a
+   * struct, union, or C++ class.
+   */
+  CXCursor_FieldDecl                     = 6,
+  /** An enumerator constant. */
+  CXCursor_EnumConstantDecl              = 7,
+  /** A function. */
+  CXCursor_FunctionDecl                  = 8,
+  /** A variable. */
+  CXCursor_VarDecl                       = 9,
+  /** A function or method parameter. */
+  CXCursor_ParmDecl                      = 10,
+  /** An Objective-C \@interface. */
+  CXCursor_ObjCInterfaceDecl             = 11,
+  /** An Objective-C \@interface for a category. */
+  CXCursor_ObjCCategoryDecl              = 12,
+  /** An Objective-C \@protocol declaration. */
+  CXCursor_ObjCProtocolDecl              = 13,
+  /** An Objective-C \@property declaration. */
+  CXCursor_ObjCPropertyDecl              = 14,
+  /** An Objective-C instance variable. */
+  CXCursor_ObjCIvarDecl                  = 15,
+  /** An Objective-C instance method. */
+  CXCursor_ObjCInstanceMethodDecl        = 16,
+  /** An Objective-C class method. */
+  CXCursor_ObjCClassMethodDecl           = 17,
+  /** An Objective-C \@implementation. */
+  CXCursor_ObjCImplementationDecl        = 18,
+  /** An Objective-C \@implementation for a category. */
+  CXCursor_ObjCCategoryImplDecl          = 19,
+  /** A typedef. */
+  CXCursor_TypedefDecl                   = 20,
+  /** A C++ class method. */
+  CXCursor_CXXMethod                     = 21,
+  /** A C++ namespace. */
+  CXCursor_Namespace                     = 22,
+  /** A linkage specification, e.g. 'extern "C"'. */
+  CXCursor_LinkageSpec                   = 23,
+  /** A C++ constructor. */
+  CXCursor_Constructor                   = 24,
+  /** A C++ destructor. */
+  CXCursor_Destructor                    = 25,
+  /** A C++ conversion function. */
+  CXCursor_ConversionFunction            = 26,
+  /** A C++ template type parameter. */
+  CXCursor_TemplateTypeParameter         = 27,
+  /** A C++ non-type template parameter. */
+  CXCursor_NonTypeTemplateParameter      = 28,
+  /** A C++ template template parameter. */
+  CXCursor_TemplateTemplateParameter     = 29,
+  /** A C++ function template. */
+  CXCursor_FunctionTemplate              = 30,
+  /** A C++ class template. */
+  CXCursor_ClassTemplate                 = 31,
+  /** A C++ class template partial specialization. */
+  CXCursor_ClassTemplatePartialSpecialization = 32,
+  /** A C++ namespace alias declaration. */
+  CXCursor_NamespaceAlias                = 33,
+  /** A C++ using directive. */
+  CXCursor_UsingDirective                = 34,
+  /** A C++ using declaration. */
+  CXCursor_UsingDeclaration              = 35,
+  /** A C++ alias declaration */
+  CXCursor_TypeAliasDecl                 = 36,
+  /** An Objective-C \@synthesize definition. */
+  CXCursor_ObjCSynthesizeDecl            = 37,
+  /** An Objective-C \@dynamic definition. */
+  CXCursor_ObjCDynamicDecl               = 38,
+  /** An access specifier. */
+  CXCursor_CXXAccessSpecifier            = 39,
+
+  CXCursor_FirstDecl                     = CXCursor_UnexposedDecl,
+  CXCursor_LastDecl                      = CXCursor_CXXAccessSpecifier,
+
+  /* References */
+  CXCursor_FirstRef                      = 40, /* Decl references */
+  CXCursor_ObjCSuperClassRef             = 40,
+  CXCursor_ObjCProtocolRef               = 41,
+  CXCursor_ObjCClassRef                  = 42,
+  /**
+   * A reference to a type declaration.
+   *
+   * A type reference occurs anywhere where a type is named but not
+   * declared. For example, given:
+   *
+   * \code
+   * typedef unsigned size_type;
+   * size_type size;
+   * \endcode
+   *
+   * The typedef is a declaration of size_type (CXCursor_TypedefDecl),
+   * while the type of the variable "size" is referenced. The cursor
+   * referenced by the type of size is the typedef for size_type.
+   */
+  CXCursor_TypeRef                       = 43,
+  CXCursor_CXXBaseSpecifier              = 44,
+  /**
+   * A reference to a class template, function template, template
+   * template parameter, or class template partial specialization.
+   */
+  CXCursor_TemplateRef                   = 45,
+  /**
+   * A reference to a namespace or namespace alias.
+   */
+  CXCursor_NamespaceRef                  = 46,
+  /**
+   * A reference to a member of a struct, union, or class that occurs in
+   * some non-expression context, e.g., a designated initializer.
+   */
+  CXCursor_MemberRef                     = 47,
+  /**
+   * A reference to a labeled statement.
+   *
+   * This cursor kind is used to describe the jump to "start_over" in the
+   * goto statement in the following example:
+   *
+   * \code
+   *   start_over:
+   *     ++counter;
+   *
+   *     goto start_over;
+   * \endcode
+   *
+   * A label reference cursor refers to a label statement.
+   */
+  CXCursor_LabelRef                      = 48,
+
+  /**
+   * A reference to a set of overloaded functions or function templates
+   * that has not yet been resolved to a specific function or function template.
+   *
+   * An overloaded declaration reference cursor occurs in C++ templates where
+   * a dependent name refers to a function. For example:
+   *
+   * \code
+   * template<typename T> void swap(T&, T&);
+   *
+   * struct X { ... };
+   * void swap(X&, X&);
+   *
+   * template<typename T>
+   * void reverse(T* first, T* last) {
+   *   while (first < last - 1) {
+   *     swap(*first, *--last);
+   *     ++first;
+   *   }
+   * }
+   *
+   * struct Y { };
+   * void swap(Y&, Y&);
+   * \endcode
+   *
+   * Here, the identifier "swap" is associated with an overloaded declaration
+   * reference. In the template definition, "swap" refers to either of the two
+   * "swap" functions declared above, so both results will be available. At
+   * instantiation time, "swap" may also refer to other functions found via
+   * argument-dependent lookup (e.g., the "swap" function at the end of the
+   * example).
+   *
+   * The functions \c clang_getNumOverloadedDecls() and
+   * \c clang_getOverloadedDecl() can be used to retrieve the definitions
+   * referenced by this cursor.
+   */
+  CXCursor_OverloadedDeclRef             = 49,
+
+  /**
+   * A reference to a variable that occurs in some non-expression
+   * context, e.g., a C++ lambda capture list.
+   */
+  CXCursor_VariableRef                   = 50,
+
+  CXCursor_LastRef                       = CXCursor_VariableRef,
+
+  /* Error conditions */
+  CXCursor_FirstInvalid                  = 70,
+  CXCursor_InvalidFile                   = 70,
+  CXCursor_NoDeclFound                   = 71,
+  CXCursor_NotImplemented                = 72,
+  CXCursor_InvalidCode                   = 73,
+  CXCursor_LastInvalid                   = CXCursor_InvalidCode,
+
+  /* Expressions */
+  CXCursor_FirstExpr                     = 100,
+
+  /**
+   * An expression whose specific kind is not exposed via this
+   * interface.
+   *
+   * Unexposed expressions have the same operations as any other kind
+   * of expression; one can extract their location information,
+   * spelling, children, etc. However, the specific kind of the
+   * expression is not reported.
+   */
+  CXCursor_UnexposedExpr                 = 100,
+
+  /**
+   * An expression that refers to some value declaration, such
+   * as a function, variable, or enumerator.
+   */
+  CXCursor_DeclRefExpr                   = 101,
+
+  /**
+   * An expression that refers to a member of a struct, union,
+   * class, Objective-C class, etc.
+   */
+  CXCursor_MemberRefExpr                 = 102,
+
+  /** An expression that calls a function. */
+  CXCursor_CallExpr                      = 103,
+
+  /** An expression that sends a message to an Objective-C
+   object or class. */
+  CXCursor_ObjCMessageExpr               = 104,
+
+  /** An expression that represents a block literal. */
+  CXCursor_BlockExpr                     = 105,
+
+  /** An integer literal.
+   */
+  CXCursor_IntegerLiteral                = 106,
+
+  /** A floating point number literal.
+   */
+  CXCursor_FloatingLiteral               = 107,
+
+  /** An imaginary number literal.
+   */
+  CXCursor_ImaginaryLiteral              = 108,
+
+  /** A string literal.
+   */
+  CXCursor_StringLiteral                 = 109,
+
+  /** A character literal.
+   */
+  CXCursor_CharacterLiteral              = 110,
+
+  /** A parenthesized expression, e.g. "(1)".
+   *
+   * This AST node is only formed if full location information is requested.
+   */
+  CXCursor_ParenExpr                     = 111,
+
+  /** This represents the unary-expression's (except sizeof and
+   * alignof).
+   */
+  CXCursor_UnaryOperator                 = 112,
+
+  /** [C99 6.5.2.1] Array Subscripting.
+   */
+  CXCursor_ArraySubscriptExpr            = 113,
+
+  /** A builtin binary operation expression such as "x + y" or
+   * "x <= y".
+   */
+  CXCursor_BinaryOperator                = 114,
+
+  /** Compound assignment such as "+=".
+   */
+  CXCursor_CompoundAssignOperator        = 115,
+
+  /** The ?: ternary operator.
+   */
+  CXCursor_ConditionalOperator           = 116,
+
+  /** An explicit cast in C (C99 6.5.4) or a C-style cast in C++
+   * (C++ [expr.cast]), which uses the syntax (Type)expr.
+   *
+   * For example: (int)f.
+   */
+  CXCursor_CStyleCastExpr                = 117,
+
+  /** [C99 6.5.2.5]
+   */
+  CXCursor_CompoundLiteralExpr           = 118,
+
+  /** Describes an C or C++ initializer list.
+   */
+  CXCursor_InitListExpr                  = 119,
+
+  /** The GNU address of label extension, representing &&label.
+   */
+  CXCursor_AddrLabelExpr                 = 120,
+
+  /** This is the GNU Statement Expression extension: ({int X=4; X;})
+   */
+  CXCursor_StmtExpr                      = 121,
+
+  /** Represents a C11 generic selection.
+   */
+  CXCursor_GenericSelectionExpr          = 122,
+
+  /** Implements the GNU __null extension, which is a name for a null
+   * pointer constant that has integral type (e.g., int or long) and is the same
+   * size and alignment as a pointer.
+   *
+   * The __null extension is typically only used by system headers, which define
+   * NULL as __null in C++ rather than using 0 (which is an integer that may not
+   * match the size of a pointer).
+   */
+  CXCursor_GNUNullExpr                   = 123,
+
+  /** C++'s static_cast<> expression.
+   */
+  CXCursor_CXXStaticCastExpr             = 124,
+
+  /** C++'s dynamic_cast<> expression.
+   */
+  CXCursor_CXXDynamicCastExpr            = 125,
+
+  /** C++'s reinterpret_cast<> expression.
+   */
+  CXCursor_CXXReinterpretCastExpr        = 126,
+
+  /** C++'s const_cast<> expression.
+   */
+  CXCursor_CXXConstCastExpr              = 127,
+
+  /** Represents an explicit C++ type conversion that uses "functional"
+   * notion (C++ [expr.type.conv]).
+   *
+   * Example:
+   * \code
+   *   x = int(0.5);
+   * \endcode
+   */
+  CXCursor_CXXFunctionalCastExpr         = 128,
+
+  /** A C++ typeid expression (C++ [expr.typeid]).
+   */
+  CXCursor_CXXTypeidExpr                 = 129,
+
+  /** [C++ 2.13.5] C++ Boolean Literal.
+   */
+  CXCursor_CXXBoolLiteralExpr            = 130,
+
+  /** [C++0x 2.14.7] C++ Pointer Literal.
+   */
+  CXCursor_CXXNullPtrLiteralExpr         = 131,
+
+  /** Represents the "this" expression in C++
+   */
+  CXCursor_CXXThisExpr                   = 132,
+
+  /** [C++ 15] C++ Throw Expression.
+   *
+   * This handles 'throw' and 'throw' assignment-expression. When
+   * assignment-expression isn't present, Op will be null.
+   */
+  CXCursor_CXXThrowExpr                  = 133,
+
+  /** A new expression for memory allocation and constructor calls, e.g:
+   * "new CXXNewExpr(foo)".
+   */
+  CXCursor_CXXNewExpr                    = 134,
+
+  /** A delete expression for memory deallocation and destructor calls,
+   * e.g. "delete[] pArray".
+   */
+  CXCursor_CXXDeleteExpr                 = 135,
+
+  /** A unary expression. (noexcept, sizeof, or other traits)
+   */
+  CXCursor_UnaryExpr                     = 136,
+
+  /** An Objective-C string literal i.e. @"foo".
+   */
+  CXCursor_ObjCStringLiteral             = 137,
+
+  /** An Objective-C \@encode expression.
+   */
+  CXCursor_ObjCEncodeExpr                = 138,
+
+  /** An Objective-C \@selector expression.
+   */
+  CXCursor_ObjCSelectorExpr              = 139,
+
+  /** An Objective-C \@protocol expression.
+   */
+  CXCursor_ObjCProtocolExpr              = 140,
+
+  /** An Objective-C "bridged" cast expression, which casts between
+   * Objective-C pointers and C pointers, transferring ownership in the process.
+   *
+   * \code
+   *   NSString *str = (__bridge_transfer NSString *)CFCreateString();
+   * \endcode
+   */
+  CXCursor_ObjCBridgedCastExpr           = 141,
+
+  /** Represents a C++0x pack expansion that produces a sequence of
+   * expressions.
+   *
+   * A pack expansion expression contains a pattern (which itself is an
+   * expression) followed by an ellipsis. For example:
+   *
+   * \code
+   * template<typename F, typename ...Types>
+   * void forward(F f, Types &&...args) {
+   *  f(static_cast<Types&&>(args)...);
+   * }
+   * \endcode
+   */
+  CXCursor_PackExpansionExpr             = 142,
+
+  /** Represents an expression that computes the length of a parameter
+   * pack.
+   *
+   * \code
+   * template<typename ...Types>
+   * struct count {
+   *   static const unsigned value = sizeof...(Types);
+   * };
+   * \endcode
+   */
+  CXCursor_SizeOfPackExpr                = 143,
+
+  /* Represents a C++ lambda expression that produces a local function
+   * object.
+   *
+   * \code
+   * void abssort(float *x, unsigned N) {
+   *   std::sort(x, x + N,
+   *             [](float a, float b) {
+   *               return std::abs(a) < std::abs(b);
+   *             });
+   * }
+   * \endcode
+   */
+  CXCursor_LambdaExpr                    = 144,
+
+  /** Objective-c Boolean Literal.
+   */
+  CXCursor_ObjCBoolLiteralExpr           = 145,
+
+  /** Represents the "self" expression in an Objective-C method.
+   */
+  CXCursor_ObjCSelfExpr                  = 146,
+
+  /** OpenMP 4.0 [2.4, Array Section].
+   */
+  CXCursor_OMPArraySectionExpr           = 147,
+
+  /** Represents an @available(...) check.
+   */
+  CXCursor_ObjCAvailabilityCheckExpr     = 148,
+
+  /**
+   * Fixed point literal
+   */
+  CXCursor_FixedPointLiteral             = 149,
+
+  CXCursor_LastExpr                      = CXCursor_FixedPointLiteral,
+
+  /* Statements */
+  CXCursor_FirstStmt                     = 200,
+  /**
+   * A statement whose specific kind is not exposed via this
+   * interface.
+   *
+   * Unexposed statements have the same operations as any other kind of
+   * statement; one can extract their location information, spelling,
+   * children, etc. However, the specific kind of the statement is not
+   * reported.
+   */
+  CXCursor_UnexposedStmt                 = 200,
+
+  /** A labelled statement in a function.
+   *
+   * This cursor kind is used to describe the "start_over:" label statement in
+   * the following example:
+   *
+   * \code
+   *   start_over:
+   *     ++counter;
+   * \endcode
+   *
+   */
+  CXCursor_LabelStmt                     = 201,
+
+  /** A group of statements like { stmt stmt }.
+   *
+   * This cursor kind is used to describe compound statements, e.g. function
+   * bodies.
+   */
+  CXCursor_CompoundStmt                  = 202,
+
+  /** A case statement.
+   */
+  CXCursor_CaseStmt                      = 203,
+
+  /** A default statement.
+   */
+  CXCursor_DefaultStmt                   = 204,
+
+  /** An if statement
+   */
+  CXCursor_IfStmt                        = 205,
+
+  /** A switch statement.
+   */
+  CXCursor_SwitchStmt                    = 206,
+
+  /** A while statement.
+   */
+  CXCursor_WhileStmt                     = 207,
+
+  /** A do statement.
+   */
+  CXCursor_DoStmt                        = 208,
+
+  /** A for statement.
+   */
+  CXCursor_ForStmt                       = 209,
+
+  /** A goto statement.
+   */
+  CXCursor_GotoStmt                      = 210,
+
+  /** An indirect goto statement.
+   */
+  CXCursor_IndirectGotoStmt              = 211,
+
+  /** A continue statement.
+   */
+  CXCursor_ContinueStmt                  = 212,
+
+  /** A break statement.
+   */
+  CXCursor_BreakStmt                     = 213,
+
+  /** A return statement.
+   */
+  CXCursor_ReturnStmt                    = 214,
+
+  /** A GCC inline assembly statement extension.
+   */
+  CXCursor_GCCAsmStmt                    = 215,
+  CXCursor_AsmStmt                       = CXCursor_GCCAsmStmt,
+
+  /** Objective-C's overall \@try-\@catch-\@finally statement.
+   */
+  CXCursor_ObjCAtTryStmt                 = 216,
+
+  /** Objective-C's \@catch statement.
+   */
+  CXCursor_ObjCAtCatchStmt               = 217,
+
+  /** Objective-C's \@finally statement.
+   */
+  CXCursor_ObjCAtFinallyStmt             = 218,
+
+  /** Objective-C's \@throw statement.
+   */
+  CXCursor_ObjCAtThrowStmt               = 219,
+
+  /** Objective-C's \@synchronized statement.
+   */
+  CXCursor_ObjCAtSynchronizedStmt        = 220,
+
+  /** Objective-C's autorelease pool statement.
+   */
+  CXCursor_ObjCAutoreleasePoolStmt       = 221,
+
+  /** Objective-C's collection statement.
+   */
+  CXCursor_ObjCForCollectionStmt         = 222,
+
+  /** C++'s catch statement.
+   */
+  CXCursor_CXXCatchStmt                  = 223,
+
+  /** C++'s try statement.
+   */
+  CXCursor_CXXTryStmt                    = 224,
+
+  /** C++'s for (* : *) statement.
+   */
+  CXCursor_CXXForRangeStmt               = 225,
+
+  /** Windows Structured Exception Handling's try statement.
+   */
+  CXCursor_SEHTryStmt                    = 226,
+
+  /** Windows Structured Exception Handling's except statement.
+   */
+  CXCursor_SEHExceptStmt                 = 227,
+
+  /** Windows Structured Exception Handling's finally statement.
+   */
+  CXCursor_SEHFinallyStmt                = 228,
+
+  /** A MS inline assembly statement extension.
+   */
+  CXCursor_MSAsmStmt                     = 229,
+
+  /** The null statement ";": C99 6.8.3p3.
+   *
+   * This cursor kind is used to describe the null statement.
+   */
+  CXCursor_NullStmt                      = 230,
+
+  /** Adaptor class for mixing declarations with statements and
+   * expressions.
+   */
+  CXCursor_DeclStmt                      = 231,
+
+  /** OpenMP parallel directive.
+   */
+  CXCursor_OMPParallelDirective          = 232,
+
+  /** OpenMP SIMD directive.
+   */
+  CXCursor_OMPSimdDirective              = 233,
+
+  /** OpenMP for directive.
+   */
+  CXCursor_OMPForDirective               = 234,
+
+  /** OpenMP sections directive.
+   */
+  CXCursor_OMPSectionsDirective          = 235,
+
+  /** OpenMP section directive.
+   */
+  CXCursor_OMPSectionDirective           = 236,
+
+  /** OpenMP single directive.
+   */
+  CXCursor_OMPSingleDirective            = 237,
+
+  /** OpenMP parallel for directive.
+   */
+  CXCursor_OMPParallelForDirective       = 238,
+
+  /** OpenMP parallel sections directive.
+   */
+  CXCursor_OMPParallelSectionsDirective  = 239,
+
+  /** OpenMP task directive.
+   */
+  CXCursor_OMPTaskDirective              = 240,
+
+  /** OpenMP master directive.
+   */
+  CXCursor_OMPMasterDirective            = 241,
+
+  /** OpenMP critical directive.
+   */
+  CXCursor_OMPCriticalDirective          = 242,
+
+  /** OpenMP taskyield directive.
+   */
+  CXCursor_OMPTaskyieldDirective         = 243,
+
+  /** OpenMP barrier directive.
+   */
+  CXCursor_OMPBarrierDirective           = 244,
+
+  /** OpenMP taskwait directive.
+   */
+  CXCursor_OMPTaskwaitDirective          = 245,
+
+  /** OpenMP flush directive.
+   */
+  CXCursor_OMPFlushDirective             = 246,
+
+  /** Windows Structured Exception Handling's leave statement.
+   */
+  CXCursor_SEHLeaveStmt                  = 247,
+
+  /** OpenMP ordered directive.
+   */
+  CXCursor_OMPOrderedDirective           = 248,
+
+  /** OpenMP atomic directive.
+   */
+  CXCursor_OMPAtomicDirective            = 249,
+
+  /** OpenMP for SIMD directive.
+   */
+  CXCursor_OMPForSimdDirective           = 250,
+
+  /** OpenMP parallel for SIMD directive.
+   */
+  CXCursor_OMPParallelForSimdDirective   = 251,
+
+  /** OpenMP target directive.
+   */
+  CXCursor_OMPTargetDirective            = 252,
+
+  /** OpenMP teams directive.
+   */
+  CXCursor_OMPTeamsDirective             = 253,
+
+  /** OpenMP taskgroup directive.
+   */
+  CXCursor_OMPTaskgroupDirective         = 254,
+
+  /** OpenMP cancellation point directive.
+   */
+  CXCursor_OMPCancellationPointDirective = 255,
+
+  /** OpenMP cancel directive.
+   */
+  CXCursor_OMPCancelDirective            = 256,
+
+  /** OpenMP target data directive.
+   */
+  CXCursor_OMPTargetDataDirective        = 257,
+
+  /** OpenMP taskloop directive.
+   */
+  CXCursor_OMPTaskLoopDirective          = 258,
+
+  /** OpenMP taskloop simd directive.
+   */
+  CXCursor_OMPTaskLoopSimdDirective      = 259,
+
+  /** OpenMP distribute directive.
+   */
+  CXCursor_OMPDistributeDirective        = 260,
+
+  /** OpenMP target enter data directive.
+   */
+  CXCursor_OMPTargetEnterDataDirective   = 261,
+
+  /** OpenMP target exit data directive.
+   */
+  CXCursor_OMPTargetExitDataDirective    = 262,
+
+  /** OpenMP target parallel directive.
+   */
+  CXCursor_OMPTargetParallelDirective    = 263,
+
+  /** OpenMP target parallel for directive.
+   */
+  CXCursor_OMPTargetParallelForDirective = 264,
+
+  /** OpenMP target update directive.
+   */
+  CXCursor_OMPTargetUpdateDirective      = 265,
+
+  /** OpenMP distribute parallel for directive.
+   */
+  CXCursor_OMPDistributeParallelForDirective = 266,
+
+  /** OpenMP distribute parallel for simd directive.
+   */
+  CXCursor_OMPDistributeParallelForSimdDirective = 267,
+
+  /** OpenMP distribute simd directive.
+   */
+  CXCursor_OMPDistributeSimdDirective = 268,
+
+  /** OpenMP target parallel for simd directive.
+   */
+  CXCursor_OMPTargetParallelForSimdDirective = 269,
+
+  /** OpenMP target simd directive.
+   */
+  CXCursor_OMPTargetSimdDirective = 270,
+
+  /** OpenMP teams distribute directive.
+   */
+  CXCursor_OMPTeamsDistributeDirective = 271,
+
+  /** OpenMP teams distribute simd directive.
+   */
+  CXCursor_OMPTeamsDistributeSimdDirective = 272,
+
+  /** OpenMP teams distribute parallel for simd directive.
+   */
+  CXCursor_OMPTeamsDistributeParallelForSimdDirective = 273,
+
+  /** OpenMP teams distribute parallel for directive.
+   */
+  CXCursor_OMPTeamsDistributeParallelForDirective = 274,
+
+  /** OpenMP target teams directive.
+   */
+  CXCursor_OMPTargetTeamsDirective = 275,
+
+  /** OpenMP target teams distribute directive.
+   */
+  CXCursor_OMPTargetTeamsDistributeDirective = 276,
+
+  /** OpenMP target teams distribute parallel for directive.
+   */
+  CXCursor_OMPTargetTeamsDistributeParallelForDirective = 277,
+
+  /** OpenMP target teams distribute parallel for simd directive.
+   */
+  CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective = 278,
+
+  /** OpenMP target teams distribute simd directive.
+   */
+  CXCursor_OMPTargetTeamsDistributeSimdDirective = 279,
+
+  /** C++2a std::bit_cast expression.
+   */
+  CXCursor_BuiltinBitCastExpr = 280,
+
+  /** OpenMP master taskloop directive.
+   */
+  CXCursor_OMPMasterTaskLoopDirective = 281,
+
+  /** OpenMP parallel master taskloop directive.
+   */
+  CXCursor_OMPParallelMasterTaskLoopDirective = 282,
+
+  /** OpenMP master taskloop simd directive.
+   */
+  CXCursor_OMPMasterTaskLoopSimdDirective      = 283,
+
+  /** OpenMP parallel master taskloop simd directive.
+   */
+  CXCursor_OMPParallelMasterTaskLoopSimdDirective      = 284,
+
+  /** OpenMP parallel master directive.
+   */
+  CXCursor_OMPParallelMasterDirective      = 285,
+
+  CXCursor_LastStmt = CXCursor_OMPParallelMasterDirective,
+
+  /**
+   * Cursor that represents the translation unit itself.
+   *
+   * The translation unit cursor exists primarily to act as the root
+   * cursor for traversing the contents of a translation unit.
+   */
+  CXCursor_TranslationUnit               = 300,
+
+  /* Attributes */
+  CXCursor_FirstAttr                     = 400,
+  /**
+   * An attribute whose specific kind is not exposed via this
+   * interface.
+   */
+  CXCursor_UnexposedAttr                 = 400,
+
+  CXCursor_IBActionAttr                  = 401,
+  CXCursor_IBOutletAttr                  = 402,
+  CXCursor_IBOutletCollectionAttr        = 403,
+  CXCursor_CXXFinalAttr                  = 404,
+  CXCursor_CXXOverrideAttr               = 405,
+  CXCursor_AnnotateAttr                  = 406,
+  CXCursor_AsmLabelAttr                  = 407,
+  CXCursor_PackedAttr                    = 408,
+  CXCursor_PureAttr                      = 409,
+  CXCursor_ConstAttr                     = 410,
+  CXCursor_NoDuplicateAttr               = 411,
+  CXCursor_CUDAConstantAttr              = 412,
+  CXCursor_CUDADeviceAttr                = 413,
+  CXCursor_CUDAGlobalAttr                = 414,
+  CXCursor_CUDAHostAttr                  = 415,
+  CXCursor_CUDASharedAttr                = 416,
+  CXCursor_VisibilityAttr                = 417,
+  CXCursor_DLLExport                     = 418,
+  CXCursor_DLLImport                     = 419,
+  CXCursor_NSReturnsRetained             = 420,
+  CXCursor_NSReturnsNotRetained          = 421,
+  CXCursor_NSReturnsAutoreleased         = 422,
+  CXCursor_NSConsumesSelf                = 423,
+  CXCursor_NSConsumed                    = 424,
+  CXCursor_ObjCException                 = 425,
+  CXCursor_ObjCNSObject                  = 426,
+  CXCursor_ObjCIndependentClass          = 427,
+  CXCursor_ObjCPreciseLifetime           = 428,
+  CXCursor_ObjCReturnsInnerPointer       = 429,
+  CXCursor_ObjCRequiresSuper             = 430,
+  CXCursor_ObjCRootClass                 = 431,
+  CXCursor_ObjCSubclassingRestricted     = 432,
+  CXCursor_ObjCExplicitProtocolImpl      = 433,
+  CXCursor_ObjCDesignatedInitializer     = 434,
+  CXCursor_ObjCRuntimeVisible            = 435,
+  CXCursor_ObjCBoxable                   = 436,
+  CXCursor_FlagEnum                      = 437,
+  CXCursor_ConvergentAttr                = 438,
+  CXCursor_WarnUnusedAttr                = 439,
+  CXCursor_WarnUnusedResultAttr          = 440,
+  CXCursor_AlignedAttr                   = 441,
+  CXCursor_LastAttr                      = CXCursor_AlignedAttr,
+
+  /* Preprocessing */
+  CXCursor_PreprocessingDirective        = 500,
+  CXCursor_MacroDefinition               = 501,
+  CXCursor_MacroExpansion                = 502,
+  CXCursor_MacroInstantiation            = CXCursor_MacroExpansion,
+  CXCursor_InclusionDirective            = 503,
+  CXCursor_FirstPreprocessing            = CXCursor_PreprocessingDirective,
+  CXCursor_LastPreprocessing             = CXCursor_InclusionDirective,
+
+  /* Extra Declarations */
+  /**
+   * A module import declaration.
+   */
+  CXCursor_ModuleImportDecl              = 600,
+  CXCursor_TypeAliasTemplateDecl         = 601,
+  /**
+   * A static_assert or _Static_assert node
+   */
+  CXCursor_StaticAssert                  = 602,
+  /**
+   * a friend declaration.
+   */
+  CXCursor_FriendDecl                    = 603,
+  CXCursor_FirstExtraDecl                = CXCursor_ModuleImportDecl,
+  CXCursor_LastExtraDecl                 = CXCursor_FriendDecl,
+
+  /**
+   * A code completion overload candidate.
+   */
+  CXCursor_OverloadCandidate             = 700
+};
+
+/**
+ * A cursor representing some element in the abstract syntax tree for
+ * a translation unit.
+ *
+ * The cursor abstraction unifies the different kinds of entities in a
+ * program--declaration, statements, expressions, references to declarations,
+ * etc.--under a single "cursor" abstraction with a common set of operations.
+ * Common operation for a cursor include: getting the physical location in
+ * a source file where the cursor points, getting the name associated with a
+ * cursor, and retrieving cursors for any child nodes of a particular cursor.
+ *
+ * Cursors can be produced in two specific ways.
+ * clang_getTranslationUnitCursor() produces a cursor for a translation unit,
+ * from which one can use clang_visitChildren() to explore the rest of the
+ * translation unit. clang_getCursor() maps from a physical source location
+ * to the entity that resides at that location, allowing one to map from the
+ * source code into the AST.
+ */
+typedef struct {
+  enum CXCursorKind kind;
+  int xdata;
+  const void *data[3];
+} CXCursor;
+
+/**
+ * \defgroup CINDEX_CURSOR_MANIP Cursor manipulations
+ *
+ * @{
+ */
+
+/**
+ * Retrieve the NULL cursor, which represents no entity.
+ */
+CINDEX_LINKAGE CXCursor clang_getNullCursor(void);
+
+/**
+ * Retrieve the cursor that represents the given translation unit.
+ *
+ * The translation unit cursor can be used to start traversing the
+ * various declarations within the given translation unit.
+ */
+CINDEX_LINKAGE CXCursor clang_getTranslationUnitCursor(CXTranslationUnit);
+
+/**
+ * Determine whether two cursors are equivalent.
+ */
+CINDEX_LINKAGE unsigned clang_equalCursors(CXCursor, CXCursor);
+
+/**
+ * Returns non-zero if \p cursor is null.
+ */
+CINDEX_LINKAGE int clang_Cursor_isNull(CXCursor cursor);
+
+/**
+ * Compute a hash value for the given cursor.
+ */
+CINDEX_LINKAGE unsigned clang_hashCursor(CXCursor);
+
+/**
+ * Retrieve the kind of the given cursor.
+ */
+CINDEX_LINKAGE enum CXCursorKind clang_getCursorKind(CXCursor);
+
+/**
+ * Determine whether the given cursor kind represents a declaration.
+ */
+CINDEX_LINKAGE unsigned clang_isDeclaration(enum CXCursorKind);
+
+/**
+ * Determine whether the given declaration is invalid.
+ *
+ * A declaration is invalid if it could not be parsed successfully.
+ *
+ * \returns non-zero if the cursor represents a declaration and it is
+ * invalid, otherwise NULL.
+ */
+CINDEX_LINKAGE unsigned clang_isInvalidDeclaration(CXCursor);
+
+/**
+ * Determine whether the given cursor kind represents a simple
+ * reference.
+ *
+ * Note that other kinds of cursors (such as expressions) can also refer to
+ * other cursors. Use clang_getCursorReferenced() to determine whether a
+ * particular cursor refers to another entity.
+ */
+CINDEX_LINKAGE unsigned clang_isReference(enum CXCursorKind);
+
+/**
+ * Determine whether the given cursor kind represents an expression.
+ */
+CINDEX_LINKAGE unsigned clang_isExpression(enum CXCursorKind);
+
+/**
+ * Determine whether the given cursor kind represents a statement.
+ */
+CINDEX_LINKAGE unsigned clang_isStatement(enum CXCursorKind);
+
+/**
+ * Determine whether the given cursor kind represents an attribute.
+ */
+CINDEX_LINKAGE unsigned clang_isAttribute(enum CXCursorKind);
+
+/**
+ * Determine whether the given cursor has any attributes.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_hasAttrs(CXCursor C);
+
+/**
+ * Determine whether the given cursor kind represents an invalid
+ * cursor.
+ */
+CINDEX_LINKAGE unsigned clang_isInvalid(enum CXCursorKind);
+
+/**
+ * Determine whether the given cursor kind represents a translation
+ * unit.
+ */
+CINDEX_LINKAGE unsigned clang_isTranslationUnit(enum CXCursorKind);
+
+/***
+ * Determine whether the given cursor represents a preprocessing
+ * element, such as a preprocessor directive or macro instantiation.
+ */
+CINDEX_LINKAGE unsigned clang_isPreprocessing(enum CXCursorKind);
+
+/***
+ * Determine whether the given cursor represents a currently
+ *  unexposed piece of the AST (e.g., CXCursor_UnexposedStmt).
+ */
+CINDEX_LINKAGE unsigned clang_isUnexposed(enum CXCursorKind);
+
+/**
+ * Describe the linkage of the entity referred to by a cursor.
+ */
+enum CXLinkageKind {
+  /** This value indicates that no linkage information is available
+   * for a provided CXCursor. */
+  CXLinkage_Invalid,
+  /**
+   * This is the linkage for variables, parameters, and so on that
+   *  have automatic storage.  This covers normal (non-extern) local variables.
+   */
+  CXLinkage_NoLinkage,
+  /** This is the linkage for static variables and static functions. */
+  CXLinkage_Internal,
+  /** This is the linkage for entities with external linkage that live
+   * in C++ anonymous namespaces.*/
+  CXLinkage_UniqueExternal,
+  /** This is the linkage for entities with true, external linkage. */
+  CXLinkage_External
+};
+
+/**
+ * Determine the linkage of the entity referred to by a given cursor.
+ */
+CINDEX_LINKAGE enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor);
+
+enum CXVisibilityKind {
+  /** This value indicates that no visibility information is available
+   * for a provided CXCursor. */
+  CXVisibility_Invalid,
+
+  /** Symbol not seen by the linker. */
+  CXVisibility_Hidden,
+  /** Symbol seen by the linker but resolves to a symbol inside this object. */
+  CXVisibility_Protected,
+  /** Symbol seen by the linker and acts like a normal symbol. */
+  CXVisibility_Default
+};
+
+/**
+ * Describe the visibility of the entity referred to by a cursor.
+ *
+ * This returns the default visibility if not explicitly specified by
+ * a visibility attribute. The default visibility may be changed by
+ * commandline arguments.
+ *
+ * \param cursor The cursor to query.
+ *
+ * \returns The visibility of the cursor.
+ */
+CINDEX_LINKAGE enum CXVisibilityKind clang_getCursorVisibility(CXCursor cursor);
+
+/**
+ * Determine the availability of the entity that this cursor refers to,
+ * taking the current target platform into account.
+ *
+ * \param cursor The cursor to query.
+ *
+ * \returns The availability of the cursor.
+ */
+CINDEX_LINKAGE enum CXAvailabilityKind
+clang_getCursorAvailability(CXCursor cursor);
+
+/**
+ * Describes the availability of a given entity on a particular platform, e.g.,
+ * a particular class might only be available on Mac OS 10.7 or newer.
+ */
+typedef struct CXPlatformAvailability {
+  /**
+   * A string that describes the platform for which this structure
+   * provides availability information.
+   *
+   * Possible values are "ios" or "macos".
+   */
+  CXString Platform;
+  /**
+   * The version number in which this entity was introduced.
+   */
+  CXVersion Introduced;
+  /**
+   * The version number in which this entity was deprecated (but is
+   * still available).
+   */
+  CXVersion Deprecated;
+  /**
+   * The version number in which this entity was obsoleted, and therefore
+   * is no longer available.
+   */
+  CXVersion Obsoleted;
+  /**
+   * Whether the entity is unconditionally unavailable on this platform.
+   */
+  int Unavailable;
+  /**
+   * An optional message to provide to a user of this API, e.g., to
+   * suggest replacement APIs.
+   */
+  CXString Message;
+} CXPlatformAvailability;
+
+/**
+ * Determine the availability of the entity that this cursor refers to
+ * on any platforms for which availability information is known.
+ *
+ * \param cursor The cursor to query.
+ *
+ * \param always_deprecated If non-NULL, will be set to indicate whether the
+ * entity is deprecated on all platforms.
+ *
+ * \param deprecated_message If non-NULL, will be set to the message text
+ * provided along with the unconditional deprecation of this entity. The client
+ * is responsible for deallocating this string.
+ *
+ * \param always_unavailable If non-NULL, will be set to indicate whether the
+ * entity is unavailable on all platforms.
+ *
+ * \param unavailable_message If non-NULL, will be set to the message text
+ * provided along with the unconditional unavailability of this entity. The
+ * client is responsible for deallocating this string.
+ *
+ * \param availability If non-NULL, an array of CXPlatformAvailability instances
+ * that will be populated with platform availability information, up to either
+ * the number of platforms for which availability information is available (as
+ * returned by this function) or \c availability_size, whichever is smaller.
+ *
+ * \param availability_size The number of elements available in the
+ * \c availability array.
+ *
+ * \returns The number of platforms (N) for which availability information is
+ * available (which is unrelated to \c availability_size).
+ *
+ * Note that the client is responsible for calling
+ * \c clang_disposeCXPlatformAvailability to free each of the
+ * platform-availability structures returned. There are
+ * \c min(N, availability_size) such structures.
+ */
+CINDEX_LINKAGE int
+clang_getCursorPlatformAvailability(CXCursor cursor,
+                                    int *always_deprecated,
+                                    CXString *deprecated_message,
+                                    int *always_unavailable,
+                                    CXString *unavailable_message,
+                                    CXPlatformAvailability *availability,
+                                    int availability_size);
+
+/**
+ * Free the memory associated with a \c CXPlatformAvailability structure.
+ */
+CINDEX_LINKAGE void
+clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability);
+
+/**
+ * Describe the "language" of the entity referred to by a cursor.
+ */
+enum CXLanguageKind {
+  CXLanguage_Invalid = 0,
+  CXLanguage_C,
+  CXLanguage_ObjC,
+  CXLanguage_CPlusPlus
+};
+
+/**
+ * Determine the "language" of the entity referred to by a given cursor.
+ */
+CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor);
+
+/**
+ * Describe the "thread-local storage (TLS) kind" of the declaration
+ * referred to by a cursor.
+ */
+enum CXTLSKind {
+  CXTLS_None = 0,
+  CXTLS_Dynamic,
+  CXTLS_Static
+};
+
+/**
+ * Determine the "thread-local storage (TLS) kind" of the declaration
+ * referred to by a cursor.
+ */
+CINDEX_LINKAGE enum CXTLSKind clang_getCursorTLSKind(CXCursor cursor);
+
+/**
+ * Returns the translation unit that a cursor originated from.
+ */
+CINDEX_LINKAGE CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor);
+
+/**
+ * A fast container representing a set of CXCursors.
+ */
+typedef struct CXCursorSetImpl *CXCursorSet;
+
+/**
+ * Creates an empty CXCursorSet.
+ */
+CINDEX_LINKAGE CXCursorSet clang_createCXCursorSet(void);
+
+/**
+ * Disposes a CXCursorSet and releases its associated memory.
+ */
+CINDEX_LINKAGE void clang_disposeCXCursorSet(CXCursorSet cset);
+
+/**
+ * Queries a CXCursorSet to see if it contains a specific CXCursor.
+ *
+ * \returns non-zero if the set contains the specified cursor.
+*/
+CINDEX_LINKAGE unsigned clang_CXCursorSet_contains(CXCursorSet cset,
+                                                   CXCursor cursor);
+
+/**
+ * Inserts a CXCursor into a CXCursorSet.
+ *
+ * \returns zero if the CXCursor was already in the set, and non-zero otherwise.
+*/
+CINDEX_LINKAGE unsigned clang_CXCursorSet_insert(CXCursorSet cset,
+                                                 CXCursor cursor);
+
+/**
+ * Determine the semantic parent of the given cursor.
+ *
+ * The semantic parent of a cursor is the cursor that semantically contains
+ * the given \p cursor. For many declarations, the lexical and semantic parents
+ * are equivalent (the lexical parent is returned by
+ * \c clang_getCursorLexicalParent()). They diverge when declarations or
+ * definitions are provided out-of-line. For example:
+ *
+ * \code
+ * class C {
+ *  void f();
+ * };
+ *
+ * void C::f() { }
+ * \endcode
+ *
+ * In the out-of-line definition of \c C::f, the semantic parent is
+ * the class \c C, of which this function is a member. The lexical parent is
+ * the place where the declaration actually occurs in the source code; in this
+ * case, the definition occurs in the translation unit. In general, the
+ * lexical parent for a given entity can change without affecting the semantics
+ * of the program, and the lexical parent of different declarations of the
+ * same entity may be different. Changing the semantic parent of a declaration,
+ * on the other hand, can have a major impact on semantics, and redeclarations
+ * of a particular entity should all have the same semantic context.
+ *
+ * In the example above, both declarations of \c C::f have \c C as their
+ * semantic context, while the lexical context of the first \c C::f is \c C
+ * and the lexical context of the second \c C::f is the translation unit.
+ *
+ * For global declarations, the semantic parent is the translation unit.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorSemanticParent(CXCursor cursor);
+
+/**
+ * Determine the lexical parent of the given cursor.
+ *
+ * The lexical parent of a cursor is the cursor in which the given \p cursor
+ * was actually written. For many declarations, the lexical and semantic parents
+ * are equivalent (the semantic parent is returned by
+ * \c clang_getCursorSemanticParent()). They diverge when declarations or
+ * definitions are provided out-of-line. For example:
+ *
+ * \code
+ * class C {
+ *  void f();
+ * };
+ *
+ * void C::f() { }
+ * \endcode
+ *
+ * In the out-of-line definition of \c C::f, the semantic parent is
+ * the class \c C, of which this function is a member. The lexical parent is
+ * the place where the declaration actually occurs in the source code; in this
+ * case, the definition occurs in the translation unit. In general, the
+ * lexical parent for a given entity can change without affecting the semantics
+ * of the program, and the lexical parent of different declarations of the
+ * same entity may be different. Changing the semantic parent of a declaration,
+ * on the other hand, can have a major impact on semantics, and redeclarations
+ * of a particular entity should all have the same semantic context.
+ *
+ * In the example above, both declarations of \c C::f have \c C as their
+ * semantic context, while the lexical context of the first \c C::f is \c C
+ * and the lexical context of the second \c C::f is the translation unit.
+ *
+ * For declarations written in the global scope, the lexical parent is
+ * the translation unit.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorLexicalParent(CXCursor cursor);
+
+/**
+ * Determine the set of methods that are overridden by the given
+ * method.
+ *
+ * In both Objective-C and C++, a method (aka virtual member function,
+ * in C++) can override a virtual method in a base class. For
+ * Objective-C, a method is said to override any method in the class's
+ * base class, its protocols, or its categories' protocols, that has the same
+ * selector and is of the same kind (class or instance).
+ * If no such method exists, the search continues to the class's superclass,
+ * its protocols, and its categories, and so on. A method from an Objective-C
+ * implementation is considered to override the same methods as its
+ * corresponding method in the interface.
+ *
+ * For C++, a virtual member function overrides any virtual member
+ * function with the same signature that occurs in its base
+ * classes. With multiple inheritance, a virtual member function can
+ * override several virtual member functions coming from different
+ * base classes.
+ *
+ * In all cases, this function determines the immediate overridden
+ * method, rather than all of the overridden methods. For example, if
+ * a method is originally declared in a class A, then overridden in B
+ * (which in inherits from A) and also in C (which inherited from B),
+ * then the only overridden method returned from this function when
+ * invoked on C's method will be B's method. The client may then
+ * invoke this function again, given the previously-found overridden
+ * methods, to map out the complete method-override set.
+ *
+ * \param cursor A cursor representing an Objective-C or C++
+ * method. This routine will compute the set of methods that this
+ * method overrides.
+ *
+ * \param overridden A pointer whose pointee will be replaced with a
+ * pointer to an array of cursors, representing the set of overridden
+ * methods. If there are no overridden methods, the pointee will be
+ * set to NULL. The pointee must be freed via a call to
+ * \c clang_disposeOverriddenCursors().
+ *
+ * \param num_overridden A pointer to the number of overridden
+ * functions, will be set to the number of overridden functions in the
+ * array pointed to by \p overridden.
+ */
+CINDEX_LINKAGE void clang_getOverriddenCursors(CXCursor cursor,
+                                               CXCursor **overridden,
+                                               unsigned *num_overridden);
+
+/**
+ * Free the set of overridden cursors returned by \c
+ * clang_getOverriddenCursors().
+ */
+CINDEX_LINKAGE void clang_disposeOverriddenCursors(CXCursor *overridden);
+
+/**
+ * Retrieve the file that is included by the given inclusion directive
+ * cursor.
+ */
+CINDEX_LINKAGE CXFile clang_getIncludedFile(CXCursor cursor);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_SOURCE Mapping between cursors and source code
+ *
+ * Cursors represent a location within the Abstract Syntax Tree (AST). These
+ * routines help map between cursors and the physical locations where the
+ * described entities occur in the source code. The mapping is provided in
+ * both directions, so one can map from source code to the AST and back.
+ *
+ * @{
+ */
+
+/**
+ * Map a source location to the cursor that describes the entity at that
+ * location in the source code.
+ *
+ * clang_getCursor() maps an arbitrary source location within a translation
+ * unit down to the most specific cursor that describes the entity at that
+ * location. For example, given an expression \c x + y, invoking
+ * clang_getCursor() with a source location pointing to "x" will return the
+ * cursor for "x"; similarly for "y". If the cursor points anywhere between
+ * "x" or "y" (e.g., on the + or the whitespace around it), clang_getCursor()
+ * will return a cursor referring to the "+" expression.
+ *
+ * \returns a cursor representing the entity at the given source location, or
+ * a NULL cursor if no such entity can be found.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, CXSourceLocation);
+
+/**
+ * Retrieve the physical location of the source constructor referenced
+ * by the given cursor.
+ *
+ * The location of a declaration is typically the location of the name of that
+ * declaration, where the name of that declaration would occur if it is
+ * unnamed, or some keyword that introduces that particular declaration.
+ * The location of a reference is where that reference occurs within the
+ * source code.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getCursorLocation(CXCursor);
+
+/**
+ * Retrieve the physical extent of the source construct referenced by
+ * the given cursor.
+ *
+ * The extent of a cursor starts with the file/line/column pointing at the
+ * first character within the source construct that the cursor refers to and
+ * ends with the last character within that source construct. For a
+ * declaration, the extent covers the declaration itself. For a reference,
+ * the extent covers the location of the reference (e.g., where the referenced
+ * entity was actually used).
+ */
+CINDEX_LINKAGE CXSourceRange clang_getCursorExtent(CXCursor);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_TYPES Type information for CXCursors
+ *
+ * @{
+ */
+
+/**
+ * Describes the kind of type
+ */
+enum CXTypeKind {
+  /**
+   * Represents an invalid type (e.g., where no type is available).
+   */
+  CXType_Invalid = 0,
+
+  /**
+   * A type whose specific kind is not exposed via this
+   * interface.
+   */
+  CXType_Unexposed = 1,
+
+  /* Builtin types */
+  CXType_Void = 2,
+  CXType_Bool = 3,
+  CXType_Char_U = 4,
+  CXType_UChar = 5,
+  CXType_Char16 = 6,
+  CXType_Char32 = 7,
+  CXType_UShort = 8,
+  CXType_UInt = 9,
+  CXType_ULong = 10,
+  CXType_ULongLong = 11,
+  CXType_UInt128 = 12,
+  CXType_Char_S = 13,
+  CXType_SChar = 14,
+  CXType_WChar = 15,
+  CXType_Short = 16,
+  CXType_Int = 17,
+  CXType_Long = 18,
+  CXType_LongLong = 19,
+  CXType_Int128 = 20,
+  CXType_Float = 21,
+  CXType_Double = 22,
+  CXType_LongDouble = 23,
+  CXType_NullPtr = 24,
+  CXType_Overload = 25,
+  CXType_Dependent = 26,
+  CXType_ObjCId = 27,
+  CXType_ObjCClass = 28,
+  CXType_ObjCSel = 29,
+  CXType_Float128 = 30,
+  CXType_Half = 31,
+  CXType_Float16 = 32,
+  CXType_ShortAccum = 33,
+  CXType_Accum = 34,
+  CXType_LongAccum = 35,
+  CXType_UShortAccum = 36,
+  CXType_UAccum = 37,
+  CXType_ULongAccum = 38,
+  CXType_FirstBuiltin = CXType_Void,
+  CXType_LastBuiltin = CXType_ULongAccum,
+
+  CXType_Complex = 100,
+  CXType_Pointer = 101,
+  CXType_BlockPointer = 102,
+  CXType_LValueReference = 103,
+  CXType_RValueReference = 104,
+  CXType_Record = 105,
+  CXType_Enum = 106,
+  CXType_Typedef = 107,
+  CXType_ObjCInterface = 108,
+  CXType_ObjCObjectPointer = 109,
+  CXType_FunctionNoProto = 110,
+  CXType_FunctionProto = 111,
+  CXType_ConstantArray = 112,
+  CXType_Vector = 113,
+  CXType_IncompleteArray = 114,
+  CXType_VariableArray = 115,
+  CXType_DependentSizedArray = 116,
+  CXType_MemberPointer = 117,
+  CXType_Auto = 118,
+
+  /**
+   * Represents a type that was referred to using an elaborated type keyword.
+   *
+   * E.g., struct S, or via a qualified name, e.g., N::M::type, or both.
+   */
+  CXType_Elaborated = 119,
+
+  /* OpenCL PipeType. */
+  CXType_Pipe = 120,
+
+  /* OpenCL builtin types. */
+  CXType_OCLImage1dRO = 121,
+  CXType_OCLImage1dArrayRO = 122,
+  CXType_OCLImage1dBufferRO = 123,
+  CXType_OCLImage2dRO = 124,
+  CXType_OCLImage2dArrayRO = 125,
+  CXType_OCLImage2dDepthRO = 126,
+  CXType_OCLImage2dArrayDepthRO = 127,
+  CXType_OCLImage2dMSAARO = 128,
+  CXType_OCLImage2dArrayMSAARO = 129,
+  CXType_OCLImage2dMSAADepthRO = 130,
+  CXType_OCLImage2dArrayMSAADepthRO = 131,
+  CXType_OCLImage3dRO = 132,
+  CXType_OCLImage1dWO = 133,
+  CXType_OCLImage1dArrayWO = 134,
+  CXType_OCLImage1dBufferWO = 135,
+  CXType_OCLImage2dWO = 136,
+  CXType_OCLImage2dArrayWO = 137,
+  CXType_OCLImage2dDepthWO = 138,
+  CXType_OCLImage2dArrayDepthWO = 139,
+  CXType_OCLImage2dMSAAWO = 140,
+  CXType_OCLImage2dArrayMSAAWO = 141,
+  CXType_OCLImage2dMSAADepthWO = 142,
+  CXType_OCLImage2dArrayMSAADepthWO = 143,
+  CXType_OCLImage3dWO = 144,
+  CXType_OCLImage1dRW = 145,
+  CXType_OCLImage1dArrayRW = 146,
+  CXType_OCLImage1dBufferRW = 147,
+  CXType_OCLImage2dRW = 148,
+  CXType_OCLImage2dArrayRW = 149,
+  CXType_OCLImage2dDepthRW = 150,
+  CXType_OCLImage2dArrayDepthRW = 151,
+  CXType_OCLImage2dMSAARW = 152,
+  CXType_OCLImage2dArrayMSAARW = 153,
+  CXType_OCLImage2dMSAADepthRW = 154,
+  CXType_OCLImage2dArrayMSAADepthRW = 155,
+  CXType_OCLImage3dRW = 156,
+  CXType_OCLSampler = 157,
+  CXType_OCLEvent = 158,
+  CXType_OCLQueue = 159,
+  CXType_OCLReserveID = 160,
+
+  CXType_ObjCObject = 161,
+  CXType_ObjCTypeParam = 162,
+  CXType_Attributed = 163,
+
+  CXType_OCLIntelSubgroupAVCMcePayload = 164,
+  CXType_OCLIntelSubgroupAVCImePayload = 165,
+  CXType_OCLIntelSubgroupAVCRefPayload = 166,
+  CXType_OCLIntelSubgroupAVCSicPayload = 167,
+  CXType_OCLIntelSubgroupAVCMceResult = 168,
+  CXType_OCLIntelSubgroupAVCImeResult = 169,
+  CXType_OCLIntelSubgroupAVCRefResult = 170,
+  CXType_OCLIntelSubgroupAVCSicResult = 171,
+  CXType_OCLIntelSubgroupAVCImeResultSingleRefStreamout = 172,
+  CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout = 173,
+  CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174,
+
+  CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175,
+
+  CXType_ExtVector = 176
+};
+
+/**
+ * Describes the calling convention of a function type
+ */
+enum CXCallingConv {
+  CXCallingConv_Default = 0,
+  CXCallingConv_C = 1,
+  CXCallingConv_X86StdCall = 2,
+  CXCallingConv_X86FastCall = 3,
+  CXCallingConv_X86ThisCall = 4,
+  CXCallingConv_X86Pascal = 5,
+  CXCallingConv_AAPCS = 6,
+  CXCallingConv_AAPCS_VFP = 7,
+  CXCallingConv_X86RegCall = 8,
+  CXCallingConv_IntelOclBicc = 9,
+  CXCallingConv_Win64 = 10,
+  /* Alias for compatibility with older versions of API. */
+  CXCallingConv_X86_64Win64 = CXCallingConv_Win64,
+  CXCallingConv_X86_64SysV = 11,
+  CXCallingConv_X86VectorCall = 12,
+  CXCallingConv_Swift = 13,
+  CXCallingConv_PreserveMost = 14,
+  CXCallingConv_PreserveAll = 15,
+  CXCallingConv_AArch64VectorCall = 16,
+
+  CXCallingConv_Invalid = 100,
+  CXCallingConv_Unexposed = 200
+};
+
+/**
+ * The type of an element in the abstract syntax tree.
+ *
+ */
+typedef struct {
+  enum CXTypeKind kind;
+  void *data[2];
+} CXType;
+
+/**
+ * Retrieve the type of a CXCursor (if any).
+ */
+CINDEX_LINKAGE CXType clang_getCursorType(CXCursor C);
+
+/**
+ * Pretty-print the underlying type using the rules of the
+ * language of the translation unit from which it came.
+ *
+ * If the type is invalid, an empty string is returned.
+ */
+CINDEX_LINKAGE CXString clang_getTypeSpelling(CXType CT);
+
+/**
+ * Retrieve the underlying type of a typedef declaration.
+ *
+ * If the cursor does not reference a typedef declaration, an invalid type is
+ * returned.
+ */
+CINDEX_LINKAGE CXType clang_getTypedefDeclUnderlyingType(CXCursor C);
+
+/**
+ * Retrieve the integer type of an enum declaration.
+ *
+ * If the cursor does not reference an enum declaration, an invalid type is
+ * returned.
+ */
+CINDEX_LINKAGE CXType clang_getEnumDeclIntegerType(CXCursor C);
+
+/**
+ * Retrieve the integer value of an enum constant declaration as a signed
+ *  long long.
+ *
+ * If the cursor does not reference an enum constant declaration, LLONG_MIN is returned.
+ * Since this is also potentially a valid constant value, the kind of the cursor
+ * must be verified before calling this function.
+ */
+CINDEX_LINKAGE long long clang_getEnumConstantDeclValue(CXCursor C);
+
+/**
+ * Retrieve the integer value of an enum constant declaration as an unsigned
+ *  long long.
+ *
+ * If the cursor does not reference an enum constant declaration, ULLONG_MAX is returned.
+ * Since this is also potentially a valid constant value, the kind of the cursor
+ * must be verified before calling this function.
+ */
+CINDEX_LINKAGE unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C);
+
+/**
+ * Retrieve the bit width of a bit field declaration as an integer.
+ *
+ * If a cursor that is not a bit field declaration is passed in, -1 is returned.
+ */
+CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
+
+/**
+ * Retrieve the number of non-variadic arguments associated with a given
+ * cursor.
+ *
+ * The number of arguments can be determined for calls as well as for
+ * declarations of functions or methods. For other cursors -1 is returned.
+ */
+CINDEX_LINKAGE int clang_Cursor_getNumArguments(CXCursor C);
+
+/**
+ * Retrieve the argument cursor of a function or method.
+ *
+ * The argument cursor can be determined for calls as well as for declarations
+ * of functions or methods. For other cursors and for invalid indices, an
+ * invalid cursor is returned.
+ */
+CINDEX_LINKAGE CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i);
+
+/**
+ * Describes the kind of a template argument.
+ *
+ * See the definition of llvm::clang::TemplateArgument::ArgKind for full
+ * element descriptions.
+ */
+enum CXTemplateArgumentKind {
+  CXTemplateArgumentKind_Null,
+  CXTemplateArgumentKind_Type,
+  CXTemplateArgumentKind_Declaration,
+  CXTemplateArgumentKind_NullPtr,
+  CXTemplateArgumentKind_Integral,
+  CXTemplateArgumentKind_Template,
+  CXTemplateArgumentKind_TemplateExpansion,
+  CXTemplateArgumentKind_Expression,
+  CXTemplateArgumentKind_Pack,
+  /* Indicates an error case, preventing the kind from being deduced. */
+  CXTemplateArgumentKind_Invalid
+};
+
+/**
+ *Returns the number of template args of a function decl representing a
+ * template specialization.
+ *
+ * If the argument cursor cannot be converted into a template function
+ * declaration, -1 is returned.
+ *
+ * For example, for the following declaration and specialization:
+ *   template <typename T, int kInt, bool kBool>
+ *   void foo() { ... }
+ *
+ *   template <>
+ *   void foo<float, -7, true>();
+ *
+ * The value 3 would be returned from this call.
+ */
+CINDEX_LINKAGE int clang_Cursor_getNumTemplateArguments(CXCursor C);
+
+/**
+ * Retrieve the kind of the I'th template argument of the CXCursor C.
+ *
+ * If the argument CXCursor does not represent a FunctionDecl, an invalid
+ * template argument kind is returned.
+ *
+ * For example, for the following declaration and specialization:
+ *   template <typename T, int kInt, bool kBool>
+ *   void foo() { ... }
+ *
+ *   template <>
+ *   void foo<float, -7, true>();
+ *
+ * For I = 0, 1, and 2, Type, Integral, and Integral will be returned,
+ * respectively.
+ */
+CINDEX_LINKAGE enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(
+    CXCursor C, unsigned I);
+
+/**
+ * Retrieve a CXType representing the type of a TemplateArgument of a
+ *  function decl representing a template specialization.
+ *
+ * If the argument CXCursor does not represent a FunctionDecl whose I'th
+ * template argument has a kind of CXTemplateArgKind_Integral, an invalid type
+ * is returned.
+ *
+ * For example, for the following declaration and specialization:
+ *   template <typename T, int kInt, bool kBool>
+ *   void foo() { ... }
+ *
+ *   template <>
+ *   void foo<float, -7, true>();
+ *
+ * If called with I = 0, "float", will be returned.
+ * Invalid types will be returned for I == 1 or 2.
+ */
+CINDEX_LINKAGE CXType clang_Cursor_getTemplateArgumentType(CXCursor C,
+                                                           unsigned I);
+
+/**
+ * Retrieve the value of an Integral TemplateArgument (of a function
+ *  decl representing a template specialization) as a signed long long.
+ *
+ * It is undefined to call this function on a CXCursor that does not represent a
+ * FunctionDecl or whose I'th template argument is not an integral value.
+ *
+ * For example, for the following declaration and specialization:
+ *   template <typename T, int kInt, bool kBool>
+ *   void foo() { ... }
+ *
+ *   template <>
+ *   void foo<float, -7, true>();
+ *
+ * If called with I = 1 or 2, -7 or true will be returned, respectively.
+ * For I == 0, this function's behavior is undefined.
+ */
+CINDEX_LINKAGE long long clang_Cursor_getTemplateArgumentValue(CXCursor C,
+                                                               unsigned I);
+
+/**
+ * Retrieve the value of an Integral TemplateArgument (of a function
+ *  decl representing a template specialization) as an unsigned long long.
+ *
+ * It is undefined to call this function on a CXCursor that does not represent a
+ * FunctionDecl or whose I'th template argument is not an integral value.
+ *
+ * For example, for the following declaration and specialization:
+ *   template <typename T, int kInt, bool kBool>
+ *   void foo() { ... }
+ *
+ *   template <>
+ *   void foo<float, 2147483649, true>();
+ *
+ * If called with I = 1 or 2, 2147483649 or true will be returned, respectively.
+ * For I == 0, this function's behavior is undefined.
+ */
+CINDEX_LINKAGE unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue(
+    CXCursor C, unsigned I);
+
+/**
+ * Determine whether two CXTypes represent the same type.
+ *
+ * \returns non-zero if the CXTypes represent the same type and
+ *          zero otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_equalTypes(CXType A, CXType B);
+
+/**
+ * Return the canonical type for a CXType.
+ *
+ * Clang's type system explicitly models typedefs and all the ways
+ * a specific type can be represented.  The canonical type is the underlying
+ * type with all the "sugar" removed.  For example, if 'T' is a typedef
+ * for 'int', the canonical type for 'T' would be 'int'.
+ */
+CINDEX_LINKAGE CXType clang_getCanonicalType(CXType T);
+
+/**
+ * Determine whether a CXType has the "const" qualifier set,
+ * without looking through typedefs that may have added "const" at a
+ * different level.
+ */
+CINDEX_LINKAGE unsigned clang_isConstQualifiedType(CXType T);
+
+/**
+ * Determine whether a  CXCursor that is a macro, is
+ * function like.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isMacroFunctionLike(CXCursor C);
+
+/**
+ * Determine whether a  CXCursor that is a macro, is a
+ * builtin one.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isMacroBuiltin(CXCursor C);
+
+/**
+ * Determine whether a  CXCursor that is a function declaration, is an
+ * inline declaration.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isFunctionInlined(CXCursor C);
+
+/**
+ * Determine whether a CXType has the "volatile" qualifier set,
+ * without looking through typedefs that may have added "volatile" at
+ * a different level.
+ */
+CINDEX_LINKAGE unsigned clang_isVolatileQualifiedType(CXType T);
+
+/**
+ * Determine whether a CXType has the "restrict" qualifier set,
+ * without looking through typedefs that may have added "restrict" at a
+ * different level.
+ */
+CINDEX_LINKAGE unsigned clang_isRestrictQualifiedType(CXType T);
+
+/**
+ * Returns the address space of the given type.
+ */
+CINDEX_LINKAGE unsigned clang_getAddressSpace(CXType T);
+
+/**
+ * Returns the typedef name of the given type.
+ */
+CINDEX_LINKAGE CXString clang_getTypedefName(CXType CT);
+
+/**
+ * For pointer types, returns the type of the pointee.
+ */
+CINDEX_LINKAGE CXType clang_getPointeeType(CXType T);
+
+/**
+ * Return the cursor for the declaration of the given type.
+ */
+CINDEX_LINKAGE CXCursor clang_getTypeDeclaration(CXType T);
+
+/**
+ * Returns the Objective-C type encoding for the specified declaration.
+ */
+CINDEX_LINKAGE CXString clang_getDeclObjCTypeEncoding(CXCursor C);
+
+/**
+ * Returns the Objective-C type encoding for the specified CXType.
+ */
+CINDEX_LINKAGE CXString clang_Type_getObjCEncoding(CXType type);
+
+/**
+ * Retrieve the spelling of a given CXTypeKind.
+ */
+CINDEX_LINKAGE CXString clang_getTypeKindSpelling(enum CXTypeKind K);
+
+/**
+ * Retrieve the calling convention associated with a function type.
+ *
+ * If a non-function type is passed in, CXCallingConv_Invalid is returned.
+ */
+CINDEX_LINKAGE enum CXCallingConv clang_getFunctionTypeCallingConv(CXType T);
+
+/**
+ * Retrieve the return type associated with a function type.
+ *
+ * If a non-function type is passed in, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_getResultType(CXType T);
+
+/**
+ * Retrieve the exception specification type associated with a function type.
+ * This is a value of type CXCursor_ExceptionSpecificationKind.
+ *
+ * If a non-function type is passed in, an error code of -1 is returned.
+ */
+CINDEX_LINKAGE int clang_getExceptionSpecificationType(CXType T);
+
+/**
+ * Retrieve the number of non-variadic parameters associated with a
+ * function type.
+ *
+ * If a non-function type is passed in, -1 is returned.
+ */
+CINDEX_LINKAGE int clang_getNumArgTypes(CXType T);
+
+/**
+ * Retrieve the type of a parameter of a function type.
+ *
+ * If a non-function type is passed in or the function does not have enough
+ * parameters, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_getArgType(CXType T, unsigned i);
+
+/**
+ * Retrieves the base type of the ObjCObjectType.
+ *
+ * If the type is not an ObjC object, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_Type_getObjCObjectBaseType(CXType T);
+
+/**
+ * Retrieve the number of protocol references associated with an ObjC object/id.
+ *
+ * If the type is not an ObjC object, 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_Type_getNumObjCProtocolRefs(CXType T);
+
+/**
+ * Retrieve the decl for a protocol reference for an ObjC object/id.
+ *
+ * If the type is not an ObjC object or there are not enough protocol
+ * references, an invalid cursor is returned.
+ */
+CINDEX_LINKAGE CXCursor clang_Type_getObjCProtocolDecl(CXType T, unsigned i);
+
+/**
+ * Retreive the number of type arguments associated with an ObjC object.
+ *
+ * If the type is not an ObjC object, 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_Type_getNumObjCTypeArgs(CXType T);
+
+/**
+ * Retrieve a type argument associated with an ObjC object.
+ *
+ * If the type is not an ObjC or the index is not valid,
+ * an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_Type_getObjCTypeArg(CXType T, unsigned i);
+
+/**
+ * Return 1 if the CXType is a variadic function type, and 0 otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_isFunctionTypeVariadic(CXType T);
+
+/**
+ * Retrieve the return type associated with a given cursor.
+ *
+ * This only returns a valid type if the cursor refers to a function or method.
+ */
+CINDEX_LINKAGE CXType clang_getCursorResultType(CXCursor C);
+
+/**
+ * Retrieve the exception specification type associated with a given cursor.
+ * This is a value of type CXCursor_ExceptionSpecificationKind.
+ *
+ * This only returns a valid result if the cursor refers to a function or method.
+ */
+CINDEX_LINKAGE int clang_getCursorExceptionSpecificationType(CXCursor C);
+
+/**
+ * Return 1 if the CXType is a POD (plain old data) type, and 0
+ *  otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_isPODType(CXType T);
+
+/**
+ * Return the element type of an array, complex, or vector type.
+ *
+ * If a type is passed in that is not an array, complex, or vector type,
+ * an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_getElementType(CXType T);
+
+/**
+ * Return the number of elements of an array or vector type.
+ *
+ * If a type is passed in that is not an array or vector type,
+ * -1 is returned.
+ */
+CINDEX_LINKAGE long long clang_getNumElements(CXType T);
+
+/**
+ * Return the element type of an array type.
+ *
+ * If a non-array type is passed in, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_getArrayElementType(CXType T);
+
+/**
+ * Return the array size of a constant array.
+ *
+ * If a non-array type is passed in, -1 is returned.
+ */
+CINDEX_LINKAGE long long clang_getArraySize(CXType T);
+
+/**
+ * Retrieve the type named by the qualified-id.
+ *
+ * If a non-elaborated type is passed in, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_Type_getNamedType(CXType T);
+
+/**
+ * Determine if a typedef is 'transparent' tag.
+ *
+ * A typedef is considered 'transparent' if it shares a name and spelling
+ * location with its underlying tag type, as is the case with the NS_ENUM macro.
+ *
+ * \returns non-zero if transparent and zero otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_Type_isTransparentTagTypedef(CXType T);
+
+enum CXTypeNullabilityKind {
+  /**
+   * Values of this type can never be null.
+   */
+  CXTypeNullability_NonNull = 0,
+  /**
+   * Values of this type can be null.
+   */
+  CXTypeNullability_Nullable = 1,
+  /**
+   * Whether values of this type can be null is (explicitly)
+   * unspecified. This captures a (fairly rare) case where we
+   * can't conclude anything about the nullability of the type even
+   * though it has been considered.
+   */
+  CXTypeNullability_Unspecified = 2,
+  /**
+   * Nullability is not applicable to this type.
+   */
+  CXTypeNullability_Invalid = 3
+};
+
+/**
+ * Retrieve the nullability kind of a pointer type.
+ */
+CINDEX_LINKAGE enum CXTypeNullabilityKind clang_Type_getNullability(CXType T);
+
+/**
+ * List the possible error codes for \c clang_Type_getSizeOf,
+ *   \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
+ *   \c clang_Cursor_getOffsetOf.
+ *
+ * A value of this enumeration type can be returned if the target type is not
+ * a valid argument to sizeof, alignof or offsetof.
+ */
+enum CXTypeLayoutError {
+  /**
+   * Type is of kind CXType_Invalid.
+   */
+  CXTypeLayoutError_Invalid = -1,
+  /**
+   * The type is an incomplete Type.
+   */
+  CXTypeLayoutError_Incomplete = -2,
+  /**
+   * The type is a dependent Type.
+   */
+  CXTypeLayoutError_Dependent = -3,
+  /**
+   * The type is not a constant size type.
+   */
+  CXTypeLayoutError_NotConstantSize = -4,
+  /**
+   * The Field name is not valid for this record.
+   */
+  CXTypeLayoutError_InvalidFieldName = -5,
+  /**
+   * The type is undeduced.
+   */
+  CXTypeLayoutError_Undeduced = -6
+};
+
+/**
+ * Return the alignment of a type in bytes as per C++[expr.alignof]
+ *   standard.
+ *
+ * If the type declaration is invalid, CXTypeLayoutError_Invalid is returned.
+ * If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete
+ *   is returned.
+ * If the type declaration is a dependent type, CXTypeLayoutError_Dependent is
+ *   returned.
+ * If the type declaration is not a constant size type,
+ *   CXTypeLayoutError_NotConstantSize is returned.
+ */
+CINDEX_LINKAGE long long clang_Type_getAlignOf(CXType T);
+
+/**
+ * Return the class type of an member pointer type.
+ *
+ * If a non-member-pointer type is passed in, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_Type_getClassType(CXType T);
+
+/**
+ * Return the size of a type in bytes as per C++[expr.sizeof] standard.
+ *
+ * If the type declaration is invalid, CXTypeLayoutError_Invalid is returned.
+ * If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete
+ *   is returned.
+ * If the type declaration is a dependent type, CXTypeLayoutError_Dependent is
+ *   returned.
+ */
+CINDEX_LINKAGE long long clang_Type_getSizeOf(CXType T);
+
+/**
+ * Return the offset of a field named S in a record of type T in bits
+ *   as it would be returned by __offsetof__ as per C++11[18.2p4]
+ *
+ * If the cursor is not a record field declaration, CXTypeLayoutError_Invalid
+ *   is returned.
+ * If the field's type declaration is an incomplete type,
+ *   CXTypeLayoutError_Incomplete is returned.
+ * If the field's type declaration is a dependent type,
+ *   CXTypeLayoutError_Dependent is returned.
+ * If the field's name S is not found,
+ *   CXTypeLayoutError_InvalidFieldName is returned.
+ */
+CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S);
+
+/**
+ * Return the type that was modified by this attributed type.
+ *
+ * If the type is not an attributed type, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_Type_getModifiedType(CXType T);
+
+/**
+ * Return the offset of the field represented by the Cursor.
+ *
+ * If the cursor is not a field declaration, -1 is returned.
+ * If the cursor semantic parent is not a record field declaration,
+ *   CXTypeLayoutError_Invalid is returned.
+ * If the field's type declaration is an incomplete type,
+ *   CXTypeLayoutError_Incomplete is returned.
+ * If the field's type declaration is a dependent type,
+ *   CXTypeLayoutError_Dependent is returned.
+ * If the field's name S is not found,
+ *   CXTypeLayoutError_InvalidFieldName is returned.
+ */
+CINDEX_LINKAGE long long clang_Cursor_getOffsetOfField(CXCursor C);
+
+/**
+ * Determine whether the given cursor represents an anonymous
+ * tag or namespace
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isAnonymous(CXCursor C);
+
+/**
+ * Determine whether the given cursor represents an anonymous record
+ * declaration.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C);
+
+/**
+ * Determine whether the given cursor represents an inline namespace
+ * declaration.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isInlineNamespace(CXCursor C);
+
+enum CXRefQualifierKind {
+  /** No ref-qualifier was provided. */
+  CXRefQualifier_None = 0,
+  /** An lvalue ref-qualifier was provided (\c &). */
+  CXRefQualifier_LValue,
+  /** An rvalue ref-qualifier was provided (\c &&). */
+  CXRefQualifier_RValue
+};
+
+/**
+ * Returns the number of template arguments for given template
+ * specialization, or -1 if type \c T is not a template specialization.
+ */
+CINDEX_LINKAGE int clang_Type_getNumTemplateArguments(CXType T);
+
+/**
+ * Returns the type template argument of a template class specialization
+ * at given index.
+ *
+ * This function only returns template type arguments and does not handle
+ * template template arguments or variadic packs.
+ */
+CINDEX_LINKAGE CXType clang_Type_getTemplateArgumentAsType(CXType T, unsigned i);
+
+/**
+ * Retrieve the ref-qualifier kind of a function or method.
+ *
+ * The ref-qualifier is returned for C++ functions or methods. For other types
+ * or non-C++ declarations, CXRefQualifier_None is returned.
+ */
+CINDEX_LINKAGE enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T);
+
+/**
+ * Returns non-zero if the cursor specifies a Record member that is a
+ *   bitfield.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isBitField(CXCursor C);
+
+/**
+ * Returns 1 if the base class specified by the cursor with kind
+ *   CX_CXXBaseSpecifier is virtual.
+ */
+CINDEX_LINKAGE unsigned clang_isVirtualBase(CXCursor);
+
+/**
+ * Represents the C++ access control level to a base class for a
+ * cursor with kind CX_CXXBaseSpecifier.
+ */
+enum CX_CXXAccessSpecifier {
+  CX_CXXInvalidAccessSpecifier,
+  CX_CXXPublic,
+  CX_CXXProtected,
+  CX_CXXPrivate
+};
+
+/**
+ * Returns the access control level for the referenced object.
+ *
+ * If the cursor refers to a C++ declaration, its access control level within its
+ * parent scope is returned. Otherwise, if the cursor refers to a base specifier or
+ * access specifier, the specifier itself is returned.
+ */
+CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor);
+
+/**
+ * Represents the storage classes as declared in the source. CX_SC_Invalid
+ * was added for the case that the passed cursor in not a declaration.
+ */
+enum CX_StorageClass {
+  CX_SC_Invalid,
+  CX_SC_None,
+  CX_SC_Extern,
+  CX_SC_Static,
+  CX_SC_PrivateExtern,
+  CX_SC_OpenCLWorkGroupLocal,
+  CX_SC_Auto,
+  CX_SC_Register
+};
+
+/**
+ * Returns the storage class for a function or variable declaration.
+ *
+ * If the passed in Cursor is not a function or variable declaration,
+ * CX_SC_Invalid is returned else the storage class.
+ */
+CINDEX_LINKAGE enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor);
+
+/**
+ * Determine the number of overloaded declarations referenced by a
+ * \c CXCursor_OverloadedDeclRef cursor.
+ *
+ * \param cursor The cursor whose overloaded declarations are being queried.
+ *
+ * \returns The number of overloaded declarations referenced by \c cursor. If it
+ * is not a \c CXCursor_OverloadedDeclRef cursor, returns 0.
+ */
+CINDEX_LINKAGE unsigned clang_getNumOverloadedDecls(CXCursor cursor);
+
+/**
+ * Retrieve a cursor for one of the overloaded declarations referenced
+ * by a \c CXCursor_OverloadedDeclRef cursor.
+ *
+ * \param cursor The cursor whose overloaded declarations are being queried.
+ *
+ * \param index The zero-based index into the set of overloaded declarations in
+ * the cursor.
+ *
+ * \returns A cursor representing the declaration referenced by the given
+ * \c cursor at the specified \c index. If the cursor does not have an
+ * associated set of overloaded declarations, or if the index is out of bounds,
+ * returns \c clang_getNullCursor();
+ */
+CINDEX_LINKAGE CXCursor clang_getOverloadedDecl(CXCursor cursor,
+                                                unsigned index);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_ATTRIBUTES Information for attributes
+ *
+ * @{
+ */
+
+/**
+ * For cursors representing an iboutletcollection attribute,
+ *  this function returns the collection element type.
+ *
+ */
+CINDEX_LINKAGE CXType clang_getIBOutletCollectionType(CXCursor);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_TRAVERSAL Traversing the AST with cursors
+ *
+ * These routines provide the ability to traverse the abstract syntax tree
+ * using cursors.
+ *
+ * @{
+ */
+
+/**
+ * Describes how the traversal of the children of a particular
+ * cursor should proceed after visiting a particular child cursor.
+ *
+ * A value of this enumeration type should be returned by each
+ * \c CXCursorVisitor to indicate how clang_visitChildren() proceed.
+ */
+enum CXChildVisitResult {
+  /**
+   * Terminates the cursor traversal.
+   */
+  CXChildVisit_Break,
+  /**
+   * Continues the cursor traversal with the next sibling of
+   * the cursor just visited, without visiting its children.
+   */
+  CXChildVisit_Continue,
+  /**
+   * Recursively traverse the children of this cursor, using
+   * the same visitor and client data.
+   */
+  CXChildVisit_Recurse
+};
+
+/**
+ * Visitor invoked for each cursor found by a traversal.
+ *
+ * This visitor function will be invoked for each cursor found by
+ * clang_visitCursorChildren(). Its first argument is the cursor being
+ * visited, its second argument is the parent visitor for that cursor,
+ * and its third argument is the client data provided to
+ * clang_visitCursorChildren().
+ *
+ * The visitor should return one of the \c CXChildVisitResult values
+ * to direct clang_visitCursorChildren().
+ */
+typedef enum CXChildVisitResult (*CXCursorVisitor)(CXCursor cursor,
+                                                   CXCursor parent,
+                                                   CXClientData client_data);
+
+/**
+ * Visit the children of a particular cursor.
+ *
+ * This function visits all the direct children of the given cursor,
+ * invoking the given \p visitor function with the cursors of each
+ * visited child. The traversal may be recursive, if the visitor returns
+ * \c CXChildVisit_Recurse. The traversal may also be ended prematurely, if
+ * the visitor returns \c CXChildVisit_Break.
+ *
+ * \param parent the cursor whose child may be visited. All kinds of
+ * cursors can be visited, including invalid cursors (which, by
+ * definition, have no children).
+ *
+ * \param visitor the visitor function that will be invoked for each
+ * child of \p parent.
+ *
+ * \param client_data pointer data supplied by the client, which will
+ * be passed to the visitor each time it is invoked.
+ *
+ * \returns a non-zero value if the traversal was terminated
+ * prematurely by the visitor returning \c CXChildVisit_Break.
+ */
+CINDEX_LINKAGE unsigned clang_visitChildren(CXCursor parent,
+                                            CXCursorVisitor visitor,
+                                            CXClientData client_data);
+#ifdef __has_feature
+#  if __has_feature(blocks)
+/**
+ * Visitor invoked for each cursor found by a traversal.
+ *
+ * This visitor block will be invoked for each cursor found by
+ * clang_visitChildrenWithBlock(). Its first argument is the cursor being
+ * visited, its second argument is the parent visitor for that cursor.
+ *
+ * The visitor should return one of the \c CXChildVisitResult values
+ * to direct clang_visitChildrenWithBlock().
+ */
+typedef enum CXChildVisitResult
+     (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
+
+/**
+ * Visits the children of a cursor using the specified block.  Behaves
+ * identically to clang_visitChildren() in all other respects.
+ */
+CINDEX_LINKAGE unsigned clang_visitChildrenWithBlock(CXCursor parent,
+                                                    CXCursorVisitorBlock block);
+#  endif
+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_XREF Cross-referencing in the AST
+ *
+ * These routines provide the ability to determine references within and
+ * across translation units, by providing the names of the entities referenced
+ * by cursors, follow reference cursors to the declarations they reference,
+ * and associate declarations with their definitions.
+ *
+ * @{
+ */
+
+/**
+ * Retrieve a Unified Symbol Resolution (USR) for the entity referenced
+ * by the given cursor.
+ *
+ * A Unified Symbol Resolution (USR) is a string that identifies a particular
+ * entity (function, class, variable, etc.) within a program. USRs can be
+ * compared across translation units to determine, e.g., when references in
+ * one translation refer to an entity defined in another translation unit.
+ */
+CINDEX_LINKAGE CXString clang_getCursorUSR(CXCursor);
+
+/**
+ * Construct a USR for a specified Objective-C class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCClass(const char *class_name);
+
+/**
+ * Construct a USR for a specified Objective-C category.
+ */
+CINDEX_LINKAGE CXString
+  clang_constructUSR_ObjCCategory(const char *class_name,
+                                 const char *category_name);
+
+/**
+ * Construct a USR for a specified Objective-C protocol.
+ */
+CINDEX_LINKAGE CXString
+  clang_constructUSR_ObjCProtocol(const char *protocol_name);
+
+/**
+ * Construct a USR for a specified Objective-C instance variable and
+ *   the USR for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCIvar(const char *name,
+                                                    CXString classUSR);
+
+/**
+ * Construct a USR for a specified Objective-C method and
+ *   the USR for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCMethod(const char *name,
+                                                      unsigned isInstanceMethod,
+                                                      CXString classUSR);
+
+/**
+ * Construct a USR for a specified Objective-C property and the USR
+ *  for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCProperty(const char *property,
+                                                        CXString classUSR);
+
+/**
+ * Retrieve a name for the entity referenced by this cursor.
+ */
+CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor);
+
+/**
+ * Retrieve a range for a piece that forms the cursors spelling name.
+ * Most of the times there is only one range for the complete spelling but for
+ * Objective-C methods and Objective-C message expressions, there are multiple
+ * pieces for each selector identifier.
+ *
+ * \param pieceIndex the index of the spelling name piece. If this is greater
+ * than the actual number of pieces, it will return a NULL (invalid) range.
+ *
+ * \param options Reserved.
+ */
+CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor,
+                                                          unsigned pieceIndex,
+                                                          unsigned options);
+
+/**
+ * Opaque pointer representing a policy that controls pretty printing
+ * for \c clang_getCursorPrettyPrinted.
+ */
+typedef void *CXPrintingPolicy;
+
+/**
+ * Properties for the printing policy.
+ *
+ * See \c clang::PrintingPolicy for more information.
+ */
+enum CXPrintingPolicyProperty {
+  CXPrintingPolicy_Indentation,
+  CXPrintingPolicy_SuppressSpecifiers,
+  CXPrintingPolicy_SuppressTagKeyword,
+  CXPrintingPolicy_IncludeTagDefinition,
+  CXPrintingPolicy_SuppressScope,
+  CXPrintingPolicy_SuppressUnwrittenScope,
+  CXPrintingPolicy_SuppressInitializers,
+  CXPrintingPolicy_ConstantArraySizeAsWritten,
+  CXPrintingPolicy_AnonymousTagLocations,
+  CXPrintingPolicy_SuppressStrongLifetime,
+  CXPrintingPolicy_SuppressLifetimeQualifiers,
+  CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors,
+  CXPrintingPolicy_Bool,
+  CXPrintingPolicy_Restrict,
+  CXPrintingPolicy_Alignof,
+  CXPrintingPolicy_UnderscoreAlignof,
+  CXPrintingPolicy_UseVoidForZeroParams,
+  CXPrintingPolicy_TerseOutput,
+  CXPrintingPolicy_PolishForDeclaration,
+  CXPrintingPolicy_Half,
+  CXPrintingPolicy_MSWChar,
+  CXPrintingPolicy_IncludeNewlines,
+  CXPrintingPolicy_MSVCFormatting,
+  CXPrintingPolicy_ConstantsAsWritten,
+  CXPrintingPolicy_SuppressImplicitBase,
+  CXPrintingPolicy_FullyQualifiedName,
+
+  CXPrintingPolicy_LastProperty = CXPrintingPolicy_FullyQualifiedName
+};
+
+/**
+ * Get a property value for the given printing policy.
+ */
+CINDEX_LINKAGE unsigned
+clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
+                                 enum CXPrintingPolicyProperty Property);
+
+/**
+ * Set a property value for the given printing policy.
+ */
+CINDEX_LINKAGE void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
+                                                     enum CXPrintingPolicyProperty Property,
+                                                     unsigned Value);
+
+/**
+ * Retrieve the default policy for the cursor.
+ *
+ * The policy should be released after use with \c
+ * clang_PrintingPolicy_dispose.
+ */
+CINDEX_LINKAGE CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor);
+
+/**
+ * Release a printing policy.
+ */
+CINDEX_LINKAGE void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy);
+
+/**
+ * Pretty print declarations.
+ *
+ * \param Cursor The cursor representing a declaration.
+ *
+ * \param Policy The policy to control the entities being printed. If
+ * NULL, a default policy is used.
+ *
+ * \returns The pretty printed declaration or the empty string for
+ * other cursors.
+ */
+CINDEX_LINKAGE CXString clang_getCursorPrettyPrinted(CXCursor Cursor,
+                                                     CXPrintingPolicy Policy);
+
+/**
+ * Retrieve the display name for the entity referenced by this cursor.
+ *
+ * The display name contains extra information that helps identify the cursor,
+ * such as the parameters of a function or template or the arguments of a
+ * class template specialization.
+ */
+CINDEX_LINKAGE CXString clang_getCursorDisplayName(CXCursor);
+
+/** For a cursor that is a reference, retrieve a cursor representing the
+ * entity that it references.
+ *
+ * Reference cursors refer to other entities in the AST. For example, an
+ * Objective-C superclass reference cursor refers to an Objective-C class.
+ * This function produces the cursor for the Objective-C class from the
+ * cursor for the superclass reference. If the input cursor is a declaration or
+ * definition, it returns that declaration or definition unchanged.
+ * Otherwise, returns the NULL cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorReferenced(CXCursor);
+
+/**
+ *  For a cursor that is either a reference to or a declaration
+ *  of some entity, retrieve a cursor that describes the definition of
+ *  that entity.
+ *
+ *  Some entities can be declared multiple times within a translation
+ *  unit, but only one of those declarations can also be a
+ *  definition. For example, given:
+ *
+ *  \code
+ *  int f(int, int);
+ *  int g(int x, int y) { return f(x, y); }
+ *  int f(int a, int b) { return a + b; }
+ *  int f(int, int);
+ *  \endcode
+ *
+ *  there are three declarations of the function "f", but only the
+ *  second one is a definition. The clang_getCursorDefinition()
+ *  function will take any cursor pointing to a declaration of "f"
+ *  (the first or fourth lines of the example) or a cursor referenced
+ *  that uses "f" (the call to "f' inside "g") and will return a
+ *  declaration cursor pointing to the definition (the second "f"
+ *  declaration).
+ *
+ *  If given a cursor for which there is no corresponding definition,
+ *  e.g., because there is no definition of that entity within this
+ *  translation unit, returns a NULL cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorDefinition(CXCursor);
+
+/**
+ * Determine whether the declaration pointed to by this cursor
+ * is also a definition of that entity.
+ */
+CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor);
+
+/**
+ * Retrieve the canonical cursor corresponding to the given cursor.
+ *
+ * In the C family of languages, many kinds of entities can be declared several
+ * times within a single translation unit. For example, a structure type can
+ * be forward-declared (possibly multiple times) and later defined:
+ *
+ * \code
+ * struct X;
+ * struct X;
+ * struct X {
+ *   int member;
+ * };
+ * \endcode
+ *
+ * The declarations and the definition of \c X are represented by three
+ * different cursors, all of which are declarations of the same underlying
+ * entity. One of these cursor is considered the "canonical" cursor, which
+ * is effectively the representative for the underlying entity. One can
+ * determine if two cursors are declarations of the same underlying entity by
+ * comparing their canonical cursors.
+ *
+ * \returns The canonical cursor for the entity referred to by the given cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getCanonicalCursor(CXCursor);
+
+/**
+ * If the cursor points to a selector identifier in an Objective-C
+ * method or message expression, this returns the selector index.
+ *
+ * After getting a cursor with #clang_getCursor, this can be called to
+ * determine if the location points to a selector identifier.
+ *
+ * \returns The selector index if the cursor is an Objective-C method or message
+ * expression and the cursor is pointing to a selector identifier, or -1
+ * otherwise.
+ */
+CINDEX_LINKAGE int clang_Cursor_getObjCSelectorIndex(CXCursor);
+
+/**
+ * Given a cursor pointing to a C++ method call or an Objective-C
+ * message, returns non-zero if the method/message is "dynamic", meaning:
+ *
+ * For a C++ method: the call is virtual.
+ * For an Objective-C message: the receiver is an object instance, not 'super'
+ * or a specific class.
+ *
+ * If the method/message is "static" or the cursor does not point to a
+ * method/message, it will return zero.
+ */
+CINDEX_LINKAGE int clang_Cursor_isDynamicCall(CXCursor C);
+
+/**
+ * Given a cursor pointing to an Objective-C message or property
+ * reference, or C++ method call, returns the CXType of the receiver.
+ */
+CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C);
+
+/**
+ * Property attributes for a \c CXCursor_ObjCPropertyDecl.
+ */
+typedef enum {
+  CXObjCPropertyAttr_noattr    = 0x00,
+  CXObjCPropertyAttr_readonly  = 0x01,
+  CXObjCPropertyAttr_getter    = 0x02,
+  CXObjCPropertyAttr_assign    = 0x04,
+  CXObjCPropertyAttr_readwrite = 0x08,
+  CXObjCPropertyAttr_retain    = 0x10,
+  CXObjCPropertyAttr_copy      = 0x20,
+  CXObjCPropertyAttr_nonatomic = 0x40,
+  CXObjCPropertyAttr_setter    = 0x80,
+  CXObjCPropertyAttr_atomic    = 0x100,
+  CXObjCPropertyAttr_weak      = 0x200,
+  CXObjCPropertyAttr_strong    = 0x400,
+  CXObjCPropertyAttr_unsafe_unretained = 0x800,
+  CXObjCPropertyAttr_class = 0x1000
+} CXObjCPropertyAttrKind;
+
+/**
+ * Given a cursor that represents a property declaration, return the
+ * associated property attributes. The bits are formed from
+ * \c CXObjCPropertyAttrKind.
+ *
+ * \param reserved Reserved for future use, pass 0.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C,
+                                                             unsigned reserved);
+
+/**
+ * Given a cursor that represents a property declaration, return the
+ * name of the method that implements the getter.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C);
+
+/**
+ * Given a cursor that represents a property declaration, return the
+ * name of the method that implements the setter, if any.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertySetterName(CXCursor C);
+
+/**
+ * 'Qualifiers' written next to the return and parameter types in
+ * Objective-C method declarations.
+ */
+typedef enum {
+  CXObjCDeclQualifier_None = 0x0,
+  CXObjCDeclQualifier_In = 0x1,
+  CXObjCDeclQualifier_Inout = 0x2,
+  CXObjCDeclQualifier_Out = 0x4,
+  CXObjCDeclQualifier_Bycopy = 0x8,
+  CXObjCDeclQualifier_Byref = 0x10,
+  CXObjCDeclQualifier_Oneway = 0x20
+} CXObjCDeclQualifierKind;
+
+/**
+ * Given a cursor that represents an Objective-C method or parameter
+ * declaration, return the associated Objective-C qualifiers for the return
+ * type or the parameter respectively. The bits are formed from
+ * CXObjCDeclQualifierKind.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C);
+
+/**
+ * Given a cursor that represents an Objective-C method or property
+ * declaration, return non-zero if the declaration was affected by "\@optional".
+ * Returns zero if the cursor is not such a declaration or it is "\@required".
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C);
+
+/**
+ * Returns non-zero if the given cursor is a variadic function or method.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C);
+
+/**
+ * Returns non-zero if the given cursor points to a symbol marked with
+ * external_source_symbol attribute.
+ *
+ * \param language If non-NULL, and the attribute is present, will be set to
+ * the 'language' string from the attribute.
+ *
+ * \param definedIn If non-NULL, and the attribute is present, will be set to
+ * the 'definedIn' string from the attribute.
+ *
+ * \param isGenerated If non-NULL, and the attribute is present, will be set to
+ * non-zero if the 'generated_declaration' is set in the attribute.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isExternalSymbol(CXCursor C,
+                                       CXString *language, CXString *definedIn,
+                                       unsigned *isGenerated);
+
+/**
+ * Given a cursor that represents a declaration, return the associated
+ * comment's source range.  The range may include multiple consecutive comments
+ * with whitespace in between.
+ */
+CINDEX_LINKAGE CXSourceRange clang_Cursor_getCommentRange(CXCursor C);
+
+/**
+ * Given a cursor that represents a declaration, return the associated
+ * comment text, including comment markers.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getRawCommentText(CXCursor C);
+
+/**
+ * Given a cursor that represents a documentable entity (e.g.,
+ * declaration), return the associated \paragraph; otherwise return the
+ * first paragraph.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getBriefCommentText(CXCursor C);
+
+/**
+ * @}
+ */
+
+/** \defgroup CINDEX_MANGLE Name Mangling API Functions
+ *
+ * @{
+ */
+
+/**
+ * Retrieve the CXString representing the mangled name of the cursor.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor);
+
+/**
+ * Retrieve the CXStrings representing the mangled symbols of the C++
+ * constructor or destructor at the cursor.
+ */
+CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(CXCursor);
+
+/**
+ * Retrieve the CXStrings representing the mangled symbols of the ObjC
+ * class interface or implementation at the cursor.
+ */
+CINDEX_LINKAGE CXStringSet *clang_Cursor_getObjCManglings(CXCursor);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_MODULE Module introspection
+ *
+ * The functions in this group provide access to information about modules.
+ *
+ * @{
+ */
+
+typedef void *CXModule;
+
+/**
+ * Given a CXCursor_ModuleImportDecl cursor, return the associated module.
+ */
+CINDEX_LINKAGE CXModule clang_Cursor_getModule(CXCursor C);
+
+/**
+ * Given a CXFile header file, return the module that contains it, if one
+ * exists.
+ */
+CINDEX_LINKAGE CXModule clang_getModuleForFile(CXTranslationUnit, CXFile);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns the module file where the provided module object came from.
+ */
+CINDEX_LINKAGE CXFile clang_Module_getASTFile(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns the parent of a sub-module or NULL if the given module is top-level,
+ * e.g. for 'std.vector' it will return the 'std' module.
+ */
+CINDEX_LINKAGE CXModule clang_Module_getParent(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns the name of the module, e.g. for the 'std.vector' sub-module it
+ * will return "vector".
+ */
+CINDEX_LINKAGE CXString clang_Module_getName(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns the full name of the module, e.g. "std.vector".
+ */
+CINDEX_LINKAGE CXString clang_Module_getFullName(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns non-zero if the module is a system one.
+ */
+CINDEX_LINKAGE int clang_Module_isSystem(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns the number of top level headers associated with this module.
+ */
+CINDEX_LINKAGE unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit,
+                                                           CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \param Index top level header index (zero-based).
+ *
+ * \returns the specified top level header associated with the module.
+ */
+CINDEX_LINKAGE
+CXFile clang_Module_getTopLevelHeader(CXTranslationUnit,
+                                      CXModule Module, unsigned Index);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CPP C++ AST introspection
+ *
+ * The routines in this group provide access information in the ASTs specific
+ * to C++ language features.
+ *
+ * @{
+ */
+
+/**
+ * Determine if a C++ constructor is a converting constructor.
+ */
+CINDEX_LINKAGE unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C);
+
+/**
+ * Determine if a C++ constructor is a copy constructor.
+ */
+CINDEX_LINKAGE unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C);
+
+/**
+ * Determine if a C++ constructor is the default constructor.
+ */
+CINDEX_LINKAGE unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C);
+
+/**
+ * Determine if a C++ constructor is a move constructor.
+ */
+CINDEX_LINKAGE unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C);
+
+/**
+ * Determine if a C++ field is declared 'mutable'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXField_isMutable(CXCursor C);
+
+/**
+ * Determine if a C++ method is declared '= default'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isDefaulted(CXCursor C);
+
+/**
+ * Determine if a C++ member function or member function template is
+ * pure virtual.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isPureVirtual(CXCursor C);
+
+/**
+ * Determine if a C++ member function or member function template is
+ * declared 'static'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
+
+/**
+ * Determine if a C++ member function or member function template is
+ * explicitly declared 'virtual' or if it overrides a virtual method from
+ * one of the base classes.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C);
+
+/**
+ * Determine if a C++ record is abstract, i.e. whether a class or struct
+ * has a pure virtual member function.
+ */
+CINDEX_LINKAGE unsigned clang_CXXRecord_isAbstract(CXCursor C);
+
+/**
+ * Determine if an enum declaration refers to a scoped enum.
+ */
+CINDEX_LINKAGE unsigned clang_EnumDecl_isScoped(CXCursor C);
+
+/**
+ * Determine if a C++ member function or member function template is
+ * declared 'const'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isConst(CXCursor C);
+
+/**
+ * Given a cursor that represents a template, determine
+ * the cursor kind of the specializations would be generated by instantiating
+ * the template.
+ *
+ * This routine can be used to determine what flavor of function template,
+ * class template, or class template partial specialization is stored in the
+ * cursor. For example, it can describe whether a class template cursor is
+ * declared with "struct", "class" or "union".
+ *
+ * \param C The cursor to query. This cursor should represent a template
+ * declaration.
+ *
+ * \returns The cursor kind of the specializations that would be generated
+ * by instantiating the template \p C. If \p C is not a template, returns
+ * \c CXCursor_NoDeclFound.
+ */
+CINDEX_LINKAGE enum CXCursorKind clang_getTemplateCursorKind(CXCursor C);
+
+/**
+ * Given a cursor that may represent a specialization or instantiation
+ * of a template, retrieve the cursor that represents the template that it
+ * specializes or from which it was instantiated.
+ *
+ * This routine determines the template involved both for explicit
+ * specializations of templates and for implicit instantiations of the template,
+ * both of which are referred to as "specializations". For a class template
+ * specialization (e.g., \c std::vector<bool>), this routine will return
+ * either the primary template (\c std::vector) or, if the specialization was
+ * instantiated from a class template partial specialization, the class template
+ * partial specialization. For a class template partial specialization and a
+ * function template specialization (including instantiations), this
+ * this routine will return the specialized template.
+ *
+ * For members of a class template (e.g., member functions, member classes, or
+ * static data members), returns the specialized or instantiated member.
+ * Although not strictly "templates" in the C++ language, members of class
+ * templates have the same notions of specializations and instantiations that
+ * templates do, so this routine treats them similarly.
+ *
+ * \param C A cursor that may be a specialization of a template or a member
+ * of a template.
+ *
+ * \returns If the given cursor is a specialization or instantiation of a
+ * template or a member thereof, the template or member that it specializes or
+ * from which it was instantiated. Otherwise, returns a NULL cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getSpecializedCursorTemplate(CXCursor C);
+
+/**
+ * Given a cursor that references something else, return the source range
+ * covering that reference.
+ *
+ * \param C A cursor pointing to a member reference, a declaration reference, or
+ * an operator call.
+ * \param NameFlags A bitset with three independent flags:
+ * CXNameRange_WantQualifier, CXNameRange_WantTemplateArgs, and
+ * CXNameRange_WantSinglePiece.
+ * \param PieceIndex For contiguous names or when passing the flag
+ * CXNameRange_WantSinglePiece, only one piece with index 0 is
+ * available. When the CXNameRange_WantSinglePiece flag is not passed for a
+ * non-contiguous names, this index can be used to retrieve the individual
+ * pieces of the name. See also CXNameRange_WantSinglePiece.
+ *
+ * \returns The piece of the name pointed to by the given cursor. If there is no
+ * name, or if the PieceIndex is out-of-range, a null-cursor will be returned.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getCursorReferenceNameRange(CXCursor C,
+                                                unsigned NameFlags,
+                                                unsigned PieceIndex);
+
+enum CXNameRefFlags {
+  /**
+   * Include the nested-name-specifier, e.g. Foo:: in x.Foo::y, in the
+   * range.
+   */
+  CXNameRange_WantQualifier = 0x1,
+
+  /**
+   * Include the explicit template arguments, e.g. \<int> in x.f<int>,
+   * in the range.
+   */
+  CXNameRange_WantTemplateArgs = 0x2,
+
+  /**
+   * If the name is non-contiguous, return the full spanning range.
+   *
+   * Non-contiguous names occur in Objective-C when a selector with two or more
+   * parameters is used, or in C++ when using an operator:
+   * \code
+   * [object doSomething:here withValue:there]; // Objective-C
+   * return some_vector[1]; // C++
+   * \endcode
+   */
+  CXNameRange_WantSinglePiece = 0x4
+};
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_LEX Token extraction and manipulation
+ *
+ * The routines in this group provide access to the tokens within a
+ * translation unit, along with a semantic mapping of those tokens to
+ * their corresponding cursors.
+ *
+ * @{
+ */
+
+/**
+ * Describes a kind of token.
+ */
+typedef enum CXTokenKind {
+  /**
+   * A token that contains some kind of punctuation.
+   */
+  CXToken_Punctuation,
+
+  /**
+   * A language keyword.
+   */
+  CXToken_Keyword,
+
+  /**
+   * An identifier (that is not a keyword).
+   */
+  CXToken_Identifier,
+
+  /**
+   * A numeric, string, or character literal.
+   */
+  CXToken_Literal,
+
+  /**
+   * A comment.
+   */
+  CXToken_Comment
+} CXTokenKind;
+
+/**
+ * Describes a single preprocessing token.
+ */
+typedef struct {
+  unsigned int_data[4];
+  void *ptr_data;
+} CXToken;
+
+/**
+ * Get the raw lexical token starting with the given location.
+ *
+ * \param TU the translation unit whose text is being tokenized.
+ *
+ * \param Location the source location with which the token starts.
+ *
+ * \returns The token starting with the given location or NULL if no such token
+ * exist. The returned pointer must be freed with clang_disposeTokens before the
+ * translation unit is destroyed.
+ */
+CINDEX_LINKAGE CXToken *clang_getToken(CXTranslationUnit TU,
+                                       CXSourceLocation Location);
+
+/**
+ * Determine the kind of the given token.
+ */
+CINDEX_LINKAGE CXTokenKind clang_getTokenKind(CXToken);
+
+/**
+ * Determine the spelling of the given token.
+ *
+ * The spelling of a token is the textual representation of that token, e.g.,
+ * the text of an identifier or keyword.
+ */
+CINDEX_LINKAGE CXString clang_getTokenSpelling(CXTranslationUnit, CXToken);
+
+/**
+ * Retrieve the source location of the given token.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getTokenLocation(CXTranslationUnit,
+                                                       CXToken);
+
+/**
+ * Retrieve a source range that covers the given token.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getTokenExtent(CXTranslationUnit, CXToken);
+
+/**
+ * Tokenize the source code described by the given range into raw
+ * lexical tokens.
+ *
+ * \param TU the translation unit whose text is being tokenized.
+ *
+ * \param Range the source range in which text should be tokenized. All of the
+ * tokens produced by tokenization will fall within this source range,
+ *
+ * \param Tokens this pointer will be set to point to the array of tokens
+ * that occur within the given source range. The returned pointer must be
+ * freed with clang_disposeTokens() before the translation unit is destroyed.
+ *
+ * \param NumTokens will be set to the number of tokens in the \c *Tokens
+ * array.
+ *
+ */
+CINDEX_LINKAGE void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
+                                   CXToken **Tokens, unsigned *NumTokens);
+
+/**
+ * Annotate the given set of tokens by providing cursors for each token
+ * that can be mapped to a specific entity within the abstract syntax tree.
+ *
+ * This token-annotation routine is equivalent to invoking
+ * clang_getCursor() for the source locations of each of the
+ * tokens. The cursors provided are filtered, so that only those
+ * cursors that have a direct correspondence to the token are
+ * accepted. For example, given a function call \c f(x),
+ * clang_getCursor() would provide the following cursors:
+ *
+ *   * when the cursor is over the 'f', a DeclRefExpr cursor referring to 'f'.
+ *   * when the cursor is over the '(' or the ')', a CallExpr referring to 'f'.
+ *   * when the cursor is over the 'x', a DeclRefExpr cursor referring to 'x'.
+ *
+ * Only the first and last of these cursors will occur within the
+ * annotate, since the tokens "f" and "x' directly refer to a function
+ * and a variable, respectively, but the parentheses are just a small
+ * part of the full syntax of the function call expression, which is
+ * not provided as an annotation.
+ *
+ * \param TU the translation unit that owns the given tokens.
+ *
+ * \param Tokens the set of tokens to annotate.
+ *
+ * \param NumTokens the number of tokens in \p Tokens.
+ *
+ * \param Cursors an array of \p NumTokens cursors, whose contents will be
+ * replaced with the cursors corresponding to each token.
+ */
+CINDEX_LINKAGE void clang_annotateTokens(CXTranslationUnit TU,
+                                         CXToken *Tokens, unsigned NumTokens,
+                                         CXCursor *Cursors);
+
+/**
+ * Free the given set of tokens.
+ */
+CINDEX_LINKAGE void clang_disposeTokens(CXTranslationUnit TU,
+                                        CXToken *Tokens, unsigned NumTokens);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_DEBUG Debugging facilities
+ *
+ * These routines are used for testing and debugging, only, and should not
+ * be relied upon.
+ *
+ * @{
+ */
+
+/* for debug/testing */
+CINDEX_LINKAGE CXString clang_getCursorKindSpelling(enum CXCursorKind Kind);
+CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor,
+                                          const char **startBuf,
+                                          const char **endBuf,
+                                          unsigned *startLine,
+                                          unsigned *startColumn,
+                                          unsigned *endLine,
+                                          unsigned *endColumn);
+CINDEX_LINKAGE void clang_enableStackTraces(void);
+CINDEX_LINKAGE void clang_executeOnThread(void (*fn)(void*), void *user_data,
+                                          unsigned stack_size);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CODE_COMPLET Code completion
+ *
+ * Code completion involves taking an (incomplete) source file, along with
+ * knowledge of where the user is actively editing that file, and suggesting
+ * syntactically- and semantically-valid constructs that the user might want to
+ * use at that particular point in the source code. These data structures and
+ * routines provide support for code completion.
+ *
+ * @{
+ */
+
+/**
+ * A semantic string that describes a code-completion result.
+ *
+ * A semantic string that describes the formatting of a code-completion
+ * result as a single "template" of text that should be inserted into the
+ * source buffer when a particular code-completion result is selected.
+ * Each semantic string is made up of some number of "chunks", each of which
+ * contains some text along with a description of what that text means, e.g.,
+ * the name of the entity being referenced, whether the text chunk is part of
+ * the template, or whether it is a "placeholder" that the user should replace
+ * with actual code,of a specific kind. See \c CXCompletionChunkKind for a
+ * description of the different kinds of chunks.
+ */
+typedef void *CXCompletionString;
+
+/**
+ * A single result of code completion.
+ */
+typedef struct {
+  /**
+   * The kind of entity that this completion refers to.
+   *
+   * The cursor kind will be a macro, keyword, or a declaration (one of the
+   * *Decl cursor kinds), describing the entity that the completion is
+   * referring to.
+   *
+   * \todo In the future, we would like to provide a full cursor, to allow
+   * the client to extract additional information from declaration.
+   */
+  enum CXCursorKind CursorKind;
+
+  /**
+   * The code-completion string that describes how to insert this
+   * code-completion result into the editing buffer.
+   */
+  CXCompletionString CompletionString;
+} CXCompletionResult;
+
+/**
+ * Describes a single piece of text within a code-completion string.
+ *
+ * Each "chunk" within a code-completion string (\c CXCompletionString) is
+ * either a piece of text with a specific "kind" that describes how that text
+ * should be interpreted by the client or is another completion string.
+ */
+enum CXCompletionChunkKind {
+  /**
+   * A code-completion string that describes "optional" text that
+   * could be a part of the template (but is not required).
+   *
+   * The Optional chunk is the only kind of chunk that has a code-completion
+   * string for its representation, which is accessible via
+   * \c clang_getCompletionChunkCompletionString(). The code-completion string
+   * describes an additional part of the template that is completely optional.
+   * For example, optional chunks can be used to describe the placeholders for
+   * arguments that match up with defaulted function parameters, e.g. given:
+   *
+   * \code
+   * void f(int x, float y = 3.14, double z = 2.71828);
+   * \endcode
+   *
+   * The code-completion string for this function would contain:
+   *   - a TypedText chunk for "f".
+   *   - a LeftParen chunk for "(".
+   *   - a Placeholder chunk for "int x"
+   *   - an Optional chunk containing the remaining defaulted arguments, e.g.,
+   *       - a Comma chunk for ","
+   *       - a Placeholder chunk for "float y"
+   *       - an Optional chunk containing the last defaulted argument:
+   *           - a Comma chunk for ","
+   *           - a Placeholder chunk for "double z"
+   *   - a RightParen chunk for ")"
+   *
+   * There are many ways to handle Optional chunks. Two simple approaches are:
+   *   - Completely ignore optional chunks, in which case the template for the
+   *     function "f" would only include the first parameter ("int x").
+   *   - Fully expand all optional chunks, in which case the template for the
+   *     function "f" would have all of the parameters.
+   */
+  CXCompletionChunk_Optional,
+  /**
+   * Text that a user would be expected to type to get this
+   * code-completion result.
+   *
+   * There will be exactly one "typed text" chunk in a semantic string, which
+   * will typically provide the spelling of a keyword or the name of a
+   * declaration that could be used at the current code point. Clients are
+   * expected to filter the code-completion results based on the text in this
+   * chunk.
+   */
+  CXCompletionChunk_TypedText,
+  /**
+   * Text that should be inserted as part of a code-completion result.
+   *
+   * A "text" chunk represents text that is part of the template to be
+   * inserted into user code should this particular code-completion result
+   * be selected.
+   */
+  CXCompletionChunk_Text,
+  /**
+   * Placeholder text that should be replaced by the user.
+   *
+   * A "placeholder" chunk marks a place where the user should insert text
+   * into the code-completion template. For example, placeholders might mark
+   * the function parameters for a function declaration, to indicate that the
+   * user should provide arguments for each of those parameters. The actual
+   * text in a placeholder is a suggestion for the text to display before
+   * the user replaces the placeholder with real code.
+   */
+  CXCompletionChunk_Placeholder,
+  /**
+   * Informative text that should be displayed but never inserted as
+   * part of the template.
+   *
+   * An "informative" chunk contains annotations that can be displayed to
+   * help the user decide whether a particular code-completion result is the
+   * right option, but which is not part of the actual template to be inserted
+   * by code completion.
+   */
+  CXCompletionChunk_Informative,
+  /**
+   * Text that describes the current parameter when code-completion is
+   * referring to function call, message send, or template specialization.
+   *
+   * A "current parameter" chunk occurs when code-completion is providing
+   * information about a parameter corresponding to the argument at the
+   * code-completion point. For example, given a function
+   *
+   * \code
+   * int add(int x, int y);
+   * \endcode
+   *
+   * and the source code \c add(, where the code-completion point is after the
+   * "(", the code-completion string will contain a "current parameter" chunk
+   * for "int x", indicating that the current argument will initialize that
+   * parameter. After typing further, to \c add(17, (where the code-completion
+   * point is after the ","), the code-completion string will contain a
+   * "current parameter" chunk to "int y".
+   */
+  CXCompletionChunk_CurrentParameter,
+  /**
+   * A left parenthesis ('('), used to initiate a function call or
+   * signal the beginning of a function parameter list.
+   */
+  CXCompletionChunk_LeftParen,
+  /**
+   * A right parenthesis (')'), used to finish a function call or
+   * signal the end of a function parameter list.
+   */
+  CXCompletionChunk_RightParen,
+  /**
+   * A left bracket ('[').
+   */
+  CXCompletionChunk_LeftBracket,
+  /**
+   * A right bracket (']').
+   */
+  CXCompletionChunk_RightBracket,
+  /**
+   * A left brace ('{').
+   */
+  CXCompletionChunk_LeftBrace,
+  /**
+   * A right brace ('}').
+   */
+  CXCompletionChunk_RightBrace,
+  /**
+   * A left angle bracket ('<').
+   */
+  CXCompletionChunk_LeftAngle,
+  /**
+   * A right angle bracket ('>').
+   */
+  CXCompletionChunk_RightAngle,
+  /**
+   * A comma separator (',').
+   */
+  CXCompletionChunk_Comma,
+  /**
+   * Text that specifies the result type of a given result.
+   *
+   * This special kind of informative chunk is not meant to be inserted into
+   * the text buffer. Rather, it is meant to illustrate the type that an
+   * expression using the given completion string would have.
+   */
+  CXCompletionChunk_ResultType,
+  /**
+   * A colon (':').
+   */
+  CXCompletionChunk_Colon,
+  /**
+   * A semicolon (';').
+   */
+  CXCompletionChunk_SemiColon,
+  /**
+   * An '=' sign.
+   */
+  CXCompletionChunk_Equal,
+  /**
+   * Horizontal space (' ').
+   */
+  CXCompletionChunk_HorizontalSpace,
+  /**
+   * Vertical space ('\\n'), after which it is generally a good idea to
+   * perform indentation.
+   */
+  CXCompletionChunk_VerticalSpace
+};
+
+/**
+ * Determine the kind of a particular chunk within a completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the kind of the chunk at the index \c chunk_number.
+ */
+CINDEX_LINKAGE enum CXCompletionChunkKind
+clang_getCompletionChunkKind(CXCompletionString completion_string,
+                             unsigned chunk_number);
+
+/**
+ * Retrieve the text associated with a particular chunk within a
+ * completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the text associated with the chunk at index \c chunk_number.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionChunkText(CXCompletionString completion_string,
+                             unsigned chunk_number);
+
+/**
+ * Retrieve the completion string associated with a particular chunk
+ * within a completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the completion string associated with the chunk at index
+ * \c chunk_number.
+ */
+CINDEX_LINKAGE CXCompletionString
+clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
+                                         unsigned chunk_number);
+
+/**
+ * Retrieve the number of chunks in the given code-completion string.
+ */
+CINDEX_LINKAGE unsigned
+clang_getNumCompletionChunks(CXCompletionString completion_string);
+
+/**
+ * Determine the priority of this code completion.
+ *
+ * The priority of a code completion indicates how likely it is that this
+ * particular completion is the completion that the user will select. The
+ * priority is selected by various internal heuristics.
+ *
+ * \param completion_string The completion string to query.
+ *
+ * \returns The priority of this completion string. Smaller values indicate
+ * higher-priority (more likely) completions.
+ */
+CINDEX_LINKAGE unsigned
+clang_getCompletionPriority(CXCompletionString completion_string);
+
+/**
+ * Determine the availability of the entity that this code-completion
+ * string refers to.
+ *
+ * \param completion_string The completion string to query.
+ *
+ * \returns The availability of the completion string.
+ */
+CINDEX_LINKAGE enum CXAvailabilityKind
+clang_getCompletionAvailability(CXCompletionString completion_string);
+
+/**
+ * Retrieve the number of annotations associated with the given
+ * completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \returns the number of annotations associated with the given completion
+ * string.
+ */
+CINDEX_LINKAGE unsigned
+clang_getCompletionNumAnnotations(CXCompletionString completion_string);
+
+/**
+ * Retrieve the annotation associated with the given completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param annotation_number the 0-based index of the annotation of the
+ * completion string.
+ *
+ * \returns annotation string associated with the completion at index
+ * \c annotation_number, or a NULL string if that annotation is not available.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionAnnotation(CXCompletionString completion_string,
+                              unsigned annotation_number);
+
+/**
+ * Retrieve the parent context of the given completion string.
+ *
+ * The parent context of a completion string is the semantic parent of
+ * the declaration (if any) that the code completion represents. For example,
+ * a code completion for an Objective-C method would have the method's class
+ * or protocol as its context.
+ *
+ * \param completion_string The code completion string whose parent is
+ * being queried.
+ *
+ * \param kind DEPRECATED: always set to CXCursor_NotImplemented if non-NULL.
+ *
+ * \returns The name of the completion parent, e.g., "NSObject" if
+ * the completion string represents a method in the NSObject class.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionParent(CXCompletionString completion_string,
+                          enum CXCursorKind *kind);
+
+/**
+ * Retrieve the brief documentation comment attached to the declaration
+ * that corresponds to the given completion string.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionBriefComment(CXCompletionString completion_string);
+
+/**
+ * Retrieve a completion string for an arbitrary declaration or macro
+ * definition cursor.
+ *
+ * \param cursor The cursor to query.
+ *
+ * \returns A non-context-sensitive completion string for declaration and macro
+ * definition cursors, or NULL for other kinds of cursors.
+ */
+CINDEX_LINKAGE CXCompletionString
+clang_getCursorCompletionString(CXCursor cursor);
+
+/**
+ * Contains the results of code-completion.
+ *
+ * This data structure contains the results of code completion, as
+ * produced by \c clang_codeCompleteAt(). Its contents must be freed by
+ * \c clang_disposeCodeCompleteResults.
+ */
+typedef struct {
+  /**
+   * The code-completion results.
+   */
+  CXCompletionResult *Results;
+
+  /**
+   * The number of code-completion results stored in the
+   * \c Results array.
+   */
+  unsigned NumResults;
+} CXCodeCompleteResults;
+
+/**
+ * Retrieve the number of fix-its for the given completion index.
+ *
+ * Calling this makes sense only if CXCodeComplete_IncludeCompletionsWithFixIts
+ * option was set.
+ *
+ * \param results The structure keeping all completion results
+ *
+ * \param completion_index The index of the completion
+ *
+ * \return The number of fix-its which must be applied before the completion at
+ * completion_index can be applied
+ */
+CINDEX_LINKAGE unsigned
+clang_getCompletionNumFixIts(CXCodeCompleteResults *results,
+                             unsigned completion_index);
+
+/**
+ * Fix-its that *must* be applied before inserting the text for the
+ * corresponding completion.
+ *
+ * By default, clang_codeCompleteAt() only returns completions with empty
+ * fix-its. Extra completions with non-empty fix-its should be explicitly
+ * requested by setting CXCodeComplete_IncludeCompletionsWithFixIts.
+ *
+ * For the clients to be able to compute position of the cursor after applying
+ * fix-its, the following conditions are guaranteed to hold for
+ * replacement_range of the stored fix-its:
+ *  - Ranges in the fix-its are guaranteed to never contain the completion
+ *  point (or identifier under completion point, if any) inside them, except
+ *  at the start or at the end of the range.
+ *  - If a fix-it range starts or ends with completion point (or starts or
+ *  ends after the identifier under completion point), it will contain at
+ *  least one character. It allows to unambiguously recompute completion
+ *  point after applying the fix-it.
+ *
+ * The intuition is that provided fix-its change code around the identifier we
+ * complete, but are not allowed to touch the identifier itself or the
+ * completion point. One example of completions with corrections are the ones
+ * replacing '.' with '->' and vice versa:
+ *
+ * std::unique_ptr<std::vector<int>> vec_ptr;
+ * In 'vec_ptr.^', one of the completions is 'push_back', it requires
+ * replacing '.' with '->'.
+ * In 'vec_ptr->^', one of the completions is 'release', it requires
+ * replacing '->' with '.'.
+ *
+ * \param results The structure keeping all completion results
+ *
+ * \param completion_index The index of the completion
+ *
+ * \param fixit_index The index of the fix-it for the completion at
+ * completion_index
+ *
+ * \param replacement_range The fix-it range that must be replaced before the
+ * completion at completion_index can be applied
+ *
+ * \returns The fix-it string that must replace the code at replacement_range
+ * before the completion at completion_index can be applied
+ */
+CINDEX_LINKAGE CXString clang_getCompletionFixIt(
+    CXCodeCompleteResults *results, unsigned completion_index,
+    unsigned fixit_index, CXSourceRange *replacement_range);
+
+/**
+ * Flags that can be passed to \c clang_codeCompleteAt() to
+ * modify its behavior.
+ *
+ * The enumerators in this enumeration can be bitwise-OR'd together to
+ * provide multiple options to \c clang_codeCompleteAt().
+ */
+enum CXCodeComplete_Flags {
+  /**
+   * Whether to include macros within the set of code
+   * completions returned.
+   */
+  CXCodeComplete_IncludeMacros = 0x01,
+
+  /**
+   * Whether to include code patterns for language constructs
+   * within the set of code completions, e.g., for loops.
+   */
+  CXCodeComplete_IncludeCodePatterns = 0x02,
+
+  /**
+   * Whether to include brief documentation within the set of code
+   * completions returned.
+   */
+  CXCodeComplete_IncludeBriefComments = 0x04,
+
+  /**
+   * Whether to speed up completion by omitting top- or namespace-level entities
+   * defined in the preamble. There's no guarantee any particular entity is
+   * omitted. This may be useful if the headers are indexed externally.
+   */
+  CXCodeComplete_SkipPreamble = 0x08,
+
+  /**
+   * Whether to include completions with small
+   * fix-its, e.g. change '.' to '->' on member access, etc.
+   */
+  CXCodeComplete_IncludeCompletionsWithFixIts = 0x10
+};
+
+/**
+ * Bits that represent the context under which completion is occurring.
+ *
+ * The enumerators in this enumeration may be bitwise-OR'd together if multiple
+ * contexts are occurring simultaneously.
+ */
+enum CXCompletionContext {
+  /**
+   * The context for completions is unexposed, as only Clang results
+   * should be included. (This is equivalent to having no context bits set.)
+   */
+  CXCompletionContext_Unexposed = 0,
+
+  /**
+   * Completions for any possible type should be included in the results.
+   */
+  CXCompletionContext_AnyType = 1 << 0,
+
+  /**
+   * Completions for any possible value (variables, function calls, etc.)
+   * should be included in the results.
+   */
+  CXCompletionContext_AnyValue = 1 << 1,
+  /**
+   * Completions for values that resolve to an Objective-C object should
+   * be included in the results.
+   */
+  CXCompletionContext_ObjCObjectValue = 1 << 2,
+  /**
+   * Completions for values that resolve to an Objective-C selector
+   * should be included in the results.
+   */
+  CXCompletionContext_ObjCSelectorValue = 1 << 3,
+  /**
+   * Completions for values that resolve to a C++ class type should be
+   * included in the results.
+   */
+  CXCompletionContext_CXXClassTypeValue = 1 << 4,
+
+  /**
+   * Completions for fields of the member being accessed using the dot
+   * operator should be included in the results.
+   */
+  CXCompletionContext_DotMemberAccess = 1 << 5,
+  /**
+   * Completions for fields of the member being accessed using the arrow
+   * operator should be included in the results.
+   */
+  CXCompletionContext_ArrowMemberAccess = 1 << 6,
+  /**
+   * Completions for properties of the Objective-C object being accessed
+   * using the dot operator should be included in the results.
+   */
+  CXCompletionContext_ObjCPropertyAccess = 1 << 7,
+
+  /**
+   * Completions for enum tags should be included in the results.
+   */
+  CXCompletionContext_EnumTag = 1 << 8,
+  /**
+   * Completions for union tags should be included in the results.
+   */
+  CXCompletionContext_UnionTag = 1 << 9,
+  /**
+   * Completions for struct tags should be included in the results.
+   */
+  CXCompletionContext_StructTag = 1 << 10,
+
+  /**
+   * Completions for C++ class names should be included in the results.
+   */
+  CXCompletionContext_ClassTag = 1 << 11,
+  /**
+   * Completions for C++ namespaces and namespace aliases should be
+   * included in the results.
+   */
+  CXCompletionContext_Namespace = 1 << 12,
+  /**
+   * Completions for C++ nested name specifiers should be included in
+   * the results.
+   */
+  CXCompletionContext_NestedNameSpecifier = 1 << 13,
+
+  /**
+   * Completions for Objective-C interfaces (classes) should be included
+   * in the results.
+   */
+  CXCompletionContext_ObjCInterface = 1 << 14,
+  /**
+   * Completions for Objective-C protocols should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCProtocol = 1 << 15,
+  /**
+   * Completions for Objective-C categories should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCCategory = 1 << 16,
+  /**
+   * Completions for Objective-C instance messages should be included
+   * in the results.
+   */
+  CXCompletionContext_ObjCInstanceMessage = 1 << 17,
+  /**
+   * Completions for Objective-C class messages should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCClassMessage = 1 << 18,
+  /**
+   * Completions for Objective-C selector names should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCSelectorName = 1 << 19,
+
+  /**
+   * Completions for preprocessor macro names should be included in
+   * the results.
+   */
+  CXCompletionContext_MacroName = 1 << 20,
+
+  /**
+   * Natural language completions should be included in the results.
+   */
+  CXCompletionContext_NaturalLanguage = 1 << 21,
+
+  /**
+   * #include file completions should be included in the results.
+   */
+  CXCompletionContext_IncludedFile = 1 << 22,
+
+  /**
+   * The current context is unknown, so set all contexts.
+   */
+  CXCompletionContext_Unknown = ((1 << 23) - 1)
+};
+
+/**
+ * Returns a default set of code-completion options that can be
+ * passed to\c clang_codeCompleteAt().
+ */
+CINDEX_LINKAGE unsigned clang_defaultCodeCompleteOptions(void);
+
+/**
+ * Perform code completion at a given location in a translation unit.
+ *
+ * This function performs code completion at a particular file, line, and
+ * column within source code, providing results that suggest potential
+ * code snippets based on the context of the completion. The basic model
+ * for code completion is that Clang will parse a complete source file,
+ * performing syntax checking up to the location where code-completion has
+ * been requested. At that point, a special code-completion token is passed
+ * to the parser, which recognizes this token and determines, based on the
+ * current location in the C/Objective-C/C++ grammar and the state of
+ * semantic analysis, what completions to provide. These completions are
+ * returned via a new \c CXCodeCompleteResults structure.
+ *
+ * Code completion itself is meant to be triggered by the client when the
+ * user types punctuation characters or whitespace, at which point the
+ * code-completion location will coincide with the cursor. For example, if \c p
+ * is a pointer, code-completion might be triggered after the "-" and then
+ * after the ">" in \c p->. When the code-completion location is after the ">",
+ * the completion results will provide, e.g., the members of the struct that
+ * "p" points to. The client is responsible for placing the cursor at the
+ * beginning of the token currently being typed, then filtering the results
+ * based on the contents of the token. For example, when code-completing for
+ * the expression \c p->get, the client should provide the location just after
+ * the ">" (e.g., pointing at the "g") to this code-completion hook. Then, the
+ * client can filter the results based on the current token text ("get"), only
+ * showing those results that start with "get". The intent of this interface
+ * is to separate the relatively high-latency acquisition of code-completion
+ * results from the filtering of results on a per-character basis, which must
+ * have a lower latency.
+ *
+ * \param TU The translation unit in which code-completion should
+ * occur. The source files for this translation unit need not be
+ * completely up-to-date (and the contents of those source files may
+ * be overridden via \p unsaved_files). Cursors referring into the
+ * translation unit may be invalidated by this invocation.
+ *
+ * \param complete_filename The name of the source file where code
+ * completion should be performed. This filename may be any file
+ * included in the translation unit.
+ *
+ * \param complete_line The line at which code-completion should occur.
+ *
+ * \param complete_column The column at which code-completion should occur.
+ * Note that the column should point just after the syntactic construct that
+ * initiated code completion, and not in the middle of a lexical token.
+ *
+ * \param unsaved_files the Files that have not yet been saved to disk
+ * but may be required for parsing or code completion, including the
+ * contents of those files.  The contents and name of these files (as
+ * specified by CXUnsavedFile) are copied when necessary, so the
+ * client only needs to guarantee their validity until the call to
+ * this function returns.
+ *
+ * \param num_unsaved_files The number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param options Extra options that control the behavior of code
+ * completion, expressed as a bitwise OR of the enumerators of the
+ * CXCodeComplete_Flags enumeration. The
+ * \c clang_defaultCodeCompleteOptions() function returns a default set
+ * of code-completion options.
+ *
+ * \returns If successful, a new \c CXCodeCompleteResults structure
+ * containing code-completion results, which should eventually be
+ * freed with \c clang_disposeCodeCompleteResults(). If code
+ * completion fails, returns NULL.
+ */
+CINDEX_LINKAGE
+CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
+                                            const char *complete_filename,
+                                            unsigned complete_line,
+                                            unsigned complete_column,
+                                            struct CXUnsavedFile *unsaved_files,
+                                            unsigned num_unsaved_files,
+                                            unsigned options);
+
+/**
+ * Sort the code-completion results in case-insensitive alphabetical
+ * order.
+ *
+ * \param Results The set of results to sort.
+ * \param NumResults The number of results in \p Results.
+ */
+CINDEX_LINKAGE
+void clang_sortCodeCompletionResults(CXCompletionResult *Results,
+                                     unsigned NumResults);
+
+/**
+ * Free the given set of code-completion results.
+ */
+CINDEX_LINKAGE
+void clang_disposeCodeCompleteResults(CXCodeCompleteResults *Results);
+
+/**
+ * Determine the number of diagnostics produced prior to the
+ * location where code completion was performed.
+ */
+CINDEX_LINKAGE
+unsigned clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *Results);
+
+/**
+ * Retrieve a diagnostic associated with the given code completion.
+ *
+ * \param Results the code completion results to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE
+CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results,
+                                             unsigned Index);
+
+/**
+ * Determines what completions are appropriate for the context
+ * the given code completion.
+ *
+ * \param Results the code completion results to query
+ *
+ * \returns the kinds of completions that are appropriate for use
+ * along with the given code completion results.
+ */
+CINDEX_LINKAGE
+unsigned long long clang_codeCompleteGetContexts(
+                                                CXCodeCompleteResults *Results);
+
+/**
+ * Returns the cursor kind for the container for the current code
+ * completion context. The container is only guaranteed to be set for
+ * contexts where a container exists (i.e. member accesses or Objective-C
+ * message sends); if there is not a container, this function will return
+ * CXCursor_InvalidCode.
+ *
+ * \param Results the code completion results to query
+ *
+ * \param IsIncomplete on return, this value will be false if Clang has complete
+ * information about the container. If Clang does not have complete
+ * information, this value will be true.
+ *
+ * \returns the container kind, or CXCursor_InvalidCode if there is not a
+ * container
+ */
+CINDEX_LINKAGE
+enum CXCursorKind clang_codeCompleteGetContainerKind(
+                                                 CXCodeCompleteResults *Results,
+                                                     unsigned *IsIncomplete);
+
+/**
+ * Returns the USR for the container for the current code completion
+ * context. If there is not a container for the current context, this
+ * function will return the empty string.
+ *
+ * \param Results the code completion results to query
+ *
+ * \returns the USR for the container
+ */
+CINDEX_LINKAGE
+CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *Results);
+
+/**
+ * Returns the currently-entered selector for an Objective-C message
+ * send, formatted like "initWithFoo:bar:". Only guaranteed to return a
+ * non-empty string for CXCompletionContext_ObjCInstanceMessage and
+ * CXCompletionContext_ObjCClassMessage.
+ *
+ * \param Results the code completion results to query
+ *
+ * \returns the selector (or partial selector) that has been entered thus far
+ * for an Objective-C message send.
+ */
+CINDEX_LINKAGE
+CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_MISC Miscellaneous utility functions
+ *
+ * @{
+ */
+
+/**
+ * Return a version string, suitable for showing to a user, but not
+ *        intended to be parsed (the format is not guaranteed to be stable).
+ */
+CINDEX_LINKAGE CXString clang_getClangVersion(void);
+
+/**
+ * Enable/disable crash recovery.
+ *
+ * \param isEnabled Flag to indicate if crash recovery is enabled.  A non-zero
+ *        value enables crash recovery, while 0 disables it.
+ */
+CINDEX_LINKAGE void clang_toggleCrashRecovery(unsigned isEnabled);
+
+ /**
+  * Visitor invoked for each file in a translation unit
+  *        (used with clang_getInclusions()).
+  *
+  * This visitor function will be invoked by clang_getInclusions() for each
+  * file included (either at the top-level or by \#include directives) within
+  * a translation unit.  The first argument is the file being included, and
+  * the second and third arguments provide the inclusion stack.  The
+  * array is sorted in order of immediate inclusion.  For example,
+  * the first element refers to the location that included 'included_file'.
+  */
+typedef void (*CXInclusionVisitor)(CXFile included_file,
+                                   CXSourceLocation* inclusion_stack,
+                                   unsigned include_len,
+                                   CXClientData client_data);
+
+/**
+ * Visit the set of preprocessor inclusions in a translation unit.
+ *   The visitor function is called with the provided data for every included
+ *   file.  This does not include headers included by the PCH file (unless one
+ *   is inspecting the inclusions in the PCH file itself).
+ */
+CINDEX_LINKAGE void clang_getInclusions(CXTranslationUnit tu,
+                                        CXInclusionVisitor visitor,
+                                        CXClientData client_data);
+
+typedef enum {
+  CXEval_Int = 1 ,
+  CXEval_Float = 2,
+  CXEval_ObjCStrLiteral = 3,
+  CXEval_StrLiteral = 4,
+  CXEval_CFStr = 5,
+  CXEval_Other = 6,
+
+  CXEval_UnExposed = 0
+
+} CXEvalResultKind ;
+
+/**
+ * Evaluation result of a cursor
+ */
+typedef void * CXEvalResult;
+
+/**
+ * If cursor is a statement declaration tries to evaluate the
+ * statement and if its variable, tries to evaluate its initializer,
+ * into its corresponding type.
+ */
+CINDEX_LINKAGE CXEvalResult clang_Cursor_Evaluate(CXCursor C);
+
+/**
+ * Returns the kind of the evaluated result.
+ */
+CINDEX_LINKAGE CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E);
+
+/**
+ * Returns the evaluation result as integer if the
+ * kind is Int.
+ */
+CINDEX_LINKAGE int clang_EvalResult_getAsInt(CXEvalResult E);
+
+/**
+ * Returns the evaluation result as a long long integer if the
+ * kind is Int. This prevents overflows that may happen if the result is
+ * returned with clang_EvalResult_getAsInt.
+ */
+CINDEX_LINKAGE long long clang_EvalResult_getAsLongLong(CXEvalResult E);
+
+/**
+ * Returns a non-zero value if the kind is Int and the evaluation
+ * result resulted in an unsigned integer.
+ */
+CINDEX_LINKAGE unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E);
+
+/**
+ * Returns the evaluation result as an unsigned integer if
+ * the kind is Int and clang_EvalResult_isUnsignedInt is non-zero.
+ */
+CINDEX_LINKAGE unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E);
+
+/**
+ * Returns the evaluation result as double if the
+ * kind is double.
+ */
+CINDEX_LINKAGE double clang_EvalResult_getAsDouble(CXEvalResult E);
+
+/**
+ * Returns the evaluation result as a constant string if the
+ * kind is other than Int or float. User must not free this pointer,
+ * instead call clang_EvalResult_dispose on the CXEvalResult returned
+ * by clang_Cursor_Evaluate.
+ */
+CINDEX_LINKAGE const char* clang_EvalResult_getAsStr(CXEvalResult E);
+
+/**
+ * Disposes the created Eval memory.
+ */
+CINDEX_LINKAGE void clang_EvalResult_dispose(CXEvalResult E);
+/**
+ * @}
+ */
+
+/** \defgroup CINDEX_REMAPPING Remapping functions
+ *
+ * @{
+ */
+
+/**
+ * A remapping of original source files and their translated files.
+ */
+typedef void *CXRemapping;
+
+/**
+ * Retrieve a remapping.
+ *
+ * \param path the path that contains metadata about remappings.
+ *
+ * \returns the requested remapping. This remapping must be freed
+ * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred.
+ */
+CINDEX_LINKAGE CXRemapping clang_getRemappings(const char *path);
+
+/**
+ * Retrieve a remapping.
+ *
+ * \param filePaths pointer to an array of file paths containing remapping info.
+ *
+ * \param numFiles number of file paths.
+ *
+ * \returns the requested remapping. This remapping must be freed
+ * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred.
+ */
+CINDEX_LINKAGE
+CXRemapping clang_getRemappingsFromFileList(const char **filePaths,
+                                            unsigned numFiles);
+
+/**
+ * Determine the number of remappings.
+ */
+CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping);
+
+/**
+ * Get the original and the associated filename from the remapping.
+ *
+ * \param original If non-NULL, will be set to the original filename.
+ *
+ * \param transformed If non-NULL, will be set to the filename that the original
+ * is associated with.
+ */
+CINDEX_LINKAGE void clang_remap_getFilenames(CXRemapping, unsigned index,
+                                     CXString *original, CXString *transformed);
+
+/**
+ * Dispose the remapping.
+ */
+CINDEX_LINKAGE void clang_remap_dispose(CXRemapping);
+
+/**
+ * @}
+ */
+
+/** \defgroup CINDEX_HIGH Higher level API functions
+ *
+ * @{
+ */
+
+enum CXVisitorResult {
+  CXVisit_Break,
+  CXVisit_Continue
+};
+
+typedef struct CXCursorAndRangeVisitor {
+  void *context;
+  enum CXVisitorResult (*visit)(void *context, CXCursor, CXSourceRange);
+} CXCursorAndRangeVisitor;
+
+typedef enum {
+  /**
+   * Function returned successfully.
+   */
+  CXResult_Success = 0,
+  /**
+   * One of the parameters was invalid for the function.
+   */
+  CXResult_Invalid = 1,
+  /**
+   * The function was terminated by a callback (e.g. it returned
+   * CXVisit_Break)
+   */
+  CXResult_VisitBreak = 2
+
+} CXResult;
+
+/**
+ * Find references of a declaration in a specific file.
+ *
+ * \param cursor pointing to a declaration or a reference of one.
+ *
+ * \param file to search for references.
+ *
+ * \param visitor callback that will receive pairs of CXCursor/CXSourceRange for
+ * each reference found.
+ * The CXSourceRange will point inside the file; if the reference is inside
+ * a macro (and not a macro argument) the CXSourceRange will be invalid.
+ *
+ * \returns one of the CXResult enumerators.
+ */
+CINDEX_LINKAGE CXResult clang_findReferencesInFile(CXCursor cursor, CXFile file,
+                                               CXCursorAndRangeVisitor visitor);
+
+/**
+ * Find #import/#include directives in a specific file.
+ *
+ * \param TU translation unit containing the file to query.
+ *
+ * \param file to search for #import/#include directives.
+ *
+ * \param visitor callback that will receive pairs of CXCursor/CXSourceRange for
+ * each directive found.
+ *
+ * \returns one of the CXResult enumerators.
+ */
+CINDEX_LINKAGE CXResult clang_findIncludesInFile(CXTranslationUnit TU,
+                                                 CXFile file,
+                                              CXCursorAndRangeVisitor visitor);
+
+#ifdef __has_feature
+#  if __has_feature(blocks)
+
+typedef enum CXVisitorResult
+    (^CXCursorAndRangeVisitorBlock)(CXCursor, CXSourceRange);
+
+CINDEX_LINKAGE
+CXResult clang_findReferencesInFileWithBlock(CXCursor, CXFile,
+                                             CXCursorAndRangeVisitorBlock);
+
+CINDEX_LINKAGE
+CXResult clang_findIncludesInFileWithBlock(CXTranslationUnit, CXFile,
+                                           CXCursorAndRangeVisitorBlock);
+
+#  endif
+#endif
+
+/**
+ * The client's data object that is associated with a CXFile.
+ */
+typedef void *CXIdxClientFile;
+
+/**
+ * The client's data object that is associated with a semantic entity.
+ */
+typedef void *CXIdxClientEntity;
+
+/**
+ * The client's data object that is associated with a semantic container
+ * of entities.
+ */
+typedef void *CXIdxClientContainer;
+
+/**
+ * The client's data object that is associated with an AST file (PCH
+ * or module).
+ */
+typedef void *CXIdxClientASTFile;
+
+/**
+ * Source location passed to index callbacks.
+ */
+typedef struct {
+  void *ptr_data[2];
+  unsigned int_data;
+} CXIdxLoc;
+
+/**
+ * Data for ppIncludedFile callback.
+ */
+typedef struct {
+  /**
+   * Location of '#' in the \#include/\#import directive.
+   */
+  CXIdxLoc hashLoc;
+  /**
+   * Filename as written in the \#include/\#import directive.
+   */
+  const char *filename;
+  /**
+   * The actual file that the \#include/\#import directive resolved to.
+   */
+  CXFile file;
+  int isImport;
+  int isAngled;
+  /**
+   * Non-zero if the directive was automatically turned into a module
+   * import.
+   */
+  int isModuleImport;
+} CXIdxIncludedFileInfo;
+
+/**
+ * Data for IndexerCallbacks#importedASTFile.
+ */
+typedef struct {
+  /**
+   * Top level AST file containing the imported PCH, module or submodule.
+   */
+  CXFile file;
+  /**
+   * The imported module or NULL if the AST file is a PCH.
+   */
+  CXModule module;
+  /**
+   * Location where the file is imported. Applicable only for modules.
+   */
+  CXIdxLoc loc;
+  /**
+   * Non-zero if an inclusion directive was automatically turned into
+   * a module import. Applicable only for modules.
+   */
+  int isImplicit;
+
+} CXIdxImportedASTFileInfo;
+
+typedef enum {
+  CXIdxEntity_Unexposed     = 0,
+  CXIdxEntity_Typedef       = 1,
+  CXIdxEntity_Function      = 2,
+  CXIdxEntity_Variable      = 3,
+  CXIdxEntity_Field         = 4,
+  CXIdxEntity_EnumConstant  = 5,
+
+  CXIdxEntity_ObjCClass     = 6,
+  CXIdxEntity_ObjCProtocol  = 7,
+  CXIdxEntity_ObjCCategory  = 8,
+
+  CXIdxEntity_ObjCInstanceMethod = 9,
+  CXIdxEntity_ObjCClassMethod    = 10,
+  CXIdxEntity_ObjCProperty  = 11,
+  CXIdxEntity_ObjCIvar      = 12,
+
+  CXIdxEntity_Enum          = 13,
+  CXIdxEntity_Struct        = 14,
+  CXIdxEntity_Union         = 15,
+
+  CXIdxEntity_CXXClass              = 16,
+  CXIdxEntity_CXXNamespace          = 17,
+  CXIdxEntity_CXXNamespaceAlias     = 18,
+  CXIdxEntity_CXXStaticVariable     = 19,
+  CXIdxEntity_CXXStaticMethod       = 20,
+  CXIdxEntity_CXXInstanceMethod     = 21,
+  CXIdxEntity_CXXConstructor        = 22,
+  CXIdxEntity_CXXDestructor         = 23,
+  CXIdxEntity_CXXConversionFunction = 24,
+  CXIdxEntity_CXXTypeAlias          = 25,
+  CXIdxEntity_CXXInterface          = 26
+
+} CXIdxEntityKind;
+
+typedef enum {
+  CXIdxEntityLang_None = 0,
+  CXIdxEntityLang_C    = 1,
+  CXIdxEntityLang_ObjC = 2,
+  CXIdxEntityLang_CXX  = 3,
+  CXIdxEntityLang_Swift  = 4
+} CXIdxEntityLanguage;
+
+/**
+ * Extra C++ template information for an entity. This can apply to:
+ * CXIdxEntity_Function
+ * CXIdxEntity_CXXClass
+ * CXIdxEntity_CXXStaticMethod
+ * CXIdxEntity_CXXInstanceMethod
+ * CXIdxEntity_CXXConstructor
+ * CXIdxEntity_CXXConversionFunction
+ * CXIdxEntity_CXXTypeAlias
+ */
+typedef enum {
+  CXIdxEntity_NonTemplate   = 0,
+  CXIdxEntity_Template      = 1,
+  CXIdxEntity_TemplatePartialSpecialization = 2,
+  CXIdxEntity_TemplateSpecialization = 3
+} CXIdxEntityCXXTemplateKind;
+
+typedef enum {
+  CXIdxAttr_Unexposed     = 0,
+  CXIdxAttr_IBAction      = 1,
+  CXIdxAttr_IBOutlet      = 2,
+  CXIdxAttr_IBOutletCollection = 3
+} CXIdxAttrKind;
+
+typedef struct {
+  CXIdxAttrKind kind;
+  CXCursor cursor;
+  CXIdxLoc loc;
+} CXIdxAttrInfo;
+
+typedef struct {
+  CXIdxEntityKind kind;
+  CXIdxEntityCXXTemplateKind templateKind;
+  CXIdxEntityLanguage lang;
+  const char *name;
+  const char *USR;
+  CXCursor cursor;
+  const CXIdxAttrInfo *const *attributes;
+  unsigned numAttributes;
+} CXIdxEntityInfo;
+
+typedef struct {
+  CXCursor cursor;
+} CXIdxContainerInfo;
+
+typedef struct {
+  const CXIdxAttrInfo *attrInfo;
+  const CXIdxEntityInfo *objcClass;
+  CXCursor classCursor;
+  CXIdxLoc classLoc;
+} CXIdxIBOutletCollectionAttrInfo;
+
+typedef enum {
+  CXIdxDeclFlag_Skipped = 0x1
+} CXIdxDeclInfoFlags;
+
+typedef struct {
+  const CXIdxEntityInfo *entityInfo;
+  CXCursor cursor;
+  CXIdxLoc loc;
+  const CXIdxContainerInfo *semanticContainer;
+  /**
+   * Generally same as #semanticContainer but can be different in
+   * cases like out-of-line C++ member functions.
+   */
+  const CXIdxContainerInfo *lexicalContainer;
+  int isRedeclaration;
+  int isDefinition;
+  int isContainer;
+  const CXIdxContainerInfo *declAsContainer;
+  /**
+   * Whether the declaration exists in code or was created implicitly
+   * by the compiler, e.g. implicit Objective-C methods for properties.
+   */
+  int isImplicit;
+  const CXIdxAttrInfo *const *attributes;
+  unsigned numAttributes;
+
+  unsigned flags;
+
+} CXIdxDeclInfo;
+
+typedef enum {
+  CXIdxObjCContainer_ForwardRef = 0,
+  CXIdxObjCContainer_Interface = 1,
+  CXIdxObjCContainer_Implementation = 2
+} CXIdxObjCContainerKind;
+
+typedef struct {
+  const CXIdxDeclInfo *declInfo;
+  CXIdxObjCContainerKind kind;
+} CXIdxObjCContainerDeclInfo;
+
+typedef struct {
+  const CXIdxEntityInfo *base;
+  CXCursor cursor;
+  CXIdxLoc loc;
+} CXIdxBaseClassInfo;
+
+typedef struct {
+  const CXIdxEntityInfo *protocol;
+  CXCursor cursor;
+  CXIdxLoc loc;
+} CXIdxObjCProtocolRefInfo;
+
+typedef struct {
+  const CXIdxObjCProtocolRefInfo *const *protocols;
+  unsigned numProtocols;
+} CXIdxObjCProtocolRefListInfo;
+
+typedef struct {
+  const CXIdxObjCContainerDeclInfo *containerInfo;
+  const CXIdxBaseClassInfo *superInfo;
+  const CXIdxObjCProtocolRefListInfo *protocols;
+} CXIdxObjCInterfaceDeclInfo;
+
+typedef struct {
+  const CXIdxObjCContainerDeclInfo *containerInfo;
+  const CXIdxEntityInfo *objcClass;
+  CXCursor classCursor;
+  CXIdxLoc classLoc;
+  const CXIdxObjCProtocolRefListInfo *protocols;
+} CXIdxObjCCategoryDeclInfo;
+
+typedef struct {
+  const CXIdxDeclInfo *declInfo;
+  const CXIdxEntityInfo *getter;
+  const CXIdxEntityInfo *setter;
+} CXIdxObjCPropertyDeclInfo;
+
+typedef struct {
+  const CXIdxDeclInfo *declInfo;
+  const CXIdxBaseClassInfo *const *bases;
+  unsigned numBases;
+} CXIdxCXXClassDeclInfo;
+
+/**
+ * Data for IndexerCallbacks#indexEntityReference.
+ *
+ * This may be deprecated in a future version as this duplicates
+ * the \c CXSymbolRole_Implicit bit in \c CXSymbolRole.
+ */
+typedef enum {
+  /**
+   * The entity is referenced directly in user's code.
+   */
+  CXIdxEntityRef_Direct = 1,
+  /**
+   * An implicit reference, e.g. a reference of an Objective-C method
+   * via the dot syntax.
+   */
+  CXIdxEntityRef_Implicit = 2
+} CXIdxEntityRefKind;
+
+/**
+ * Roles that are attributed to symbol occurrences.
+ *
+ * Internal: this currently mirrors low 9 bits of clang::index::SymbolRole with
+ * higher bits zeroed. These high bits may be exposed in the future.
+ */
+typedef enum {
+  CXSymbolRole_None = 0,
+  CXSymbolRole_Declaration = 1 << 0,
+  CXSymbolRole_Definition = 1 << 1,
+  CXSymbolRole_Reference = 1 << 2,
+  CXSymbolRole_Read = 1 << 3,
+  CXSymbolRole_Write = 1 << 4,
+  CXSymbolRole_Call = 1 << 5,
+  CXSymbolRole_Dynamic = 1 << 6,
+  CXSymbolRole_AddressOf = 1 << 7,
+  CXSymbolRole_Implicit = 1 << 8
+} CXSymbolRole;
+
+/**
+ * Data for IndexerCallbacks#indexEntityReference.
+ */
+typedef struct {
+  CXIdxEntityRefKind kind;
+  /**
+   * Reference cursor.
+   */
+  CXCursor cursor;
+  CXIdxLoc loc;
+  /**
+   * The entity that gets referenced.
+   */
+  const CXIdxEntityInfo *referencedEntity;
+  /**
+   * Immediate "parent" of the reference. For example:
+   *
+   * \code
+   * Foo *var;
+   * \endcode
+   *
+   * The parent of reference of type 'Foo' is the variable 'var'.
+   * For references inside statement bodies of functions/methods,
+   * the parentEntity will be the function/method.
+   */
+  const CXIdxEntityInfo *parentEntity;
+  /**
+   * Lexical container context of the reference.
+   */
+  const CXIdxContainerInfo *container;
+  /**
+   * Sets of symbol roles of the reference.
+   */
+  CXSymbolRole role;
+} CXIdxEntityRefInfo;
+
+/**
+ * A group of callbacks used by #clang_indexSourceFile and
+ * #clang_indexTranslationUnit.
+ */
+typedef struct {
+  /**
+   * Called periodically to check whether indexing should be aborted.
+   * Should return 0 to continue, and non-zero to abort.
+   */
+  int (*abortQuery)(CXClientData client_data, void *reserved);
+
+  /**
+   * Called at the end of indexing; passes the complete diagnostic set.
+   */
+  void (*diagnostic)(CXClientData client_data,
+                     CXDiagnosticSet, void *reserved);
+
+  CXIdxClientFile (*enteredMainFile)(CXClientData client_data,
+                                     CXFile mainFile, void *reserved);
+
+  /**
+   * Called when a file gets \#included/\#imported.
+   */
+  CXIdxClientFile (*ppIncludedFile)(CXClientData client_data,
+                                    const CXIdxIncludedFileInfo *);
+
+  /**
+   * Called when a AST file (PCH or module) gets imported.
+   *
+   * AST files will not get indexed (there will not be callbacks to index all
+   * the entities in an AST file). The recommended action is that, if the AST
+   * file is not already indexed, to initiate a new indexing job specific to
+   * the AST file.
+   */
+  CXIdxClientASTFile (*importedASTFile)(CXClientData client_data,
+                                        const CXIdxImportedASTFileInfo *);
+
+  /**
+   * Called at the beginning of indexing a translation unit.
+   */
+  CXIdxClientContainer (*startedTranslationUnit)(CXClientData client_data,
+                                                 void *reserved);
+
+  void (*indexDeclaration)(CXClientData client_data,
+                           const CXIdxDeclInfo *);
+
+  /**
+   * Called to index a reference of an entity.
+   */
+  void (*indexEntityReference)(CXClientData client_data,
+                               const CXIdxEntityRefInfo *);
+
+} IndexerCallbacks;
+
+CINDEX_LINKAGE int clang_index_isEntityObjCContainerKind(CXIdxEntityKind);
+CINDEX_LINKAGE const CXIdxObjCContainerDeclInfo *
+clang_index_getObjCContainerDeclInfo(const CXIdxDeclInfo *);
+
+CINDEX_LINKAGE const CXIdxObjCInterfaceDeclInfo *
+clang_index_getObjCInterfaceDeclInfo(const CXIdxDeclInfo *);
+
+CINDEX_LINKAGE
+const CXIdxObjCCategoryDeclInfo *
+clang_index_getObjCCategoryDeclInfo(const CXIdxDeclInfo *);
+
+CINDEX_LINKAGE const CXIdxObjCProtocolRefListInfo *
+clang_index_getObjCProtocolRefListInfo(const CXIdxDeclInfo *);
+
+CINDEX_LINKAGE const CXIdxObjCPropertyDeclInfo *
+clang_index_getObjCPropertyDeclInfo(const CXIdxDeclInfo *);
+
+CINDEX_LINKAGE const CXIdxIBOutletCollectionAttrInfo *
+clang_index_getIBOutletCollectionAttrInfo(const CXIdxAttrInfo *);
+
+CINDEX_LINKAGE const CXIdxCXXClassDeclInfo *
+clang_index_getCXXClassDeclInfo(const CXIdxDeclInfo *);
+
+/**
+ * For retrieving a custom CXIdxClientContainer attached to a
+ * container.
+ */
+CINDEX_LINKAGE CXIdxClientContainer
+clang_index_getClientContainer(const CXIdxContainerInfo *);
+
+/**
+ * For setting a custom CXIdxClientContainer attached to a
+ * container.
+ */
+CINDEX_LINKAGE void
+clang_index_setClientContainer(const CXIdxContainerInfo *,CXIdxClientContainer);
+
+/**
+ * For retrieving a custom CXIdxClientEntity attached to an entity.
+ */
+CINDEX_LINKAGE CXIdxClientEntity
+clang_index_getClientEntity(const CXIdxEntityInfo *);
+
+/**
+ * For setting a custom CXIdxClientEntity attached to an entity.
+ */
+CINDEX_LINKAGE void
+clang_index_setClientEntity(const CXIdxEntityInfo *, CXIdxClientEntity);
+
+/**
+ * An indexing action/session, to be applied to one or multiple
+ * translation units.
+ */
+typedef void *CXIndexAction;
+
+/**
+ * An indexing action/session, to be applied to one or multiple
+ * translation units.
+ *
+ * \param CIdx The index object with which the index action will be associated.
+ */
+CINDEX_LINKAGE CXIndexAction clang_IndexAction_create(CXIndex CIdx);
+
+/**
+ * Destroy the given index action.
+ *
+ * The index action must not be destroyed until all of the translation units
+ * created within that index action have been destroyed.
+ */
+CINDEX_LINKAGE void clang_IndexAction_dispose(CXIndexAction);
+
+typedef enum {
+  /**
+   * Used to indicate that no special indexing options are needed.
+   */
+  CXIndexOpt_None = 0x0,
+
+  /**
+   * Used to indicate that IndexerCallbacks#indexEntityReference should
+   * be invoked for only one reference of an entity per source file that does
+   * not also include a declaration/definition of the entity.
+   */
+  CXIndexOpt_SuppressRedundantRefs = 0x1,
+
+  /**
+   * Function-local symbols should be indexed. If this is not set
+   * function-local symbols will be ignored.
+   */
+  CXIndexOpt_IndexFunctionLocalSymbols = 0x2,
+
+  /**
+   * Implicit function/class template instantiations should be indexed.
+   * If this is not set, implicit instantiations will be ignored.
+   */
+  CXIndexOpt_IndexImplicitTemplateInstantiations = 0x4,
+
+  /**
+   * Suppress all compiler warnings when parsing for indexing.
+   */
+  CXIndexOpt_SuppressWarnings = 0x8,
+
+  /**
+   * Skip a function/method body that was already parsed during an
+   * indexing session associated with a \c CXIndexAction object.
+   * Bodies in system headers are always skipped.
+   */
+  CXIndexOpt_SkipParsedBodiesInSession = 0x10
+
+} CXIndexOptFlags;
+
+/**
+ * Index the given source file and the translation unit corresponding
+ * to that file via callbacks implemented through #IndexerCallbacks.
+ *
+ * \param client_data pointer data supplied by the client, which will
+ * be passed to the invoked callbacks.
+ *
+ * \param index_callbacks Pointer to indexing callbacks that the client
+ * implements.
+ *
+ * \param index_callbacks_size Size of #IndexerCallbacks structure that gets
+ * passed in index_callbacks.
+ *
+ * \param index_options A bitmask of options that affects how indexing is
+ * performed. This should be a bitwise OR of the CXIndexOpt_XXX flags.
+ *
+ * \param[out] out_TU pointer to store a \c CXTranslationUnit that can be
+ * reused after indexing is finished. Set to \c NULL if you do not require it.
+ *
+ * \returns 0 on success or if there were errors from which the compiler could
+ * recover.  If there is a failure from which there is no recovery, returns
+ * a non-zero \c CXErrorCode.
+ *
+ * The rest of the parameters are the same as #clang_parseTranslationUnit.
+ */
+CINDEX_LINKAGE int clang_indexSourceFile(CXIndexAction,
+                                         CXClientData client_data,
+                                         IndexerCallbacks *index_callbacks,
+                                         unsigned index_callbacks_size,
+                                         unsigned index_options,
+                                         const char *source_filename,
+                                         const char * const *command_line_args,
+                                         int num_command_line_args,
+                                         struct CXUnsavedFile *unsaved_files,
+                                         unsigned num_unsaved_files,
+                                         CXTranslationUnit *out_TU,
+                                         unsigned TU_options);
+
+/**
+ * Same as clang_indexSourceFile but requires a full command line
+ * for \c command_line_args including argv[0]. This is useful if the standard
+ * library paths are relative to the binary.
+ */
+CINDEX_LINKAGE int clang_indexSourceFileFullArgv(
+    CXIndexAction, CXClientData client_data, IndexerCallbacks *index_callbacks,
+    unsigned index_callbacks_size, unsigned index_options,
+    const char *source_filename, const char *const *command_line_args,
+    int num_command_line_args, struct CXUnsavedFile *unsaved_files,
+    unsigned num_unsaved_files, CXTranslationUnit *out_TU, unsigned TU_options);
+
+/**
+ * Index the given translation unit via callbacks implemented through
+ * #IndexerCallbacks.
+ *
+ * The order of callback invocations is not guaranteed to be the same as
+ * when indexing a source file. The high level order will be:
+ *
+ *   -Preprocessor callbacks invocations
+ *   -Declaration/reference callbacks invocations
+ *   -Diagnostic callback invocations
+ *
+ * The parameters are the same as #clang_indexSourceFile.
+ *
+ * \returns If there is a failure from which there is no recovery, returns
+ * non-zero, otherwise returns 0.
+ */
+CINDEX_LINKAGE int clang_indexTranslationUnit(CXIndexAction,
+                                              CXClientData client_data,
+                                              IndexerCallbacks *index_callbacks,
+                                              unsigned index_callbacks_size,
+                                              unsigned index_options,
+                                              CXTranslationUnit);
+
+/**
+ * Retrieve the CXIdxFile, file, line, column, and offset represented by
+ * the given CXIdxLoc.
+ *
+ * If the location refers into a macro expansion, retrieves the
+ * location of the macro expansion and if it refers into a macro argument
+ * retrieves the location of the argument.
+ */
+CINDEX_LINKAGE void clang_indexLoc_getFileLocation(CXIdxLoc loc,
+                                                   CXIdxClientFile *indexFile,
+                                                   CXFile *file,
+                                                   unsigned *line,
+                                                   unsigned *column,
+                                                   unsigned *offset);
+
+/**
+ * Retrieve the CXSourceLocation represented by the given CXIdxLoc.
+ */
+CINDEX_LINKAGE
+CXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc loc);
+
+/**
+ * Visitor invoked for each field found by a traversal.
+ *
+ * This visitor function will be invoked for each field found by
+ * \c clang_Type_visitFields. Its first argument is the cursor being
+ * visited, its second argument is the client data provided to
+ * \c clang_Type_visitFields.
+ *
+ * The visitor should return one of the \c CXVisitorResult values
+ * to direct \c clang_Type_visitFields.
+ */
+typedef enum CXVisitorResult (*CXFieldVisitor)(CXCursor C,
+                                               CXClientData client_data);
+
+/**
+ * Visit the fields of a particular type.
+ *
+ * This function visits all the direct fields of the given cursor,
+ * invoking the given \p visitor function with the cursors of each
+ * visited field. The traversal may be ended prematurely, if
+ * the visitor returns \c CXFieldVisit_Break.
+ *
+ * \param T the record type whose field may be visited.
+ *
+ * \param visitor the visitor function that will be invoked for each
+ * field of \p T.
+ *
+ * \param client_data pointer data supplied by the client, which will
+ * be passed to the visitor each time it is invoked.
+ *
+ * \returns a non-zero value if the traversal was terminated
+ * prematurely by the visitor returning \c CXFieldVisit_Break.
+ */
+CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T,
+                                               CXFieldVisitor visitor,
+                                               CXClientData client_data);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+LLVM_CLANG_C_EXTERN_C_END
+
+#endif
diff --git a/pkgs/ffigen/third_party/libclang/include/clang-c/Platform.h b/pkgs/ffigen/third_party/libclang/include/clang-c/Platform.h
new file mode 100644
index 0000000..3bb66bb
--- /dev/null
+++ b/pkgs/ffigen/third_party/libclang/include/clang-c/Platform.h
@@ -0,0 +1,44 @@
+/*===-- clang-c/Platform.h - C Index platform decls   -------------*- C -*-===*\
+|*                                                                            *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
+|* Exceptions.                                                                *|
+|* See https://llvm.org/LICENSE.txt for license information.                  *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides platform specific macros (dllimport, deprecated, ...) *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_PLATFORM_H
+#define LLVM_CLANG_C_PLATFORM_H
+
+#include "clang-c/ExternC.h"
+
+LLVM_CLANG_C_EXTERN_C_BEGIN
+
+/* MSVC DLL import/export. */
+#ifdef _MSC_VER
+  #ifdef _CINDEX_LIB_
+    #define CINDEX_LINKAGE __declspec(dllexport)
+  #else
+    #define CINDEX_LINKAGE __declspec(dllimport)
+  #endif
+#else
+  #define CINDEX_LINKAGE
+#endif
+
+#ifdef __GNUC__
+  #define CINDEX_DEPRECATED __attribute__((deprecated))
+#else
+  #ifdef _MSC_VER
+    #define CINDEX_DEPRECATED __declspec(deprecated)
+  #else
+    #define CINDEX_DEPRECATED
+  #endif
+#endif
+
+LLVM_CLANG_C_EXTERN_C_END
+
+#endif
diff --git a/pkgs/ffigen/third_party/libclang/license.txt b/pkgs/ffigen/third_party/libclang/license.txt
new file mode 100644
index 0000000..428da30
--- /dev/null
+++ b/pkgs/ffigen/third_party/libclang/license.txt
@@ -0,0 +1,224 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+    1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+    2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+    3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+    4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+    5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+    6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+    7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+    8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+    9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+    END OF TERMS AND CONDITIONS
+
+    APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+    Copyright [yyyy] [name of copyright owner]
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+
+--- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
+
+Files generated from libclang source code are
+- example/libclang-example/generated_bindings.dart
+- lib/src/header_parser/clang_bindings/clang_bindings.dart
+- test/large_integration_tests/_expected_libclang_bindings.dart
diff --git a/pkgs/ffigen/third_party/sqlite/license.txt b/pkgs/ffigen/third_party/sqlite/license.txt
new file mode 100644
index 0000000..d1a956a
--- /dev/null
+++ b/pkgs/ffigen/third_party/sqlite/license.txt
@@ -0,0 +1,11 @@
+2001-09-15
+
+The author disclaims copyright to this source code.  In place of
+a legal notice, here is a blessing:
+
+    May you do good and not evil.
+    May you find forgiveness for yourself and forgive others.
+    May you share freely, never taking more than you give.
+
+Files generated from sqlite source code are
+- test/large_integration_tests/_expected_sqlite_bindings.dart
diff --git a/pkgs/ffigen/third_party/sqlite/sqlite3.h b/pkgs/ffigen/third_party/sqlite/sqlite3.h
new file mode 100644
index 0000000..f34a7b5
--- /dev/null
+++ b/pkgs/ffigen/third_party/sqlite/sqlite3.h
@@ -0,0 +1,12168 @@
+/*
+** 2001-09-15
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This header file defines the interface that the SQLite library
+** presents to client programs.  If a C-function, structure, datatype,
+** or constant definition does not appear in this file, then it is
+** not a published API of SQLite, is subject to change without
+** notice, and should not be referenced by programs that use SQLite.
+**
+** Some of the definitions that are in this file are marked as
+** "experimental".  Experimental interfaces are normally new
+** features recently added to SQLite.  We do not anticipate changes
+** to experimental interfaces but reserve the right to make minor changes
+** if experience from use "in the wild" suggest such changes are prudent.
+**
+** The official C-language API documentation for SQLite is derived
+** from comments in this file.  This file is the authoritative source
+** on how SQLite interfaces are supposed to operate.
+**
+** The name of this file under configuration management is "sqlite.h.in".
+** The makefile makes some minor changes to this file (such as inserting
+** the version number) and changes its name to "sqlite3.h" as
+** part of the build process.
+*/
+#ifndef SQLITE3_H
+#define SQLITE3_H
+#include <stdarg.h>     /* Needed for the definition of va_list */
+
+/*
+** Make sure we can call this stuff from C++.
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+** Provide the ability to override linkage features of the interface.
+*/
+#ifndef SQLITE_EXTERN
+# define SQLITE_EXTERN extern
+#endif
+#ifndef SQLITE_API
+# define SQLITE_API
+#endif
+#ifndef SQLITE_CDECL
+# define SQLITE_CDECL
+#endif
+#ifndef SQLITE_APICALL
+# define SQLITE_APICALL
+#endif
+#ifndef SQLITE_STDCALL
+# define SQLITE_STDCALL SQLITE_APICALL
+#endif
+#ifndef SQLITE_CALLBACK
+# define SQLITE_CALLBACK
+#endif
+#ifndef SQLITE_SYSAPI
+# define SQLITE_SYSAPI
+#endif
+
+/*
+** These no-op macros are used in front of interfaces to mark those
+** interfaces as either deprecated or experimental.  New applications
+** should not use deprecated interfaces - they are supported for backwards
+** compatibility only.  Application writers should be aware that
+** experimental interfaces are subject to change in point releases.
+**
+** These macros used to resolve to various kinds of compiler magic that
+** would generate warning messages when they were used.  But that
+** compiler magic ended up generating such a flurry of bug reports
+** that we have taken it all out and gone back to using simple
+** noop macros.
+*/
+#define SQLITE_DEPRECATED
+#define SQLITE_EXPERIMENTAL
+
+/*
+** Ensure these symbols were not defined by some previous header file.
+*/
+#ifdef SQLITE_VERSION
+# undef SQLITE_VERSION
+#endif
+#ifdef SQLITE_VERSION_NUMBER
+# undef SQLITE_VERSION_NUMBER
+#endif
+
+/*
+** CAPI3REF: Compile-Time Library Version Numbers
+**
+** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header
+** evaluates to a string literal that is the SQLite version in the
+** format "X.Y.Z" where X is the major version number (always 3 for
+** SQLite3) and Y is the minor version number and Z is the release number.)^
+** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer
+** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
+** numbers used in [SQLITE_VERSION].)^
+** The SQLITE_VERSION_NUMBER for any given release of SQLite will also
+** be larger than the release from which it is derived.  Either Y will
+** be held constant and Z will be incremented or else Y will be incremented
+** and Z will be reset to zero.
+**
+** Since [version 3.6.18] ([dateof:3.6.18]), 
+** SQLite source code has been stored in the
+** <a href="http://www.fossil-scm.org/">Fossil configuration management
+** system</a>.  ^The SQLITE_SOURCE_ID macro evaluates to
+** a string which identifies a particular check-in of SQLite
+** within its configuration management system.  ^The SQLITE_SOURCE_ID
+** string contains the date and time of the check-in (UTC) and a SHA1
+** or SHA3-256 hash of the entire source tree.  If the source code has
+** been edited in any way since it was last checked in, then the last
+** four hexadecimal digits of the hash may be modified.
+**
+** See also: [sqlite3_libversion()],
+** [sqlite3_libversion_number()], [sqlite3_sourceid()],
+** [sqlite_version()] and [sqlite_source_id()].
+*/
+#define SQLITE_VERSION        "3.32.3"
+#define SQLITE_VERSION_NUMBER 3032003
+#define SQLITE_SOURCE_ID      "2020-06-18 14:00:33 7ebdfa80be8e8e73324b8d66b3460222eb74c7e9dfd655b48d6ca7e1933cc8fd"
+
+/*
+** CAPI3REF: Run-Time Library Version Numbers
+** KEYWORDS: sqlite3_version sqlite3_sourceid
+**
+** These interfaces provide the same information as the [SQLITE_VERSION],
+** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
+** but are associated with the library instead of the header file.  ^(Cautious
+** programmers might include assert() statements in their application to
+** verify that values returned by these interfaces match the macros in
+** the header, and thus ensure that the application is
+** compiled with matching library and header files.
+**
+** <blockquote><pre>
+** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
+** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
+** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
+** </pre></blockquote>)^
+**
+** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION]
+** macro.  ^The sqlite3_libversion() function returns a pointer to the
+** to the sqlite3_version[] string constant.  The sqlite3_libversion()
+** function is provided for use in DLLs since DLL users usually do not have
+** direct access to string constants within the DLL.  ^The
+** sqlite3_libversion_number() function returns an integer equal to
+** [SQLITE_VERSION_NUMBER].  ^(The sqlite3_sourceid() function returns 
+** a pointer to a string constant whose value is the same as the 
+** [SQLITE_SOURCE_ID] C preprocessor macro.  Except if SQLite is built
+** using an edited copy of [the amalgamation], then the last four characters
+** of the hash might be different from [SQLITE_SOURCE_ID].)^
+**
+** See also: [sqlite_version()] and [sqlite_source_id()].
+*/
+SQLITE_API SQLITE_EXTERN const char sqlite3_version[];
+SQLITE_API const char *sqlite3_libversion(void);
+SQLITE_API const char *sqlite3_sourceid(void);
+SQLITE_API int sqlite3_libversion_number(void);
+
+/*
+** CAPI3REF: Run-Time Library Compilation Options Diagnostics
+**
+** ^The sqlite3_compileoption_used() function returns 0 or 1 
+** indicating whether the specified option was defined at 
+** compile time.  ^The SQLITE_ prefix may be omitted from the 
+** option name passed to sqlite3_compileoption_used().  
+**
+** ^The sqlite3_compileoption_get() function allows iterating
+** over the list of options that were defined at compile time by
+** returning the N-th compile time option string.  ^If N is out of range,
+** sqlite3_compileoption_get() returns a NULL pointer.  ^The SQLITE_ 
+** prefix is omitted from any strings returned by 
+** sqlite3_compileoption_get().
+**
+** ^Support for the diagnostic functions sqlite3_compileoption_used()
+** and sqlite3_compileoption_get() may be omitted by specifying the 
+** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time.
+**
+** See also: SQL functions [sqlite_compileoption_used()] and
+** [sqlite_compileoption_get()] and the [compile_options pragma].
+*/
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
+SQLITE_API const char *sqlite3_compileoption_get(int N);
+#else
+# define sqlite3_compileoption_used(X) 0
+# define sqlite3_compileoption_get(X)  ((void*)0)
+#endif
+
+/*
+** CAPI3REF: Test To See If The Library Is Threadsafe
+**
+** ^The sqlite3_threadsafe() function returns zero if and only if
+** SQLite was compiled with mutexing code omitted due to the
+** [SQLITE_THREADSAFE] compile-time option being set to 0.
+**
+** SQLite can be compiled with or without mutexes.  When
+** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes
+** are enabled and SQLite is threadsafe.  When the
+** [SQLITE_THREADSAFE] macro is 0, 
+** the mutexes are omitted.  Without the mutexes, it is not safe
+** to use SQLite concurrently from more than one thread.
+**
+** Enabling mutexes incurs a measurable performance penalty.
+** So if speed is of utmost importance, it makes sense to disable
+** the mutexes.  But for maximum safety, mutexes should be enabled.
+** ^The default behavior is for mutexes to be enabled.
+**
+** This interface can be used by an application to make sure that the
+** version of SQLite that it is linking against was compiled with
+** the desired setting of the [SQLITE_THREADSAFE] macro.
+**
+** This interface only reports on the compile-time mutex setting
+** of the [SQLITE_THREADSAFE] flag.  If SQLite is compiled with
+** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
+** can be fully or partially disabled using a call to [sqlite3_config()]
+** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
+** or [SQLITE_CONFIG_SERIALIZED].  ^(The return value of the
+** sqlite3_threadsafe() function shows only the compile-time setting of
+** thread safety, not any run-time changes to that setting made by
+** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
+** is unchanged by calls to sqlite3_config().)^
+**
+** See the [threading mode] documentation for additional information.
+*/
+SQLITE_API int sqlite3_threadsafe(void);
+
+/*
+** CAPI3REF: Database Connection Handle
+** KEYWORDS: {database connection} {database connections}
+**
+** Each open SQLite database is represented by a pointer to an instance of
+** the opaque structure named "sqlite3".  It is useful to think of an sqlite3
+** pointer as an object.  The [sqlite3_open()], [sqlite3_open16()], and
+** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
+** and [sqlite3_close_v2()] are its destructors.  There are many other
+** interfaces (such as
+** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
+** [sqlite3_busy_timeout()] to name but three) that are methods on an
+** sqlite3 object.
+*/
+typedef struct sqlite3 sqlite3;
+
+/*
+** CAPI3REF: 64-Bit Integer Types
+** KEYWORDS: sqlite_int64 sqlite_uint64
+**
+** Because there is no cross-platform way to specify 64-bit integer types
+** SQLite includes typedefs for 64-bit signed and unsigned integers.
+**
+** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions.
+** The sqlite_int64 and sqlite_uint64 types are supported for backwards
+** compatibility only.
+**
+** ^The sqlite3_int64 and sqlite_int64 types can store integer values
+** between -9223372036854775808 and +9223372036854775807 inclusive.  ^The
+** sqlite3_uint64 and sqlite_uint64 types can store integer values 
+** between 0 and +18446744073709551615 inclusive.
+*/
+#ifdef SQLITE_INT64_TYPE
+  typedef SQLITE_INT64_TYPE sqlite_int64;
+# ifdef SQLITE_UINT64_TYPE
+    typedef SQLITE_UINT64_TYPE sqlite_uint64;
+# else  
+    typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
+# endif
+#elif defined(_MSC_VER) || defined(__BORLANDC__)
+  typedef __int64 sqlite_int64;
+  typedef unsigned __int64 sqlite_uint64;
+#else
+  typedef long long int sqlite_int64;
+  typedef unsigned long long int sqlite_uint64;
+#endif
+typedef sqlite_int64 sqlite3_int64;
+typedef sqlite_uint64 sqlite3_uint64;
+
+/*
+** If compiling for a processor that lacks floating point support,
+** substitute integer for floating-point.
+*/
+#ifdef SQLITE_OMIT_FLOATING_POINT
+# define double sqlite3_int64
+#endif
+
+/*
+** CAPI3REF: Closing A Database Connection
+** DESTRUCTOR: sqlite3
+**
+** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
+** for the [sqlite3] object.
+** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
+** the [sqlite3] object is successfully destroyed and all associated
+** resources are deallocated.
+**
+** Ideally, applications should [sqlite3_finalize | finalize] all
+** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and 
+** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
+** with the [sqlite3] object prior to attempting to close the object.
+** ^If the database connection is associated with unfinalized prepared
+** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
+** sqlite3_close() will leave the database connection open and return
+** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
+** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
+** it returns [SQLITE_OK] regardless, but instead of deallocating the database
+** connection immediately, it marks the database connection as an unusable
+** "zombie" and makes arrangements to automatically deallocate the database
+** connection after all prepared statements are finalized, all BLOB handles
+** are closed, and all backups have finished. The sqlite3_close_v2() interface
+** is intended for use with host languages that are garbage collected, and
+** where the order in which destructors are called is arbitrary.
+**
+** ^If an [sqlite3] object is destroyed while a transaction is open,
+** the transaction is automatically rolled back.
+**
+** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
+** must be either a NULL
+** pointer or an [sqlite3] object pointer obtained
+** from [sqlite3_open()], [sqlite3_open16()], or
+** [sqlite3_open_v2()], and not previously closed.
+** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
+** argument is a harmless no-op.
+*/
+SQLITE_API int sqlite3_close(sqlite3*);
+SQLITE_API int sqlite3_close_v2(sqlite3*);
+
+/*
+** The type for a callback function.
+** This is legacy and deprecated.  It is included for historical
+** compatibility and is not documented.
+*/
+typedef int (*sqlite3_callback)(void*,int,char**, char**);
+
+/*
+** CAPI3REF: One-Step Query Execution Interface
+** METHOD: sqlite3
+**
+** The sqlite3_exec() interface is a convenience wrapper around
+** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
+** that allows an application to run multiple statements of SQL
+** without having to use a lot of C code. 
+**
+** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded,
+** semicolon-separate SQL statements passed into its 2nd argument,
+** in the context of the [database connection] passed in as its 1st
+** argument.  ^If the callback function of the 3rd argument to
+** sqlite3_exec() is not NULL, then it is invoked for each result row
+** coming out of the evaluated SQL statements.  ^The 4th argument to
+** sqlite3_exec() is relayed through to the 1st argument of each
+** callback invocation.  ^If the callback pointer to sqlite3_exec()
+** is NULL, then no callback is ever invoked and result rows are
+** ignored.
+**
+** ^If an error occurs while evaluating the SQL statements passed into
+** sqlite3_exec(), then execution of the current statement stops and
+** subsequent statements are skipped.  ^If the 5th parameter to sqlite3_exec()
+** is not NULL then any error message is written into memory obtained
+** from [sqlite3_malloc()] and passed back through the 5th parameter.
+** To avoid memory leaks, the application should invoke [sqlite3_free()]
+** on error message strings returned through the 5th parameter of
+** sqlite3_exec() after the error message string is no longer needed.
+** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors
+** occur, then sqlite3_exec() sets the pointer in its 5th parameter to
+** NULL before returning.
+**
+** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec()
+** routine returns SQLITE_ABORT without invoking the callback again and
+** without running any subsequent SQL statements.
+**
+** ^The 2nd argument to the sqlite3_exec() callback function is the
+** number of columns in the result.  ^The 3rd argument to the sqlite3_exec()
+** callback is an array of pointers to strings obtained as if from
+** [sqlite3_column_text()], one for each column.  ^If an element of a
+** result row is NULL then the corresponding string pointer for the
+** sqlite3_exec() callback is a NULL pointer.  ^The 4th argument to the
+** sqlite3_exec() callback is an array of pointers to strings where each
+** entry represents the name of corresponding result column as obtained
+** from [sqlite3_column_name()].
+**
+** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer
+** to an empty string, or a pointer that contains only whitespace and/or 
+** SQL comments, then no SQL statements are evaluated and the database
+** is not changed.
+**
+** Restrictions:
+**
+** <ul>
+** <li> The application must ensure that the 1st parameter to sqlite3_exec()
+**      is a valid and open [database connection].
+** <li> The application must not close the [database connection] specified by
+**      the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
+** <li> The application must not modify the SQL statement text passed into
+**      the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
+** </ul>
+*/
+SQLITE_API int sqlite3_exec(
+  sqlite3*,                                  /* An open database */
+  const char *sql,                           /* SQL to be evaluated */
+  int (*callback)(void*,int,char**,char**),  /* Callback function */
+  void *,                                    /* 1st argument to callback */
+  char **errmsg                              /* Error msg written here */
+);
+
+/*
+** CAPI3REF: Result Codes
+** KEYWORDS: {result code definitions}
+**
+** Many SQLite functions return an integer result code from the set shown
+** here in order to indicate success or failure.
+**
+** New error codes may be added in future versions of SQLite.
+**
+** See also: [extended result code definitions]
+*/
+#define SQLITE_OK           0   /* Successful result */
+/* beginning-of-error-codes */
+#define SQLITE_ERROR        1   /* Generic error */
+#define SQLITE_INTERNAL     2   /* Internal logic error in SQLite */
+#define SQLITE_PERM         3   /* Access permission denied */
+#define SQLITE_ABORT        4   /* Callback routine requested an abort */
+#define SQLITE_BUSY         5   /* The database file is locked */
+#define SQLITE_LOCKED       6   /* A table in the database is locked */
+#define SQLITE_NOMEM        7   /* A malloc() failed */
+#define SQLITE_READONLY     8   /* Attempt to write a readonly database */
+#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite3_interrupt()*/
+#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
+#define SQLITE_CORRUPT     11   /* The database disk image is malformed */
+#define SQLITE_NOTFOUND    12   /* Unknown opcode in sqlite3_file_control() */
+#define SQLITE_FULL        13   /* Insertion failed because database is full */
+#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
+#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
+#define SQLITE_EMPTY       16   /* Internal use only */
+#define SQLITE_SCHEMA      17   /* The database schema changed */
+#define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */
+#define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */
+#define SQLITE_MISMATCH    20   /* Data type mismatch */
+#define SQLITE_MISUSE      21   /* Library used incorrectly */
+#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
+#define SQLITE_AUTH        23   /* Authorization denied */
+#define SQLITE_FORMAT      24   /* Not used */
+#define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
+#define SQLITE_NOTADB      26   /* File opened that is not a database file */
+#define SQLITE_NOTICE      27   /* Notifications from sqlite3_log() */
+#define SQLITE_WARNING     28   /* Warnings from sqlite3_log() */
+#define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
+#define SQLITE_DONE        101  /* sqlite3_step() has finished executing */
+/* end-of-error-codes */
+
+/*
+** CAPI3REF: Extended Result Codes
+** KEYWORDS: {extended result code definitions}
+**
+** In its default configuration, SQLite API routines return one of 30 integer
+** [result codes].  However, experience has shown that many of
+** these result codes are too coarse-grained.  They do not provide as
+** much information about problems as programmers might like.  In an effort to
+** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8]
+** and later) include
+** support for additional result codes that provide more detailed information
+** about errors. These [extended result codes] are enabled or disabled
+** on a per database connection basis using the
+** [sqlite3_extended_result_codes()] API.  Or, the extended code for
+** the most recent error can be obtained using
+** [sqlite3_extended_errcode()].
+*/
+#define SQLITE_ERROR_MISSING_COLLSEQ   (SQLITE_ERROR | (1<<8))
+#define SQLITE_ERROR_RETRY             (SQLITE_ERROR | (2<<8))
+#define SQLITE_ERROR_SNAPSHOT          (SQLITE_ERROR | (3<<8))
+#define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))
+#define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))
+#define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))
+#define SQLITE_IOERR_FSYNC             (SQLITE_IOERR | (4<<8))
+#define SQLITE_IOERR_DIR_FSYNC         (SQLITE_IOERR | (5<<8))
+#define SQLITE_IOERR_TRUNCATE          (SQLITE_IOERR | (6<<8))
+#define SQLITE_IOERR_FSTAT             (SQLITE_IOERR | (7<<8))
+#define SQLITE_IOERR_UNLOCK            (SQLITE_IOERR | (8<<8))
+#define SQLITE_IOERR_RDLOCK            (SQLITE_IOERR | (9<<8))
+#define SQLITE_IOERR_DELETE            (SQLITE_IOERR | (10<<8))
+#define SQLITE_IOERR_BLOCKED           (SQLITE_IOERR | (11<<8))
+#define SQLITE_IOERR_NOMEM             (SQLITE_IOERR | (12<<8))
+#define SQLITE_IOERR_ACCESS            (SQLITE_IOERR | (13<<8))
+#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
+#define SQLITE_IOERR_LOCK              (SQLITE_IOERR | (15<<8))
+#define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
+#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
+#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
+#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
+#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
+#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
+#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
+#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
+#define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
+#define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
+#define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
+#define SQLITE_IOERR_VNODE             (SQLITE_IOERR | (27<<8))
+#define SQLITE_IOERR_AUTH              (SQLITE_IOERR | (28<<8))
+#define SQLITE_IOERR_BEGIN_ATOMIC      (SQLITE_IOERR | (29<<8))
+#define SQLITE_IOERR_COMMIT_ATOMIC     (SQLITE_IOERR | (30<<8))
+#define SQLITE_IOERR_ROLLBACK_ATOMIC   (SQLITE_IOERR | (31<<8))
+#define SQLITE_IOERR_DATA              (SQLITE_IOERR | (32<<8))
+#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
+#define SQLITE_LOCKED_VTAB             (SQLITE_LOCKED |  (2<<8))
+#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
+#define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
+#define SQLITE_BUSY_TIMEOUT            (SQLITE_BUSY   |  (3<<8))
+#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
+#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
+#define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
+#define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
+#define SQLITE_CANTOPEN_DIRTYWAL       (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
+#define SQLITE_CANTOPEN_SYMLINK        (SQLITE_CANTOPEN | (6<<8))
+#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
+#define SQLITE_CORRUPT_SEQUENCE        (SQLITE_CORRUPT | (2<<8))
+#define SQLITE_CORRUPT_INDEX           (SQLITE_CORRUPT | (3<<8))
+#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
+#define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
+#define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
+#define SQLITE_READONLY_DBMOVED        (SQLITE_READONLY | (4<<8))
+#define SQLITE_READONLY_CANTINIT       (SQLITE_READONLY | (5<<8))
+#define SQLITE_READONLY_DIRECTORY      (SQLITE_READONLY | (6<<8))
+#define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
+#define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (1<<8))
+#define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (2<<8))
+#define SQLITE_CONSTRAINT_FOREIGNKEY   (SQLITE_CONSTRAINT | (3<<8))
+#define SQLITE_CONSTRAINT_FUNCTION     (SQLITE_CONSTRAINT | (4<<8))
+#define SQLITE_CONSTRAINT_NOTNULL      (SQLITE_CONSTRAINT | (5<<8))
+#define SQLITE_CONSTRAINT_PRIMARYKEY   (SQLITE_CONSTRAINT | (6<<8))
+#define SQLITE_CONSTRAINT_TRIGGER      (SQLITE_CONSTRAINT | (7<<8))
+#define SQLITE_CONSTRAINT_UNIQUE       (SQLITE_CONSTRAINT | (8<<8))
+#define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
+#define SQLITE_CONSTRAINT_ROWID        (SQLITE_CONSTRAINT |(10<<8))
+#define SQLITE_CONSTRAINT_PINNED       (SQLITE_CONSTRAINT |(11<<8))
+#define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
+#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
+#define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
+#define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
+#define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
+#define SQLITE_OK_SYMLINK              (SQLITE_OK | (2<<8))
+
+/*
+** CAPI3REF: Flags For File Open Operations
+**
+** These bit values are intended for use in the
+** 3rd parameter to the [sqlite3_open_v2()] interface and
+** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
+*/
+#define SQLITE_OPEN_READONLY         0x00000001  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_READWRITE        0x00000002  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_CREATE           0x00000004  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_DELETEONCLOSE    0x00000008  /* VFS only */
+#define SQLITE_OPEN_EXCLUSIVE        0x00000010  /* VFS only */
+#define SQLITE_OPEN_AUTOPROXY        0x00000020  /* VFS only */
+#define SQLITE_OPEN_URI              0x00000040  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_MEMORY           0x00000080  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_MAIN_DB          0x00000100  /* VFS only */
+#define SQLITE_OPEN_TEMP_DB          0x00000200  /* VFS only */
+#define SQLITE_OPEN_TRANSIENT_DB     0x00000400  /* VFS only */
+#define SQLITE_OPEN_MAIN_JOURNAL     0x00000800  /* VFS only */
+#define SQLITE_OPEN_TEMP_JOURNAL     0x00001000  /* VFS only */
+#define SQLITE_OPEN_SUBJOURNAL       0x00002000  /* VFS only */
+#define SQLITE_OPEN_MASTER_JOURNAL   0x00004000  /* VFS only */
+#define SQLITE_OPEN_NOMUTEX          0x00008000  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_FULLMUTEX        0x00010000  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_SHAREDCACHE      0x00020000  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_PRIVATECACHE     0x00040000  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_WAL              0x00080000  /* VFS only */
+#define SQLITE_OPEN_NOFOLLOW         0x01000000  /* Ok for sqlite3_open_v2() */
+
+/* Reserved:                         0x00F00000 */
+
+/*
+** CAPI3REF: Device Characteristics
+**
+** The xDeviceCharacteristics method of the [sqlite3_io_methods]
+** object returns an integer which is a vector of these
+** bit values expressing I/O characteristics of the mass storage
+** device that holds the file that the [sqlite3_io_methods]
+** refers to.
+**
+** The SQLITE_IOCAP_ATOMIC property means that all writes of
+** any size are atomic.  The SQLITE_IOCAP_ATOMICnnn values
+** mean that writes of blocks that are nnn bytes in size and
+** are aligned to an address which is an integer multiple of
+** nnn are atomic.  The SQLITE_IOCAP_SAFE_APPEND value means
+** that when data is appended to a file, the data is appended
+** first then the size of the file is extended, never the other
+** way around.  The SQLITE_IOCAP_SEQUENTIAL property means that
+** information is written to disk in the same order as calls
+** to xWrite().  The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that
+** after reboot following a crash or power loss, the only bytes in a
+** file that were written at the application level might have changed
+** and that adjacent bytes, even bytes within the same sector are
+** guaranteed to be unchanged.  The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
+** flag indicates that a file cannot be deleted when open.  The
+** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
+** read-only media and cannot be changed even by processes with
+** elevated privileges.
+**
+** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying
+** filesystem supports doing multiple write operations atomically when those
+** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
+** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
+*/
+#define SQLITE_IOCAP_ATOMIC                 0x00000001
+#define SQLITE_IOCAP_ATOMIC512              0x00000002
+#define SQLITE_IOCAP_ATOMIC1K               0x00000004
+#define SQLITE_IOCAP_ATOMIC2K               0x00000008
+#define SQLITE_IOCAP_ATOMIC4K               0x00000010
+#define SQLITE_IOCAP_ATOMIC8K               0x00000020
+#define SQLITE_IOCAP_ATOMIC16K              0x00000040
+#define SQLITE_IOCAP_ATOMIC32K              0x00000080
+#define SQLITE_IOCAP_ATOMIC64K              0x00000100
+#define SQLITE_IOCAP_SAFE_APPEND            0x00000200
+#define SQLITE_IOCAP_SEQUENTIAL             0x00000400
+#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN  0x00000800
+#define SQLITE_IOCAP_POWERSAFE_OVERWRITE    0x00001000
+#define SQLITE_IOCAP_IMMUTABLE              0x00002000
+#define SQLITE_IOCAP_BATCH_ATOMIC           0x00004000
+
+/*
+** CAPI3REF: File Locking Levels
+**
+** SQLite uses one of these integer values as the second
+** argument to calls it makes to the xLock() and xUnlock() methods
+** of an [sqlite3_io_methods] object.
+*/
+#define SQLITE_LOCK_NONE          0
+#define SQLITE_LOCK_SHARED        1
+#define SQLITE_LOCK_RESERVED      2
+#define SQLITE_LOCK_PENDING       3
+#define SQLITE_LOCK_EXCLUSIVE     4
+
+/*
+** CAPI3REF: Synchronization Type Flags
+**
+** When SQLite invokes the xSync() method of an
+** [sqlite3_io_methods] object it uses a combination of
+** these integer values as the second argument.
+**
+** When the SQLITE_SYNC_DATAONLY flag is used, it means that the
+** sync operation only needs to flush data to mass storage.  Inode
+** information need not be flushed. If the lower four bits of the flag
+** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics.
+** If the lower four bits equal SQLITE_SYNC_FULL, that means
+** to use Mac OS X style fullsync instead of fsync().
+**
+** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags
+** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL
+** settings.  The [synchronous pragma] determines when calls to the
+** xSync VFS method occur and applies uniformly across all platforms.
+** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how
+** energetic or rigorous or forceful the sync operations are and
+** only make a difference on Mac OSX for the default SQLite code.
+** (Third-party VFS implementations might also make the distinction
+** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the
+** operating systems natively supported by SQLite, only Mac OSX
+** cares about the difference.)
+*/
+#define SQLITE_SYNC_NORMAL        0x00002
+#define SQLITE_SYNC_FULL          0x00003
+#define SQLITE_SYNC_DATAONLY      0x00010
+
+/*
+** CAPI3REF: OS Interface Open File Handle
+**
+** An [sqlite3_file] object represents an open file in the 
+** [sqlite3_vfs | OS interface layer].  Individual OS interface
+** implementations will
+** want to subclass this object by appending additional fields
+** for their own use.  The pMethods entry is a pointer to an
+** [sqlite3_io_methods] object that defines methods for performing
+** I/O operations on the open file.
+*/
+typedef struct sqlite3_file sqlite3_file;
+struct sqlite3_file {
+  const struct sqlite3_io_methods *pMethods;  /* Methods for an open file */
+};
+
+/*
+** CAPI3REF: OS Interface File Virtual Methods Object
+**
+** Every file opened by the [sqlite3_vfs.xOpen] method populates an
+** [sqlite3_file] object (or, more commonly, a subclass of the
+** [sqlite3_file] object) with a pointer to an instance of this object.
+** This object defines the methods used to perform various operations
+** against the open file represented by the [sqlite3_file] object.
+**
+** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element 
+** to a non-NULL pointer, then the sqlite3_io_methods.xClose method
+** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed.  The
+** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen]
+** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element
+** to NULL.
+**
+** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or
+** [SQLITE_SYNC_FULL].  The first choice is the normal fsync().
+** The second choice is a Mac OS X style fullsync.  The [SQLITE_SYNC_DATAONLY]
+** flag may be ORed in to indicate that only the data of the file
+** and not its inode needs to be synced.
+**
+** The integer values to xLock() and xUnlock() are one of
+** <ul>
+** <li> [SQLITE_LOCK_NONE],
+** <li> [SQLITE_LOCK_SHARED],
+** <li> [SQLITE_LOCK_RESERVED],
+** <li> [SQLITE_LOCK_PENDING], or
+** <li> [SQLITE_LOCK_EXCLUSIVE].
+** </ul>
+** xLock() increases the lock. xUnlock() decreases the lock.
+** The xCheckReservedLock() method checks whether any database connection,
+** either in this process or in some other process, is holding a RESERVED,
+** PENDING, or EXCLUSIVE lock on the file.  It returns true
+** if such a lock exists and false otherwise.
+**
+** The xFileControl() method is a generic interface that allows custom
+** VFS implementations to directly control an open file using the
+** [sqlite3_file_control()] interface.  The second "op" argument is an
+** integer opcode.  The third argument is a generic pointer intended to
+** point to a structure that may contain arguments or space in which to
+** write return values.  Potential uses for xFileControl() might be
+** functions to enable blocking locks with timeouts, to change the
+** locking strategy (for example to use dot-file locks), to inquire
+** about the status of a lock, or to break stale locks.  The SQLite
+** core reserves all opcodes less than 100 for its own use.
+** A [file control opcodes | list of opcodes] less than 100 is available.
+** Applications that define a custom xFileControl method should use opcodes
+** greater than 100 to avoid conflicts.  VFS implementations should
+** return [SQLITE_NOTFOUND] for file control opcodes that they do not
+** recognize.
+**
+** The xSectorSize() method returns the sector size of the
+** device that underlies the file.  The sector size is the
+** minimum write that can be performed without disturbing
+** other bytes in the file.  The xDeviceCharacteristics()
+** method returns a bit vector describing behaviors of the
+** underlying device:
+**
+** <ul>
+** <li> [SQLITE_IOCAP_ATOMIC]
+** <li> [SQLITE_IOCAP_ATOMIC512]
+** <li> [SQLITE_IOCAP_ATOMIC1K]
+** <li> [SQLITE_IOCAP_ATOMIC2K]
+** <li> [SQLITE_IOCAP_ATOMIC4K]
+** <li> [SQLITE_IOCAP_ATOMIC8K]
+** <li> [SQLITE_IOCAP_ATOMIC16K]
+** <li> [SQLITE_IOCAP_ATOMIC32K]
+** <li> [SQLITE_IOCAP_ATOMIC64K]
+** <li> [SQLITE_IOCAP_SAFE_APPEND]
+** <li> [SQLITE_IOCAP_SEQUENTIAL]
+** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
+** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
+** <li> [SQLITE_IOCAP_IMMUTABLE]
+** <li> [SQLITE_IOCAP_BATCH_ATOMIC]
+** </ul>
+**
+** The SQLITE_IOCAP_ATOMIC property means that all writes of
+** any size are atomic.  The SQLITE_IOCAP_ATOMICnnn values
+** mean that writes of blocks that are nnn bytes in size and
+** are aligned to an address which is an integer multiple of
+** nnn are atomic.  The SQLITE_IOCAP_SAFE_APPEND value means
+** that when data is appended to a file, the data is appended
+** first then the size of the file is extended, never the other
+** way around.  The SQLITE_IOCAP_SEQUENTIAL property means that
+** information is written to disk in the same order as calls
+** to xWrite().
+**
+** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill
+** in the unread portions of the buffer with zeros.  A VFS that
+** fails to zero-fill short reads might seem to work.  However,
+** failure to zero-fill short reads will eventually lead to
+** database corruption.
+*/
+typedef struct sqlite3_io_methods sqlite3_io_methods;
+struct sqlite3_io_methods {
+  int iVersion;
+  int (*xClose)(sqlite3_file*);
+  int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
+  int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);
+  int (*xTruncate)(sqlite3_file*, sqlite3_int64 size);
+  int (*xSync)(sqlite3_file*, int flags);
+  int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize);
+  int (*xLock)(sqlite3_file*, int);
+  int (*xUnlock)(sqlite3_file*, int);
+  int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
+  int (*xFileControl)(sqlite3_file*, int op, void *pArg);
+  int (*xSectorSize)(sqlite3_file*);
+  int (*xDeviceCharacteristics)(sqlite3_file*);
+  /* Methods above are valid for version 1 */
+  int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
+  int (*xShmLock)(sqlite3_file*, int offset, int n, int flags);
+  void (*xShmBarrier)(sqlite3_file*);
+  int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
+  /* Methods above are valid for version 2 */
+  int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
+  int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p);
+  /* Methods above are valid for version 3 */
+  /* Additional methods may be added in future releases */
+};
+
+/*
+** CAPI3REF: Standard File Control Opcodes
+** KEYWORDS: {file control opcodes} {file control opcode}
+**
+** These integer constants are opcodes for the xFileControl method
+** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
+** interface.
+**
+** <ul>
+** <li>[[SQLITE_FCNTL_LOCKSTATE]]
+** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging.  This
+** opcode causes the xFileControl method to write the current state of
+** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
+** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
+** into an integer that the pArg argument points to. This capability
+** is used during testing and is only available when the SQLITE_TEST
+** compile-time option is used.
+**
+** <li>[[SQLITE_FCNTL_SIZE_HINT]]
+** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
+** layer a hint of how large the database file will grow to be during the
+** current transaction.  This hint is not guaranteed to be accurate but it
+** is often close.  The underlying VFS might choose to preallocate database
+** file space based on this hint in order to help writes to the database
+** file run faster.
+**
+** <li>[[SQLITE_FCNTL_SIZE_LIMIT]]
+** The [SQLITE_FCNTL_SIZE_LIMIT] opcode is used by in-memory VFS that
+** implements [sqlite3_deserialize()] to set an upper bound on the size
+** of the in-memory database.  The argument is a pointer to a [sqlite3_int64].
+** If the integer pointed to is negative, then it is filled in with the
+** current limit.  Otherwise the limit is set to the larger of the value
+** of the integer pointed to and the current database size.  The integer
+** pointed to is set to the new limit.
+**
+** <li>[[SQLITE_FCNTL_CHUNK_SIZE]]
+** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
+** extends and truncates the database file in chunks of a size specified
+** by the user. The fourth argument to [sqlite3_file_control()] should 
+** point to an integer (type int) containing the new chunk-size to use
+** for the nominated database. Allocating database file space in large
+** chunks (say 1MB at a time), may reduce file-system fragmentation and
+** improve performance on some systems.
+**
+** <li>[[SQLITE_FCNTL_FILE_POINTER]]
+** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer
+** to the [sqlite3_file] object associated with a particular database
+** connection.  See also [SQLITE_FCNTL_JOURNAL_POINTER].
+**
+** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]]
+** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer
+** to the [sqlite3_file] object associated with the journal file (either
+** the [rollback journal] or the [write-ahead log]) for a particular database
+** connection.  See also [SQLITE_FCNTL_FILE_POINTER].
+**
+** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
+** No longer in use.
+**
+** <li>[[SQLITE_FCNTL_SYNC]]
+** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
+** sent to the VFS immediately before the xSync method is invoked on a
+** database file descriptor. Or, if the xSync method is not invoked 
+** because the user has configured SQLite with 
+** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place 
+** of the xSync method. In most cases, the pointer argument passed with
+** this file-control is NULL. However, if the database file is being synced
+** as part of a multi-database commit, the argument points to a nul-terminated
+** string containing the transactions master-journal file name. VFSes that 
+** do not need this signal should silently ignore this opcode. Applications 
+** should not call [sqlite3_file_control()] with this opcode as doing so may 
+** disrupt the operation of the specialized VFSes that do require it.  
+**
+** <li>[[SQLITE_FCNTL_COMMIT_PHASETWO]]
+** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite
+** and sent to the VFS after a transaction has been committed immediately
+** but before the database is unlocked. VFSes that do not need this signal
+** should silently ignore this opcode. Applications should not call
+** [sqlite3_file_control()] with this opcode as doing so may disrupt the 
+** operation of the specialized VFSes that do require it.  
+**
+** <li>[[SQLITE_FCNTL_WIN32_AV_RETRY]]
+** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
+** retry counts and intervals for certain disk I/O operations for the
+** windows [VFS] in order to provide robustness in the presence of
+** anti-virus programs.  By default, the windows VFS will retry file read,
+** file write, and file delete operations up to 10 times, with a delay
+** of 25 milliseconds before the first retry and with the delay increasing
+** by an additional 25 milliseconds with each subsequent retry.  This
+** opcode allows these two values (10 retries and 25 milliseconds of delay)
+** to be adjusted.  The values are changed for all database connections
+** within the same process.  The argument is a pointer to an array of two
+** integers where the first integer is the new retry count and the second
+** integer is the delay.  If either integer is negative, then the setting
+** is not changed but instead the prior value of that setting is written
+** into the array entry, allowing the current retry settings to be
+** interrogated.  The zDbName parameter is ignored.
+**
+** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
+** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
+** persistent [WAL | Write Ahead Log] setting.  By default, the auxiliary
+** write ahead log ([WAL file]) and shared memory
+** files used for transaction control
+** are automatically deleted when the latest connection to the database
+** closes.  Setting persistent WAL mode causes those files to persist after
+** close.  Persisting the files is useful when other processes that do not
+** have write permission on the directory containing the database file want
+** to read the database file, as the WAL and shared memory files must exist
+** in order for the database to be readable.  The fourth parameter to
+** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
+** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
+** WAL mode.  If the integer is -1, then it is overwritten with the current
+** WAL persistence setting.
+**
+** <li>[[SQLITE_FCNTL_POWERSAFE_OVERWRITE]]
+** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the
+** persistent "powersafe-overwrite" or "PSOW" setting.  The PSOW setting
+** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the
+** xDeviceCharacteristics methods. The fourth parameter to
+** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
+** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage
+** mode.  If the integer is -1, then it is overwritten with the current
+** zero-damage mode setting.
+**
+** <li>[[SQLITE_FCNTL_OVERWRITE]]
+** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
+** a write transaction to indicate that, unless it is rolled back for some
+** reason, the entire database file will be overwritten by the current 
+** transaction. This is used by VACUUM operations.
+**
+** <li>[[SQLITE_FCNTL_VFSNAME]]
+** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of
+** all [VFSes] in the VFS stack.  The names are of all VFS shims and the
+** final bottom-level VFS are written into memory obtained from 
+** [sqlite3_malloc()] and the result is stored in the char* variable
+** that the fourth parameter of [sqlite3_file_control()] points to.
+** The caller is responsible for freeing the memory when done.  As with
+** all file-control actions, there is no guarantee that this will actually
+** do anything.  Callers should initialize the char* variable to a NULL
+** pointer in case this file-control is not implemented.  This file-control
+** is intended for diagnostic use only.
+**
+** <li>[[SQLITE_FCNTL_VFS_POINTER]]
+** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level
+** [VFSes] currently in use.  ^(The argument X in
+** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be
+** of type "[sqlite3_vfs] **".  This opcodes will set *X
+** to a pointer to the top-level VFS.)^
+** ^When there are multiple VFS shims in the stack, this opcode finds the
+** upper-most shim only.
+**
+** <li>[[SQLITE_FCNTL_PRAGMA]]
+** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] 
+** file control is sent to the open [sqlite3_file] object corresponding
+** to the database file to which the pragma statement refers. ^The argument
+** to the [SQLITE_FCNTL_PRAGMA] file control is an array of
+** pointers to strings (char**) in which the second element of the array
+** is the name of the pragma and the third element is the argument to the
+** pragma or NULL if the pragma has no argument.  ^The handler for an
+** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element
+** of the char** argument point to a string obtained from [sqlite3_mprintf()]
+** or the equivalent and that string will become the result of the pragma or
+** the error message if the pragma fails. ^If the
+** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal 
+** [PRAGMA] processing continues.  ^If the [SQLITE_FCNTL_PRAGMA]
+** file control returns [SQLITE_OK], then the parser assumes that the
+** VFS has handled the PRAGMA itself and the parser generates a no-op
+** prepared statement if result string is NULL, or that returns a copy
+** of the result string if the string is non-NULL.
+** ^If the [SQLITE_FCNTL_PRAGMA] file control returns
+** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
+** that the VFS encountered an error while handling the [PRAGMA] and the
+** compilation of the PRAGMA fails with an error.  ^The [SQLITE_FCNTL_PRAGMA]
+** file control occurs at the beginning of pragma statement analysis and so
+** it is able to override built-in [PRAGMA] statements.
+**
+** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
+** ^The [SQLITE_FCNTL_BUSYHANDLER]
+** file-control may be invoked by SQLite on the database file handle
+** shortly after it is opened in order to provide a custom VFS with access
+** to the connection's busy-handler callback. The argument is of type (void**)
+** - an array of two (void *) values. The first (void *) actually points
+** to a function of type (int (*)(void *)). In order to invoke the connection's
+** busy-handler, this function should be invoked with the second (void *) in
+** the array as the only argument. If it returns non-zero, then the operation
+** should be retried. If it returns zero, the custom VFS should abandon the
+** current operation.
+**
+** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
+** ^Applications can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control
+** to have SQLite generate a
+** temporary filename using the same algorithm that is followed to generate
+** temporary filenames for TEMP tables and other internal uses.  The
+** argument should be a char** which will be filled with the filename
+** written into memory obtained from [sqlite3_malloc()].  The caller should
+** invoke [sqlite3_free()] on the result to avoid a memory leak.
+**
+** <li>[[SQLITE_FCNTL_MMAP_SIZE]]
+** The [SQLITE_FCNTL_MMAP_SIZE] file control is used to query or set the
+** maximum number of bytes that will be used for memory-mapped I/O.
+** The argument is a pointer to a value of type sqlite3_int64 that
+** is an advisory maximum number of bytes in the file to memory map.  The
+** pointer is overwritten with the old value.  The limit is not changed if
+** the value originally pointed to is negative, and so the current limit 
+** can be queried by passing in a pointer to a negative number.  This
+** file-control is used internally to implement [PRAGMA mmap_size].
+**
+** <li>[[SQLITE_FCNTL_TRACE]]
+** The [SQLITE_FCNTL_TRACE] file control provides advisory information
+** to the VFS about what the higher layers of the SQLite stack are doing.
+** This file control is used by some VFS activity tracing [shims].
+** The argument is a zero-terminated string.  Higher layers in the
+** SQLite stack may generate instances of this file control if
+** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
+**
+** <li>[[SQLITE_FCNTL_HAS_MOVED]]
+** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
+** pointer to an integer and it writes a boolean into that integer depending
+** on whether or not the file has been renamed, moved, or deleted since it
+** was first opened.
+**
+** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
+** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
+** underlying native file handle associated with a file handle.  This file
+** control interprets its argument as a pointer to a native file handle and
+** writes the resulting value there.
+**
+** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
+** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging.  This
+** opcode causes the xFileControl method to swap the file handle with the one
+** pointed to by the pArg argument.  This capability is used during testing
+** and only needs to be supported when SQLITE_TEST is defined.
+**
+** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
+** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
+** be advantageous to block on the next WAL lock if the lock is not immediately
+** available.  The WAL subsystem issues this signal during rare
+** circumstances in order to fix a problem with priority inversion.
+** Applications should <em>not</em> use this file-control.
+**
+** <li>[[SQLITE_FCNTL_ZIPVFS]]
+** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other
+** VFS should return SQLITE_NOTFOUND for this opcode.
+**
+** <li>[[SQLITE_FCNTL_RBU]]
+** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
+** the RBU extension only.  All other VFS should return SQLITE_NOTFOUND for
+** this opcode.  
+**
+** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]]
+** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then
+** the file descriptor is placed in "batch write mode", which
+** means all subsequent write operations will be deferred and done
+** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].  Systems
+** that do not support batch atomic writes will return SQLITE_NOTFOUND.
+** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to
+** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or
+** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make
+** no VFS interface calls on the same [sqlite3_file] file descriptor
+** except for calls to the xWrite method and the xFileControl method
+** with [SQLITE_FCNTL_SIZE_HINT].
+**
+** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]]
+** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write
+** operations since the previous successful call to 
+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically.
+** This file control returns [SQLITE_OK] if and only if the writes were
+** all performed successfully and have been committed to persistent storage.
+** ^Regardless of whether or not it is successful, this file control takes
+** the file descriptor out of batch write mode so that all subsequent
+** write operations are independent.
+** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without
+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
+**
+** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]]
+** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write
+** operations since the previous successful call to 
+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
+** ^This file control takes the file descriptor out of batch write mode
+** so that all subsequent write operations are independent.
+** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
+**
+** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
+** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS
+** to block for up to M milliseconds before failing when attempting to 
+** obtain a file lock using the xLock or xShmLock methods of the VFS. 
+** The parameter is a pointer to a 32-bit signed integer that contains
+** the value that M is to be set to. Before returning, the 32-bit signed
+** integer is overwritten with the previous value of M.
+**
+** <li>[[SQLITE_FCNTL_DATA_VERSION]]
+** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
+** a database file.  The argument is a pointer to a 32-bit unsigned integer.
+** The "data version" for the pager is written into the pointer.  The
+** "data version" changes whenever any change occurs to the corresponding
+** database file, either through SQL statements on the same database
+** connection or through transactions committed by separate database
+** connections possibly in other processes. The [sqlite3_total_changes()]
+** interface can be used to find if any database on the connection has changed,
+** but that interface responds to changes on TEMP as well as MAIN and does
+** not provide a mechanism to detect changes to MAIN only.  Also, the
+** [sqlite3_total_changes()] interface responds to internal changes only and
+** omits changes made by other database connections.  The
+** [PRAGMA data_version] command provides a mechanism to detect changes to
+** a single attached database that occur due to other database connections,
+** but omits changes implemented by the database connection on which it is
+** called.  This file control is the only mechanism to detect changes that
+** happen either internally or externally and that are associated with
+** a particular attached database.
+**
+** <li>[[SQLITE_FCNTL_CKPT_START]]
+** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint
+** in wal mode before the client starts to copy pages from the wal
+** file to the database file.
+**
+** <li>[[SQLITE_FCNTL_CKPT_DONE]]
+** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
+** in wal mode after the client has finished copying pages from the wal
+** file to the database file, but before the *-shm file is updated to
+** record the fact that the pages have been checkpointed.
+** </ul>
+*/
+#define SQLITE_FCNTL_LOCKSTATE               1
+#define SQLITE_FCNTL_GET_LOCKPROXYFILE       2
+#define SQLITE_FCNTL_SET_LOCKPROXYFILE       3
+#define SQLITE_FCNTL_LAST_ERRNO              4
+#define SQLITE_FCNTL_SIZE_HINT               5
+#define SQLITE_FCNTL_CHUNK_SIZE              6
+#define SQLITE_FCNTL_FILE_POINTER            7
+#define SQLITE_FCNTL_SYNC_OMITTED            8
+#define SQLITE_FCNTL_WIN32_AV_RETRY          9
+#define SQLITE_FCNTL_PERSIST_WAL            10
+#define SQLITE_FCNTL_OVERWRITE              11
+#define SQLITE_FCNTL_VFSNAME                12
+#define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
+#define SQLITE_FCNTL_PRAGMA                 14
+#define SQLITE_FCNTL_BUSYHANDLER            15
+#define SQLITE_FCNTL_TEMPFILENAME           16
+#define SQLITE_FCNTL_MMAP_SIZE              18
+#define SQLITE_FCNTL_TRACE                  19
+#define SQLITE_FCNTL_HAS_MOVED              20
+#define SQLITE_FCNTL_SYNC                   21
+#define SQLITE_FCNTL_COMMIT_PHASETWO        22
+#define SQLITE_FCNTL_WIN32_SET_HANDLE       23
+#define SQLITE_FCNTL_WAL_BLOCK              24
+#define SQLITE_FCNTL_ZIPVFS                 25
+#define SQLITE_FCNTL_RBU                    26
+#define SQLITE_FCNTL_VFS_POINTER            27
+#define SQLITE_FCNTL_JOURNAL_POINTER        28
+#define SQLITE_FCNTL_WIN32_GET_HANDLE       29
+#define SQLITE_FCNTL_PDB                    30
+#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE     31
+#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE    32
+#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE  33
+#define SQLITE_FCNTL_LOCK_TIMEOUT           34
+#define SQLITE_FCNTL_DATA_VERSION           35
+#define SQLITE_FCNTL_SIZE_LIMIT             36
+#define SQLITE_FCNTL_CKPT_DONE              37
+#define SQLITE_FCNTL_RESERVE_BYTES          38
+#define SQLITE_FCNTL_CKPT_START             39
+
+/* deprecated names */
+#define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
+#define SQLITE_SET_LOCKPROXYFILE      SQLITE_FCNTL_SET_LOCKPROXYFILE
+#define SQLITE_LAST_ERRNO             SQLITE_FCNTL_LAST_ERRNO
+
+
+/*
+** CAPI3REF: Mutex Handle
+**
+** The mutex module within SQLite defines [sqlite3_mutex] to be an
+** abstract type for a mutex object.  The SQLite core never looks
+** at the internal representation of an [sqlite3_mutex].  It only
+** deals with pointers to the [sqlite3_mutex] object.
+**
+** Mutexes are created using [sqlite3_mutex_alloc()].
+*/
+typedef struct sqlite3_mutex sqlite3_mutex;
+
+/*
+** CAPI3REF: Loadable Extension Thunk
+**
+** A pointer to the opaque sqlite3_api_routines structure is passed as
+** the third parameter to entry points of [loadable extensions].  This
+** structure must be typedefed in order to work around compiler warnings
+** on some platforms.
+*/
+typedef struct sqlite3_api_routines sqlite3_api_routines;
+
+/*
+** CAPI3REF: OS Interface Object
+**
+** An instance of the sqlite3_vfs object defines the interface between
+** the SQLite core and the underlying operating system.  The "vfs"
+** in the name of the object stands for "virtual file system".  See
+** the [VFS | VFS documentation] for further information.
+**
+** The VFS interface is sometimes extended by adding new methods onto
+** the end.  Each time such an extension occurs, the iVersion field
+** is incremented.  The iVersion value started out as 1 in
+** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
+** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
+** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6].  Additional fields
+** may be appended to the sqlite3_vfs object and the iVersion value
+** may increase again in future versions of SQLite.
+** Note that due to an oversight, the structure
+** of the sqlite3_vfs object changed in the transition from
+** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
+** and yet the iVersion field was not increased.
+**
+** The szOsFile field is the size of the subclassed [sqlite3_file]
+** structure used by this VFS.  mxPathname is the maximum length of
+** a pathname in this VFS.
+**
+** Registered sqlite3_vfs objects are kept on a linked list formed by
+** the pNext pointer.  The [sqlite3_vfs_register()]
+** and [sqlite3_vfs_unregister()] interfaces manage this list
+** in a thread-safe way.  The [sqlite3_vfs_find()] interface
+** searches the list.  Neither the application code nor the VFS
+** implementation should use the pNext pointer.
+**
+** The pNext field is the only field in the sqlite3_vfs
+** structure that SQLite will ever modify.  SQLite will only access
+** or modify this field while holding a particular static mutex.
+** The application should never modify anything within the sqlite3_vfs
+** object once the object has been registered.
+**
+** The zName field holds the name of the VFS module.  The name must
+** be unique across all VFS modules.
+**
+** [[sqlite3_vfs.xOpen]]
+** ^SQLite guarantees that the zFilename parameter to xOpen
+** is either a NULL pointer or string obtained
+** from xFullPathname() with an optional suffix added.
+** ^If a suffix is added to the zFilename parameter, it will
+** consist of a single "-" character followed by no more than
+** 11 alphanumeric and/or "-" characters.
+** ^SQLite further guarantees that
+** the string will be valid and unchanged until xClose() is
+** called. Because of the previous sentence,
+** the [sqlite3_file] can safely store a pointer to the
+** filename if it needs to remember the filename for some reason.
+** If the zFilename parameter to xOpen is a NULL pointer then xOpen
+** must invent its own temporary name for the file.  ^Whenever the 
+** xFilename parameter is NULL it will also be the case that the
+** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
+**
+** The flags argument to xOpen() includes all bits set in
+** the flags argument to [sqlite3_open_v2()].  Or if [sqlite3_open()]
+** or [sqlite3_open16()] is used, then flags includes at least
+** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. 
+** If xOpen() opens a file read-only then it sets *pOutFlags to
+** include [SQLITE_OPEN_READONLY].  Other bits in *pOutFlags may be set.
+**
+** ^(SQLite will also add one of the following flags to the xOpen()
+** call, depending on the object being opened:
+**
+** <ul>
+** <li>  [SQLITE_OPEN_MAIN_DB]
+** <li>  [SQLITE_OPEN_MAIN_JOURNAL]
+** <li>  [SQLITE_OPEN_TEMP_DB]
+** <li>  [SQLITE_OPEN_TEMP_JOURNAL]
+** <li>  [SQLITE_OPEN_TRANSIENT_DB]
+** <li>  [SQLITE_OPEN_SUBJOURNAL]
+** <li>  [SQLITE_OPEN_MASTER_JOURNAL]
+** <li>  [SQLITE_OPEN_WAL]
+** </ul>)^
+**
+** The file I/O implementation can use the object type flags to
+** change the way it deals with files.  For example, an application
+** that does not care about crash recovery or rollback might make
+** the open of a journal file a no-op.  Writes to this journal would
+** also be no-ops, and any attempt to read the journal would return
+** SQLITE_IOERR.  Or the implementation might recognize that a database
+** file will be doing page-aligned sector reads and writes in a random
+** order and set up its I/O subsystem accordingly.
+**
+** SQLite might also add one of the following flags to the xOpen method:
+**
+** <ul>
+** <li> [SQLITE_OPEN_DELETEONCLOSE]
+** <li> [SQLITE_OPEN_EXCLUSIVE]
+** </ul>
+**
+** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
+** deleted when it is closed.  ^The [SQLITE_OPEN_DELETEONCLOSE]
+** will be set for TEMP databases and their journals, transient
+** databases, and subjournals.
+**
+** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
+** with the [SQLITE_OPEN_CREATE] flag, which are both directly
+** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
+** API.  The SQLITE_OPEN_EXCLUSIVE flag, when paired with the 
+** SQLITE_OPEN_CREATE, is used to indicate that file should always
+** be created, and that it is an error if it already exists.
+** It is <i>not</i> used to indicate the file should be opened 
+** for exclusive access.
+**
+** ^At least szOsFile bytes of memory are allocated by SQLite
+** to hold the [sqlite3_file] structure passed as the third
+** argument to xOpen.  The xOpen method does not have to
+** allocate the structure; it should just fill it in.  Note that
+** the xOpen method must set the sqlite3_file.pMethods to either
+** a valid [sqlite3_io_methods] object or to NULL.  xOpen must do
+** this even if the open fails.  SQLite expects that the sqlite3_file.pMethods
+** element will be valid after xOpen returns regardless of the success
+** or failure of the xOpen call.
+**
+** [[sqlite3_vfs.xAccess]]
+** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
+** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
+** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
+** to test whether a file is at least readable.  The SQLITE_ACCESS_READ
+** flag is never actually used and is not implemented in the built-in
+** VFSes of SQLite.  The file is named by the second argument and can be a
+** directory. The xAccess method returns [SQLITE_OK] on success or some
+** non-zero error code if there is an I/O error or if the name of
+** the file given in the second argument is illegal.  If SQLITE_OK
+** is returned, then non-zero or zero is written into *pResOut to indicate
+** whether or not the file is accessible.  
+**
+** ^SQLite will always allocate at least mxPathname+1 bytes for the
+** output buffer xFullPathname.  The exact size of the output buffer
+** is also passed as a parameter to both  methods. If the output buffer
+** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
+** handled as a fatal error by SQLite, vfs implementations should endeavor
+** to prevent this by setting mxPathname to a sufficiently large value.
+**
+** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64()
+** interfaces are not strictly a part of the filesystem, but they are
+** included in the VFS structure for completeness.
+** The xRandomness() function attempts to return nBytes bytes
+** of good-quality randomness into zOut.  The return value is
+** the actual number of bytes of randomness obtained.
+** The xSleep() method causes the calling thread to sleep for at
+** least the number of microseconds given.  ^The xCurrentTime()
+** method returns a Julian Day Number for the current date and time as
+** a floating point value.
+** ^The xCurrentTimeInt64() method returns, as an integer, the Julian
+** Day Number multiplied by 86400000 (the number of milliseconds in 
+** a 24-hour day).  
+** ^SQLite will use the xCurrentTimeInt64() method to get the current
+** date and time if that method is available (if iVersion is 2 or 
+** greater and the function pointer is not NULL) and will fall back
+** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
+**
+** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces
+** are not used by the SQLite core.  These optional interfaces are provided
+** by some VFSes to facilitate testing of the VFS code. By overriding 
+** system calls with functions under its control, a test program can
+** simulate faults and error conditions that would otherwise be difficult
+** or impossible to induce.  The set of system calls that can be overridden
+** varies from one VFS to another, and from one version of the same VFS to the
+** next.  Applications that use these interfaces must be prepared for any
+** or all of these interfaces to be NULL or for their behavior to change
+** from one release to the next.  Applications must not attempt to access
+** any of these methods if the iVersion of the VFS is less than 3.
+*/
+typedef struct sqlite3_vfs sqlite3_vfs;
+typedef void (*sqlite3_syscall_ptr)(void);
+struct sqlite3_vfs {
+  int iVersion;            /* Structure version number (currently 3) */
+  int szOsFile;            /* Size of subclassed sqlite3_file */
+  int mxPathname;          /* Maximum file pathname length */
+  sqlite3_vfs *pNext;      /* Next registered VFS */
+  const char *zName;       /* Name of this virtual file system */
+  void *pAppData;          /* Pointer to application-specific data */
+  int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
+               int flags, int *pOutFlags);
+  int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
+  int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
+  int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
+  void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
+  void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
+  void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
+  void (*xDlClose)(sqlite3_vfs*, void*);
+  int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
+  int (*xSleep)(sqlite3_vfs*, int microseconds);
+  int (*xCurrentTime)(sqlite3_vfs*, double*);
+  int (*xGetLastError)(sqlite3_vfs*, int, char *);
+  /*
+  ** The methods above are in version 1 of the sqlite_vfs object
+  ** definition.  Those that follow are added in version 2 or later
+  */
+  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
+  /*
+  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
+  ** Those below are for version 3 and greater.
+  */
+  int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr);
+  sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName);
+  const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
+  /*
+  ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
+  ** New fields may be appended in future versions.  The iVersion
+  ** value will increment whenever this happens. 
+  */
+};
+
+/*
+** CAPI3REF: Flags for the xAccess VFS method
+**
+** These integer constants can be used as the third parameter to
+** the xAccess method of an [sqlite3_vfs] object.  They determine
+** what kind of permissions the xAccess method is looking for.
+** With SQLITE_ACCESS_EXISTS, the xAccess method
+** simply checks whether the file exists.
+** With SQLITE_ACCESS_READWRITE, the xAccess method
+** checks whether the named directory is both readable and writable
+** (in other words, if files can be added, removed, and renamed within
+** the directory).
+** The SQLITE_ACCESS_READWRITE constant is currently used only by the
+** [temp_store_directory pragma], though this could change in a future
+** release of SQLite.
+** With SQLITE_ACCESS_READ, the xAccess method
+** checks whether the file is readable.  The SQLITE_ACCESS_READ constant is
+** currently unused, though it might be used in a future release of
+** SQLite.
+*/
+#define SQLITE_ACCESS_EXISTS    0
+#define SQLITE_ACCESS_READWRITE 1   /* Used by PRAGMA temp_store_directory */
+#define SQLITE_ACCESS_READ      2   /* Unused */
+
+/*
+** CAPI3REF: Flags for the xShmLock VFS method
+**
+** These integer constants define the various locking operations
+** allowed by the xShmLock method of [sqlite3_io_methods].  The
+** following are the only legal combinations of flags to the
+** xShmLock method:
+**
+** <ul>
+** <li>  SQLITE_SHM_LOCK | SQLITE_SHM_SHARED
+** <li>  SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE
+** <li>  SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED
+** <li>  SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE
+** </ul>
+**
+** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as
+** was given on the corresponding lock.  
+**
+** The xShmLock method can transition between unlocked and SHARED or
+** between unlocked and EXCLUSIVE.  It cannot transition between SHARED
+** and EXCLUSIVE.
+*/
+#define SQLITE_SHM_UNLOCK       1
+#define SQLITE_SHM_LOCK         2
+#define SQLITE_SHM_SHARED       4
+#define SQLITE_SHM_EXCLUSIVE    8
+
+/*
+** CAPI3REF: Maximum xShmLock index
+**
+** The xShmLock method on [sqlite3_io_methods] may use values
+** between 0 and this upper bound as its "offset" argument.
+** The SQLite core will never attempt to acquire or release a
+** lock outside of this range
+*/
+#define SQLITE_SHM_NLOCK        8
+
+
+/*
+** CAPI3REF: Initialize The SQLite Library
+**
+** ^The sqlite3_initialize() routine initializes the
+** SQLite library.  ^The sqlite3_shutdown() routine
+** deallocates any resources that were allocated by sqlite3_initialize().
+** These routines are designed to aid in process initialization and
+** shutdown on embedded systems.  Workstation applications using
+** SQLite normally do not need to invoke either of these routines.
+**
+** A call to sqlite3_initialize() is an "effective" call if it is
+** the first time sqlite3_initialize() is invoked during the lifetime of
+** the process, or if it is the first time sqlite3_initialize() is invoked
+** following a call to sqlite3_shutdown().  ^(Only an effective call
+** of sqlite3_initialize() does any initialization.  All other calls
+** are harmless no-ops.)^
+**
+** A call to sqlite3_shutdown() is an "effective" call if it is the first
+** call to sqlite3_shutdown() since the last sqlite3_initialize().  ^(Only
+** an effective call to sqlite3_shutdown() does any deinitialization.
+** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^
+**
+** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown()
+** is not.  The sqlite3_shutdown() interface must only be called from a
+** single thread.  All open [database connections] must be closed and all
+** other SQLite resources must be deallocated prior to invoking
+** sqlite3_shutdown().
+**
+** Among other things, ^sqlite3_initialize() will invoke
+** sqlite3_os_init().  Similarly, ^sqlite3_shutdown()
+** will invoke sqlite3_os_end().
+**
+** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success.
+** ^If for some reason, sqlite3_initialize() is unable to initialize
+** the library (perhaps it is unable to allocate a needed resource such
+** as a mutex) it returns an [error code] other than [SQLITE_OK].
+**
+** ^The sqlite3_initialize() routine is called internally by many other
+** SQLite interfaces so that an application usually does not need to
+** invoke sqlite3_initialize() directly.  For example, [sqlite3_open()]
+** calls sqlite3_initialize() so the SQLite library will be automatically
+** initialized when [sqlite3_open()] is called if it has not be initialized
+** already.  ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT]
+** compile-time option, then the automatic calls to sqlite3_initialize()
+** are omitted and the application must call sqlite3_initialize() directly
+** prior to using any other SQLite interface.  For maximum portability,
+** it is recommended that applications always invoke sqlite3_initialize()
+** directly prior to using any other SQLite interface.  Future releases
+** of SQLite may require this.  In other words, the behavior exhibited
+** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the
+** default behavior in some future release of SQLite.
+**
+** The sqlite3_os_init() routine does operating-system specific
+** initialization of the SQLite library.  The sqlite3_os_end()
+** routine undoes the effect of sqlite3_os_init().  Typical tasks
+** performed by these routines include allocation or deallocation
+** of static resources, initialization of global variables,
+** setting up a default [sqlite3_vfs] module, or setting up
+** a default configuration using [sqlite3_config()].
+**
+** The application should never invoke either sqlite3_os_init()
+** or sqlite3_os_end() directly.  The application should only invoke
+** sqlite3_initialize() and sqlite3_shutdown().  The sqlite3_os_init()
+** interface is called automatically by sqlite3_initialize() and
+** sqlite3_os_end() is called by sqlite3_shutdown().  Appropriate
+** implementations for sqlite3_os_init() and sqlite3_os_end()
+** are built into SQLite when it is compiled for Unix, Windows, or OS/2.
+** When [custom builds | built for other platforms]
+** (using the [SQLITE_OS_OTHER=1] compile-time
+** option) the application must supply a suitable implementation for
+** sqlite3_os_init() and sqlite3_os_end().  An application-supplied
+** implementation of sqlite3_os_init() or sqlite3_os_end()
+** must return [SQLITE_OK] on success and some other [error code] upon
+** failure.
+*/
+SQLITE_API int sqlite3_initialize(void);
+SQLITE_API int sqlite3_shutdown(void);
+SQLITE_API int sqlite3_os_init(void);
+SQLITE_API int sqlite3_os_end(void);
+
+/*
+** CAPI3REF: Configuring The SQLite Library
+**
+** The sqlite3_config() interface is used to make global configuration
+** changes to SQLite in order to tune SQLite to the specific needs of
+** the application.  The default configuration is recommended for most
+** applications and so this routine is usually not necessary.  It is
+** provided to support rare applications with unusual needs.
+**
+** <b>The sqlite3_config() interface is not threadsafe. The application
+** must ensure that no other SQLite interfaces are invoked by other
+** threads while sqlite3_config() is running.</b>
+**
+** The sqlite3_config() interface
+** may only be invoked prior to library initialization using
+** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
+** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
+** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
+** Note, however, that ^sqlite3_config() can be called as part of the
+** implementation of an application-defined [sqlite3_os_init()].
+**
+** The first argument to sqlite3_config() is an integer
+** [configuration option] that determines
+** what property of SQLite is to be configured.  Subsequent arguments
+** vary depending on the [configuration option]
+** in the first argument.
+**
+** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
+** ^If the option is unknown or SQLite is unable to set the option
+** then this routine returns a non-zero [error code].
+*/
+SQLITE_API int sqlite3_config(int, ...);
+
+/*
+** CAPI3REF: Configure database connections
+** METHOD: sqlite3
+**
+** The sqlite3_db_config() interface is used to make configuration
+** changes to a [database connection].  The interface is similar to
+** [sqlite3_config()] except that the changes apply to a single
+** [database connection] (specified in the first argument).
+**
+** The second argument to sqlite3_db_config(D,V,...)  is the
+** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code 
+** that indicates what aspect of the [database connection] is being configured.
+** Subsequent arguments vary depending on the configuration verb.
+**
+** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
+** the call is considered successful.
+*/
+SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
+
+/*
+** CAPI3REF: Memory Allocation Routines
+**
+** An instance of this object defines the interface between SQLite
+** and low-level memory allocation routines.
+**
+** This object is used in only one place in the SQLite interface.
+** A pointer to an instance of this object is the argument to
+** [sqlite3_config()] when the configuration option is
+** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC].  
+** By creating an instance of this object
+** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC])
+** during configuration, an application can specify an alternative
+** memory allocation subsystem for SQLite to use for all of its
+** dynamic memory needs.
+**
+** Note that SQLite comes with several [built-in memory allocators]
+** that are perfectly adequate for the overwhelming majority of applications
+** and that this object is only useful to a tiny minority of applications
+** with specialized memory allocation requirements.  This object is
+** also used during testing of SQLite in order to specify an alternative
+** memory allocator that simulates memory out-of-memory conditions in
+** order to verify that SQLite recovers gracefully from such
+** conditions.
+**
+** The xMalloc, xRealloc, and xFree methods must work like the
+** malloc(), realloc() and free() functions from the standard C library.
+** ^SQLite guarantees that the second argument to
+** xRealloc is always a value returned by a prior call to xRoundup.
+**
+** xSize should return the allocated size of a memory allocation
+** previously obtained from xMalloc or xRealloc.  The allocated size
+** is always at least as big as the requested size but may be larger.
+**
+** The xRoundup method returns what would be the allocated size of
+** a memory allocation given a particular requested size.  Most memory
+** allocators round up memory allocations at least to the next multiple
+** of 8.  Some allocators round up to a larger multiple or to a power of 2.
+** Every memory allocation request coming in through [sqlite3_malloc()]
+** or [sqlite3_realloc()] first calls xRoundup.  If xRoundup returns 0, 
+** that causes the corresponding memory allocation to fail.
+**
+** The xInit method initializes the memory allocator.  For example,
+** it might allocate any required mutexes or initialize internal data
+** structures.  The xShutdown method is invoked (indirectly) by
+** [sqlite3_shutdown()] and should deallocate any resources acquired
+** by xInit.  The pAppData pointer is used as the only parameter to
+** xInit and xShutdown.
+**
+** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes
+** the xInit method, so the xInit method need not be threadsafe.  The
+** xShutdown method is only called from [sqlite3_shutdown()] so it does
+** not need to be threadsafe either.  For all other methods, SQLite
+** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the
+** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which
+** it is by default) and so the methods are automatically serialized.
+** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other
+** methods must be threadsafe or else make their own arrangements for
+** serialization.
+**
+** SQLite will never invoke xInit() more than once without an intervening
+** call to xShutdown().
+*/
+typedef struct sqlite3_mem_methods sqlite3_mem_methods;
+struct sqlite3_mem_methods {
+  void *(*xMalloc)(int);         /* Memory allocation function */
+  void (*xFree)(void*);          /* Free a prior allocation */
+  void *(*xRealloc)(void*,int);  /* Resize an allocation */
+  int (*xSize)(void*);           /* Return the size of an allocation */
+  int (*xRoundup)(int);          /* Round up request size to allocation size */
+  int (*xInit)(void*);           /* Initialize the memory allocator */
+  void (*xShutdown)(void*);      /* Deinitialize the memory allocator */
+  void *pAppData;                /* Argument to xInit() and xShutdown() */
+};
+
+/*
+** CAPI3REF: Configuration Options
+** KEYWORDS: {configuration option}
+**
+** These constants are the available integer configuration options that
+** can be passed as the first argument to the [sqlite3_config()] interface.
+**
+** New configuration options may be added in future releases of SQLite.
+** Existing configuration options might be discontinued.  Applications
+** should check the return code from [sqlite3_config()] to make sure that
+** the call worked.  The [sqlite3_config()] interface will return a
+** non-zero [error code] if a discontinued or unsupported configuration option
+** is invoked.
+**
+** <dl>
+** [[SQLITE_CONFIG_SINGLETHREAD]] <dt>SQLITE_CONFIG_SINGLETHREAD</dt>
+** <dd>There are no arguments to this option.  ^This option sets the
+** [threading mode] to Single-thread.  In other words, it disables
+** all mutexing and puts SQLite into a mode where it can only be used
+** by a single thread.   ^If SQLite is compiled with
+** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
+** it is not possible to change the [threading mode] from its default
+** value of Single-thread and so [sqlite3_config()] will return 
+** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD
+** configuration option.</dd>
+**
+** [[SQLITE_CONFIG_MULTITHREAD]] <dt>SQLITE_CONFIG_MULTITHREAD</dt>
+** <dd>There are no arguments to this option.  ^This option sets the
+** [threading mode] to Multi-thread.  In other words, it disables
+** mutexing on [database connection] and [prepared statement] objects.
+** The application is responsible for serializing access to
+** [database connections] and [prepared statements].  But other mutexes
+** are enabled so that SQLite will be safe to use in a multi-threaded
+** environment as long as no two threads attempt to use the same
+** [database connection] at the same time.  ^If SQLite is compiled with
+** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
+** it is not possible to set the Multi-thread [threading mode] and
+** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
+** SQLITE_CONFIG_MULTITHREAD configuration option.</dd>
+**
+** [[SQLITE_CONFIG_SERIALIZED]] <dt>SQLITE_CONFIG_SERIALIZED</dt>
+** <dd>There are no arguments to this option.  ^This option sets the
+** [threading mode] to Serialized. In other words, this option enables
+** all mutexes including the recursive
+** mutexes on [database connection] and [prepared statement] objects.
+** In this mode (which is the default when SQLite is compiled with
+** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access
+** to [database connections] and [prepared statements] so that the
+** application is free to use the same [database connection] or the
+** same [prepared statement] in different threads at the same time.
+** ^If SQLite is compiled with
+** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
+** it is not possible to set the Serialized [threading mode] and
+** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
+** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
+**
+** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
+** <dd> ^(The SQLITE_CONFIG_MALLOC option takes a single argument which is 
+** a pointer to an instance of the [sqlite3_mem_methods] structure.
+** The argument specifies
+** alternative low-level memory allocation routines to be used in place of
+** the memory allocation routines built into SQLite.)^ ^SQLite makes
+** its own private copy of the content of the [sqlite3_mem_methods] structure
+** before the [sqlite3_config()] call returns.</dd>
+**
+** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
+** <dd> ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which
+** is a pointer to an instance of the [sqlite3_mem_methods] structure.
+** The [sqlite3_mem_methods]
+** structure is filled with the currently defined memory allocation routines.)^
+** This option can be used to overload the default memory allocation
+** routines with a wrapper that simulations memory allocation failure or
+** tracks memory usage, for example. </dd>
+**
+** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt>
+** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of
+** type int, interpreted as a boolean, which if true provides a hint to
+** SQLite that it should avoid large memory allocations if possible.
+** SQLite will run faster if it is free to make large memory allocations,
+** but some application might prefer to run slower in exchange for
+** guarantees about memory fragmentation that are possible if large
+** allocations are avoided.  This hint is normally off.
+** </dd>
+**
+** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
+** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
+** interpreted as a boolean, which enables or disables the collection of
+** memory allocation statistics. ^(When memory allocation statistics are
+** disabled, the following SQLite interfaces become non-operational:
+**   <ul>
+**   <li> [sqlite3_hard_heap_limit64()]
+**   <li> [sqlite3_memory_used()]
+**   <li> [sqlite3_memory_highwater()]
+**   <li> [sqlite3_soft_heap_limit64()]
+**   <li> [sqlite3_status64()]
+**   </ul>)^
+** ^Memory allocation statistics are enabled by default unless SQLite is
+** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
+** allocation statistics are disabled by default.
+** </dd>
+**
+** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
+** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used.
+** </dd>
+**
+** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
+** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
+** that SQLite can use for the database page cache with the default page
+** cache implementation.  
+** This configuration option is a no-op if an application-defined page
+** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
+** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
+** 8-byte aligned memory (pMem), the size of each page cache line (sz),
+** and the number of cache lines (N).
+** The sz argument should be the size of the largest database page
+** (a power of two between 512 and 65536) plus some extra bytes for each
+** page header.  ^The number of extra bytes needed by the page header
+** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ].
+** ^It is harmless, apart from the wasted memory,
+** for the sz parameter to be larger than necessary.  The pMem
+** argument must be either a NULL pointer or a pointer to an 8-byte
+** aligned block of memory of at least sz*N bytes, otherwise
+** subsequent behavior is undefined.
+** ^When pMem is not NULL, SQLite will strive to use the memory provided
+** to satisfy page cache needs, falling back to [sqlite3_malloc()] if
+** a page cache line is larger than sz bytes or if all of the pMem buffer
+** is exhausted.
+** ^If pMem is NULL and N is non-zero, then each database connection
+** does an initial bulk allocation for page cache memory
+** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or
+** of -1024*N bytes if N is negative, . ^If additional
+** page cache memory is needed beyond what is provided by the initial
+** allocation, then SQLite goes to [sqlite3_malloc()] separately for each
+** additional cache line. </dd>
+**
+** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
+** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer 
+** that SQLite will use for all of its dynamic memory allocation needs
+** beyond those provided for by [SQLITE_CONFIG_PAGECACHE].
+** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
+** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
+** [SQLITE_ERROR] if invoked otherwise.
+** ^There are three arguments to SQLITE_CONFIG_HEAP:
+** An 8-byte aligned pointer to the memory,
+** the number of bytes in the memory buffer, and the minimum allocation size.
+** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts
+** to using its default memory allocator (the system malloc() implementation),
+** undoing any prior invocation of [SQLITE_CONFIG_MALLOC].  ^If the
+** memory pointer is not NULL then the alternative memory
+** allocator is engaged to handle all of SQLites memory allocation needs.
+** The first pointer (the memory pointer) must be aligned to an 8-byte
+** boundary or subsequent behavior of SQLite will be undefined.
+** The minimum allocation size is capped at 2**12. Reasonable values
+** for the minimum allocation size are 2**5 through 2**8.</dd>
+**
+** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
+** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a
+** pointer to an instance of the [sqlite3_mutex_methods] structure.
+** The argument specifies alternative low-level mutex routines to be used
+** in place the mutex routines built into SQLite.)^  ^SQLite makes a copy of
+** the content of the [sqlite3_mutex_methods] structure before the call to
+** [sqlite3_config()] returns. ^If SQLite is compiled with
+** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
+** the entire mutexing subsystem is omitted from the build and hence calls to
+** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will
+** return [SQLITE_ERROR].</dd>
+**
+** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
+** <dd> ^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which
+** is a pointer to an instance of the [sqlite3_mutex_methods] structure.  The
+** [sqlite3_mutex_methods]
+** structure is filled with the currently defined mutex routines.)^
+** This option can be used to overload the default mutex allocation
+** routines with a wrapper used to track mutex usage for performance
+** profiling or testing, for example.   ^If SQLite is compiled with
+** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
+** the entire mutexing subsystem is omitted from the build and hence calls to
+** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will
+** return [SQLITE_ERROR].</dd>
+**
+** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
+** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine
+** the default size of lookaside memory on each [database connection].
+** The first argument is the
+** size of each lookaside buffer slot and the second is the number of
+** slots allocated to each database connection.)^  ^(SQLITE_CONFIG_LOOKASIDE
+** sets the <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
+** option to [sqlite3_db_config()] can be used to change the lookaside
+** configuration on individual connections.)^ </dd>
+**
+** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
+** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is 
+** a pointer to an [sqlite3_pcache_methods2] object.  This object specifies
+** the interface to a custom page cache implementation.)^
+** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd>
+**
+** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
+** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which
+** is a pointer to an [sqlite3_pcache_methods2] object.  SQLite copies of
+** the current page cache implementation into that object.)^ </dd>
+**
+** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
+** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
+** global [error log].
+** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
+** function with a call signature of void(*)(void*,int,const char*), 
+** and a pointer to void. ^If the function pointer is not NULL, it is
+** invoked by [sqlite3_log()] to process each logging event.  ^If the
+** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op.
+** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is
+** passed through as the first parameter to the application-defined logger
+** function whenever that function is invoked.  ^The second parameter to
+** the logger function is a copy of the first parameter to the corresponding
+** [sqlite3_log()] call and is intended to be a [result code] or an
+** [extended result code].  ^The third parameter passed to the logger is
+** log message after formatting via [sqlite3_snprintf()].
+** The SQLite logging interface is not reentrant; the logger function
+** supplied by the application must not invoke any SQLite interface.
+** In a multi-threaded application, the application-defined logger
+** function must be threadsafe. </dd>
+**
+** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
+** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int.
+** If non-zero, then URI handling is globally enabled. If the parameter is zero,
+** then URI handling is globally disabled.)^ ^If URI handling is globally
+** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()],
+** [sqlite3_open16()] or
+** specified as part of [ATTACH] commands are interpreted as URIs, regardless
+** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
+** connection is opened. ^If it is globally disabled, filenames are
+** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
+** database connection is opened. ^(By default, URI handling is globally
+** disabled. The default value may be changed by compiling with the
+** [SQLITE_USE_URI] symbol defined.)^
+**
+** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
+** <dd>^The SQLITE_CONFIG_COVERING_INDEX_SCAN option takes a single integer
+** argument which is interpreted as a boolean in order to enable or disable
+** the use of covering indices for full table scans in the query optimizer.
+** ^The default setting is determined
+** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
+** if that compile-time option is omitted.
+** The ability to disable the use of covering indices for full table scans
+** is because some incorrectly coded legacy applications might malfunction
+** when the optimization is enabled.  Providing the ability to
+** disable the optimization allows the older, buggy application code to work
+** without change even with newer versions of SQLite.
+**
+** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
+** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
+** <dd> These options are obsolete and should not be used by new code.
+** They are retained for backwards compatibility but are now no-ops.
+** </dd>
+**
+** [[SQLITE_CONFIG_SQLLOG]]
+** <dt>SQLITE_CONFIG_SQLLOG
+** <dd>This option is only available if sqlite is compiled with the
+** [SQLITE_ENABLE_SQLLOG] pre-processor macro defined. The first argument should
+** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int).
+** The second should be of type (void*). The callback is invoked by the library
+** in three separate circumstances, identified by the value passed as the
+** fourth parameter. If the fourth parameter is 0, then the database connection
+** passed as the second argument has just been opened. The third argument
+** points to a buffer containing the name of the main database file. If the
+** fourth parameter is 1, then the SQL statement that the third parameter
+** points to has just been executed. Or, if the fourth parameter is 2, then
+** the connection being passed as the second parameter is being closed. The
+** third parameter is passed NULL In this case.  An example of using this
+** configuration option can be seen in the "test_sqllog.c" source file in
+** the canonical SQLite source tree.</dd>
+**
+** [[SQLITE_CONFIG_MMAP_SIZE]]
+** <dt>SQLITE_CONFIG_MMAP_SIZE
+** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
+** that are the default mmap size limit (the default setting for
+** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
+** ^The default setting can be overridden by each database connection using
+** either the [PRAGMA mmap_size] command, or by using the
+** [SQLITE_FCNTL_MMAP_SIZE] file control.  ^(The maximum allowed mmap size
+** will be silently truncated if necessary so that it does not exceed the
+** compile-time maximum mmap size set by the
+** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
+** ^If either argument to this option is negative, then that argument is
+** changed to its compile-time default.
+**
+** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
+** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
+** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is
+** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro
+** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
+** that specifies the maximum size of the created heap.
+**
+** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
+** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
+** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which
+** is a pointer to an integer and writes into that integer the number of extra
+** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE].
+** The amount of extra space required can change depending on the compiler,
+** target platform, and SQLite version.
+**
+** [[SQLITE_CONFIG_PMASZ]]
+** <dt>SQLITE_CONFIG_PMASZ
+** <dd>^The SQLITE_CONFIG_PMASZ option takes a single parameter which
+** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded
+** sorter to that integer.  The default minimum PMA Size is set by the
+** [SQLITE_SORTER_PMASZ] compile-time option.  New threads are launched
+** to help with sort operations when multithreaded sorting
+** is enabled (using the [PRAGMA threads] command) and the amount of content
+** to be sorted exceeds the page size times the minimum of the
+** [PRAGMA cache_size] setting and this value.
+**
+** [[SQLITE_CONFIG_STMTJRNL_SPILL]]
+** <dt>SQLITE_CONFIG_STMTJRNL_SPILL
+** <dd>^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which
+** becomes the [statement journal] spill-to-disk threshold.  
+** [Statement journals] are held in memory until their size (in bytes)
+** exceeds this threshold, at which point they are written to disk.
+** Or if the threshold is -1, statement journals are always held
+** exclusively in memory.
+** Since many statement journals never become large, setting the spill
+** threshold to a value such as 64KiB can greatly reduce the amount of
+** I/O required to support statement rollback.
+** The default value for this setting is controlled by the
+** [SQLITE_STMTJRNL_SPILL] compile-time option.
+**
+** [[SQLITE_CONFIG_SORTERREF_SIZE]]
+** <dt>SQLITE_CONFIG_SORTERREF_SIZE
+** <dd>The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter
+** of type (int) - the new value of the sorter-reference size threshold.
+** Usually, when SQLite uses an external sort to order records according
+** to an ORDER BY clause, all fields required by the caller are present in the
+** sorted records. However, if SQLite determines based on the declared type
+** of a table column that its values are likely to be very large - larger
+** than the configured sorter-reference size threshold - then a reference
+** is stored in each sorted record and the required column values loaded
+** from the database as records are returned in sorted order. The default
+** value for this option is to never use this optimization. Specifying a 
+** negative value for this option restores the default behaviour.
+** This option is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
+**
+** [[SQLITE_CONFIG_MEMDB_MAXSIZE]]
+** <dt>SQLITE_CONFIG_MEMDB_MAXSIZE
+** <dd>The SQLITE_CONFIG_MEMDB_MAXSIZE option accepts a single parameter
+** [sqlite3_int64] parameter which is the default maximum size for an in-memory
+** database created using [sqlite3_deserialize()].  This default maximum
+** size can be adjusted up or down for individual databases using the
+** [SQLITE_FCNTL_SIZE_LIMIT] [sqlite3_file_control|file-control].  If this
+** configuration setting is never used, then the default maximum is determined
+** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option.  If that
+** compile-time option is not set, then the default maximum is 1073741824.
+** </dl>
+*/
+#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
+#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
+#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
+#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
+#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
+#define SQLITE_CONFIG_SCRATCH       6  /* No longer used */
+#define SQLITE_CONFIG_PAGECACHE     7  /* void*, int sz, int N */
+#define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
+#define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
+#define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
+#define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
+/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ 
+#define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
+#define SQLITE_CONFIG_PCACHE       14  /* no-op */
+#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
+#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
+#define SQLITE_CONFIG_URI          17  /* int */
+#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
+#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
+#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
+#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
+#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
+#define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
+#define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
+#define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
+#define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
+#define SQLITE_CONFIG_SMALL_MALLOC        27  /* boolean */
+#define SQLITE_CONFIG_SORTERREF_SIZE      28  /* int nByte */
+#define SQLITE_CONFIG_MEMDB_MAXSIZE       29  /* sqlite3_int64 */
+
+/*
+** CAPI3REF: Database Connection Configuration Options
+**
+** These constants are the available integer configuration options that
+** can be passed as the second argument to the [sqlite3_db_config()] interface.
+**
+** New configuration options may be added in future releases of SQLite.
+** Existing configuration options might be discontinued.  Applications
+** should check the return code from [sqlite3_db_config()] to make sure that
+** the call worked.  ^The [sqlite3_db_config()] interface will return a
+** non-zero [error code] if a discontinued or unsupported configuration option
+** is invoked.
+**
+** <dl>
+** [[SQLITE_DBCONFIG_LOOKASIDE]]
+** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
+** <dd> ^This option takes three additional arguments that determine the 
+** [lookaside memory allocator] configuration for the [database connection].
+** ^The first argument (the third parameter to [sqlite3_db_config()] is a
+** pointer to a memory buffer to use for lookaside memory.
+** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
+** may be NULL in which case SQLite will allocate the
+** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the
+** size of each lookaside buffer slot.  ^The third argument is the number of
+** slots.  The size of the buffer in the first argument must be greater than
+** or equal to the product of the second and third arguments.  The buffer
+** must be aligned to an 8-byte boundary.  ^If the second argument to
+** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally
+** rounded down to the next smaller multiple of 8.  ^(The lookaside memory
+** configuration for a database connection can only be changed when that
+** connection is not currently using lookaside memory, or in other words
+** when the "current value" returned by
+** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
+** Any attempt to change the lookaside memory configuration when lookaside
+** memory is in use leaves the configuration unchanged and returns 
+** [SQLITE_BUSY].)^</dd>
+**
+** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
+** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
+** <dd> ^This option is used to enable or disable the enforcement of
+** [foreign key constraints].  There should be two additional arguments.
+** The first argument is an integer which is 0 to disable FK enforcement,
+** positive to enable FK enforcement or negative to leave FK enforcement
+** unchanged.  The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether FK enforcement is off or on
+** following this call.  The second parameter may be a NULL pointer, in
+** which case the FK enforcement setting is not reported back. </dd>
+**
+** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
+** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
+** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
+** There should be two additional arguments.
+** The first argument is an integer which is 0 to disable triggers,
+** positive to enable triggers or negative to leave the setting unchanged.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether triggers are disabled or enabled
+** following this call.  The second parameter may be a NULL pointer, in
+** which case the trigger setting is not reported back. </dd>
+**
+** [[SQLITE_DBCONFIG_ENABLE_VIEW]]
+** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt>
+** <dd> ^This option is used to enable or disable [CREATE VIEW | views].
+** There should be two additional arguments.
+** The first argument is an integer which is 0 to disable views,
+** positive to enable views or negative to leave the setting unchanged.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether views are disabled or enabled
+** following this call.  The second parameter may be a NULL pointer, in
+** which case the view setting is not reported back. </dd>
+**
+** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
+** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
+** <dd> ^This option is used to enable or disable the
+** [fts3_tokenizer()] function which is part of the
+** [FTS3] full-text search engine extension.
+** There should be two additional arguments.
+** The first argument is an integer which is 0 to disable fts3_tokenizer() or
+** positive to enable fts3_tokenizer() or negative to leave the setting
+** unchanged.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
+** following this call.  The second parameter may be a NULL pointer, in
+** which case the new setting is not reported back. </dd>
+**
+** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
+** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
+** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
+** interface independently of the [load_extension()] SQL function.
+** The [sqlite3_enable_load_extension()] API enables or disables both the
+** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
+** There should be two additional arguments.
+** When the first argument to this interface is 1, then only the C-API is
+** enabled and the SQL function remains disabled.  If the first argument to
+** this interface is 0, then both the C-API and the SQL function are disabled.
+** If the first argument is -1, then no changes are made to state of either the
+** C-API or the SQL function.
+** The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
+** is disabled or enabled following this call.  The second parameter may
+** be a NULL pointer, in which case the new setting is not reported back.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
+** <dd> ^This option is used to change the name of the "main" database
+** schema.  ^The sole argument is a pointer to a constant UTF8 string
+** which will become the new schema name in place of "main".  ^SQLite
+** does not make a copy of the new main schema name string, so the application
+** must ensure that the argument passed into this DBCONFIG option is unchanged
+** until after the database connection closes.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] 
+** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
+** <dd> Usually, when a database in wal mode is closed or detached from a 
+** database handle, SQLite checks if this will mean that there are now no 
+** connections at all to the database. If so, it performs a checkpoint 
+** operation before closing the connection. This option may be used to
+** override this behaviour. The first parameter passed to this operation
+** is an integer - positive to disable checkpoints-on-close, or zero (the
+** default) to enable them, and negative to leave the setting unchanged.
+** The second parameter is a pointer to an integer
+** into which is written 0 or 1 to indicate whether checkpoints-on-close
+** have been disabled - 0 if they are not disabled, 1 if they are.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
+** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
+** the [query planner stability guarantee] (QPSG).  When the QPSG is active,
+** a single SQL query statement will always use the same algorithm regardless
+** of values of [bound parameters].)^ The QPSG disables some query optimizations
+** that look at the values of bound parameters, which can make some queries
+** slower.  But the QPSG has the advantage of more predictable behavior.  With
+** the QPSG active, SQLite will always use the same query plan in the field as
+** was used during testing in the lab.
+** The first argument to this setting is an integer which is 0 to disable 
+** the QPSG, positive to enable QPSG, or negative to leave the setting
+** unchanged. The second parameter is a pointer to an integer into which
+** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
+** following this call.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
+** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not 
+** include output for any operations performed by trigger programs. This
+** option is used to set or clear (the default) a flag that governs this
+** behavior. The first parameter passed to this operation is an integer -
+** positive to enable output for trigger programs, or zero to disable it,
+** or negative to leave the setting unchanged.
+** The second parameter is a pointer to an integer into which is written 
+** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if 
+** it is not disabled, 1 if it is.  
+** </dd>
+**
+** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
+** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
+** [VACUUM] in order to reset a database back to an empty database
+** with no schema and no content. The following process works even for
+** a badly corrupted database file:
+** <ol>
+** <li> If the database connection is newly opened, make sure it has read the
+**      database schema by preparing then discarding some query against the
+**      database, or calling sqlite3_table_column_metadata(), ignoring any
+**      errors.  This step is only necessary if the application desires to keep
+**      the database in WAL mode after the reset if it was in WAL mode before
+**      the reset.  
+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
+** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
+** </ol>
+** Because resetting a database is destructive and irreversible, the
+** process requires the use of this obscure API and multiple steps to help
+** ensure that it does not happen by accident.
+**
+** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
+** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
+** "defensive" flag for a database connection.  When the defensive
+** flag is enabled, language features that allow ordinary SQL to 
+** deliberately corrupt the database file are disabled.  The disabled
+** features include but are not limited to the following:
+** <ul>
+** <li> The [PRAGMA writable_schema=ON] statement.
+** <li> The [PRAGMA journal_mode=OFF] statement.
+** <li> Writes to the [sqlite_dbpage] virtual table.
+** <li> Direct writes to [shadow tables].
+** </ul>
+** </dd>
+**
+** [[SQLITE_DBCONFIG_WRITABLE_SCHEMA]] <dt>SQLITE_DBCONFIG_WRITABLE_SCHEMA</dt>
+** <dd>The SQLITE_DBCONFIG_WRITABLE_SCHEMA option activates or deactivates the
+** "writable_schema" flag. This has the same effect and is logically equivalent
+** to setting [PRAGMA writable_schema=ON] or [PRAGMA writable_schema=OFF].
+** The first argument to this setting is an integer which is 0 to disable 
+** the writable_schema, positive to enable writable_schema, or negative to
+** leave the setting unchanged. The second parameter is a pointer to an
+** integer into which is written 0 or 1 to indicate whether the writable_schema
+** is enabled or disabled following this call.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]]
+** <dt>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE</dt>
+** <dd>The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates
+** the legacy behavior of the [ALTER TABLE RENAME] command such it
+** behaves as it did prior to [version 3.24.0] (2018-06-04).  See the
+** "Compatibility Notice" on the [ALTER TABLE RENAME documentation] for
+** additional information. This feature can also be turned on and off
+** using the [PRAGMA legacy_alter_table] statement.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_DQS_DML]]
+** <dt>SQLITE_DBCONFIG_DQS_DML</td>
+** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
+** the legacy [double-quoted string literal] misfeature for DML statements
+** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_DQS_DDL]]
+** <dt>SQLITE_DBCONFIG_DQS_DDL</td>
+** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates
+** the legacy [double-quoted string literal] misfeature for DDL statements,
+** such as CREATE TABLE and CREATE INDEX. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]]
+** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td>
+** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to
+** assume that database schemas (the contents of the [sqlite_master] tables)
+** are untainted by malicious content.
+** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite
+** takes additional defensive steps to protect the application from harm
+** including:
+** <ul>
+** <li> Prohibit the use of SQL functions inside triggers, views,
+** CHECK constraints, DEFAULT clauses, expression indexes, 
+** partial indexes, or generated columns
+** unless those functions are tagged with [SQLITE_INNOCUOUS].
+** <li> Prohibit the use of virtual tables inside of triggers or views
+** unless those virtual tables are tagged with [SQLITE_VTAB_INNOCUOUS].
+** </ul>
+** This setting defaults to "on" for legacy compatibility, however
+** all applications are advised to turn it off if possible. This setting
+** can also be controlled using the [PRAGMA trusted_schema] statement.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]]
+** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</td>
+** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates
+** the legacy file format flag.  When activated, this flag causes all newly
+** created database file to have a schema format version number (the 4-byte
+** integer found at offset 44 into the database header) of 1.  This in turn
+** means that the resulting database file will be readable and writable by
+** any SQLite version back to 3.0.0 ([dateof:3.0.0]).  Without this setting,
+** newly created databases are generally not understandable by SQLite versions
+** prior to 3.3.0 ([dateof:3.3.0]).  As these words are written, there
+** is now scarcely any need to generated database files that are compatible 
+** all the way back to version 3.0.0, and so this setting is of little
+** practical use, but is provided so that SQLite can continue to claim the
+** ability to generate new database files that are compatible with  version
+** 3.0.0.
+** <p>Note that when the SQLITE_DBCONFIG_LEGACY_FILE_FORMAT setting is on,
+** the [VACUUM] command will fail with an obscure error when attempting to
+** process a table with generated columns and a descending index.  This is
+** not considered a bug since SQLite versions 3.3.0 and earlier do not support
+** either generated columns or decending indexes.
+** </dd>
+** </dl>
+*/
+#define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
+#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
+#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
+#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
+#define SQLITE_DBCONFIG_TRIGGER_EQP           1008 /* int int* */
+#define SQLITE_DBCONFIG_RESET_DATABASE        1009 /* int int* */
+#define SQLITE_DBCONFIG_DEFENSIVE             1010 /* int int* */
+#define SQLITE_DBCONFIG_WRITABLE_SCHEMA       1011 /* int int* */
+#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE    1012 /* int int* */
+#define SQLITE_DBCONFIG_DQS_DML               1013 /* int int* */
+#define SQLITE_DBCONFIG_DQS_DDL               1014 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_VIEW           1015 /* int int* */
+#define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT    1016 /* int int* */
+#define SQLITE_DBCONFIG_TRUSTED_SCHEMA        1017 /* int int* */
+#define SQLITE_DBCONFIG_MAX                   1017 /* Largest DBCONFIG */
+
+/*
+** CAPI3REF: Enable Or Disable Extended Result Codes
+** METHOD: sqlite3
+**
+** ^The sqlite3_extended_result_codes() routine enables or disables the
+** [extended result codes] feature of SQLite. ^The extended result
+** codes are disabled by default for historical compatibility.
+*/
+SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
+
+/*
+** CAPI3REF: Last Insert Rowid
+** METHOD: sqlite3
+**
+** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
+** has a unique 64-bit signed
+** integer key called the [ROWID | "rowid"]. ^The rowid is always available
+** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
+** names are not also used by explicitly declared columns. ^If
+** the table has a column of type [INTEGER PRIMARY KEY] then that column
+** is another alias for the rowid.
+**
+** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
+** the most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
+** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred 
+** on the database connection D, then sqlite3_last_insert_rowid(D) returns 
+** zero.
+**
+** As well as being set automatically as rows are inserted into database
+** tables, the value returned by this function may be set explicitly by
+** [sqlite3_set_last_insert_rowid()]
+**
+** Some virtual table implementations may INSERT rows into rowid tables as
+** part of committing a transaction (e.g. to flush data accumulated in memory
+** to disk). In this case subsequent calls to this function return the rowid
+** associated with these internal INSERT operations, which leads to 
+** unintuitive results. Virtual table implementations that do write to rowid
+** tables in this way can avoid this problem by restoring the original 
+** rowid value using [sqlite3_set_last_insert_rowid()] before returning 
+** control to the user.
+**
+** ^(If an [INSERT] occurs within a trigger then this routine will 
+** return the [rowid] of the inserted row as long as the trigger is 
+** running. Once the trigger program ends, the value returned 
+** by this routine reverts to what it was before the trigger was fired.)^
+**
+** ^An [INSERT] that fails due to a constraint violation is not a
+** successful [INSERT] and does not change the value returned by this
+** routine.  ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
+** and INSERT OR ABORT make no changes to the return value of this
+** routine when their insertion fails.  ^(When INSERT OR REPLACE
+** encounters a constraint violation, it does not fail.  The
+** INSERT continues to completion after deleting rows that caused
+** the constraint problem so INSERT OR REPLACE will always change
+** the return value of this interface.)^
+**
+** ^For the purposes of this routine, an [INSERT] is considered to
+** be successful even if it is subsequently rolled back.
+**
+** This function is accessible to SQL statements via the
+** [last_insert_rowid() SQL function].
+**
+** If a separate thread performs a new [INSERT] on the same
+** database connection while the [sqlite3_last_insert_rowid()]
+** function is running and thus changes the last insert [rowid],
+** then the value returned by [sqlite3_last_insert_rowid()] is
+** unpredictable and might not equal either the old or the new
+** last insert [rowid].
+*/
+SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
+
+/*
+** CAPI3REF: Set the Last Insert Rowid value.
+** METHOD: sqlite3
+**
+** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
+** set the value returned by calling sqlite3_last_insert_rowid(D) to R 
+** without inserting a row into the database.
+*/
+SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
+
+/*
+** CAPI3REF: Count The Number Of Rows Modified
+** METHOD: sqlite3
+**
+** ^This function returns the number of rows modified, inserted or
+** deleted by the most recently completed INSERT, UPDATE or DELETE
+** statement on the database connection specified by the only parameter.
+** ^Executing any other type of SQL statement does not modify the value
+** returned by this function.
+**
+** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
+** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], 
+** [foreign key actions] or [REPLACE] constraint resolution are not counted.
+** 
+** Changes to a view that are intercepted by 
+** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value 
+** returned by sqlite3_changes() immediately after an INSERT, UPDATE or 
+** DELETE statement run on a view is always zero. Only changes made to real 
+** tables are counted.
+**
+** Things are more complicated if the sqlite3_changes() function is
+** executed while a trigger program is running. This may happen if the
+** program uses the [changes() SQL function], or if some other callback
+** function invokes sqlite3_changes() directly. Essentially:
+** 
+** <ul>
+**   <li> ^(Before entering a trigger program the value returned by
+**        sqlite3_changes() function is saved. After the trigger program 
+**        has finished, the original value is restored.)^
+** 
+**   <li> ^(Within a trigger program each INSERT, UPDATE and DELETE 
+**        statement sets the value returned by sqlite3_changes() 
+**        upon completion as normal. Of course, this value will not include 
+**        any changes performed by sub-triggers, as the sqlite3_changes() 
+**        value will be saved and restored after each sub-trigger has run.)^
+** </ul>
+** 
+** ^This means that if the changes() SQL function (or similar) is used
+** by the first INSERT, UPDATE or DELETE statement within a trigger, it 
+** returns the value as set when the calling statement began executing.
+** ^If it is used by the second or subsequent such statement within a trigger 
+** program, the value returned reflects the number of rows modified by the 
+** previous INSERT, UPDATE or DELETE statement within the same trigger.
+**
+** If a separate thread makes changes on the same database connection
+** while [sqlite3_changes()] is running then the value returned
+** is unpredictable and not meaningful.
+**
+** See also:
+** <ul>
+** <li> the [sqlite3_total_changes()] interface
+** <li> the [count_changes pragma]
+** <li> the [changes() SQL function]
+** <li> the [data_version pragma]
+** </ul>
+*/
+SQLITE_API int sqlite3_changes(sqlite3*);
+
+/*
+** CAPI3REF: Total Number Of Rows Modified
+** METHOD: sqlite3
+**
+** ^This function returns the total number of rows inserted, modified or
+** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
+** since the database connection was opened, including those executed as
+** part of trigger programs. ^Executing any other type of SQL statement
+** does not affect the value returned by sqlite3_total_changes().
+** 
+** ^Changes made as part of [foreign key actions] are included in the
+** count, but those made as part of REPLACE constraint resolution are
+** not. ^Changes to a view that are intercepted by INSTEAD OF triggers 
+** are not counted.
+**
+** The [sqlite3_total_changes(D)] interface only reports the number
+** of rows that changed due to SQL statement run against database
+** connection D.  Any changes by other database connections are ignored.
+** To detect changes against a database file from other database
+** connections use the [PRAGMA data_version] command or the
+** [SQLITE_FCNTL_DATA_VERSION] [file control].
+** 
+** If a separate thread makes changes on the same database connection
+** while [sqlite3_total_changes()] is running then the value
+** returned is unpredictable and not meaningful.
+**
+** See also:
+** <ul>
+** <li> the [sqlite3_changes()] interface
+** <li> the [count_changes pragma]
+** <li> the [changes() SQL function]
+** <li> the [data_version pragma]
+** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
+** </ul>
+*/
+SQLITE_API int sqlite3_total_changes(sqlite3*);
+
+/*
+** CAPI3REF: Interrupt A Long-Running Query
+** METHOD: sqlite3
+**
+** ^This function causes any pending database operation to abort and
+** return at its earliest opportunity. This routine is typically
+** called in response to a user action such as pressing "Cancel"
+** or Ctrl-C where the user wants a long query operation to halt
+** immediately.
+**
+** ^It is safe to call this routine from a thread different from the
+** thread that is currently running the database operation.  But it
+** is not safe to call this routine with a [database connection] that
+** is closed or might close before sqlite3_interrupt() returns.
+**
+** ^If an SQL operation is very nearly finished at the time when
+** sqlite3_interrupt() is called, then it might not have an opportunity
+** to be interrupted and might continue to completion.
+**
+** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT].
+** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE
+** that is inside an explicit transaction, then the entire transaction
+** will be rolled back automatically.
+**
+** ^The sqlite3_interrupt(D) call is in effect until all currently running
+** SQL statements on [database connection] D complete.  ^Any new SQL statements
+** that are started after the sqlite3_interrupt() call and before the 
+** running statement count reaches zero are interrupted as if they had been
+** running prior to the sqlite3_interrupt() call.  ^New SQL statements
+** that are started after the running statement count reaches zero are
+** not effected by the sqlite3_interrupt().
+** ^A call to sqlite3_interrupt(D) that occurs when there are no running
+** SQL statements is a no-op and has no effect on SQL statements
+** that are started after the sqlite3_interrupt() call returns.
+*/
+SQLITE_API void sqlite3_interrupt(sqlite3*);
+
+/*
+** CAPI3REF: Determine If An SQL Statement Is Complete
+**
+** These routines are useful during command-line input to determine if the
+** currently entered text seems to form a complete SQL statement or
+** if additional input is needed before sending the text into
+** SQLite for parsing.  ^These routines return 1 if the input string
+** appears to be a complete SQL statement.  ^A statement is judged to be
+** complete if it ends with a semicolon token and is not a prefix of a
+** well-formed CREATE TRIGGER statement.  ^Semicolons that are embedded within
+** string literals or quoted identifier names or comments are not
+** independent tokens (they are part of the token in which they are
+** embedded) and thus do not count as a statement terminator.  ^Whitespace
+** and comments that follow the final semicolon are ignored.
+**
+** ^These routines return 0 if the statement is incomplete.  ^If a
+** memory allocation fails, then SQLITE_NOMEM is returned.
+**
+** ^These routines do not parse the SQL statements thus
+** will not detect syntactically incorrect SQL.
+**
+** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior 
+** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked
+** automatically by sqlite3_complete16().  If that initialization fails,
+** then the return value from sqlite3_complete16() will be non-zero
+** regardless of whether or not the input SQL is complete.)^
+**
+** The input to [sqlite3_complete()] must be a zero-terminated
+** UTF-8 string.
+**
+** The input to [sqlite3_complete16()] must be a zero-terminated
+** UTF-16 string in native byte order.
+*/
+SQLITE_API int sqlite3_complete(const char *sql);
+SQLITE_API int sqlite3_complete16(const void *sql);
+
+/*
+** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
+** KEYWORDS: {busy-handler callback} {busy handler}
+** METHOD: sqlite3
+**
+** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
+** that might be invoked with argument P whenever
+** an attempt is made to access a database table associated with
+** [database connection] D when another thread
+** or process has the table locked.
+** The sqlite3_busy_handler() interface is used to implement
+** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout].
+**
+** ^If the busy callback is NULL, then [SQLITE_BUSY]
+** is returned immediately upon encountering the lock.  ^If the busy callback
+** is not NULL, then the callback might be invoked with two arguments.
+**
+** ^The first argument to the busy handler is a copy of the void* pointer which
+** is the third argument to sqlite3_busy_handler().  ^The second argument to
+** the busy handler callback is the number of times that the busy handler has
+** been invoked previously for the same locking event.  ^If the
+** busy callback returns 0, then no additional attempts are made to
+** access the database and [SQLITE_BUSY] is returned
+** to the application.
+** ^If the callback returns non-zero, then another attempt
+** is made to access the database and the cycle repeats.
+**
+** The presence of a busy handler does not guarantee that it will be invoked
+** when there is lock contention. ^If SQLite determines that invoking the busy
+** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY]
+** to the application instead of invoking the 
+** busy handler.
+** Consider a scenario where one process is holding a read lock that
+** it is trying to promote to a reserved lock and
+** a second process is holding a reserved lock that it is trying
+** to promote to an exclusive lock.  The first process cannot proceed
+** because it is blocked by the second and the second process cannot
+** proceed because it is blocked by the first.  If both processes
+** invoke the busy handlers, neither will make any progress.  Therefore,
+** SQLite returns [SQLITE_BUSY] for the first process, hoping that this
+** will induce the first process to release its read lock and allow
+** the second process to proceed.
+**
+** ^The default busy callback is NULL.
+**
+** ^(There can only be a single busy handler defined for each
+** [database connection].  Setting a new busy handler clears any
+** previously set handler.)^  ^Note that calling [sqlite3_busy_timeout()]
+** or evaluating [PRAGMA busy_timeout=N] will change the
+** busy handler and thus clear any previously set busy handler.
+**
+** The busy callback should not take any actions which modify the
+** database connection that invoked the busy handler.  In other words,
+** the busy handler is not reentrant.  Any such actions
+** result in undefined behavior.
+** 
+** A busy handler must not close the database connection
+** or [prepared statement] that invoked the busy handler.
+*/
+SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
+
+/*
+** CAPI3REF: Set A Busy Timeout
+** METHOD: sqlite3
+**
+** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
+** for a specified amount of time when a table is locked.  ^The handler
+** will sleep multiple times until at least "ms" milliseconds of sleeping
+** have accumulated.  ^After at least "ms" milliseconds of sleeping,
+** the handler returns 0 which causes [sqlite3_step()] to return
+** [SQLITE_BUSY].
+**
+** ^Calling this routine with an argument less than or equal to zero
+** turns off all busy handlers.
+**
+** ^(There can only be a single busy handler for a particular
+** [database connection] at any given moment.  If another busy handler
+** was defined  (using [sqlite3_busy_handler()]) prior to calling
+** this routine, that other busy handler is cleared.)^
+**
+** See also:  [PRAGMA busy_timeout]
+*/
+SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
+
+/*
+** CAPI3REF: Convenience Routines For Running Queries
+** METHOD: sqlite3
+**
+** This is a legacy interface that is preserved for backwards compatibility.
+** Use of this interface is not recommended.
+**
+** Definition: A <b>result table</b> is memory data structure created by the
+** [sqlite3_get_table()] interface.  A result table records the
+** complete query results from one or more queries.
+**
+** The table conceptually has a number of rows and columns.  But
+** these numbers are not part of the result table itself.  These
+** numbers are obtained separately.  Let N be the number of rows
+** and M be the number of columns.
+**
+** A result table is an array of pointers to zero-terminated UTF-8 strings.
+** There are (N+1)*M elements in the array.  The first M pointers point
+** to zero-terminated strings that  contain the names of the columns.
+** The remaining entries all point to query results.  NULL values result
+** in NULL pointers.  All other values are in their UTF-8 zero-terminated
+** string representation as returned by [sqlite3_column_text()].
+**
+** A result table might consist of one or more memory allocations.
+** It is not safe to pass a result table directly to [sqlite3_free()].
+** A result table should be deallocated using [sqlite3_free_table()].
+**
+** ^(As an example of the result table format, suppose a query result
+** is as follows:
+**
+** <blockquote><pre>
+**        Name        | Age
+**        -----------------------
+**        Alice       | 43
+**        Bob         | 28
+**        Cindy       | 21
+** </pre></blockquote>
+**
+** There are two columns (M==2) and three rows (N==3).  Thus the
+** result table has 8 entries.  Suppose the result table is stored
+** in an array named azResult.  Then azResult holds this content:
+**
+** <blockquote><pre>
+**        azResult&#91;0] = "Name";
+**        azResult&#91;1] = "Age";
+**        azResult&#91;2] = "Alice";
+**        azResult&#91;3] = "43";
+**        azResult&#91;4] = "Bob";
+**        azResult&#91;5] = "28";
+**        azResult&#91;6] = "Cindy";
+**        azResult&#91;7] = "21";
+** </pre></blockquote>)^
+**
+** ^The sqlite3_get_table() function evaluates one or more
+** semicolon-separated SQL statements in the zero-terminated UTF-8
+** string of its 2nd parameter and returns a result table to the
+** pointer given in its 3rd parameter.
+**
+** After the application has finished with the result from sqlite3_get_table(),
+** it must pass the result table pointer to sqlite3_free_table() in order to
+** release the memory that was malloced.  Because of the way the
+** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling
+** function must not try to call [sqlite3_free()] directly.  Only
+** [sqlite3_free_table()] is able to release the memory properly and safely.
+**
+** The sqlite3_get_table() interface is implemented as a wrapper around
+** [sqlite3_exec()].  The sqlite3_get_table() routine does not have access
+** to any internal data structures of SQLite.  It uses only the public
+** interface defined here.  As a consequence, errors that occur in the
+** wrapper layer outside of the internal [sqlite3_exec()] call are not
+** reflected in subsequent calls to [sqlite3_errcode()] or
+** [sqlite3_errmsg()].
+*/
+SQLITE_API int sqlite3_get_table(
+  sqlite3 *db,          /* An open database */
+  const char *zSql,     /* SQL to be evaluated */
+  char ***pazResult,    /* Results of the query */
+  int *pnRow,           /* Number of result rows written here */
+  int *pnColumn,        /* Number of result columns written here */
+  char **pzErrmsg       /* Error msg written here */
+);
+SQLITE_API void sqlite3_free_table(char **result);
+
+/*
+** CAPI3REF: Formatted String Printing Functions
+**
+** These routines are work-alikes of the "printf()" family of functions
+** from the standard C library.
+** These routines understand most of the common formatting options from
+** the standard library printf() 
+** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).
+** See the [built-in printf()] documentation for details.
+**
+** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
+** results into memory obtained from [sqlite3_malloc64()].
+** The strings returned by these two routines should be
+** released by [sqlite3_free()].  ^Both routines return a
+** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough
+** memory to hold the resulting string.
+**
+** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
+** the standard C library.  The result is written into the
+** buffer supplied as the second parameter whose size is given by
+** the first parameter. Note that the order of the
+** first two parameters is reversed from snprintf().)^  This is an
+** historical accident that cannot be fixed without breaking
+** backwards compatibility.  ^(Note also that sqlite3_snprintf()
+** returns a pointer to its buffer instead of the number of
+** characters actually written into the buffer.)^  We admit that
+** the number of characters written would be a more useful return
+** value but we cannot change the implementation of sqlite3_snprintf()
+** now without breaking compatibility.
+**
+** ^As long as the buffer size is greater than zero, sqlite3_snprintf()
+** guarantees that the buffer is always zero-terminated.  ^The first
+** parameter "n" is the total size of the buffer, including space for
+** the zero terminator.  So the longest string that can be completely
+** written will be n-1 characters.
+**
+** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
+**
+** See also:  [built-in printf()], [printf() SQL function]
+*/
+SQLITE_API char *sqlite3_mprintf(const char*,...);
+SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
+SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
+SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
+
+/*
+** CAPI3REF: Memory Allocation Subsystem
+**
+** The SQLite core uses these three routines for all of its own
+** internal memory allocation needs. "Core" in the previous sentence
+** does not include operating-system specific [VFS] implementation.  The
+** Windows VFS uses native malloc() and free() for some operations.
+**
+** ^The sqlite3_malloc() routine returns a pointer to a block
+** of memory at least N bytes in length, where N is the parameter.
+** ^If sqlite3_malloc() is unable to obtain sufficient free
+** memory, it returns a NULL pointer.  ^If the parameter N to
+** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
+** a NULL pointer.
+**
+** ^The sqlite3_malloc64(N) routine works just like
+** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead
+** of a signed 32-bit integer.
+**
+** ^Calling sqlite3_free() with a pointer previously returned
+** by sqlite3_malloc() or sqlite3_realloc() releases that memory so
+** that it might be reused.  ^The sqlite3_free() routine is
+** a no-op if is called with a NULL pointer.  Passing a NULL pointer
+** to sqlite3_free() is harmless.  After being freed, memory
+** should neither be read nor written.  Even reading previously freed
+** memory might result in a segmentation fault or other severe error.
+** Memory corruption, a segmentation fault, or other severe error
+** might result if sqlite3_free() is called with a non-NULL pointer that
+** was not obtained from sqlite3_malloc() or sqlite3_realloc().
+**
+** ^The sqlite3_realloc(X,N) interface attempts to resize a
+** prior memory allocation X to be at least N bytes.
+** ^If the X parameter to sqlite3_realloc(X,N)
+** is a NULL pointer then its behavior is identical to calling
+** sqlite3_malloc(N).
+** ^If the N parameter to sqlite3_realloc(X,N) is zero or
+** negative then the behavior is exactly the same as calling
+** sqlite3_free(X).
+** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation
+** of at least N bytes in size or NULL if insufficient memory is available.
+** ^If M is the size of the prior allocation, then min(N,M) bytes
+** of the prior allocation are copied into the beginning of buffer returned
+** by sqlite3_realloc(X,N) and the prior allocation is freed.
+** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the
+** prior allocation is not freed.
+**
+** ^The sqlite3_realloc64(X,N) interfaces works the same as
+** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead
+** of a 32-bit signed integer.
+**
+** ^If X is a memory allocation previously obtained from sqlite3_malloc(),
+** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then
+** sqlite3_msize(X) returns the size of that memory allocation in bytes.
+** ^The value returned by sqlite3_msize(X) might be larger than the number
+** of bytes requested when X was allocated.  ^If X is a NULL pointer then
+** sqlite3_msize(X) returns zero.  If X points to something that is not
+** the beginning of memory allocation, or if it points to a formerly
+** valid memory allocation that has now been freed, then the behavior
+** of sqlite3_msize(X) is undefined and possibly harmful.
+**
+** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(),
+** sqlite3_malloc64(), and sqlite3_realloc64()
+** is always aligned to at least an 8 byte boundary, or to a
+** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
+** option is used.
+**
+** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
+** must be either NULL or else pointers obtained from a prior
+** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
+** not yet been released.
+**
+** The application must not read or write any part of
+** a block of memory after it has been released using
+** [sqlite3_free()] or [sqlite3_realloc()].
+*/
+SQLITE_API void *sqlite3_malloc(int);
+SQLITE_API void *sqlite3_malloc64(sqlite3_uint64);
+SQLITE_API void *sqlite3_realloc(void*, int);
+SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64);
+SQLITE_API void sqlite3_free(void*);
+SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
+
+/*
+** CAPI3REF: Memory Allocator Statistics
+**
+** SQLite provides these two interfaces for reporting on the status
+** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
+** routines, which form the built-in memory allocation subsystem.
+**
+** ^The [sqlite3_memory_used()] routine returns the number of bytes
+** of memory currently outstanding (malloced but not freed).
+** ^The [sqlite3_memory_highwater()] routine returns the maximum
+** value of [sqlite3_memory_used()] since the high-water mark
+** was last reset.  ^The values returned by [sqlite3_memory_used()] and
+** [sqlite3_memory_highwater()] include any overhead
+** added by SQLite in its implementation of [sqlite3_malloc()],
+** but not overhead added by the any underlying system library
+** routines that [sqlite3_malloc()] may call.
+**
+** ^The memory high-water mark is reset to the current value of
+** [sqlite3_memory_used()] if and only if the parameter to
+** [sqlite3_memory_highwater()] is true.  ^The value returned
+** by [sqlite3_memory_highwater(1)] is the high-water mark
+** prior to the reset.
+*/
+SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
+SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
+
+/*
+** CAPI3REF: Pseudo-Random Number Generator
+**
+** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
+** select random [ROWID | ROWIDs] when inserting new records into a table that
+** already uses the largest possible [ROWID].  The PRNG is also used for
+** the built-in random() and randomblob() SQL functions.  This interface allows
+** applications to access the same PRNG for other purposes.
+**
+** ^A call to this routine stores N bytes of randomness into buffer P.
+** ^The P parameter can be a NULL pointer.
+**
+** ^If this routine has not been previously called or if the previous
+** call had N less than one or a NULL pointer for P, then the PRNG is
+** seeded using randomness obtained from the xRandomness method of
+** the default [sqlite3_vfs] object.
+** ^If the previous call to this routine had an N of 1 or more and a
+** non-NULL P then the pseudo-randomness is generated
+** internally and without recourse to the [sqlite3_vfs] xRandomness
+** method.
+*/
+SQLITE_API void sqlite3_randomness(int N, void *P);
+
+/*
+** CAPI3REF: Compile-Time Authorization Callbacks
+** METHOD: sqlite3
+** KEYWORDS: {authorizer callback}
+**
+** ^This routine registers an authorizer callback with a particular
+** [database connection], supplied in the first argument.
+** ^The authorizer callback is invoked as SQL statements are being compiled
+** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
+** [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()],
+** and [sqlite3_prepare16_v3()].  ^At various
+** points during the compilation process, as logic is being created
+** to perform various actions, the authorizer callback is invoked to
+** see if those actions are allowed.  ^The authorizer callback should
+** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the
+** specific action but allow the SQL statement to continue to be
+** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be
+** rejected with an error.  ^If the authorizer callback returns
+** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY]
+** then the [sqlite3_prepare_v2()] or equivalent call that triggered
+** the authorizer will fail with an error message.
+**
+** When the callback returns [SQLITE_OK], that means the operation
+** requested is ok.  ^When the callback returns [SQLITE_DENY], the
+** [sqlite3_prepare_v2()] or equivalent call that triggered the
+** authorizer will fail with an error message explaining that
+** access is denied. 
+**
+** ^The first parameter to the authorizer callback is a copy of the third
+** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
+** to the callback is an integer [SQLITE_COPY | action code] that specifies
+** the particular action to be authorized. ^The third through sixth parameters
+** to the callback are either NULL pointers or zero-terminated strings
+** that contain additional details about the action to be authorized.
+** Applications must always be prepared to encounter a NULL pointer in any
+** of the third through the sixth parameters of the authorization callback.
+**
+** ^If the action code is [SQLITE_READ]
+** and the callback returns [SQLITE_IGNORE] then the
+** [prepared statement] statement is constructed to substitute
+** a NULL value in place of the table column that would have
+** been read if [SQLITE_OK] had been returned.  The [SQLITE_IGNORE]
+** return can be used to deny an untrusted user access to individual
+** columns of a table.
+** ^When a table is referenced by a [SELECT] but no column values are
+** extracted from that table (for example in a query like
+** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback
+** is invoked once for that table with a column name that is an empty string.
+** ^If the action code is [SQLITE_DELETE] and the callback returns
+** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
+** [truncate optimization] is disabled and all rows are deleted individually.
+**
+** An authorizer is used when [sqlite3_prepare | preparing]
+** SQL statements from an untrusted source, to ensure that the SQL statements
+** do not try to access data they are not allowed to see, or that they do not
+** try to execute malicious statements that damage the database.  For
+** example, an application may allow a user to enter arbitrary
+** SQL queries for evaluation by a database.  But the application does
+** not want the user to be able to make arbitrary changes to the
+** database.  An authorizer could then be put in place while the
+** user-entered SQL is being [sqlite3_prepare | prepared] that
+** disallows everything except [SELECT] statements.
+**
+** Applications that need to process SQL from untrusted sources
+** might also consider lowering resource limits using [sqlite3_limit()]
+** and limiting database size using the [max_page_count] [PRAGMA]
+** in addition to using an authorizer.
+**
+** ^(Only a single authorizer can be in place on a database connection
+** at a time.  Each call to sqlite3_set_authorizer overrides the
+** previous call.)^  ^Disable the authorizer by installing a NULL callback.
+** The authorizer is disabled by default.
+**
+** The authorizer callback must not do anything that will modify
+** the database connection that invoked the authorizer callback.
+** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
+** database connections for the meaning of "modify" in this paragraph.
+**
+** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the
+** statement might be re-prepared during [sqlite3_step()] due to a 
+** schema change.  Hence, the application should ensure that the
+** correct authorizer callback remains in place during the [sqlite3_step()].
+**
+** ^Note that the authorizer callback is invoked only during
+** [sqlite3_prepare()] or its variants.  Authorization is not
+** performed during statement evaluation in [sqlite3_step()], unless
+** as stated in the previous paragraph, sqlite3_step() invokes
+** sqlite3_prepare_v2() to reprepare a statement after a schema change.
+*/
+SQLITE_API int sqlite3_set_authorizer(
+  sqlite3*,
+  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
+  void *pUserData
+);
+
+/*
+** CAPI3REF: Authorizer Return Codes
+**
+** The [sqlite3_set_authorizer | authorizer callback function] must
+** return either [SQLITE_OK] or one of these two constants in order
+** to signal SQLite whether or not the action is permitted.  See the
+** [sqlite3_set_authorizer | authorizer documentation] for additional
+** information.
+**
+** Note that SQLITE_IGNORE is also used as a [conflict resolution mode]
+** returned from the [sqlite3_vtab_on_conflict()] interface.
+*/
+#define SQLITE_DENY   1   /* Abort the SQL statement with an error */
+#define SQLITE_IGNORE 2   /* Don't allow access, but don't generate an error */
+
+/*
+** CAPI3REF: Authorizer Action Codes
+**
+** The [sqlite3_set_authorizer()] interface registers a callback function
+** that is invoked to authorize certain SQL statement actions.  The
+** second parameter to the callback is an integer code that specifies
+** what action is being authorized.  These are the integer action codes that
+** the authorizer callback may be passed.
+**
+** These action code values signify what kind of operation is to be
+** authorized.  The 3rd and 4th parameters to the authorization
+** callback function will be parameters or NULL depending on which of these
+** codes is used as the second parameter.  ^(The 5th parameter to the
+** authorizer callback is the name of the database ("main", "temp",
+** etc.) if applicable.)^  ^The 6th parameter to the authorizer callback
+** is the name of the inner-most trigger or view that is responsible for
+** the access attempt or NULL if this access attempt is directly from
+** top-level SQL code.
+*/
+/******************************************* 3rd ************ 4th ***********/
+#define SQLITE_CREATE_INDEX          1   /* Index Name      Table Name      */
+#define SQLITE_CREATE_TABLE          2   /* Table Name      NULL            */
+#define SQLITE_CREATE_TEMP_INDEX     3   /* Index Name      Table Name      */
+#define SQLITE_CREATE_TEMP_TABLE     4   /* Table Name      NULL            */
+#define SQLITE_CREATE_TEMP_TRIGGER   5   /* Trigger Name    Table Name      */
+#define SQLITE_CREATE_TEMP_VIEW      6   /* View Name       NULL            */
+#define SQLITE_CREATE_TRIGGER        7   /* Trigger Name    Table Name      */
+#define SQLITE_CREATE_VIEW           8   /* View Name       NULL            */
+#define SQLITE_DELETE                9   /* Table Name      NULL            */
+#define SQLITE_DROP_INDEX           10   /* Index Name      Table Name      */
+#define SQLITE_DROP_TABLE           11   /* Table Name      NULL            */
+#define SQLITE_DROP_TEMP_INDEX      12   /* Index Name      Table Name      */
+#define SQLITE_DROP_TEMP_TABLE      13   /* Table Name      NULL            */
+#define SQLITE_DROP_TEMP_TRIGGER    14   /* Trigger Name    Table Name      */
+#define SQLITE_DROP_TEMP_VIEW       15   /* View Name       NULL            */
+#define SQLITE_DROP_TRIGGER         16   /* Trigger Name    Table Name      */
+#define SQLITE_DROP_VIEW            17   /* View Name       NULL            */
+#define SQLITE_INSERT               18   /* Table Name      NULL            */
+#define SQLITE_PRAGMA               19   /* Pragma Name     1st arg or NULL */
+#define SQLITE_READ                 20   /* Table Name      Column Name     */
+#define SQLITE_SELECT               21   /* NULL            NULL            */
+#define SQLITE_TRANSACTION          22   /* Operation       NULL            */
+#define SQLITE_UPDATE               23   /* Table Name      Column Name     */
+#define SQLITE_ATTACH               24   /* Filename        NULL            */
+#define SQLITE_DETACH               25   /* Database Name   NULL            */
+#define SQLITE_ALTER_TABLE          26   /* Database Name   Table Name      */
+#define SQLITE_REINDEX              27   /* Index Name      NULL            */
+#define SQLITE_ANALYZE              28   /* Table Name      NULL            */
+#define SQLITE_CREATE_VTABLE        29   /* Table Name      Module Name     */
+#define SQLITE_DROP_VTABLE          30   /* Table Name      Module Name     */
+#define SQLITE_FUNCTION             31   /* NULL            Function Name   */
+#define SQLITE_SAVEPOINT            32   /* Operation       Savepoint Name  */
+#define SQLITE_COPY                  0   /* No longer used */
+#define SQLITE_RECURSIVE            33   /* NULL            NULL            */
+
+/*
+** CAPI3REF: Tracing And Profiling Functions
+** METHOD: sqlite3
+**
+** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
+** instead of the routines described here.
+**
+** These routines register callback functions that can be used for
+** tracing and profiling the execution of SQL statements.
+**
+** ^The callback function registered by sqlite3_trace() is invoked at
+** various times when an SQL statement is being run by [sqlite3_step()].
+** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the
+** SQL statement text as the statement first begins executing.
+** ^(Additional sqlite3_trace() callbacks might occur
+** as each triggered subprogram is entered.  The callbacks for triggers
+** contain a UTF-8 SQL comment that identifies the trigger.)^
+**
+** The [SQLITE_TRACE_SIZE_LIMIT] compile-time option can be used to limit
+** the length of [bound parameter] expansion in the output of sqlite3_trace().
+**
+** ^The callback function registered by sqlite3_profile() is invoked
+** as each SQL statement finishes.  ^The profile callback contains
+** the original statement text and an estimate of wall-clock time
+** of how long that statement took to run.  ^The profile callback
+** time is in units of nanoseconds, however the current implementation
+** is only capable of millisecond resolution so the six least significant
+** digits in the time are meaningless.  Future versions of SQLite
+** might provide greater resolution on the profiler callback.  Invoking
+** either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the
+** profile callback.
+*/
+SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
+   void(*xTrace)(void*,const char*), void*);
+SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
+   void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
+
+/*
+** CAPI3REF: SQL Trace Event Codes
+** KEYWORDS: SQLITE_TRACE
+**
+** These constants identify classes of events that can be monitored
+** using the [sqlite3_trace_v2()] tracing logic.  The M argument
+** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
+** the following constants.  ^The first argument to the trace callback
+** is one of the following constants.
+**
+** New tracing constants may be added in future releases.
+**
+** ^A trace callback has four arguments: xCallback(T,C,P,X).
+** ^The T argument is one of the integer type codes above.
+** ^The C argument is a copy of the context pointer passed in as the
+** fourth argument to [sqlite3_trace_v2()].
+** The P and X arguments are pointers whose meanings depend on T.
+**
+** <dl>
+** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt>
+** <dd>^An SQLITE_TRACE_STMT callback is invoked when a prepared statement
+** first begins running and possibly at other times during the
+** execution of the prepared statement, such as at the start of each
+** trigger subprogram. ^The P argument is a pointer to the
+** [prepared statement]. ^The X argument is a pointer to a string which
+** is the unexpanded SQL text of the prepared statement or an SQL comment 
+** that indicates the invocation of a trigger.  ^The callback can compute
+** the same text that would have been returned by the legacy [sqlite3_trace()]
+** interface by using the X argument when X begins with "--" and invoking
+** [sqlite3_expanded_sql(P)] otherwise.
+**
+** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt>
+** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
+** information as is provided by the [sqlite3_profile()] callback.
+** ^The P argument is a pointer to the [prepared statement] and the
+** X argument points to a 64-bit integer which is the estimated of
+** the number of nanosecond that the prepared statement took to run.
+** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
+**
+** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
+** <dd>^An SQLITE_TRACE_ROW callback is invoked whenever a prepared
+** statement generates a single row of result.  
+** ^The P argument is a pointer to the [prepared statement] and the
+** X argument is unused.
+**
+** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt>
+** <dd>^An SQLITE_TRACE_CLOSE callback is invoked when a database
+** connection closes.
+** ^The P argument is a pointer to the [database connection] object
+** and the X argument is unused.
+** </dl>
+*/
+#define SQLITE_TRACE_STMT       0x01
+#define SQLITE_TRACE_PROFILE    0x02
+#define SQLITE_TRACE_ROW        0x04
+#define SQLITE_TRACE_CLOSE      0x08
+
+/*
+** CAPI3REF: SQL Trace Hook
+** METHOD: sqlite3
+**
+** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback
+** function X against [database connection] D, using property mask M
+** and context pointer P.  ^If the X callback is
+** NULL or if the M mask is zero, then tracing is disabled.  The
+** M argument should be the bitwise OR-ed combination of
+** zero or more [SQLITE_TRACE] constants.
+**
+** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides 
+** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().
+**
+** ^The X callback is invoked whenever any of the events identified by 
+** mask M occur.  ^The integer return value from the callback is currently
+** ignored, though this may change in future releases.  Callback
+** implementations should return zero to ensure future compatibility.
+**
+** ^A trace callback is invoked with four arguments: callback(T,C,P,X).
+** ^The T argument is one of the [SQLITE_TRACE]
+** constants to indicate why the callback was invoked.
+** ^The C argument is a copy of the context pointer.
+** The P and X arguments are pointers whose meanings depend on T.
+**
+** The sqlite3_trace_v2() interface is intended to replace the legacy
+** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
+** are deprecated.
+*/
+SQLITE_API int sqlite3_trace_v2(
+  sqlite3*,
+  unsigned uMask,
+  int(*xCallback)(unsigned,void*,void*,void*),
+  void *pCtx
+);
+
+/*
+** CAPI3REF: Query Progress Callbacks
+** METHOD: sqlite3
+**
+** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
+** function X to be invoked periodically during long running calls to
+** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
+** database connection D.  An example use for this
+** interface is to keep a GUI updated during a large query.
+**
+** ^The parameter P is passed through as the only parameter to the 
+** callback function X.  ^The parameter N is the approximate number of 
+** [virtual machine instructions] that are evaluated between successive
+** invocations of the callback X.  ^If N is less than one then the progress
+** handler is disabled.
+**
+** ^Only a single progress handler may be defined at one time per
+** [database connection]; setting a new progress handler cancels the
+** old one.  ^Setting parameter X to NULL disables the progress handler.
+** ^The progress handler is also disabled by setting N to a value less
+** than 1.
+**
+** ^If the progress callback returns non-zero, the operation is
+** interrupted.  This feature can be used to implement a
+** "Cancel" button on a GUI progress dialog box.
+**
+** The progress handler callback must not do anything that will modify
+** the database connection that invoked the progress handler.
+** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
+** database connections for the meaning of "modify" in this paragraph.
+**
+*/
+SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+
+/*
+** CAPI3REF: Opening A New Database Connection
+** CONSTRUCTOR: sqlite3
+**
+** ^These routines open an SQLite database file as specified by the 
+** filename argument. ^The filename argument is interpreted as UTF-8 for
+** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
+** order for sqlite3_open16(). ^(A [database connection] handle is usually
+** returned in *ppDb, even if an error occurs.  The only exception is that
+** if SQLite is unable to allocate memory to hold the [sqlite3] object,
+** a NULL will be written into *ppDb instead of a pointer to the [sqlite3]
+** object.)^ ^(If the database is opened (and/or created) successfully, then
+** [SQLITE_OK] is returned.  Otherwise an [error code] is returned.)^ ^The
+** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
+** an English language description of the error following a failure of any
+** of the sqlite3_open() routines.
+**
+** ^The default encoding will be UTF-8 for databases created using
+** sqlite3_open() or sqlite3_open_v2().  ^The default encoding for databases
+** created using sqlite3_open16() will be UTF-16 in the native byte order.
+**
+** Whether or not an error occurs when it is opened, resources
+** associated with the [database connection] handle should be released by
+** passing it to [sqlite3_close()] when it is no longer required.
+**
+** The sqlite3_open_v2() interface works like sqlite3_open()
+** except that it accepts two additional parameters for additional control
+** over the new database connection.  ^(The flags parameter to
+** sqlite3_open_v2() must include, at a minimum, one of the following
+** three flag combinations:)^
+**
+** <dl>
+** ^(<dt>[SQLITE_OPEN_READONLY]</dt>
+** <dd>The database is opened in read-only mode.  If the database does not
+** already exist, an error is returned.</dd>)^
+**
+** ^(<dt>[SQLITE_OPEN_READWRITE]</dt>
+** <dd>The database is opened for reading and writing if possible, or reading
+** only if the file is write protected by the operating system.  In either
+** case the database must already exist, otherwise an error is returned.</dd>)^
+**
+** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
+** <dd>The database is opened for reading and writing, and is created if
+** it does not already exist. This is the behavior that is always used for
+** sqlite3_open() and sqlite3_open16().</dd>)^
+** </dl>
+**
+** In addition to the required flags, the following optional flags are
+** also supported:
+**
+** <dl>
+** ^(<dt>[SQLITE_OPEN_URI]</dt>
+** <dd>The filename can be interpreted as a URI if this flag is set.</dd>)^
+**
+** ^(<dt>[SQLITE_OPEN_MEMORY]</dt>
+** <dd>The database will be opened as an in-memory database.  The database
+** is named by the "filename" argument for the purposes of cache-sharing,
+** if shared cache mode is enabled, but the "filename" is otherwise ignored.
+** </dd>)^
+**
+** ^(<dt>[SQLITE_OPEN_NOMUTEX]</dt>
+** <dd>The new database connection will use the "multi-thread"
+** [threading mode].)^  This means that separate threads are allowed
+** to use SQLite at the same time, as long as each thread is using
+** a different [database connection].
+**
+** ^(<dt>[SQLITE_OPEN_FULLMUTEX]</dt>
+** <dd>The new database connection will use the "serialized"
+** [threading mode].)^  This means the multiple threads can safely
+** attempt to use the same database connection at the same time.
+** (Mutexes will block any actual concurrency, but in this mode
+** there is no harm in trying.)
+**
+** ^(<dt>[SQLITE_OPEN_SHAREDCACHE]</dt>
+** <dd>The database is opened [shared cache] enabled, overriding
+** the default shared cache setting provided by
+** [sqlite3_enable_shared_cache()].)^
+**
+** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
+** <dd>The database is opened [shared cache] disabled, overriding
+** the default shared cache setting provided by
+** [sqlite3_enable_shared_cache()].)^
+**
+** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
+** <dd>The database filename is not allowed to be a symbolic link</dd>
+** </dl>)^
+**
+** If the 3rd parameter to sqlite3_open_v2() is not one of the
+** required combinations shown above optionally combined with other
+** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
+** then the behavior is undefined.
+**
+** ^The fourth parameter to sqlite3_open_v2() is the name of the
+** [sqlite3_vfs] object that defines the operating system interface that
+** the new database connection should use.  ^If the fourth parameter is
+** a NULL pointer then the default [sqlite3_vfs] object is used.
+**
+** ^If the filename is ":memory:", then a private, temporary in-memory database
+** is created for the connection.  ^This in-memory database will vanish when
+** the database connection is closed.  Future versions of SQLite might
+** make use of additional special filenames that begin with the ":" character.
+** It is recommended that when a database filename actually does begin with
+** a ":" character you should prefix the filename with a pathname such as
+** "./" to avoid ambiguity.
+**
+** ^If the filename is an empty string, then a private, temporary
+** on-disk database will be created.  ^This private database will be
+** automatically deleted as soon as the database connection is closed.
+**
+** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3>
+**
+** ^If [URI filename] interpretation is enabled, and the filename argument
+** begins with "file:", then the filename is interpreted as a URI. ^URI
+** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
+** set in the third argument to sqlite3_open_v2(), or if it has
+** been enabled globally using the [SQLITE_CONFIG_URI] option with the
+** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
+** URI filename interpretation is turned off
+** by default, but future releases of SQLite might enable URI filename
+** interpretation by default.  See "[URI filenames]" for additional
+** information.
+**
+** URI filenames are parsed according to RFC 3986. ^If the URI contains an
+** authority, then it must be either an empty string or the string 
+** "localhost". ^If the authority is not an empty string or "localhost", an 
+** error is returned to the caller. ^The fragment component of a URI, if 
+** present, is ignored.
+**
+** ^SQLite uses the path component of the URI as the name of the disk file
+** which contains the database. ^If the path begins with a '/' character, 
+** then it is interpreted as an absolute path. ^If the path does not begin 
+** with a '/' (meaning that the authority section is omitted from the URI)
+** then the path is interpreted as a relative path. 
+** ^(On windows, the first component of an absolute path 
+** is a drive specification (e.g. "C:").)^
+**
+** [[core URI query parameters]]
+** The query component of a URI may contain parameters that are interpreted
+** either by SQLite itself, or by a [VFS | custom VFS implementation].
+** SQLite and its built-in [VFSes] interpret the
+** following query parameters:
+**
+** <ul>
+**   <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
+**     a VFS object that provides the operating system interface that should
+**     be used to access the database file on disk. ^If this option is set to
+**     an empty string the default VFS object is used. ^Specifying an unknown
+**     VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is
+**     present, then the VFS specified by the option takes precedence over
+**     the value passed as the fourth parameter to sqlite3_open_v2().
+**
+**   <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw",
+**     "rwc", or "memory". Attempting to set it to any other value is
+**     an error)^. 
+**     ^If "ro" is specified, then the database is opened for read-only 
+**     access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the 
+**     third argument to sqlite3_open_v2(). ^If the mode option is set to 
+**     "rw", then the database is opened for read-write (but not create) 
+**     access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had 
+**     been set. ^Value "rwc" is equivalent to setting both 
+**     SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE.  ^If the mode option is
+**     set to "memory" then a pure [in-memory database] that never reads
+**     or writes from disk is used. ^It is an error to specify a value for
+**     the mode parameter that is less restrictive than that specified by
+**     the flags passed in the third parameter to sqlite3_open_v2().
+**
+**   <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or
+**     "private". ^Setting it to "shared" is equivalent to setting the
+**     SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to
+**     sqlite3_open_v2(). ^Setting the cache parameter to "private" is 
+**     equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
+**     ^If sqlite3_open_v2() is used and the "cache" parameter is present in
+**     a URI filename, its value overrides any behavior requested by setting
+**     SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
+**
+**  <li> <b>psow</b>: ^The psow parameter indicates whether or not the
+**     [powersafe overwrite] property does or does not apply to the
+**     storage media on which the database file resides.
+**
+**  <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
+**     which if set disables file locking in rollback journal modes.  This
+**     is useful for accessing a database on a filesystem that does not
+**     support locking.  Caution:  Database corruption might result if two
+**     or more processes write to the same database and any one of those
+**     processes uses nolock=1.
+**
+**  <li> <b>immutable</b>: ^The immutable parameter is a boolean query
+**     parameter that indicates that the database file is stored on
+**     read-only media.  ^When immutable is set, SQLite assumes that the
+**     database file cannot be changed, even by a process with higher
+**     privilege, and so the database is opened read-only and all locking
+**     and change detection is disabled.  Caution: Setting the immutable
+**     property on a database file that does in fact change can result
+**     in incorrect query results and/or [SQLITE_CORRUPT] errors.
+**     See also: [SQLITE_IOCAP_IMMUTABLE].
+**       
+** </ul>
+**
+** ^Specifying an unknown parameter in the query component of a URI is not an
+** error.  Future versions of SQLite might understand additional query
+** parameters.  See "[query parameters with special meaning to SQLite]" for
+** additional information.
+**
+** [[URI filename examples]] <h3>URI filename examples</h3>
+**
+** <table border="1" align=center cellpadding=5>
+** <tr><th> URI filenames <th> Results
+** <tr><td> file:data.db <td> 
+**          Open the file "data.db" in the current directory.
+** <tr><td> file:/home/fred/data.db<br>
+**          file:///home/fred/data.db <br> 
+**          file://localhost/home/fred/data.db <br> <td> 
+**          Open the database file "/home/fred/data.db".
+** <tr><td> file://darkstar/home/fred/data.db <td> 
+**          An error. "darkstar" is not a recognized authority.
+** <tr><td style="white-space:nowrap"> 
+**          file:///C:/Documents%20and%20Settings/fred/Desktop/data.db
+**     <td> Windows only: Open the file "data.db" on fred's desktop on drive
+**          C:. Note that the %20 escaping in this example is not strictly 
+**          necessary - space characters can be used literally
+**          in URI filenames.
+** <tr><td> file:data.db?mode=ro&cache=private <td> 
+**          Open file "data.db" in the current directory for read-only access.
+**          Regardless of whether or not shared-cache mode is enabled by
+**          default, use a private cache.
+** <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td>
+**          Open file "/home/fred/data.db". Use the special VFS "unix-dotfile"
+**          that uses dot-files in place of posix advisory locking.
+** <tr><td> file:data.db?mode=readonly <td> 
+**          An error. "readonly" is not a valid option for the "mode" parameter.
+** </table>
+**
+** ^URI hexadecimal escape sequences (%HH) are supported within the path and
+** query components of a URI. A hexadecimal escape sequence consists of a
+** percent sign - "%" - followed by exactly two hexadecimal digits 
+** specifying an octet value. ^Before the path or query components of a
+** URI filename are interpreted, they are encoded using UTF-8 and all 
+** hexadecimal escape sequences replaced by a single byte containing the
+** corresponding octet. If this process generates an invalid UTF-8 encoding,
+** the results are undefined.
+**
+** <b>Note to Windows users:</b>  The encoding used for the filename argument
+** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever
+** codepage is currently defined.  Filenames containing international
+** characters must be converted to UTF-8 prior to passing them into
+** sqlite3_open() or sqlite3_open_v2().
+**
+** <b>Note to Windows Runtime users:</b>  The temporary directory must be set
+** prior to calling sqlite3_open() or sqlite3_open_v2().  Otherwise, various
+** features that require the use of temporary files may fail.
+**
+** See also: [sqlite3_temp_directory]
+*/
+SQLITE_API int sqlite3_open(
+  const char *filename,   /* Database filename (UTF-8) */
+  sqlite3 **ppDb          /* OUT: SQLite db handle */
+);
+SQLITE_API int sqlite3_open16(
+  const void *filename,   /* Database filename (UTF-16) */
+  sqlite3 **ppDb          /* OUT: SQLite db handle */
+);
+SQLITE_API int sqlite3_open_v2(
+  const char *filename,   /* Database filename (UTF-8) */
+  sqlite3 **ppDb,         /* OUT: SQLite db handle */
+  int flags,              /* Flags */
+  const char *zVfs        /* Name of VFS module to use */
+);
+
+/*
+** CAPI3REF: Obtain Values For URI Parameters
+**
+** These are utility routines, useful to [VFS|custom VFS implementations],
+** that check if a database file was a URI that contained a specific query 
+** parameter, and if so obtains the value of that query parameter.
+**
+** The first parameter to these interfaces (hereafter referred to
+** as F) must be one of:
+** <ul>
+** <li> A database filename pointer created by the SQLite core and
+** passed into the xOpen() method of a VFS implemention, or
+** <li> A filename obtained from [sqlite3_db_filename()], or
+** <li> A new filename constructed using [sqlite3_create_filename()].
+** </ul>
+** If the F parameter is not one of the above, then the behavior is
+** undefined and probably undesirable.  Older versions of SQLite were
+** more tolerant of invalid F parameters than newer versions.
+**
+** If F is a suitable filename (as described in the previous paragraph)
+** and if P is the name of the query parameter, then
+** sqlite3_uri_parameter(F,P) returns the value of the P
+** parameter if it exists or a NULL pointer if P does not appear as a 
+** query parameter on F.  If P is a query parameter of F and it
+** has no explicit value, then sqlite3_uri_parameter(F,P) returns
+** a pointer to an empty string.
+**
+** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean
+** parameter and returns true (1) or false (0) according to the value
+** of P.  The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the
+** value of query parameter P is one of "yes", "true", or "on" in any
+** case or if the value begins with a non-zero number.  The 
+** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of
+** query parameter P is one of "no", "false", or "off" in any case or
+** if the value begins with a numeric zero.  If P is not a query
+** parameter on F or if the value of P does not match any of the
+** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0).
+**
+** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
+** 64-bit signed integer and returns that integer, or D if P does not
+** exist.  If the value of P is something other than an integer, then
+** zero is returned.
+**
+** The sqlite3_uri_key(F,N) returns a pointer to the name (not
+** the value) of the N-th query parameter for filename F, or a NULL
+** pointer if N is less than zero or greater than the number of query
+** parameters minus 1.  The N value is zero-based so N should be 0 to obtain
+** the name of the first query parameter, 1 for the second parameter, and
+** so forth.
+** 
+** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and
+** sqlite3_uri_boolean(F,P,B) returns B.  If F is not a NULL pointer and
+** is not a database file pathname pointer that the SQLite core passed
+** into the xOpen VFS method, then the behavior of this routine is undefined
+** and probably undesirable.
+**
+** Beginning with SQLite [version 3.31.0] ([dateof:3.31.0]) the input F
+** parameter can also be the name of a rollback journal file or WAL file
+** in addition to the main database file.  Prior to version 3.31.0, these
+** routines would only work if F was the name of the main database file.
+** When the F parameter is the name of the rollback journal or WAL file,
+** it has access to all the same query parameters as were found on the
+** main database file.
+**
+** See the [URI filename] documentation for additional information.
+*/
+SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
+SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
+SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N);
+
+/*
+** CAPI3REF:  Translate filenames
+**
+** These routines are available to [VFS|custom VFS implementations] for
+** translating filenames between the main database file, the journal file,
+** and the WAL file.
+**
+** If F is the name of an sqlite database file, journal file, or WAL file
+** passed by the SQLite core into the VFS, then sqlite3_filename_database(F)
+** returns the name of the corresponding database file.
+**
+** If F is the name of an sqlite database file, journal file, or WAL file
+** passed by the SQLite core into the VFS, or if F is a database filename
+** obtained from [sqlite3_db_filename()], then sqlite3_filename_journal(F)
+** returns the name of the corresponding rollback journal file.
+**
+** If F is the name of an sqlite database file, journal file, or WAL file
+** that was passed by the SQLite core into the VFS, or if F is a database
+** filename obtained from [sqlite3_db_filename()], then
+** sqlite3_filename_wal(F) returns the name of the corresponding
+** WAL file.
+**
+** In all of the above, if F is not the name of a database, journal or WAL
+** filename passed into the VFS from the SQLite core and F is not the
+** return value from [sqlite3_db_filename()], then the result is
+** undefined and is likely a memory access violation.
+*/
+SQLITE_API const char *sqlite3_filename_database(const char*);
+SQLITE_API const char *sqlite3_filename_journal(const char*);
+SQLITE_API const char *sqlite3_filename_wal(const char*);
+
+/*
+** CAPI3REF:  Database File Corresponding To A Journal
+**
+** ^If X is the name of a rollback or WAL-mode journal file that is
+** passed into the xOpen method of [sqlite3_vfs], then 
+** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
+** object that represents the main database file.
+**
+** This routine is intended for use in custom [VFS] implementations
+** only.  It is not a general-purpose interface.
+** The argument sqlite3_file_object(X) must be a filename pointer that
+** has been passed into [sqlite3_vfs].xOpen method where the 
+** flags parameter to xOpen contains one of the bits
+** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL].  Any other use
+** of this routine results in undefined and probably undesirable
+** behavior.
+*/
+SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
+
+/*
+** CAPI3REF: Create and Destroy VFS Filenames
+**
+** These interfces are provided for use by [VFS shim] implementations and
+** are not useful outside of that context.
+**
+** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of
+** database filename D with corresponding journal file J and WAL file W and
+** with N URI parameters key/values pairs in the array P.  The result from
+** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that
+** is safe to pass to routines like:
+** <ul>
+** <li> [sqlite3_uri_parameter()],
+** <li> [sqlite3_uri_boolean()],
+** <li> [sqlite3_uri_int64()],
+** <li> [sqlite3_uri_key()], 
+** <li> [sqlite3_filename_database()],
+** <li> [sqlite3_filename_journal()], or
+** <li> [sqlite3_filename_wal()].
+** </ul>
+** If a memory allocation error occurs, sqlite3_create_filename() might
+** return a NULL pointer.  The memory obtained from sqlite3_create_filename(X)
+** must be released by a corresponding call to sqlite3_free_filename(Y).
+**
+** The P parameter in sqlite3_create_filename(D,J,W,N,P) should be an array
+** of 2*N pointers to strings.  Each pair of pointers in this array corresponds
+** to a key and value for a query parameter.  The P parameter may be a NULL
+** pointer if N is zero.  None of the 2*N pointers in the P array may be
+** NULL pointers and key pointers should not be empty strings.
+** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
+** be NULL pointers, though they can be empty strings.
+**
+** The sqlite3_free_filename(Y) routine releases a memory allocation
+** previously obtained from sqlite3_create_filename().  Invoking
+** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
+**
+** If the Y parameter to sqlite3_free_filename(Y) is anything other
+** than a NULL pointer or a pointer previously acquired from
+** sqlite3_create_filename(), then bad things such as heap
+** corruption or segfaults may occur. The value Y should be 
+** used again after sqlite3_free_filename(Y) has been called.  This means
+** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y,
+** then the corresponding [sqlite3_module.xClose() method should also be
+** invoked prior to calling sqlite3_free_filename(Y).
+*/
+SQLITE_API char *sqlite3_create_filename(
+  const char *zDatabase,
+  const char *zJournal,
+  const char *zWal,
+  int nParam,
+  const char **azParam
+);
+SQLITE_API void sqlite3_free_filename(char*);
+
+/*
+** CAPI3REF: Error Codes And Messages
+** METHOD: sqlite3
+**
+** ^If the most recent sqlite3_* API call associated with 
+** [database connection] D failed, then the sqlite3_errcode(D) interface
+** returns the numeric [result code] or [extended result code] for that
+** API call.
+** ^The sqlite3_extended_errcode()
+** interface is the same except that it always returns the 
+** [extended result code] even when extended result codes are
+** disabled.
+**
+** The values returned by sqlite3_errcode() and/or
+** sqlite3_extended_errcode() might change with each API call.
+** Except, there are some interfaces that are guaranteed to never
+** change the value of the error code.  The error-code preserving
+** interfaces are:
+**
+** <ul>
+** <li> sqlite3_errcode()
+** <li> sqlite3_extended_errcode()
+** <li> sqlite3_errmsg()
+** <li> sqlite3_errmsg16()
+** </ul>
+**
+** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
+** text that describes the error, as either UTF-8 or UTF-16 respectively.
+** ^(Memory to hold the error message string is managed internally.
+** The application does not need to worry about freeing the result.
+** However, the error string might be overwritten or deallocated by
+** subsequent calls to other SQLite interface functions.)^
+**
+** ^The sqlite3_errstr() interface returns the English-language text
+** that describes the [result code], as UTF-8.
+** ^(Memory to hold the error message string is managed internally
+** and must not be freed by the application)^.
+**
+** When the serialized [threading mode] is in use, it might be the
+** case that a second error occurs on a separate thread in between
+** the time of the first error and the call to these interfaces.
+** When that happens, the second error will be reported since these
+** interfaces always report the most recent result.  To avoid
+** this, each thread can obtain exclusive use of the [database connection] D
+** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning
+** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
+** all calls to the interfaces listed here are completed.
+**
+** If an interface fails with SQLITE_MISUSE, that means the interface
+** was invoked incorrectly by the application.  In that case, the
+** error code and message may or may not be set.
+*/
+SQLITE_API int sqlite3_errcode(sqlite3 *db);
+SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
+SQLITE_API const char *sqlite3_errmsg(sqlite3*);
+SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *sqlite3_errstr(int);
+
+/*
+** CAPI3REF: Prepared Statement Object
+** KEYWORDS: {prepared statement} {prepared statements}
+**
+** An instance of this object represents a single SQL statement that
+** has been compiled into binary form and is ready to be evaluated.
+**
+** Think of each SQL statement as a separate computer program.  The
+** original SQL text is source code.  A prepared statement object 
+** is the compiled object code.  All SQL must be converted into a
+** prepared statement before it can be run.
+**
+** The life-cycle of a prepared statement object usually goes like this:
+**
+** <ol>
+** <li> Create the prepared statement object using [sqlite3_prepare_v2()].
+** <li> Bind values to [parameters] using the sqlite3_bind_*()
+**      interfaces.
+** <li> Run the SQL by calling [sqlite3_step()] one or more times.
+** <li> Reset the prepared statement using [sqlite3_reset()] then go back
+**      to step 2.  Do this zero or more times.
+** <li> Destroy the object using [sqlite3_finalize()].
+** </ol>
+*/
+typedef struct sqlite3_stmt sqlite3_stmt;
+
+/*
+** CAPI3REF: Run-time Limits
+** METHOD: sqlite3
+**
+** ^(This interface allows the size of various constructs to be limited
+** on a connection by connection basis.  The first parameter is the
+** [database connection] whose limit is to be set or queried.  The
+** second parameter is one of the [limit categories] that define a
+** class of constructs to be size limited.  The third parameter is the
+** new limit for that construct.)^
+**
+** ^If the new limit is a negative number, the limit is unchanged.
+** ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a 
+** [limits | hard upper bound]
+** set at compile-time by a C preprocessor macro called
+** [limits | SQLITE_MAX_<i>NAME</i>].
+** (The "_LIMIT_" in the name is changed to "_MAX_".))^
+** ^Attempts to increase a limit above its hard upper bound are
+** silently truncated to the hard upper bound.
+**
+** ^Regardless of whether or not the limit was changed, the 
+** [sqlite3_limit()] interface returns the prior value of the limit.
+** ^Hence, to find the current value of a limit without changing it,
+** simply invoke this interface with the third parameter set to -1.
+**
+** Run-time limits are intended for use in applications that manage
+** both their own internal database and also databases that are controlled
+** by untrusted external sources.  An example application might be a
+** web browser that has its own databases for storing history and
+** separate databases controlled by JavaScript applications downloaded
+** off the Internet.  The internal databases can be given the
+** large, default limits.  Databases managed by external sources can
+** be given much smaller limits designed to prevent a denial of service
+** attack.  Developers might also want to use the [sqlite3_set_authorizer()]
+** interface to further control untrusted SQL.  The size of the database
+** created by an untrusted script can be contained using the
+** [max_page_count] [PRAGMA].
+**
+** New run-time limit categories may be added in future releases.
+*/
+SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
+
+/*
+** CAPI3REF: Run-Time Limit Categories
+** KEYWORDS: {limit category} {*limit categories}
+**
+** These constants define various performance limits
+** that can be lowered at run-time using [sqlite3_limit()].
+** The synopsis of the meanings of the various limits is shown below.
+** Additional information is available at [limits | Limits in SQLite].
+**
+** <dl>
+** [[SQLITE_LIMIT_LENGTH]] ^(<dt>SQLITE_LIMIT_LENGTH</dt>
+** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^
+**
+** [[SQLITE_LIMIT_SQL_LENGTH]] ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt>
+** <dd>The maximum length of an SQL statement, in bytes.</dd>)^
+**
+** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt>
+** <dd>The maximum number of columns in a table definition or in the
+** result set of a [SELECT] or the maximum number of columns in an index
+** or in an ORDER BY or GROUP BY clause.</dd>)^
+**
+** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
+** <dd>The maximum depth of the parse tree on any expression.</dd>)^
+**
+** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
+** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
+**
+** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
+** <dd>The maximum number of instructions in a virtual machine program
+** used to implement an SQL statement.  If [sqlite3_prepare_v2()] or
+** the equivalent tries to allocate space for more than this many opcodes
+** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
+**
+** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
+** <dd>The maximum number of arguments on a function.</dd>)^
+**
+** [[SQLITE_LIMIT_ATTACHED]] ^(<dt>SQLITE_LIMIT_ATTACHED</dt>
+** <dd>The maximum number of [ATTACH | attached databases].)^</dd>
+**
+** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]]
+** ^(<dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
+** <dd>The maximum length of the pattern argument to the [LIKE] or
+** [GLOB] operators.</dd>)^
+**
+** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
+** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
+** <dd>The maximum index number of any [parameter] in an SQL statement.)^
+**
+** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
+** <dd>The maximum depth of recursion for triggers.</dd>)^
+**
+** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
+** <dd>The maximum number of auxiliary worker threads that a single
+** [prepared statement] may start.</dd>)^
+** </dl>
+*/
+#define SQLITE_LIMIT_LENGTH                    0
+#define SQLITE_LIMIT_SQL_LENGTH                1
+#define SQLITE_LIMIT_COLUMN                    2
+#define SQLITE_LIMIT_EXPR_DEPTH                3
+#define SQLITE_LIMIT_COMPOUND_SELECT           4
+#define SQLITE_LIMIT_VDBE_OP                   5
+#define SQLITE_LIMIT_FUNCTION_ARG              6
+#define SQLITE_LIMIT_ATTACHED                  7
+#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH       8
+#define SQLITE_LIMIT_VARIABLE_NUMBER           9
+#define SQLITE_LIMIT_TRIGGER_DEPTH            10
+#define SQLITE_LIMIT_WORKER_THREADS           11
+
+/*
+** CAPI3REF: Prepare Flags
+**
+** These constants define various flags that can be passed into
+** "prepFlags" parameter of the [sqlite3_prepare_v3()] and
+** [sqlite3_prepare16_v3()] interfaces.
+**
+** New flags may be added in future releases of SQLite.
+**
+** <dl>
+** [[SQLITE_PREPARE_PERSISTENT]] ^(<dt>SQLITE_PREPARE_PERSISTENT</dt>
+** <dd>The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner
+** that the prepared statement will be retained for a long time and
+** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()]
+** and [sqlite3_prepare16_v3()] assume that the prepared statement will 
+** be used just once or at most a few times and then destroyed using
+** [sqlite3_finalize()] relatively soon. The current implementation acts
+** on this hint by avoiding the use of [lookaside memory] so as not to
+** deplete the limited store of lookaside memory. Future versions of
+** SQLite may act on this hint differently.
+**
+** [[SQLITE_PREPARE_NORMALIZE]] <dt>SQLITE_PREPARE_NORMALIZE</dt>
+** <dd>The SQLITE_PREPARE_NORMALIZE flag is a no-op. This flag used
+** to be required for any prepared statement that wanted to use the
+** [sqlite3_normalized_sql()] interface.  However, the
+** [sqlite3_normalized_sql()] interface is now available to all
+** prepared statements, regardless of whether or not they use this
+** flag.
+**
+** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
+** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
+** to return an error (error code SQLITE_ERROR) if the statement uses
+** any virtual tables.
+** </dl>
+*/
+#define SQLITE_PREPARE_PERSISTENT              0x01
+#define SQLITE_PREPARE_NORMALIZE               0x02
+#define SQLITE_PREPARE_NO_VTAB                 0x04
+
+/*
+** CAPI3REF: Compiling An SQL Statement
+** KEYWORDS: {SQL statement compiler}
+** METHOD: sqlite3
+** CONSTRUCTOR: sqlite3_stmt
+**
+** To execute an SQL statement, it must first be compiled into a byte-code
+** program using one of these routines.  Or, in other words, these routines
+** are constructors for the [prepared statement] object.
+**
+** The preferred routine to use is [sqlite3_prepare_v2()].  The
+** [sqlite3_prepare()] interface is legacy and should be avoided.
+** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used
+** for special purposes.
+**
+** The use of the UTF-8 interfaces is preferred, as SQLite currently
+** does all parsing using UTF-8.  The UTF-16 interfaces are provided
+** as a convenience.  The UTF-16 interfaces work by converting the
+** input text into UTF-8, then invoking the corresponding UTF-8 interface.
+**
+** The first argument, "db", is a [database connection] obtained from a
+** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
+** [sqlite3_open16()].  The database connection must not have been closed.
+**
+** The second argument, "zSql", is the statement to be compiled, encoded
+** as either UTF-8 or UTF-16.  The sqlite3_prepare(), sqlite3_prepare_v2(),
+** and sqlite3_prepare_v3()
+** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(),
+** and sqlite3_prepare16_v3() use UTF-16.
+**
+** ^If the nByte argument is negative, then zSql is read up to the
+** first zero terminator. ^If nByte is positive, then it is the
+** number of bytes read from zSql.  ^If nByte is zero, then no prepared
+** statement is generated.
+** If the caller knows that the supplied string is nul-terminated, then
+** there is a small performance advantage to passing an nByte parameter that
+** is the number of bytes in the input string <i>including</i>
+** the nul-terminator.
+**
+** ^If pzTail is not NULL then *pzTail is made to point to the first byte
+** past the end of the first SQL statement in zSql.  These routines only
+** compile the first statement in zSql, so *pzTail is left pointing to
+** what remains uncompiled.
+**
+** ^*ppStmt is left pointing to a compiled [prepared statement] that can be
+** executed using [sqlite3_step()].  ^If there is an error, *ppStmt is set
+** to NULL.  ^If the input text contains no SQL (if the input is an empty
+** string or a comment) then *ppStmt is set to NULL.
+** The calling procedure is responsible for deleting the compiled
+** SQL statement using [sqlite3_finalize()] after it has finished with it.
+** ppStmt may not be NULL.
+**
+** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK];
+** otherwise an [error code] is returned.
+**
+** The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(),
+** and sqlite3_prepare16_v3() interfaces are recommended for all new programs.
+** The older interfaces (sqlite3_prepare() and sqlite3_prepare16())
+** are retained for backwards compatibility, but their use is discouraged.
+** ^In the "vX" interfaces, the prepared statement
+** that is returned (the [sqlite3_stmt] object) contains a copy of the
+** original SQL text. This causes the [sqlite3_step()] interface to
+** behave differently in three ways:
+**
+** <ol>
+** <li>
+** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it
+** always used to do, [sqlite3_step()] will automatically recompile the SQL
+** statement and try to run it again. As many as [SQLITE_MAX_SCHEMA_RETRY]
+** retries will occur before sqlite3_step() gives up and returns an error.
+** </li>
+**
+** <li>
+** ^When an error occurs, [sqlite3_step()] will return one of the detailed
+** [error codes] or [extended error codes].  ^The legacy behavior was that
+** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
+** and the application would have to make a second call to [sqlite3_reset()]
+** in order to find the underlying cause of the problem. With the "v2" prepare
+** interfaces, the underlying reason for the error is returned immediately.
+** </li>
+**
+** <li>
+** ^If the specific value bound to a [parameter | host parameter] in the 
+** WHERE clause might influence the choice of query plan for a statement,
+** then the statement will be automatically recompiled, as if there had been 
+** a schema change, on the first [sqlite3_step()] call following any change
+** to the [sqlite3_bind_text | bindings] of that [parameter]. 
+** ^The specific value of a WHERE-clause [parameter] might influence the 
+** choice of query plan if the parameter is the left-hand side of a [LIKE]
+** or [GLOB] operator or if the parameter is compared to an indexed column
+** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled.
+** </li>
+** </ol>
+**
+** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
+** the extra prepFlags parameter, which is a bit array consisting of zero or
+** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags.  ^The
+** sqlite3_prepare_v2() interface works exactly the same as
+** sqlite3_prepare_v3() with a zero prepFlags parameter.
+*/
+SQLITE_API int sqlite3_prepare(
+  sqlite3 *db,            /* Database handle */
+  const char *zSql,       /* SQL statement, UTF-8 encoded */
+  int nByte,              /* Maximum length of zSql in bytes. */
+  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
+);
+SQLITE_API int sqlite3_prepare_v2(
+  sqlite3 *db,            /* Database handle */
+  const char *zSql,       /* SQL statement, UTF-8 encoded */
+  int nByte,              /* Maximum length of zSql in bytes. */
+  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
+);
+SQLITE_API int sqlite3_prepare_v3(
+  sqlite3 *db,            /* Database handle */
+  const char *zSql,       /* SQL statement, UTF-8 encoded */
+  int nByte,              /* Maximum length of zSql in bytes. */
+  unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
+  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
+);
+SQLITE_API int sqlite3_prepare16(
+  sqlite3 *db,            /* Database handle */
+  const void *zSql,       /* SQL statement, UTF-16 encoded */
+  int nByte,              /* Maximum length of zSql in bytes. */
+  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
+);
+SQLITE_API int sqlite3_prepare16_v2(
+  sqlite3 *db,            /* Database handle */
+  const void *zSql,       /* SQL statement, UTF-16 encoded */
+  int nByte,              /* Maximum length of zSql in bytes. */
+  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
+);
+SQLITE_API int sqlite3_prepare16_v3(
+  sqlite3 *db,            /* Database handle */
+  const void *zSql,       /* SQL statement, UTF-16 encoded */
+  int nByte,              /* Maximum length of zSql in bytes. */
+  unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
+  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
+  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
+);
+
+/*
+** CAPI3REF: Retrieving Statement SQL
+** METHOD: sqlite3_stmt
+**
+** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8
+** SQL text used to create [prepared statement] P if P was
+** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
+** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
+** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
+** string containing the SQL text of prepared statement P with
+** [bound parameters] expanded.
+** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
+** string containing the normalized SQL text of prepared statement P.  The
+** semantics used to normalize a SQL statement are unspecified and subject
+** to change.  At a minimum, literal values will be replaced with suitable
+** placeholders.
+**
+** ^(For example, if a prepared statement is created using the SQL
+** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
+** and parameter :xyz is unbound, then sqlite3_sql() will return
+** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
+** will return "SELECT 2345,NULL".)^
+**
+** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory
+** is available to hold the result, or if the result would exceed the
+** the maximum string length determined by the [SQLITE_LIMIT_LENGTH].
+**
+** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
+** bound parameter expansions.  ^The [SQLITE_OMIT_TRACE] compile-time
+** option causes sqlite3_expanded_sql() to always return NULL.
+**
+** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
+** are managed by SQLite and are automatically freed when the prepared
+** statement is finalized.
+** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
+** is obtained from [sqlite3_malloc()] and must be free by the application
+** by passing it to [sqlite3_free()].
+*/
+SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
+SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
+SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
+
+/*
+** CAPI3REF: Determine If An SQL Statement Writes The Database
+** METHOD: sqlite3_stmt
+**
+** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
+** and only if the [prepared statement] X makes no direct changes to
+** the content of the database file.
+**
+** Note that [application-defined SQL functions] or
+** [virtual tables] might change the database indirectly as a side effect.  
+** ^(For example, if an application defines a function "eval()" that 
+** calls [sqlite3_exec()], then the following SQL statement would
+** change the database file through side-effects:
+**
+** <blockquote><pre>
+**    SELECT eval('DELETE FROM t1') FROM t2;
+** </pre></blockquote>
+**
+** But because the [SELECT] statement does not change the database file
+** directly, sqlite3_stmt_readonly() would still return true.)^
+**
+** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK],
+** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true,
+** since the statements themselves do not actually modify the database but
+** rather they control the timing of when other statements modify the 
+** database.  ^The [ATTACH] and [DETACH] statements also cause
+** sqlite3_stmt_readonly() to return true since, while those statements
+** change the configuration of a database connection, they do not make 
+** changes to the content of the database files on disk.
+** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since
+** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
+** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
+** sqlite3_stmt_readonly() returns false for those commands.
+*/
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
+
+/*
+** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
+** METHOD: sqlite3_stmt
+**
+** ^The sqlite3_stmt_isexplain(S) interface returns 1 if the
+** prepared statement S is an EXPLAIN statement, or 2 if the
+** statement S is an EXPLAIN QUERY PLAN.
+** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is
+** an ordinary statement or a NULL pointer.
+*/
+SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
+
+/*
+** CAPI3REF: Determine If A Prepared Statement Has Been Reset
+** METHOD: sqlite3_stmt
+**
+** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
+** [prepared statement] S has been stepped at least once using 
+** [sqlite3_step(S)] but has neither run to completion (returned
+** [SQLITE_DONE] from [sqlite3_step(S)]) nor
+** been reset using [sqlite3_reset(S)].  ^The sqlite3_stmt_busy(S)
+** interface returns false if S is a NULL pointer.  If S is not a 
+** NULL pointer and is not a pointer to a valid [prepared statement]
+** object, then the behavior is undefined and probably undesirable.
+**
+** This interface can be used in combination [sqlite3_next_stmt()]
+** to locate all prepared statements associated with a database 
+** connection that are in need of being reset.  This can be used,
+** for example, in diagnostic routines to search for prepared 
+** statements that are holding a transaction open.
+*/
+SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
+
+/*
+** CAPI3REF: Dynamically Typed Value Object
+** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
+**
+** SQLite uses the sqlite3_value object to represent all values
+** that can be stored in a database table. SQLite uses dynamic typing
+** for the values it stores.  ^Values stored in sqlite3_value objects
+** can be integers, floating point values, strings, BLOBs, or NULL.
+**
+** An sqlite3_value object may be either "protected" or "unprotected".
+** Some interfaces require a protected sqlite3_value.  Other interfaces
+** will accept either a protected or an unprotected sqlite3_value.
+** Every interface that accepts sqlite3_value arguments specifies
+** whether or not it requires a protected sqlite3_value.  The
+** [sqlite3_value_dup()] interface can be used to construct a new 
+** protected sqlite3_value from an unprotected sqlite3_value.
+**
+** The terms "protected" and "unprotected" refer to whether or not
+** a mutex is held.  An internal mutex is held for a protected
+** sqlite3_value object but no mutex is held for an unprotected
+** sqlite3_value object.  If SQLite is compiled to be single-threaded
+** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
+** or if SQLite is run in one of reduced mutex modes 
+** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
+** then there is no distinction between protected and unprotected
+** sqlite3_value objects and they can be used interchangeably.  However,
+** for maximum code portability it is recommended that applications
+** still make the distinction between protected and unprotected
+** sqlite3_value objects even when not strictly required.
+**
+** ^The sqlite3_value objects that are passed as parameters into the
+** implementation of [application-defined SQL functions] are protected.
+** ^The sqlite3_value object returned by
+** [sqlite3_column_value()] is unprotected.
+** Unprotected sqlite3_value objects may only be used as arguments
+** to [sqlite3_result_value()], [sqlite3_bind_value()], and
+** [sqlite3_value_dup()].
+** The [sqlite3_value_blob | sqlite3_value_type()] family of
+** interfaces require protected sqlite3_value objects.
+*/
+typedef struct sqlite3_value sqlite3_value;
+
+/*
+** CAPI3REF: SQL Function Context Object
+**
+** The context in which an SQL function executes is stored in an
+** sqlite3_context object.  ^A pointer to an sqlite3_context object
+** is always first parameter to [application-defined SQL functions].
+** The application-defined SQL function implementation will pass this
+** pointer through into calls to [sqlite3_result_int | sqlite3_result()],
+** [sqlite3_aggregate_context()], [sqlite3_user_data()],
+** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()],
+** and/or [sqlite3_set_auxdata()].
+*/
+typedef struct sqlite3_context sqlite3_context;
+
+/*
+** CAPI3REF: Binding Values To Prepared Statements
+** KEYWORDS: {host parameter} {host parameters} {host parameter name}
+** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
+** METHOD: sqlite3_stmt
+**
+** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
+** literals may be replaced by a [parameter] that matches one of following
+** templates:
+**
+** <ul>
+** <li>  ?
+** <li>  ?NNN
+** <li>  :VVV
+** <li>  @VVV
+** <li>  $VVV
+** </ul>
+**
+** In the templates above, NNN represents an integer literal,
+** and VVV represents an alphanumeric identifier.)^  ^The values of these
+** parameters (also called "host parameter names" or "SQL parameters")
+** can be set using the sqlite3_bind_*() routines defined here.
+**
+** ^The first argument to the sqlite3_bind_*() routines is always
+** a pointer to the [sqlite3_stmt] object returned from
+** [sqlite3_prepare_v2()] or its variants.
+**
+** ^The second argument is the index of the SQL parameter to be set.
+** ^The leftmost SQL parameter has an index of 1.  ^When the same named
+** SQL parameter is used more than once, second and subsequent
+** occurrences have the same index as the first occurrence.
+** ^The index for named parameters can be looked up using the
+** [sqlite3_bind_parameter_index()] API if desired.  ^The index
+** for "?NNN" parameters is the value of NNN.
+** ^The NNN value must be between 1 and the [sqlite3_limit()]
+** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 32766).
+**
+** ^The third argument is the value to bind to the parameter.
+** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
+** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
+** is ignored and the end result is the same as sqlite3_bind_null().
+** ^If the third parameter to sqlite3_bind_text() is not NULL, then
+** it should be a pointer to well-formed UTF8 text.
+** ^If the third parameter to sqlite3_bind_text16() is not NULL, then
+** it should be a pointer to well-formed UTF16 text.
+** ^If the third parameter to sqlite3_bind_text64() is not NULL, then
+** it should be a pointer to a well-formed unicode string that is
+** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
+** otherwise.
+**
+** [[byte-order determination rules]] ^The byte-order of
+** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
+** found in first character, which is removed, or in the absence of a BOM
+** the byte order is the native byte order of the host
+** machine for sqlite3_bind_text16() or the byte order specified in
+** the 6th parameter for sqlite3_bind_text64().)^ 
+** ^If UTF16 input text contains invalid unicode
+** characters, then SQLite might change those invalid characters
+** into the unicode replacement character: U+FFFD.
+**
+** ^(In those routines that have a fourth argument, its value is the
+** number of bytes in the parameter.  To be clear: the value is the
+** number of <u>bytes</u> in the value, not the number of characters.)^
+** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16()
+** is negative, then the length of the string is
+** the number of bytes up to the first zero terminator.
+** If the fourth parameter to sqlite3_bind_blob() is negative, then
+** the behavior is undefined.
+** If a non-negative fourth parameter is provided to sqlite3_bind_text()
+** or sqlite3_bind_text16() or sqlite3_bind_text64() then
+** that parameter must be the byte offset
+** where the NUL terminator would occur assuming the string were NUL
+** terminated.  If any NUL characters occurs at byte offsets less than 
+** the value of the fourth parameter then the resulting string value will
+** contain embedded NULs.  The result of expressions involving strings
+** with embedded NULs is undefined.
+**
+** ^The fifth argument to the BLOB and string binding interfaces
+** is a destructor used to dispose of the BLOB or
+** string after SQLite has finished with it.  ^The destructor is called
+** to dispose of the BLOB or string even if the call to the bind API fails,
+** except the destructor is not called if the third parameter is a NULL
+** pointer or the fourth parameter is negative.
+** ^If the fifth argument is
+** the special value [SQLITE_STATIC], then SQLite assumes that the
+** information is in static, unmanaged space and does not need to be freed.
+** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
+** SQLite makes its own private copy of the data immediately, before
+** the sqlite3_bind_*() routine returns.
+**
+** ^The sixth argument to sqlite3_bind_text64() must be one of
+** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
+** to specify the encoding of the text in the third parameter.  If
+** the sixth argument to sqlite3_bind_text64() is not one of the
+** allowed values shown above, or if the text encoding is different
+** from the encoding specified by the sixth parameter, then the behavior
+** is undefined.
+**
+** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
+** is filled with zeroes.  ^A zeroblob uses a fixed amount of memory
+** (just an integer to hold its size) while it is being processed.
+** Zeroblobs are intended to serve as placeholders for BLOBs whose
+** content is later written using
+** [sqlite3_blob_open | incremental BLOB I/O] routines.
+** ^A negative value for the zeroblob results in a zero-length BLOB.
+**
+** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
+** [prepared statement] S to have an SQL value of NULL, but to also be
+** associated with the pointer P of type T.  ^D is either a NULL pointer or
+** a pointer to a destructor function for P. ^SQLite will invoke the
+** destructor D with a single argument of P when it is finished using
+** P.  The T parameter should be a static string, preferably a string
+** literal. The sqlite3_bind_pointer() routine is part of the
+** [pointer passing interface] added for SQLite 3.20.0.
+**
+** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
+** for the [prepared statement] or with a prepared statement for which
+** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
+** then the call will return [SQLITE_MISUSE].  If any sqlite3_bind_()
+** routine is passed a [prepared statement] that has been finalized, the
+** result is undefined and probably harmful.
+**
+** ^Bindings are not cleared by the [sqlite3_reset()] routine.
+** ^Unbound parameters are interpreted as NULL.
+**
+** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an
+** [error code] if anything goes wrong.
+** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB
+** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or
+** [SQLITE_MAX_LENGTH].
+** ^[SQLITE_RANGE] is returned if the parameter
+** index is out of range.  ^[SQLITE_NOMEM] is returned if malloc() fails.
+**
+** See also: [sqlite3_bind_parameter_count()],
+** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
+*/
+SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+                        void(*)(void*));
+SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
+SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
+SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
+SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+                         void(*)(void*), unsigned char encoding);
+SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
+SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
+SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
+
+/*
+** CAPI3REF: Number Of SQL Parameters
+** METHOD: sqlite3_stmt
+**
+** ^This routine can be used to find the number of [SQL parameters]
+** in a [prepared statement].  SQL parameters are tokens of the
+** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
+** placeholders for values that are [sqlite3_bind_blob | bound]
+** to the parameters at a later time.
+**
+** ^(This routine actually returns the index of the largest (rightmost)
+** parameter. For all forms except ?NNN, this will correspond to the
+** number of unique parameters.  If parameters of the ?NNN form are used,
+** there may be gaps in the list.)^
+**
+** See also: [sqlite3_bind_blob|sqlite3_bind()],
+** [sqlite3_bind_parameter_name()], and
+** [sqlite3_bind_parameter_index()].
+*/
+SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
+
+/*
+** CAPI3REF: Name Of A Host Parameter
+** METHOD: sqlite3_stmt
+**
+** ^The sqlite3_bind_parameter_name(P,N) interface returns
+** the name of the N-th [SQL parameter] in the [prepared statement] P.
+** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
+** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
+** respectively.
+** In other words, the initial ":" or "$" or "@" or "?"
+** is included as part of the name.)^
+** ^Parameters of the form "?" without a following integer have no name
+** and are referred to as "nameless" or "anonymous parameters".
+**
+** ^The first host parameter has an index of 1, not 0.
+**
+** ^If the value N is out of range or if the N-th parameter is
+** nameless, then NULL is returned.  ^The returned string is
+** always in UTF-8 encoding even if the named parameter was
+** originally specified as UTF-16 in [sqlite3_prepare16()],
+** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
+**
+** See also: [sqlite3_bind_blob|sqlite3_bind()],
+** [sqlite3_bind_parameter_count()], and
+** [sqlite3_bind_parameter_index()].
+*/
+SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+
+/*
+** CAPI3REF: Index Of A Parameter With A Given Name
+** METHOD: sqlite3_stmt
+**
+** ^Return the index of an SQL parameter given its name.  ^The
+** index value returned is suitable for use as the second
+** parameter to [sqlite3_bind_blob|sqlite3_bind()].  ^A zero
+** is returned if no matching parameter is found.  ^The parameter
+** name must be given in UTF-8 even if the original statement
+** was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or
+** [sqlite3_prepare16_v3()].
+**
+** See also: [sqlite3_bind_blob|sqlite3_bind()],
+** [sqlite3_bind_parameter_count()], and
+** [sqlite3_bind_parameter_name()].
+*/
+SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+
+/*
+** CAPI3REF: Reset All Bindings On A Prepared Statement
+** METHOD: sqlite3_stmt
+**
+** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset
+** the [sqlite3_bind_blob | bindings] on a [prepared statement].
+** ^Use this routine to reset all host parameters to NULL.
+*/
+SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
+
+/*
+** CAPI3REF: Number Of Columns In A Result Set
+** METHOD: sqlite3_stmt
+**
+** ^Return the number of columns in the result set returned by the
+** [prepared statement]. ^If this routine returns 0, that means the 
+** [prepared statement] returns no data (for example an [UPDATE]).
+** ^However, just because this routine returns a positive number does not
+** mean that one or more rows of data will be returned.  ^A SELECT statement
+** will always have a positive sqlite3_column_count() but depending on the
+** WHERE clause constraints and the table content, it might return no rows.
+**
+** See also: [sqlite3_data_count()]
+*/
+SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
+
+/*
+** CAPI3REF: Column Names In A Result Set
+** METHOD: sqlite3_stmt
+**
+** ^These routines return the name assigned to a particular column
+** in the result set of a [SELECT] statement.  ^The sqlite3_column_name()
+** interface returns a pointer to a zero-terminated UTF-8 string
+** and sqlite3_column_name16() returns a pointer to a zero-terminated
+** UTF-16 string.  ^The first parameter is the [prepared statement]
+** that implements the [SELECT] statement. ^The second parameter is the
+** column number.  ^The leftmost column is number 0.
+**
+** ^The returned string pointer is valid until either the [prepared statement]
+** is destroyed by [sqlite3_finalize()] or until the statement is automatically
+** reprepared by the first call to [sqlite3_step()] for a particular run
+** or until the next call to
+** sqlite3_column_name() or sqlite3_column_name16() on the same column.
+**
+** ^If sqlite3_malloc() fails during the processing of either routine
+** (for example during a conversion from UTF-8 to UTF-16) then a
+** NULL pointer is returned.
+**
+** ^The name of a result column is the value of the "AS" clause for
+** that column, if there is an AS clause.  If there is no AS clause
+** then the name of the column is unspecified and may change from
+** one release of SQLite to the next.
+*/
+SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
+SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
+
+/*
+** CAPI3REF: Source Of Data In A Query Result
+** METHOD: sqlite3_stmt
+**
+** ^These routines provide a means to determine the database, table, and
+** table column that is the origin of a particular result column in
+** [SELECT] statement.
+** ^The name of the database or table or column can be returned as
+** either a UTF-8 or UTF-16 string.  ^The _database_ routines return
+** the database name, the _table_ routines return the table name, and
+** the origin_ routines return the column name.
+** ^The returned string is valid until the [prepared statement] is destroyed
+** using [sqlite3_finalize()] or until the statement is automatically
+** reprepared by the first call to [sqlite3_step()] for a particular run
+** or until the same information is requested
+** again in a different encoding.
+**
+** ^The names returned are the original un-aliased names of the
+** database, table, and column.
+**
+** ^The first argument to these interfaces is a [prepared statement].
+** ^These functions return information about the Nth result column returned by
+** the statement, where N is the second function argument.
+** ^The left-most column is column 0 for these routines.
+**
+** ^If the Nth column returned by the statement is an expression or
+** subquery and is not a column value, then all of these functions return
+** NULL.  ^These routines might also return NULL if a memory allocation error
+** occurs.  ^Otherwise, they return the name of the attached database, table,
+** or column that query result column was extracted from.
+**
+** ^As with all other SQLite APIs, those whose names end with "16" return
+** UTF-16 encoded strings and the other functions return UTF-8.
+**
+** ^These APIs are only available if the library was compiled with the
+** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol.
+**
+** If two or more threads call one or more
+** [sqlite3_column_database_name | column metadata interfaces]
+** for the same [prepared statement] and result column
+** at the same time then the results are undefined.
+*/
+SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
+
+/*
+** CAPI3REF: Declared Datatype Of A Query Result
+** METHOD: sqlite3_stmt
+**
+** ^(The first parameter is a [prepared statement].
+** If this statement is a [SELECT] statement and the Nth column of the
+** returned result set of that [SELECT] is a table column (not an
+** expression or subquery) then the declared type of the table
+** column is returned.)^  ^If the Nth column of the result set is an
+** expression or subquery, then a NULL pointer is returned.
+** ^The returned string is always UTF-8 encoded.
+**
+** ^(For example, given the database schema:
+**
+** CREATE TABLE t1(c1 VARIANT);
+**
+** and the following statement to be compiled:
+**
+** SELECT c1 + 1, c1 FROM t1;
+**
+** this routine would return the string "VARIANT" for the second result
+** column (i==1), and a NULL pointer for the first result column (i==0).)^
+**
+** ^SQLite uses dynamic run-time typing.  ^So just because a column
+** is declared to contain a particular type does not mean that the
+** data stored in that column is of the declared type.  SQLite is
+** strongly typed, but the typing is dynamic not static.  ^Type
+** is associated with individual values, not with the containers
+** used to hold those values.
+*/
+SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
+
+/*
+** CAPI3REF: Evaluate An SQL Statement
+** METHOD: sqlite3_stmt
+**
+** After a [prepared statement] has been prepared using any of
+** [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()],
+** or [sqlite3_prepare16_v3()] or one of the legacy
+** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
+** must be called one or more times to evaluate the statement.
+**
+** The details of the behavior of the sqlite3_step() interface depend
+** on whether the statement was prepared using the newer "vX" interfaces
+** [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()],
+** [sqlite3_prepare16_v2()] or the older legacy
+** interfaces [sqlite3_prepare()] and [sqlite3_prepare16()].  The use of the
+** new "vX" interface is recommended for new applications but the legacy
+** interface will continue to be supported.
+**
+** ^In the legacy interface, the return value will be either [SQLITE_BUSY],
+** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
+** ^With the "v2" interface, any of the other [result codes] or
+** [extended result codes] might be returned as well.
+**
+** ^[SQLITE_BUSY] means that the database engine was unable to acquire the
+** database locks it needs to do its job.  ^If the statement is a [COMMIT]
+** or occurs outside of an explicit transaction, then you can retry the
+** statement.  If the statement is not a [COMMIT] and occurs within an
+** explicit transaction then you should rollback the transaction before
+** continuing.
+**
+** ^[SQLITE_DONE] means that the statement has finished executing
+** successfully.  sqlite3_step() should not be called again on this virtual
+** machine without first calling [sqlite3_reset()] to reset the virtual
+** machine back to its initial state.
+**
+** ^If the SQL statement being executed returns any data, then [SQLITE_ROW]
+** is returned each time a new row of data is ready for processing by the
+** caller. The values may be accessed using the [column access functions].
+** sqlite3_step() is called again to retrieve the next row of data.
+**
+** ^[SQLITE_ERROR] means that a run-time error (such as a constraint
+** violation) has occurred.  sqlite3_step() should not be called again on
+** the VM. More information may be found by calling [sqlite3_errmsg()].
+** ^With the legacy interface, a more specific error code (for example,
+** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
+** can be obtained by calling [sqlite3_reset()] on the
+** [prepared statement].  ^In the "v2" interface,
+** the more specific error code is returned directly by sqlite3_step().
+**
+** [SQLITE_MISUSE] means that the this routine was called inappropriately.
+** Perhaps it was called on a [prepared statement] that has
+** already been [sqlite3_finalize | finalized] or on one that had
+** previously returned [SQLITE_ERROR] or [SQLITE_DONE].  Or it could
+** be the case that the same database connection is being used by two or
+** more threads at the same moment in time.
+**
+** For all versions of SQLite up to and including 3.6.23.1, a call to
+** [sqlite3_reset()] was required after sqlite3_step() returned anything
+** other than [SQLITE_ROW] before any subsequent invocation of
+** sqlite3_step().  Failure to reset the prepared statement using 
+** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
+** sqlite3_step().  But after [version 3.6.23.1] ([dateof:3.6.23.1],
+** sqlite3_step() began
+** calling [sqlite3_reset()] automatically in this circumstance rather
+** than returning [SQLITE_MISUSE].  This is not considered a compatibility
+** break because any application that ever receives an SQLITE_MISUSE error
+** is broken by definition.  The [SQLITE_OMIT_AUTORESET] compile-time option
+** can be used to restore the legacy behavior.
+**
+** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
+** API always returns a generic error code, [SQLITE_ERROR], following any
+** error other than [SQLITE_BUSY] and [SQLITE_MISUSE].  You must call
+** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
+** specific [error codes] that better describes the error.
+** We admit that this is a goofy design.  The problem has been fixed
+** with the "v2" interface.  If you prepare all of your SQL statements
+** using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()]
+** or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead
+** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
+** then the more specific [error codes] are returned directly
+** by sqlite3_step().  The use of the "vX" interfaces is recommended.
+*/
+SQLITE_API int sqlite3_step(sqlite3_stmt*);
+
+/*
+** CAPI3REF: Number of columns in a result set
+** METHOD: sqlite3_stmt
+**
+** ^The sqlite3_data_count(P) interface returns the number of columns in the
+** current row of the result set of [prepared statement] P.
+** ^If prepared statement P does not have results ready to return
+** (via calls to the [sqlite3_column_int | sqlite3_column()] family of
+** interfaces) then sqlite3_data_count(P) returns 0.
+** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
+** ^The sqlite3_data_count(P) routine returns 0 if the previous call to
+** [sqlite3_step](P) returned [SQLITE_DONE].  ^The sqlite3_data_count(P)
+** will return non-zero if previous call to [sqlite3_step](P) returned
+** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
+** where it always returns zero since each step of that multi-step
+** pragma returns 0 columns of data.
+**
+** See also: [sqlite3_column_count()]
+*/
+SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
+
+/*
+** CAPI3REF: Fundamental Datatypes
+** KEYWORDS: SQLITE_TEXT
+**
+** ^(Every value in SQLite has one of five fundamental datatypes:
+**
+** <ul>
+** <li> 64-bit signed integer
+** <li> 64-bit IEEE floating point number
+** <li> string
+** <li> BLOB
+** <li> NULL
+** </ul>)^
+**
+** These constants are codes for each of those types.
+**
+** Note that the SQLITE_TEXT constant was also used in SQLite version 2
+** for a completely different meaning.  Software that links against both
+** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not
+** SQLITE_TEXT.
+*/
+#define SQLITE_INTEGER  1
+#define SQLITE_FLOAT    2
+#define SQLITE_BLOB     4
+#define SQLITE_NULL     5
+#ifdef SQLITE_TEXT
+# undef SQLITE_TEXT
+#else
+# define SQLITE_TEXT     3
+#endif
+#define SQLITE3_TEXT     3
+
+/*
+** CAPI3REF: Result Values From A Query
+** KEYWORDS: {column access functions}
+** METHOD: sqlite3_stmt
+**
+** <b>Summary:</b>
+** <blockquote><table border=0 cellpadding=0 cellspacing=0>
+** <tr><td><b>sqlite3_column_blob</b><td>&rarr;<td>BLOB result
+** <tr><td><b>sqlite3_column_double</b><td>&rarr;<td>REAL result
+** <tr><td><b>sqlite3_column_int</b><td>&rarr;<td>32-bit INTEGER result
+** <tr><td><b>sqlite3_column_int64</b><td>&rarr;<td>64-bit INTEGER result
+** <tr><td><b>sqlite3_column_text</b><td>&rarr;<td>UTF-8 TEXT result
+** <tr><td><b>sqlite3_column_text16</b><td>&rarr;<td>UTF-16 TEXT result
+** <tr><td><b>sqlite3_column_value</b><td>&rarr;<td>The result as an 
+** [sqlite3_value|unprotected sqlite3_value] object.
+** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
+** <tr><td><b>sqlite3_column_bytes</b><td>&rarr;<td>Size of a BLOB
+** or a UTF-8 TEXT result in bytes
+** <tr><td><b>sqlite3_column_bytes16&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
+** TEXT in bytes
+** <tr><td><b>sqlite3_column_type</b><td>&rarr;<td>Default
+** datatype of the result
+** </table></blockquote>
+**
+** <b>Details:</b>
+**
+** ^These routines return information about a single column of the current
+** result row of a query.  ^In every case the first argument is a pointer
+** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
+** that was returned from [sqlite3_prepare_v2()] or one of its variants)
+** and the second argument is the index of the column for which information
+** should be returned. ^The leftmost column of the result set has the index 0.
+** ^The number of columns in the result can be determined using
+** [sqlite3_column_count()].
+**
+** If the SQL statement does not currently point to a valid row, or if the
+** column index is out of range, the result is undefined.
+** These routines may only be called when the most recent call to
+** [sqlite3_step()] has returned [SQLITE_ROW] and neither
+** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
+** If any of these routines are called after [sqlite3_reset()] or
+** [sqlite3_finalize()] or after [sqlite3_step()] has returned
+** something other than [SQLITE_ROW], the results are undefined.
+** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
+** are called from a different thread while any of these routines
+** are pending, then the results are undefined.
+**
+** The first six interfaces (_blob, _double, _int, _int64, _text, and _text16)
+** each return the value of a result column in a specific data format.  If
+** the result column is not initially in the requested format (for example,
+** if the query returns an integer but the sqlite3_column_text() interface
+** is used to extract the value) then an automatic type conversion is performed.
+**
+** ^The sqlite3_column_type() routine returns the
+** [SQLITE_INTEGER | datatype code] for the initial data type
+** of the result column.  ^The returned value is one of [SQLITE_INTEGER],
+** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].
+** The return value of sqlite3_column_type() can be used to decide which
+** of the first six interface should be used to extract the column value.
+** The value returned by sqlite3_column_type() is only meaningful if no
+** automatic type conversions have occurred for the value in question.  
+** After a type conversion, the result of calling sqlite3_column_type()
+** is undefined, though harmless.  Future
+** versions of SQLite may change the behavior of sqlite3_column_type()
+** following a type conversion.
+**
+** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes()
+** or sqlite3_column_bytes16() interfaces can be used to determine the size
+** of that BLOB or string.
+**
+** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
+** routine returns the number of bytes in that BLOB or string.
+** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts
+** the string to UTF-8 and then returns the number of bytes.
+** ^If the result is a numeric value then sqlite3_column_bytes() uses
+** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns
+** the number of bytes in that string.
+** ^If the result is NULL, then sqlite3_column_bytes() returns zero.
+**
+** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16()
+** routine returns the number of bytes in that BLOB or string.
+** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts
+** the string to UTF-16 and then returns the number of bytes.
+** ^If the result is a numeric value then sqlite3_column_bytes16() uses
+** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns
+** the number of bytes in that string.
+** ^If the result is NULL, then sqlite3_column_bytes16() returns zero.
+**
+** ^The values returned by [sqlite3_column_bytes()] and 
+** [sqlite3_column_bytes16()] do not include the zero terminators at the end
+** of the string.  ^For clarity: the values returned by
+** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of
+** bytes in the string, not the number of characters.
+**
+** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
+** even empty strings, are always zero-terminated.  ^The return
+** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
+**
+** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
+** [unprotected sqlite3_value] object.  In a multithreaded environment,
+** an unprotected sqlite3_value object may only be used safely with
+** [sqlite3_bind_value()] and [sqlite3_result_value()].
+** If the [unprotected sqlite3_value] object returned by
+** [sqlite3_column_value()] is used in any other way, including calls
+** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
+** or [sqlite3_value_bytes()], the behavior is not threadsafe.
+** Hence, the sqlite3_column_value() interface
+** is normally only useful within the implementation of 
+** [application-defined SQL functions] or [virtual tables], not within
+** top-level application code.
+**
+** The these routines may attempt to convert the datatype of the result.
+** ^For example, if the internal representation is FLOAT and a text result
+** is requested, [sqlite3_snprintf()] is used internally to perform the
+** conversion automatically.  ^(The following table details the conversions
+** that are applied:
+**
+** <blockquote>
+** <table border="1">
+** <tr><th> Internal<br>Type <th> Requested<br>Type <th>  Conversion
+**
+** <tr><td>  NULL    <td> INTEGER   <td> Result is 0
+** <tr><td>  NULL    <td>  FLOAT    <td> Result is 0.0
+** <tr><td>  NULL    <td>   TEXT    <td> Result is a NULL pointer
+** <tr><td>  NULL    <td>   BLOB    <td> Result is a NULL pointer
+** <tr><td> INTEGER  <td>  FLOAT    <td> Convert from integer to float
+** <tr><td> INTEGER  <td>   TEXT    <td> ASCII rendering of the integer
+** <tr><td> INTEGER  <td>   BLOB    <td> Same as INTEGER->TEXT
+** <tr><td>  FLOAT   <td> INTEGER   <td> [CAST] to INTEGER
+** <tr><td>  FLOAT   <td>   TEXT    <td> ASCII rendering of the float
+** <tr><td>  FLOAT   <td>   BLOB    <td> [CAST] to BLOB
+** <tr><td>  TEXT    <td> INTEGER   <td> [CAST] to INTEGER
+** <tr><td>  TEXT    <td>  FLOAT    <td> [CAST] to REAL
+** <tr><td>  TEXT    <td>   BLOB    <td> No change
+** <tr><td>  BLOB    <td> INTEGER   <td> [CAST] to INTEGER
+** <tr><td>  BLOB    <td>  FLOAT    <td> [CAST] to REAL
+** <tr><td>  BLOB    <td>   TEXT    <td> Add a zero terminator if needed
+** </table>
+** </blockquote>)^
+**
+** Note that when type conversions occur, pointers returned by prior
+** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
+** sqlite3_column_text16() may be invalidated.
+** Type conversions and pointer invalidations might occur
+** in the following cases:
+**
+** <ul>
+** <li> The initial content is a BLOB and sqlite3_column_text() or
+**      sqlite3_column_text16() is called.  A zero-terminator might
+**      need to be added to the string.</li>
+** <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or
+**      sqlite3_column_text16() is called.  The content must be converted
+**      to UTF-16.</li>
+** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or
+**      sqlite3_column_text() is called.  The content must be converted
+**      to UTF-8.</li>
+** </ul>
+**
+** ^Conversions between UTF-16be and UTF-16le are always done in place and do
+** not invalidate a prior pointer, though of course the content of the buffer
+** that the prior pointer references will have been modified.  Other kinds
+** of conversion are done in place when it is possible, but sometimes they
+** are not possible and in those cases prior pointers are invalidated.
+**
+** The safest policy is to invoke these routines
+** in one of the following ways:
+**
+** <ul>
+**  <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
+**  <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
+**  <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
+** </ul>
+**
+** In other words, you should call sqlite3_column_text(),
+** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result
+** into the desired format, then invoke sqlite3_column_bytes() or
+** sqlite3_column_bytes16() to find the size of the result.  Do not mix calls
+** to sqlite3_column_text() or sqlite3_column_blob() with calls to
+** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16()
+** with calls to sqlite3_column_bytes().
+**
+** ^The pointers returned are valid until a type conversion occurs as
+** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
+** [sqlite3_finalize()] is called.  ^The memory space used to hold strings
+** and BLOBs is freed automatically.  Do not pass the pointers returned
+** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
+** [sqlite3_free()].
+**
+** As long as the input parameters are correct, these routines will only
+** fail if an out-of-memory error occurs during a format conversion.
+** Only the following subset of interfaces are subject to out-of-memory
+** errors:
+**
+** <ul>
+** <li> sqlite3_column_blob()
+** <li> sqlite3_column_text()
+** <li> sqlite3_column_text16()
+** <li> sqlite3_column_bytes()
+** <li> sqlite3_column_bytes16()
+** </ul>
+**
+** If an out-of-memory error occurs, then the return value from these
+** routines is the same as if the column had contained an SQL NULL value.
+** Valid SQL NULL returns can be distinguished from out-of-memory errors
+** by invoking the [sqlite3_errcode()] immediately after the suspect
+** return value is obtained and before any
+** other SQLite interface is called on the same [database connection].
+*/
+SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
+SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
+
+/*
+** CAPI3REF: Destroy A Prepared Statement Object
+** DESTRUCTOR: sqlite3_stmt
+**
+** ^The sqlite3_finalize() function is called to delete a [prepared statement].
+** ^If the most recent evaluation of the statement encountered no errors
+** or if the statement is never been evaluated, then sqlite3_finalize() returns
+** SQLITE_OK.  ^If the most recent evaluation of statement S failed, then
+** sqlite3_finalize(S) returns the appropriate [error code] or
+** [extended error code].
+**
+** ^The sqlite3_finalize(S) routine can be called at any point during
+** the life cycle of [prepared statement] S:
+** before statement S is ever evaluated, after
+** one or more calls to [sqlite3_reset()], or after any call
+** to [sqlite3_step()] regardless of whether or not the statement has
+** completed execution.
+**
+** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.
+**
+** The application must finalize every [prepared statement] in order to avoid
+** resource leaks.  It is a grievous error for the application to try to use
+** a prepared statement after it has been finalized.  Any use of a prepared
+** statement after it has been finalized can result in undefined and
+** undesirable behavior such as segfaults and heap corruption.
+*/
+SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
+
+/*
+** CAPI3REF: Reset A Prepared Statement Object
+** METHOD: sqlite3_stmt
+**
+** The sqlite3_reset() function is called to reset a [prepared statement]
+** object back to its initial state, ready to be re-executed.
+** ^Any SQL statement variables that had values bound to them using
+** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
+** Use [sqlite3_clear_bindings()] to reset the bindings.
+**
+** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S
+** back to the beginning of its program.
+**
+** ^If the most recent call to [sqlite3_step(S)] for the
+** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],
+** or if [sqlite3_step(S)] has never before been called on S,
+** then [sqlite3_reset(S)] returns [SQLITE_OK].
+**
+** ^If the most recent call to [sqlite3_step(S)] for the
+** [prepared statement] S indicated an error, then
+** [sqlite3_reset(S)] returns an appropriate [error code].
+**
+** ^The [sqlite3_reset(S)] interface does not change the values
+** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
+*/
+SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
+
+/*
+** CAPI3REF: Create Or Redefine SQL Functions
+** KEYWORDS: {function creation routines}
+** METHOD: sqlite3
+**
+** ^These functions (collectively known as "function creation routines")
+** are used to add SQL functions or aggregates or to redefine the behavior
+** of existing SQL functions or aggregates. The only differences between
+** the three "sqlite3_create_function*" routines are the text encoding 
+** expected for the second parameter (the name of the function being 
+** created) and the presence or absence of a destructor callback for
+** the application data pointer. Function sqlite3_create_window_function()
+** is similar, but allows the user to supply the extra callback functions
+** needed by [aggregate window functions].
+**
+** ^The first parameter is the [database connection] to which the SQL
+** function is to be added.  ^If an application uses more than one database
+** connection then application-defined SQL functions must be added
+** to each database connection separately.
+**
+** ^The second parameter is the name of the SQL function to be created or
+** redefined.  ^The length of the name is limited to 255 bytes in a UTF-8
+** representation, exclusive of the zero-terminator.  ^Note that the name
+** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes.  
+** ^Any attempt to create a function with a longer name
+** will result in [SQLITE_MISUSE] being returned.
+**
+** ^The third parameter (nArg)
+** is the number of arguments that the SQL function or
+** aggregate takes. ^If this parameter is -1, then the SQL function or
+** aggregate may take any number of arguments between 0 and the limit
+** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]).  If the third
+** parameter is less than -1 or greater than 127 then the behavior is
+** undefined.
+**
+** ^The fourth parameter, eTextRep, specifies what
+** [SQLITE_UTF8 | text encoding] this SQL function prefers for
+** its parameters.  The application should set this parameter to
+** [SQLITE_UTF16LE] if the function implementation invokes 
+** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the
+** implementation invokes [sqlite3_value_text16be()] on an input, or
+** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8]
+** otherwise.  ^The same SQL function may be registered multiple times using
+** different preferred text encodings, with different implementations for
+** each encoding.
+** ^When multiple implementations of the same function are available, SQLite
+** will pick the one that involves the least amount of data conversion.
+**
+** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC]
+** to signal that the function will always return the same result given
+** the same inputs within a single SQL statement.  Most SQL functions are
+** deterministic.  The built-in [random()] SQL function is an example of a
+** function that is not deterministic.  The SQLite query planner is able to
+** perform additional optimizations on deterministic functions, so use
+** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
+**
+** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY]
+** flag, which if present prevents the function from being invoked from
+** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions,
+** index expressions, or the WHERE clause of partial indexes.
+**
+** <span style="background-color:#ffff90;">
+** For best security, the [SQLITE_DIRECTONLY] flag is recommended for
+** all application-defined SQL functions that do not need to be
+** used inside of triggers, view, CHECK constraints, or other elements of
+** the database schema.  This flags is especially recommended for SQL 
+** functions that have side effects or reveal internal application state.
+** Without this flag, an attacker might be able to modify the schema of
+** a database file to include invocations of the function with parameters
+** chosen by the attacker, which the application will then execute when
+** the database file is opened and read.
+** </span>
+**
+** ^(The fifth parameter is an arbitrary pointer.  The implementation of the
+** function can gain access to this pointer using [sqlite3_user_data()].)^
+**
+** ^The sixth, seventh and eighth parameters passed to the three
+** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
+** pointers to C-language functions that implement the SQL function or
+** aggregate. ^A scalar SQL function requires an implementation of the xFunc
+** callback only; NULL pointers must be passed as the xStep and xFinal
+** parameters. ^An aggregate SQL function requires an implementation of xStep
+** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
+** SQL function or aggregate, pass NULL pointers for all three function
+** callbacks.
+**
+** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue 
+** and xInverse) passed to sqlite3_create_window_function are pointers to
+** C-language callbacks that implement the new function. xStep and xFinal
+** must both be non-NULL. xValue and xInverse may either both be NULL, in
+** which case a regular aggregate function is created, or must both be 
+** non-NULL, in which case the new function may be used as either an aggregate
+** or aggregate window function. More details regarding the implementation
+** of aggregate window functions are 
+** [user-defined window functions|available here].
+**
+** ^(If the final parameter to sqlite3_create_function_v2() or
+** sqlite3_create_window_function() is not NULL, then it is destructor for
+** the application data pointer. The destructor is invoked when the function 
+** is deleted, either by being overloaded or when the database connection 
+** closes.)^ ^The destructor is also invoked if the call to 
+** sqlite3_create_function_v2() fails.  ^When the destructor callback is
+** invoked, it is passed a single argument which is a copy of the application
+** data pointer which was the fifth parameter to sqlite3_create_function_v2().
+**
+** ^It is permitted to register multiple implementations of the same
+** functions with the same name but with either differing numbers of
+** arguments or differing preferred text encodings.  ^SQLite will use
+** the implementation that most closely matches the way in which the
+** SQL function is used.  ^A function implementation with a non-negative
+** nArg parameter is a better match than a function implementation with
+** a negative nArg.  ^A function where the preferred text encoding
+** matches the database encoding is a better
+** match than a function where the encoding is different.  
+** ^A function where the encoding difference is between UTF16le and UTF16be
+** is a closer match than a function where the encoding difference is
+** between UTF8 and UTF16.
+**
+** ^Built-in functions may be overloaded by new application-defined functions.
+**
+** ^An application-defined function is permitted to call other
+** SQLite interfaces.  However, such calls must not
+** close the database connection nor finalize or reset the prepared
+** statement in which the function is running.
+*/
+SQLITE_API int sqlite3_create_function(
+  sqlite3 *db,
+  const char *zFunctionName,
+  int nArg,
+  int eTextRep,
+  void *pApp,
+  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+  void (*xFinal)(sqlite3_context*)
+);
+SQLITE_API int sqlite3_create_function16(
+  sqlite3 *db,
+  const void *zFunctionName,
+  int nArg,
+  int eTextRep,
+  void *pApp,
+  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+  void (*xFinal)(sqlite3_context*)
+);
+SQLITE_API int sqlite3_create_function_v2(
+  sqlite3 *db,
+  const char *zFunctionName,
+  int nArg,
+  int eTextRep,
+  void *pApp,
+  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+  void (*xFinal)(sqlite3_context*),
+  void(*xDestroy)(void*)
+);
+SQLITE_API int sqlite3_create_window_function(
+  sqlite3 *db,
+  const char *zFunctionName,
+  int nArg,
+  int eTextRep,
+  void *pApp,
+  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+  void (*xFinal)(sqlite3_context*),
+  void (*xValue)(sqlite3_context*),
+  void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
+  void(*xDestroy)(void*)
+);
+
+/*
+** CAPI3REF: Text Encodings
+**
+** These constant define integer codes that represent the various
+** text encodings supported by SQLite.
+*/
+#define SQLITE_UTF8           1    /* IMP: R-37514-35566 */
+#define SQLITE_UTF16LE        2    /* IMP: R-03371-37637 */
+#define SQLITE_UTF16BE        3    /* IMP: R-51971-34154 */
+#define SQLITE_UTF16          4    /* Use native byte order */
+#define SQLITE_ANY            5    /* Deprecated */
+#define SQLITE_UTF16_ALIGNED  8    /* sqlite3_create_collation only */
+
+/*
+** CAPI3REF: Function Flags
+**
+** These constants may be ORed together with the 
+** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
+** to [sqlite3_create_function()], [sqlite3_create_function16()], or
+** [sqlite3_create_function_v2()].
+**
+** <dl>
+** [[SQLITE_DETERMINISTIC]] <dt>SQLITE_DETERMINISTIC</dt><dd>
+** The SQLITE_DETERMINISTIC flag means that the new function always gives
+** the same output when the input parameters are the same.
+** The [abs|abs() function] is deterministic, for example, but
+** [randomblob|randomblob()] is not.  Functions must
+** be deterministic in order to be used in certain contexts such as
+** with the WHERE clause of [partial indexes] or in [generated columns].
+** SQLite might also optimize deterministic functions by factoring them
+** out of inner loops.
+** </dd>
+** 
+** [[SQLITE_DIRECTONLY]] <dt>SQLITE_DIRECTONLY</dt><dd>
+** The SQLITE_DIRECTONLY flag means that the function may only be invoked
+** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in 
+** schema structures such as [CHECK constraints], [DEFAULT clauses],
+** [expression indexes], [partial indexes], or [generated columns].
+** The SQLITE_DIRECTONLY flags is a security feature which is recommended
+** for all [application-defined SQL functions], and especially for functions
+** that have side-effects or that could potentially leak sensitive
+** information.
+** </dd>
+**
+** [[SQLITE_INNOCUOUS]] <dt>SQLITE_INNOCUOUS</dt><dd>
+** The SQLITE_INNOCUOUS flag means that the function is unlikely
+** to cause problems even if misused.  An innocuous function should have
+** no side effects and should not depend on any values other than its
+** input parameters. The [abs|abs() function] is an example of an
+** innocuous function.
+** The [load_extension() SQL function] is not innocuous because of its
+** side effects.
+** <p> SQLITE_INNOCUOUS is similar to SQLITE_DETERMINISTIC, but is not
+** exactly the same.  The [random|random() function] is an example of a
+** function that is innocuous but not deterministic.
+** <p>Some heightened security settings
+** ([SQLITE_DBCONFIG_TRUSTED_SCHEMA] and [PRAGMA trusted_schema=OFF])
+** disable the use of SQL functions inside views and triggers and in
+** schema structures such as [CHECK constraints], [DEFAULT clauses],
+** [expression indexes], [partial indexes], and [generated columns] unless
+** the function is tagged with SQLITE_INNOCUOUS.  Most built-in functions
+** are innocuous.  Developers are advised to avoid using the
+** SQLITE_INNOCUOUS flag for application-defined functions unless the
+** function has been carefully audited and found to be free of potentially
+** security-adverse side-effects and information-leaks.
+** </dd>
+**
+** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd>
+** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call
+** [sqlite3_value_subtype()] to inspect the sub-types of its arguments.
+** Specifying this flag makes no difference for scalar or aggregate user
+** functions. However, if it is not specified for a user-defined window
+** function, then any sub-types belonging to arguments passed to the window
+** function may be discarded before the window function is called (i.e.
+** sqlite3_value_subtype() will always return 0).
+** </dd>
+** </dl>
+*/
+#define SQLITE_DETERMINISTIC    0x000000800
+#define SQLITE_DIRECTONLY       0x000080000
+#define SQLITE_SUBTYPE          0x000100000
+#define SQLITE_INNOCUOUS        0x000200000
+
+/*
+** CAPI3REF: Deprecated Functions
+** DEPRECATED
+**
+** These functions are [deprecated].  In order to maintain
+** backwards compatibility with older code, these functions continue 
+** to be supported.  However, new applications should avoid
+** the use of these functions.  To encourage programmers to avoid
+** these functions, we will not explain what they do.
+*/
+#ifndef SQLITE_OMIT_DEPRECATED
+SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
+SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+                      void*,sqlite3_int64);
+#endif
+
+/*
+** CAPI3REF: Obtaining SQL Values
+** METHOD: sqlite3_value
+**
+** <b>Summary:</b>
+** <blockquote><table border=0 cellpadding=0 cellspacing=0>
+** <tr><td><b>sqlite3_value_blob</b><td>&rarr;<td>BLOB value
+** <tr><td><b>sqlite3_value_double</b><td>&rarr;<td>REAL value
+** <tr><td><b>sqlite3_value_int</b><td>&rarr;<td>32-bit INTEGER value
+** <tr><td><b>sqlite3_value_int64</b><td>&rarr;<td>64-bit INTEGER value
+** <tr><td><b>sqlite3_value_pointer</b><td>&rarr;<td>Pointer value
+** <tr><td><b>sqlite3_value_text</b><td>&rarr;<td>UTF-8 TEXT value
+** <tr><td><b>sqlite3_value_text16</b><td>&rarr;<td>UTF-16 TEXT value in
+** the native byteorder
+** <tr><td><b>sqlite3_value_text16be</b><td>&rarr;<td>UTF-16be TEXT value
+** <tr><td><b>sqlite3_value_text16le</b><td>&rarr;<td>UTF-16le TEXT value
+** <tr><td>&nbsp;<td>&nbsp;<td>&nbsp;
+** <tr><td><b>sqlite3_value_bytes</b><td>&rarr;<td>Size of a BLOB
+** or a UTF-8 TEXT in bytes
+** <tr><td><b>sqlite3_value_bytes16&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
+** TEXT in bytes
+** <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
+** datatype of the value
+** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
+** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
+** against a virtual table.
+** <tr><td><b>sqlite3_value_frombind&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>True if value originated from a [bound parameter]
+** </table></blockquote>
+**
+** <b>Details:</b>
+**
+** These routines extract type, size, and content information from
+** [protected sqlite3_value] objects.  Protected sqlite3_value objects
+** are used to pass parameter information into the functions that
+** implement [application-defined SQL functions] and [virtual tables].
+**
+** These routines work only with [protected sqlite3_value] objects.
+** Any attempt to use these routines on an [unprotected sqlite3_value]
+** is not threadsafe.
+**
+** ^These routines work just like the corresponding [column access functions]
+** except that these routines take a single [protected sqlite3_value] object
+** pointer instead of a [sqlite3_stmt*] pointer and an integer column number.
+**
+** ^The sqlite3_value_text16() interface extracts a UTF-16 string
+** in the native byte-order of the host machine.  ^The
+** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
+** extract UTF-16 strings as big-endian and little-endian respectively.
+**
+** ^If [sqlite3_value] object V was initialized 
+** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)]
+** and if X and Y are strings that compare equal according to strcmp(X,Y),
+** then sqlite3_value_pointer(V,Y) will return the pointer P.  ^Otherwise,
+** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer() 
+** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
+**
+** ^(The sqlite3_value_type(V) interface returns the
+** [SQLITE_INTEGER | datatype code] for the initial datatype of the
+** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER],
+** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^
+** Other interfaces might change the datatype for an sqlite3_value object.
+** For example, if the datatype is initially SQLITE_INTEGER and
+** sqlite3_value_text(V) is called to extract a text value for that
+** integer, then subsequent calls to sqlite3_value_type(V) might return
+** SQLITE_TEXT.  Whether or not a persistent internal datatype conversion
+** occurs is undefined and may change from one release of SQLite to the next.
+**
+** ^(The sqlite3_value_numeric_type() interface attempts to apply
+** numeric affinity to the value.  This means that an attempt is
+** made to convert the value to an integer or floating point.  If
+** such a conversion is possible without loss of information (in other
+** words, if the value is a string that looks like a number)
+** then the conversion is performed.  Otherwise no conversion occurs.
+** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
+**
+** ^Within the [xUpdate] method of a [virtual table], the
+** sqlite3_value_nochange(X) interface returns true if and only if
+** the column corresponding to X is unchanged by the UPDATE operation
+** that the xUpdate method call was invoked to implement and if
+** and the prior [xColumn] method call that was invoked to extracted
+** the value for that column returned without setting a result (probably
+** because it queried [sqlite3_vtab_nochange()] and found that the column
+** was unchanging).  ^Within an [xUpdate] method, any value for which
+** sqlite3_value_nochange(X) is true will in all other respects appear
+** to be a NULL value.  If sqlite3_value_nochange(X) is invoked anywhere other
+** than within an [xUpdate] method call for an UPDATE statement, then
+** the return value is arbitrary and meaningless.
+**
+** ^The sqlite3_value_frombind(X) interface returns non-zero if the
+** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
+** interfaces.  ^If X comes from an SQL literal value, or a table column,
+** or an expression, then sqlite3_value_frombind(X) returns zero.
+**
+** Please pay particular attention to the fact that the pointer returned
+** from [sqlite3_value_blob()], [sqlite3_value_text()], or
+** [sqlite3_value_text16()] can be invalidated by a subsequent call to
+** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
+** or [sqlite3_value_text16()].
+**
+** These routines must be called from the same thread as
+** the SQL function that supplied the [sqlite3_value*] parameters.
+**
+** As long as the input parameter is correct, these routines can only
+** fail if an out-of-memory error occurs during a format conversion.
+** Only the following subset of interfaces are subject to out-of-memory
+** errors:
+**
+** <ul>
+** <li> sqlite3_value_blob()
+** <li> sqlite3_value_text()
+** <li> sqlite3_value_text16()
+** <li> sqlite3_value_text16le()
+** <li> sqlite3_value_text16be()
+** <li> sqlite3_value_bytes()
+** <li> sqlite3_value_bytes16()
+** </ul>
+**
+** If an out-of-memory error occurs, then the return value from these
+** routines is the same as if the column had contained an SQL NULL value.
+** Valid SQL NULL returns can be distinguished from out-of-memory errors
+** by invoking the [sqlite3_errcode()] immediately after the suspect
+** return value is obtained and before any
+** other SQLite interface is called on the same [database connection].
+*/
+SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
+SQLITE_API double sqlite3_value_double(sqlite3_value*);
+SQLITE_API int sqlite3_value_int(sqlite3_value*);
+SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
+SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*);
+SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
+SQLITE_API int sqlite3_value_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
+SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
+
+/*
+** CAPI3REF: Finding The Subtype Of SQL Values
+** METHOD: sqlite3_value
+**
+** The sqlite3_value_subtype(V) function returns the subtype for
+** an [application-defined SQL function] argument V.  The subtype
+** information can be used to pass a limited amount of context from
+** one SQL function to another.  Use the [sqlite3_result_subtype()]
+** routine to set the subtype for the return value of an SQL function.
+*/
+SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
+
+/*
+** CAPI3REF: Copy And Free SQL Values
+** METHOD: sqlite3_value
+**
+** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
+** object D and returns a pointer to that copy.  ^The [sqlite3_value] returned
+** is a [protected sqlite3_value] object even if the input is not.
+** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
+** memory allocation fails.
+**
+** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
+** previously obtained from [sqlite3_value_dup()].  ^If V is a NULL pointer
+** then sqlite3_value_free(V) is a harmless no-op.
+*/
+SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
+SQLITE_API void sqlite3_value_free(sqlite3_value*);
+
+/*
+** CAPI3REF: Obtain Aggregate Function Context
+** METHOD: sqlite3_context
+**
+** Implementations of aggregate SQL functions use this
+** routine to allocate memory for storing their state.
+**
+** ^The first time the sqlite3_aggregate_context(C,N) routine is called 
+** for a particular aggregate function, SQLite allocates
+** N bytes of memory, zeroes out that memory, and returns a pointer
+** to the new memory. ^On second and subsequent calls to
+** sqlite3_aggregate_context() for the same aggregate function instance,
+** the same buffer is returned.  Sqlite3_aggregate_context() is normally
+** called once for each invocation of the xStep callback and then one
+** last time when the xFinal callback is invoked.  ^(When no rows match
+** an aggregate query, the xStep() callback of the aggregate function
+** implementation is never called and xFinal() is called exactly once.
+** In those cases, sqlite3_aggregate_context() might be called for the
+** first time from within xFinal().)^
+**
+** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer 
+** when first called if N is less than or equal to zero or if a memory
+** allocate error occurs.
+**
+** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
+** determined by the N parameter on first successful call.  Changing the
+** value of N in any subsequent call to sqlite3_aggregate_context() within
+** the same aggregate function instance will not resize the memory
+** allocation.)^  Within the xFinal callback, it is customary to set
+** N=0 in calls to sqlite3_aggregate_context(C,N) so that no 
+** pointless memory allocations occur.
+**
+** ^SQLite automatically frees the memory allocated by 
+** sqlite3_aggregate_context() when the aggregate query concludes.
+**
+** The first parameter must be a copy of the
+** [sqlite3_context | SQL function context] that is the first parameter
+** to the xStep or xFinal callback routine that implements the aggregate
+** function.
+**
+** This routine must be called from the same thread in which
+** the aggregate SQL function is running.
+*/
+SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+
+/*
+** CAPI3REF: User Data For Functions
+** METHOD: sqlite3_context
+**
+** ^The sqlite3_user_data() interface returns a copy of
+** the pointer that was the pUserData parameter (the 5th parameter)
+** of the [sqlite3_create_function()]
+** and [sqlite3_create_function16()] routines that originally
+** registered the application defined function.
+**
+** This routine must be called from the same thread in which
+** the application-defined function is running.
+*/
+SQLITE_API void *sqlite3_user_data(sqlite3_context*);
+
+/*
+** CAPI3REF: Database Connection For Functions
+** METHOD: sqlite3_context
+**
+** ^The sqlite3_context_db_handle() interface returns a copy of
+** the pointer to the [database connection] (the 1st parameter)
+** of the [sqlite3_create_function()]
+** and [sqlite3_create_function16()] routines that originally
+** registered the application defined function.
+*/
+SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
+
+/*
+** CAPI3REF: Function Auxiliary Data
+** METHOD: sqlite3_context
+**
+** These functions may be used by (non-aggregate) SQL functions to
+** associate metadata with argument values. If the same value is passed to
+** multiple invocations of the same SQL function during query execution, under
+** some circumstances the associated metadata may be preserved.  An example
+** of where this might be useful is in a regular-expression matching
+** function. The compiled version of the regular expression can be stored as
+** metadata associated with the pattern string.  
+** Then as long as the pattern string remains the same,
+** the compiled regular expression can be reused on multiple
+** invocations of the same function.
+**
+** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata
+** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
+** value to the application-defined function.  ^N is zero for the left-most
+** function argument.  ^If there is no metadata
+** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
+** returns a NULL pointer.
+**
+** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
+** argument of the application-defined function.  ^Subsequent
+** calls to sqlite3_get_auxdata(C,N) return P from the most recent
+** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
+** NULL if the metadata has been discarded.
+** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
+** SQLite will invoke the destructor function X with parameter P exactly
+** once, when the metadata is discarded.
+** SQLite is free to discard the metadata at any time, including: <ul>
+** <li> ^(when the corresponding function parameter changes)^, or
+** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+**      SQL statement)^, or
+** <li> ^(when sqlite3_set_auxdata() is invoked again on the same
+**       parameter)^, or
+** <li> ^(during the original sqlite3_set_auxdata() call when a memory 
+**      allocation error occurs.)^ </ul>
+**
+** Note the last bullet in particular.  The destructor X in 
+** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
+** sqlite3_set_auxdata() interface even returns.  Hence sqlite3_set_auxdata()
+** should be called near the end of the function implementation and the
+** function implementation should not make any use of P after
+** sqlite3_set_auxdata() has been called.
+**
+** ^(In practice, metadata is preserved between function calls for
+** function parameters that are compile-time constants, including literal
+** values and [parameters] and expressions composed from the same.)^
+**
+** The value of the N parameter to these interfaces should be non-negative.
+** Future enhancements may make use of negative N values to define new
+** kinds of function caching behavior.
+**
+** These routines must be called from the same thread in which
+** the SQL function is running.
+*/
+SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
+SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
+
+
+/*
+** CAPI3REF: Constants Defining Special Destructor Behavior
+**
+** These are special values for the destructor that is passed in as the
+** final argument to routines like [sqlite3_result_blob()].  ^If the destructor
+** argument is SQLITE_STATIC, it means that the content pointer is constant
+** and will never change.  It does not need to be destroyed.  ^The
+** SQLITE_TRANSIENT value means that the content will likely change in
+** the near future and that SQLite should make its own private copy of
+** the content before returning.
+**
+** The typedef is necessary to work around problems in certain
+** C++ compilers.
+*/
+typedef void (*sqlite3_destructor_type)(void*);
+#define SQLITE_STATIC      ((sqlite3_destructor_type)0)
+#define SQLITE_TRANSIENT   ((sqlite3_destructor_type)-1)
+
+/*
+** CAPI3REF: Setting The Result Of An SQL Function
+** METHOD: sqlite3_context
+**
+** These routines are used by the xFunc or xFinal callbacks that
+** implement SQL functions and aggregates.  See
+** [sqlite3_create_function()] and [sqlite3_create_function16()]
+** for additional information.
+**
+** These functions work very much like the [parameter binding] family of
+** functions used to bind values to host parameters in prepared statements.
+** Refer to the [SQL parameter] documentation for additional information.
+**
+** ^The sqlite3_result_blob() interface sets the result from
+** an application-defined function to be the BLOB whose content is pointed
+** to by the second parameter and which is N bytes long where N is the
+** third parameter.
+**
+** ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N)
+** interfaces set the result of the application-defined function to be
+** a BLOB containing all zero bytes and N bytes in size.
+**
+** ^The sqlite3_result_double() interface sets the result from
+** an application-defined function to be a floating point value specified
+** by its 2nd argument.
+**
+** ^The sqlite3_result_error() and sqlite3_result_error16() functions
+** cause the implemented SQL function to throw an exception.
+** ^SQLite uses the string pointed to by the
+** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
+** as the text of an error message.  ^SQLite interprets the error
+** message string from sqlite3_result_error() as UTF-8. ^SQLite
+** interprets the string from sqlite3_result_error16() as UTF-16 using
+** the same [byte-order determination rules] as [sqlite3_bind_text16()].
+** ^If the third parameter to sqlite3_result_error()
+** or sqlite3_result_error16() is negative then SQLite takes as the error
+** message all text up through the first zero character.
+** ^If the third parameter to sqlite3_result_error() or
+** sqlite3_result_error16() is non-negative then SQLite takes that many
+** bytes (not characters) from the 2nd parameter as the error message.
+** ^The sqlite3_result_error() and sqlite3_result_error16()
+** routines make a private copy of the error message text before
+** they return.  Hence, the calling function can deallocate or
+** modify the text after they return without harm.
+** ^The sqlite3_result_error_code() function changes the error code
+** returned by SQLite as a result of an error in a function.  ^By default,
+** the error code is SQLITE_ERROR.  ^A subsequent call to sqlite3_result_error()
+** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
+**
+** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an
+** error indicating that a string or BLOB is too long to represent.
+**
+** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an
+** error indicating that a memory allocation failed.
+**
+** ^The sqlite3_result_int() interface sets the return value
+** of the application-defined function to be the 32-bit signed integer
+** value given in the 2nd argument.
+** ^The sqlite3_result_int64() interface sets the return value
+** of the application-defined function to be the 64-bit signed integer
+** value given in the 2nd argument.
+**
+** ^The sqlite3_result_null() interface sets the return value
+** of the application-defined function to be NULL.
+**
+** ^The sqlite3_result_text(), sqlite3_result_text16(),
+** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
+** set the return value of the application-defined function to be
+** a text string which is represented as UTF-8, UTF-16 native byte order,
+** UTF-16 little endian, or UTF-16 big endian, respectively.
+** ^The sqlite3_result_text64() interface sets the return value of an
+** application-defined function to be a text string in an encoding
+** specified by the fifth (and last) parameter, which must be one
+** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
+** ^SQLite takes the text result from the application from
+** the 2nd parameter of the sqlite3_result_text* interfaces.
+** ^If the 3rd parameter to the sqlite3_result_text* interfaces
+** is negative, then SQLite takes result text from the 2nd parameter
+** through the first zero character.
+** ^If the 3rd parameter to the sqlite3_result_text* interfaces
+** is non-negative, then as many bytes (not characters) of the text
+** pointed to by the 2nd parameter are taken as the application-defined
+** function result.  If the 3rd parameter is non-negative, then it
+** must be the byte offset into the string where the NUL terminator would
+** appear if the string where NUL terminated.  If any NUL characters occur
+** in the string at a byte offset that is less than the value of the 3rd
+** parameter, then the resulting string will contain embedded NULs and the
+** result of expressions operating on strings with embedded NULs is undefined.
+** ^If the 4th parameter to the sqlite3_result_text* interfaces
+** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
+** function as the destructor on the text or BLOB result when it has
+** finished using that result.
+** ^If the 4th parameter to the sqlite3_result_text* interfaces or to
+** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite
+** assumes that the text or BLOB result is in constant space and does not
+** copy the content of the parameter nor call a destructor on the content
+** when it has finished using that result.
+** ^If the 4th parameter to the sqlite3_result_text* interfaces
+** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
+** then SQLite makes a copy of the result into space obtained
+** from [sqlite3_malloc()] before it returns.
+**
+** ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and
+** sqlite3_result_text16be() routines, and for sqlite3_result_text64()
+** when the encoding is not UTF8, if the input UTF16 begins with a
+** byte-order mark (BOM, U+FEFF) then the BOM is removed from the
+** string and the rest of the string is interpreted according to the
+** byte-order specified by the BOM.  ^The byte-order specified by
+** the BOM at the beginning of the text overrides the byte-order
+** specified by the interface procedure.  ^So, for example, if
+** sqlite3_result_text16le() is invoked with text that begins
+** with bytes 0xfe, 0xff (a big-endian byte-order mark) then the
+** first two bytes of input are skipped and the remaining input
+** is interpreted as UTF16BE text.
+**
+** ^For UTF16 input text to the sqlite3_result_text16(),
+** sqlite3_result_text16be(), sqlite3_result_text16le(), and
+** sqlite3_result_text64() routines, if the text contains invalid
+** UTF16 characters, the invalid characters might be converted
+** into the unicode replacement character, U+FFFD.
+**
+** ^The sqlite3_result_value() interface sets the result of
+** the application-defined function to be a copy of the
+** [unprotected sqlite3_value] object specified by the 2nd parameter.  ^The
+** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
+** so that the [sqlite3_value] specified in the parameter may change or
+** be deallocated after sqlite3_result_value() returns without harm.
+** ^A [protected sqlite3_value] object may always be used where an
+** [unprotected sqlite3_value] object is required, so either
+** kind of [sqlite3_value] object can be used with this interface.
+**
+** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an
+** SQL NULL value, just like [sqlite3_result_null(C)], except that it
+** also associates the host-language pointer P or type T with that 
+** NULL value such that the pointer can be retrieved within an
+** [application-defined SQL function] using [sqlite3_value_pointer()].
+** ^If the D parameter is not NULL, then it is a pointer to a destructor
+** for the P parameter.  ^SQLite invokes D with P as its only argument
+** when SQLite is finished with P.  The T parameter should be a static
+** string and preferably a string literal. The sqlite3_result_pointer()
+** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
+**
+** If these routines are called from within the different thread
+** than the one containing the application-defined function that received
+** the [sqlite3_context] pointer, the results are undefined.
+*/
+SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
+                           sqlite3_uint64,void(*)(void*));
+SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
+SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
+SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
+SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+SQLITE_API void sqlite3_result_null(sqlite3_context*);
+SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+                           void(*)(void*), unsigned char encoding);
+SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*));
+SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
+SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
+
+
+/*
+** CAPI3REF: Setting The Subtype Of An SQL Function
+** METHOD: sqlite3_context
+**
+** The sqlite3_result_subtype(C,T) function causes the subtype of
+** the result from the [application-defined SQL function] with 
+** [sqlite3_context] C to be the value T.  Only the lower 8 bits 
+** of the subtype T are preserved in current versions of SQLite;
+** higher order bits are discarded.
+** The number of subtype bytes preserved by SQLite might increase
+** in future releases of SQLite.
+*/
+SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
+
+/*
+** CAPI3REF: Define New Collating Sequences
+** METHOD: sqlite3
+**
+** ^These functions add, remove, or modify a [collation] associated
+** with the [database connection] specified as the first argument.
+**
+** ^The name of the collation is a UTF-8 string
+** for sqlite3_create_collation() and sqlite3_create_collation_v2()
+** and a UTF-16 string in native byte order for sqlite3_create_collation16().
+** ^Collation names that compare equal according to [sqlite3_strnicmp()] are
+** considered to be the same name.
+**
+** ^(The third argument (eTextRep) must be one of the constants:
+** <ul>
+** <li> [SQLITE_UTF8],
+** <li> [SQLITE_UTF16LE],
+** <li> [SQLITE_UTF16BE],
+** <li> [SQLITE_UTF16], or
+** <li> [SQLITE_UTF16_ALIGNED].
+** </ul>)^
+** ^The eTextRep argument determines the encoding of strings passed
+** to the collating function callback, xCompare.
+** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
+** force strings to be UTF16 with native byte order.
+** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
+** on an even byte address.
+**
+** ^The fourth argument, pArg, is an application data pointer that is passed
+** through as the first argument to the collating function callback.
+**
+** ^The fifth argument, xCompare, is a pointer to the collating function.
+** ^Multiple collating functions can be registered using the same name but
+** with different eTextRep parameters and SQLite will use whichever
+** function requires the least amount of data transformation.
+** ^If the xCompare argument is NULL then the collating function is
+** deleted.  ^When all collating functions having the same name are deleted,
+** that collation is no longer usable.
+**
+** ^The collating function callback is invoked with a copy of the pArg 
+** application data pointer and with two strings in the encoding specified
+** by the eTextRep argument.  The two integer parameters to the collating
+** function callback are the length of the two strings, in bytes. The collating
+** function must return an integer that is negative, zero, or positive
+** if the first string is less than, equal to, or greater than the second,
+** respectively.  A collating function must always return the same answer
+** given the same inputs.  If two or more collating functions are registered
+** to the same collation name (using different eTextRep values) then all
+** must give an equivalent answer when invoked with equivalent strings.
+** The collating function must obey the following properties for all
+** strings A, B, and C:
+**
+** <ol>
+** <li> If A==B then B==A.
+** <li> If A==B and B==C then A==C.
+** <li> If A&lt;B THEN B&gt;A.
+** <li> If A&lt;B and B&lt;C then A&lt;C.
+** </ol>
+**
+** If a collating function fails any of the above constraints and that
+** collating function is registered and used, then the behavior of SQLite
+** is undefined.
+**
+** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation()
+** with the addition that the xDestroy callback is invoked on pArg when
+** the collating function is deleted.
+** ^Collating functions are deleted when they are overridden by later
+** calls to the collation creation functions or when the
+** [database connection] is closed using [sqlite3_close()].
+**
+** ^The xDestroy callback is <u>not</u> called if the 
+** sqlite3_create_collation_v2() function fails.  Applications that invoke
+** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should 
+** check the return code and dispose of the application data pointer
+** themselves rather than expecting SQLite to deal with it for them.
+** This is different from every other SQLite interface.  The inconsistency 
+** is unfortunate but cannot be changed without breaking backwards 
+** compatibility.
+**
+** See also:  [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
+*/
+SQLITE_API int sqlite3_create_collation(
+  sqlite3*, 
+  const char *zName, 
+  int eTextRep, 
+  void *pArg,
+  int(*xCompare)(void*,int,const void*,int,const void*)
+);
+SQLITE_API int sqlite3_create_collation_v2(
+  sqlite3*, 
+  const char *zName, 
+  int eTextRep, 
+  void *pArg,
+  int(*xCompare)(void*,int,const void*,int,const void*),
+  void(*xDestroy)(void*)
+);
+SQLITE_API int sqlite3_create_collation16(
+  sqlite3*, 
+  const void *zName,
+  int eTextRep, 
+  void *pArg,
+  int(*xCompare)(void*,int,const void*,int,const void*)
+);
+
+/*
+** CAPI3REF: Collation Needed Callbacks
+** METHOD: sqlite3
+**
+** ^To avoid having to register all collation sequences before a database
+** can be used, a single callback function may be registered with the
+** [database connection] to be invoked whenever an undefined collation
+** sequence is required.
+**
+** ^If the function is registered using the sqlite3_collation_needed() API,
+** then it is passed the names of undefined collation sequences as strings
+** encoded in UTF-8. ^If sqlite3_collation_needed16() is used,
+** the names are passed as UTF-16 in machine native byte order.
+** ^A call to either function replaces the existing collation-needed callback.
+**
+** ^(When the callback is invoked, the first argument passed is a copy
+** of the second argument to sqlite3_collation_needed() or
+** sqlite3_collation_needed16().  The second argument is the database
+** connection.  The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE],
+** or [SQLITE_UTF16LE], indicating the most desirable form of the collation
+** sequence function required.  The fourth parameter is the name of the
+** required collation sequence.)^
+**
+** The callback function should register the desired collation using
+** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
+** [sqlite3_create_collation_v2()].
+*/
+SQLITE_API int sqlite3_collation_needed(
+  sqlite3*, 
+  void*, 
+  void(*)(void*,sqlite3*,int eTextRep,const char*)
+);
+SQLITE_API int sqlite3_collation_needed16(
+  sqlite3*, 
+  void*,
+  void(*)(void*,sqlite3*,int eTextRep,const void*)
+);
+
+#ifdef SQLITE_ENABLE_CEROD
+/*
+** Specify the activation key for a CEROD database.  Unless 
+** activated, none of the CEROD routines will work.
+*/
+SQLITE_API void sqlite3_activate_cerod(
+  const char *zPassPhrase        /* Activation phrase */
+);
+#endif
+
+/*
+** CAPI3REF: Suspend Execution For A Short Time
+**
+** The sqlite3_sleep() function causes the current thread to suspend execution
+** for at least a number of milliseconds specified in its parameter.
+**
+** If the operating system does not support sleep requests with
+** millisecond time resolution, then the time will be rounded up to
+** the nearest second. The number of milliseconds of sleep actually
+** requested from the operating system is returned.
+**
+** ^SQLite implements this interface by calling the xSleep()
+** method of the default [sqlite3_vfs] object.  If the xSleep() method
+** of the default VFS is not implemented correctly, or not implemented at
+** all, then the behavior of sqlite3_sleep() may deviate from the description
+** in the previous paragraphs.
+*/
+SQLITE_API int sqlite3_sleep(int);
+
+/*
+** CAPI3REF: Name Of The Folder Holding Temporary Files
+**
+** ^(If this global variable is made to point to a string which is
+** the name of a folder (a.k.a. directory), then all temporary files
+** created by SQLite when using a built-in [sqlite3_vfs | VFS]
+** will be placed in that directory.)^  ^If this variable
+** is a NULL pointer, then SQLite performs a search for an appropriate
+** temporary file directory.
+**
+** Applications are strongly discouraged from using this global variable.
+** It is required to set a temporary folder on Windows Runtime (WinRT).
+** But for all other platforms, it is highly recommended that applications
+** neither read nor write this variable.  This global variable is a relic
+** that exists for backwards compatibility of legacy applications and should
+** be avoided in new projects.
+**
+** It is not safe to read or modify this variable in more than one
+** thread at a time.  It is not safe to read or modify this variable
+** if a [database connection] is being used at the same time in a separate
+** thread.
+** It is intended that this variable be set once
+** as part of process initialization and before any SQLite interface
+** routines have been called and that this variable remain unchanged
+** thereafter.
+**
+** ^The [temp_store_directory pragma] may modify this variable and cause
+** it to point to memory obtained from [sqlite3_malloc].  ^Furthermore,
+** the [temp_store_directory pragma] always assumes that any string
+** that this variable points to is held in memory obtained from 
+** [sqlite3_malloc] and the pragma may attempt to free that memory
+** using [sqlite3_free].
+** Hence, if this variable is modified directly, either it should be
+** made NULL or made to point to memory obtained from [sqlite3_malloc]
+** or else the use of the [temp_store_directory pragma] should be avoided.
+** Except when requested by the [temp_store_directory pragma], SQLite
+** does not free the memory that sqlite3_temp_directory points to.  If
+** the application wants that memory to be freed, it must do
+** so itself, taking care to only do so after all [database connection]
+** objects have been destroyed.
+**
+** <b>Note to Windows Runtime users:</b>  The temporary directory must be set
+** prior to calling [sqlite3_open] or [sqlite3_open_v2].  Otherwise, various
+** features that require the use of temporary files may fail.  Here is an
+** example of how to do this using C++ with the Windows Runtime:
+**
+** <blockquote><pre>
+** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
+** &nbsp;     TemporaryFolder->Path->Data();
+** char zPathBuf&#91;MAX_PATH + 1&#93;;
+** memset(zPathBuf, 0, sizeof(zPathBuf));
+** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
+** &nbsp;     NULL, NULL);
+** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
+** </pre></blockquote>
+*/
+SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;
+
+/*
+** CAPI3REF: Name Of The Folder Holding Database Files
+**
+** ^(If this global variable is made to point to a string which is
+** the name of a folder (a.k.a. directory), then all database files
+** specified with a relative pathname and created or accessed by
+** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed
+** to be relative to that directory.)^ ^If this variable is a NULL
+** pointer, then SQLite assumes that all database files specified
+** with a relative pathname are relative to the current directory
+** for the process.  Only the windows VFS makes use of this global
+** variable; it is ignored by the unix VFS.
+**
+** Changing the value of this variable while a database connection is
+** open can result in a corrupt database.
+**
+** It is not safe to read or modify this variable in more than one
+** thread at a time.  It is not safe to read or modify this variable
+** if a [database connection] is being used at the same time in a separate
+** thread.
+** It is intended that this variable be set once
+** as part of process initialization and before any SQLite interface
+** routines have been called and that this variable remain unchanged
+** thereafter.
+**
+** ^The [data_store_directory pragma] may modify this variable and cause
+** it to point to memory obtained from [sqlite3_malloc].  ^Furthermore,
+** the [data_store_directory pragma] always assumes that any string
+** that this variable points to is held in memory obtained from 
+** [sqlite3_malloc] and the pragma may attempt to free that memory
+** using [sqlite3_free].
+** Hence, if this variable is modified directly, either it should be
+** made NULL or made to point to memory obtained from [sqlite3_malloc]
+** or else the use of the [data_store_directory pragma] should be avoided.
+*/
+SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
+
+/*
+** CAPI3REF: Win32 Specific Interface
+**
+** These interfaces are available only on Windows.  The
+** [sqlite3_win32_set_directory] interface is used to set the value associated
+** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to
+** zValue, depending on the value of the type parameter.  The zValue parameter
+** should be NULL to cause the previous value to be freed via [sqlite3_free];
+** a non-NULL value will be copied into memory obtained from [sqlite3_malloc]
+** prior to being used.  The [sqlite3_win32_set_directory] interface returns
+** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported,
+** or [SQLITE_NOMEM] if memory could not be allocated.  The value of the
+** [sqlite3_data_directory] variable is intended to act as a replacement for
+** the current directory on the sub-platforms of Win32 where that concept is
+** not present, e.g. WinRT and UWP.  The [sqlite3_win32_set_directory8] and
+** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the
+** sqlite3_win32_set_directory interface except the string parameter must be
+** UTF-8 or UTF-16, respectively.
+*/
+SQLITE_API int sqlite3_win32_set_directory(
+  unsigned long type, /* Identifier for directory being set or reset */
+  void *zValue        /* New value for directory being set or reset */
+);
+SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue);
+SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue);
+
+/*
+** CAPI3REF: Win32 Directory Types
+**
+** These macros are only available on Windows.  They define the allowed values
+** for the type argument to the [sqlite3_win32_set_directory] interface.
+*/
+#define SQLITE_WIN32_DATA_DIRECTORY_TYPE  1
+#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE  2
+
+/*
+** CAPI3REF: Test For Auto-Commit Mode
+** KEYWORDS: {autocommit mode}
+** METHOD: sqlite3
+**
+** ^The sqlite3_get_autocommit() interface returns non-zero or
+** zero if the given database connection is or is not in autocommit mode,
+** respectively.  ^Autocommit mode is on by default.
+** ^Autocommit mode is disabled by a [BEGIN] statement.
+** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
+**
+** If certain kinds of errors occur on a statement within a multi-statement
+** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
+** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
+** transaction might be rolled back automatically.  The only way to
+** find out whether SQLite automatically rolled back the transaction after
+** an error is to use this function.
+**
+** If another thread changes the autocommit status of the database
+** connection while this routine is running, then the return value
+** is undefined.
+*/
+SQLITE_API int sqlite3_get_autocommit(sqlite3*);
+
+/*
+** CAPI3REF: Find The Database Handle Of A Prepared Statement
+** METHOD: sqlite3_stmt
+**
+** ^The sqlite3_db_handle interface returns the [database connection] handle
+** to which a [prepared statement] belongs.  ^The [database connection]
+** returned by sqlite3_db_handle is the same [database connection]
+** that was the first argument
+** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
+** create the statement in the first place.
+*/
+SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
+
+/*
+** CAPI3REF: Return The Filename For A Database Connection
+** METHOD: sqlite3
+**
+** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename
+** associated with database N of connection D.
+** ^If there is no attached database N on the database
+** connection D, or if database N is a temporary or in-memory database, then
+** this function will return either a NULL pointer or an empty string.
+**
+** ^The string value returned by this routine is owned and managed by
+** the database connection.  ^The value will be valid until the database N
+** is [DETACH]-ed or until the database connection closes.
+**
+** ^The filename returned by this function is the output of the
+** xFullPathname method of the [VFS].  ^In other words, the filename
+** will be an absolute pathname, even if the filename used
+** to open the database originally was a URI or relative pathname.
+**
+** If the filename pointer returned by this routine is not NULL, then it
+** can be used as the filename input parameter to these routines:
+** <ul>
+** <li> [sqlite3_uri_parameter()]
+** <li> [sqlite3_uri_boolean()]
+** <li> [sqlite3_uri_int64()]
+** <li> [sqlite3_filename_database()]
+** <li> [sqlite3_filename_journal()]
+** <li> [sqlite3_filename_wal()]
+** </ul>
+*/
+SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
+
+/*
+** CAPI3REF: Determine if a database is read-only
+** METHOD: sqlite3
+**
+** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
+** of connection D is read-only, 0 if it is read/write, or -1 if N is not
+** the name of a database on connection D.
+*/
+SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
+
+/*
+** CAPI3REF: Find the next prepared statement
+** METHOD: sqlite3
+**
+** ^This interface returns a pointer to the next [prepared statement] after
+** pStmt associated with the [database connection] pDb.  ^If pStmt is NULL
+** then this interface returns a pointer to the first prepared statement
+** associated with the database connection pDb.  ^If no prepared statement
+** satisfies the conditions of this routine, it returns NULL.
+**
+** The [database connection] pointer D in a call to
+** [sqlite3_next_stmt(D,S)] must refer to an open database
+** connection and in particular must not be a NULL pointer.
+*/
+SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
+
+/*
+** CAPI3REF: Commit And Rollback Notification Callbacks
+** METHOD: sqlite3
+**
+** ^The sqlite3_commit_hook() interface registers a callback
+** function to be invoked whenever a transaction is [COMMIT | committed].
+** ^Any callback set by a previous call to sqlite3_commit_hook()
+** for the same database connection is overridden.
+** ^The sqlite3_rollback_hook() interface registers a callback
+** function to be invoked whenever a transaction is [ROLLBACK | rolled back].
+** ^Any callback set by a previous call to sqlite3_rollback_hook()
+** for the same database connection is overridden.
+** ^The pArg argument is passed through to the callback.
+** ^If the callback on a commit hook function returns non-zero,
+** then the commit is converted into a rollback.
+**
+** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions
+** return the P argument from the previous call of the same function
+** on the same [database connection] D, or NULL for
+** the first call for each function on D.
+**
+** The commit and rollback hook callbacks are not reentrant.
+** The callback implementation must not do anything that will modify
+** the database connection that invoked the callback.  Any actions
+** to modify the database connection must be deferred until after the
+** completion of the [sqlite3_step()] call that triggered the commit
+** or rollback hook in the first place.
+** Note that running any other SQL statements, including SELECT statements,
+** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify
+** the database connections for the meaning of "modify" in this paragraph.
+**
+** ^Registering a NULL function disables the callback.
+**
+** ^When the commit hook callback routine returns zero, the [COMMIT]
+** operation is allowed to continue normally.  ^If the commit hook
+** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK].
+** ^The rollback hook is invoked on a rollback that results from a commit
+** hook returning non-zero, just as it would be with any other rollback.
+**
+** ^For the purposes of this API, a transaction is said to have been
+** rolled back if an explicit "ROLLBACK" statement is executed, or
+** an error or constraint causes an implicit rollback to occur.
+** ^The rollback callback is not invoked if a transaction is
+** automatically rolled back because the database connection is closed.
+**
+** See also the [sqlite3_update_hook()] interface.
+*/
+SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+
+/*
+** CAPI3REF: Data Change Notification Callbacks
+** METHOD: sqlite3
+**
+** ^The sqlite3_update_hook() interface registers a callback function
+** with the [database connection] identified by the first argument
+** to be invoked whenever a row is updated, inserted or deleted in
+** a [rowid table].
+** ^Any callback set by a previous call to this function
+** for the same database connection is overridden.
+**
+** ^The second argument is a pointer to the function to invoke when a
+** row is updated, inserted or deleted in a rowid table.
+** ^The first argument to the callback is a copy of the third argument
+** to sqlite3_update_hook().
+** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
+** or [SQLITE_UPDATE], depending on the operation that caused the callback
+** to be invoked.
+** ^The third and fourth arguments to the callback contain pointers to the
+** database and table name containing the affected row.
+** ^The final callback parameter is the [rowid] of the row.
+** ^In the case of an update, this is the [rowid] after the update takes place.
+**
+** ^(The update hook is not invoked when internal system tables are
+** modified (i.e. sqlite_master and sqlite_sequence).)^
+** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
+**
+** ^In the current implementation, the update hook
+** is not invoked when conflicting rows are deleted because of an
+** [ON CONFLICT | ON CONFLICT REPLACE] clause.  ^Nor is the update hook
+** invoked when rows are deleted using the [truncate optimization].
+** The exceptions defined in this paragraph might change in a future
+** release of SQLite.
+**
+** The update hook implementation must not do anything that will modify
+** the database connection that invoked the update hook.  Any actions
+** to modify the database connection must be deferred until after the
+** completion of the [sqlite3_step()] call that triggered the update hook.
+** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
+** database connections for the meaning of "modify" in this paragraph.
+**
+** ^The sqlite3_update_hook(D,C,P) function
+** returns the P argument from the previous call
+** on the same [database connection] D, or NULL for
+** the first call on D.
+**
+** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
+** and [sqlite3_preupdate_hook()] interfaces.
+*/
+SQLITE_API void *sqlite3_update_hook(
+  sqlite3*, 
+  void(*)(void *,int ,char const *,char const *,sqlite3_int64),
+  void*
+);
+
+/*
+** CAPI3REF: Enable Or Disable Shared Pager Cache
+**
+** ^(This routine enables or disables the sharing of the database cache
+** and schema data structures between [database connection | connections]
+** to the same database. Sharing is enabled if the argument is true
+** and disabled if the argument is false.)^
+**
+** ^Cache sharing is enabled and disabled for an entire process.
+** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). 
+** In prior versions of SQLite,
+** sharing was enabled or disabled for each thread separately.
+**
+** ^(The cache sharing mode set by this interface effects all subsequent
+** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()].
+** Existing database connections continue to use the sharing mode
+** that was in effect at the time they were opened.)^
+**
+** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled
+** successfully.  An [error code] is returned otherwise.)^
+**
+** ^Shared cache is disabled by default. It is recommended that it stay
+** that way.  In other words, do not use this routine.  This interface
+** continues to be provided for historical compatibility, but its use is
+** discouraged.  Any use of shared cache is discouraged.  If shared cache
+** must be used, it is recommended that shared cache only be enabled for
+** individual database connections using the [sqlite3_open_v2()] interface
+** with the [SQLITE_OPEN_SHAREDCACHE] flag.
+**
+** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0
+** and will always return SQLITE_MISUSE. On those systems, 
+** shared cache mode should be enabled per-database connection via 
+** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE].
+**
+** This interface is threadsafe on processors where writing a
+** 32-bit integer is atomic.
+**
+** See Also:  [SQLite Shared-Cache Mode]
+*/
+SQLITE_API int sqlite3_enable_shared_cache(int);
+
+/*
+** CAPI3REF: Attempt To Free Heap Memory
+**
+** ^The sqlite3_release_memory() interface attempts to free N bytes
+** of heap memory by deallocating non-essential memory allocations
+** held by the database library.   Memory used to cache database
+** pages to improve performance is an example of non-essential memory.
+** ^sqlite3_release_memory() returns the number of bytes actually freed,
+** which might be more or less than the amount requested.
+** ^The sqlite3_release_memory() routine is a no-op returning zero
+** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT].
+**
+** See also: [sqlite3_db_release_memory()]
+*/
+SQLITE_API int sqlite3_release_memory(int);
+
+/*
+** CAPI3REF: Free Memory Used By A Database Connection
+** METHOD: sqlite3
+**
+** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
+** memory as possible from database connection D. Unlike the
+** [sqlite3_release_memory()] interface, this interface is in effect even
+** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
+** omitted.
+**
+** See also: [sqlite3_release_memory()]
+*/
+SQLITE_API int sqlite3_db_release_memory(sqlite3*);
+
+/*
+** CAPI3REF: Impose A Limit On Heap Size
+**
+** These interfaces impose limits on the amount of heap memory that will be
+** by all database connections within a single process.
+**
+** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
+** soft limit on the amount of heap memory that may be allocated by SQLite.
+** ^SQLite strives to keep heap memory utilization below the soft heap
+** limit by reducing the number of pages held in the page cache
+** as heap memory usages approaches the limit.
+** ^The soft heap limit is "soft" because even though SQLite strives to stay
+** below the limit, it will exceed the limit rather than generate
+** an [SQLITE_NOMEM] error.  In other words, the soft heap limit 
+** is advisory only.
+**
+** ^The sqlite3_hard_heap_limit64(N) interface sets a hard upper bound of
+** N bytes on the amount of memory that will be allocated.  ^The
+** sqlite3_hard_heap_limit64(N) interface is similar to
+** sqlite3_soft_heap_limit64(N) except that memory allocations will fail
+** when the hard heap limit is reached.
+**
+** ^The return value from both sqlite3_soft_heap_limit64() and
+** sqlite3_hard_heap_limit64() is the size of
+** the heap limit prior to the call, or negative in the case of an
+** error.  ^If the argument N is negative
+** then no change is made to the heap limit.  Hence, the current
+** size of heap limits can be determined by invoking
+** sqlite3_soft_heap_limit64(-1) or sqlite3_hard_heap_limit(-1).
+**
+** ^Setting the heap limits to zero disables the heap limiter mechanism.
+**
+** ^The soft heap limit may not be greater than the hard heap limit.
+** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N)
+** is invoked with a value of N that is greater than the hard heap limit,
+** the the soft heap limit is set to the value of the hard heap limit.
+** ^The soft heap limit is automatically enabled whenever the hard heap
+** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and
+** the soft heap limit is outside the range of 1..N, then the soft heap
+** limit is set to N.  ^Invoking sqlite3_soft_heap_limit64(0) when the
+** hard heap limit is enabled makes the soft heap limit equal to the
+** hard heap limit.
+**
+** The memory allocation limits can also be adjusted using
+** [PRAGMA soft_heap_limit] and [PRAGMA hard_heap_limit].
+**
+** ^(The heap limits are not enforced in the current implementation
+** if one or more of following conditions are true:
+**
+** <ul>
+** <li> The limit value is set to zero.
+** <li> Memory accounting is disabled using a combination of the
+**      [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
+**      the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
+** <li> An alternative page cache implementation is specified using
+**      [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...).
+** <li> The page cache allocates from its own memory pool supplied
+**      by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
+**      from the heap.
+** </ul>)^
+**
+** The circumstances under which SQLite will enforce the heap limits may
+** changes in future releases of SQLite.
+*/
+SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
+SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N);
+
+/*
+** CAPI3REF: Deprecated Soft Heap Limit Interface
+** DEPRECATED
+**
+** This is a deprecated version of the [sqlite3_soft_heap_limit64()]
+** interface.  This routine is provided for historical compatibility
+** only.  All new applications should use the
+** [sqlite3_soft_heap_limit64()] interface rather than this one.
+*/
+SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
+
+
+/*
+** CAPI3REF: Extract Metadata About A Column Of A Table
+** METHOD: sqlite3
+**
+** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
+** information about column C of table T in database D
+** on [database connection] X.)^  ^The sqlite3_table_column_metadata()
+** interface returns SQLITE_OK and fills in the non-NULL pointers in
+** the final five arguments with appropriate values if the specified
+** column exists.  ^The sqlite3_table_column_metadata() interface returns
+** SQLITE_ERROR if the specified column does not exist.
+** ^If the column-name parameter to sqlite3_table_column_metadata() is a
+** NULL pointer, then this routine simply checks for the existence of the
+** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
+** does not.  If the table name parameter T in a call to
+** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is
+** undefined behavior.
+**
+** ^The column is identified by the second, third and fourth parameters to
+** this function. ^(The second parameter is either the name of the database
+** (i.e. "main", "temp", or an attached database) containing the specified
+** table or NULL.)^ ^If it is NULL, then all attached databases are searched
+** for the table using the same algorithm used by the database engine to
+** resolve unqualified table references.
+**
+** ^The third and fourth parameters to this function are the table and column
+** name of the desired column, respectively.
+**
+** ^Metadata is returned by writing to the memory locations passed as the 5th
+** and subsequent parameters to this function. ^Any of these arguments may be
+** NULL, in which case the corresponding element of metadata is omitted.
+**
+** ^(<blockquote>
+** <table border="1">
+** <tr><th> Parameter <th> Output<br>Type <th>  Description
+**
+** <tr><td> 5th <td> const char* <td> Data type
+** <tr><td> 6th <td> const char* <td> Name of default collation sequence
+** <tr><td> 7th <td> int         <td> True if column has a NOT NULL constraint
+** <tr><td> 8th <td> int         <td> True if column is part of the PRIMARY KEY
+** <tr><td> 9th <td> int         <td> True if column is [AUTOINCREMENT]
+** </table>
+** </blockquote>)^
+**
+** ^The memory pointed to by the character pointers returned for the
+** declaration type and collation sequence is valid until the next
+** call to any SQLite API function.
+**
+** ^If the specified table is actually a view, an [error code] is returned.
+**
+** ^If the specified column is "rowid", "oid" or "_rowid_" and the table 
+** is not a [WITHOUT ROWID] table and an
+** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
+** parameters are set for the explicitly declared column. ^(If there is no
+** [INTEGER PRIMARY KEY] column, then the outputs
+** for the [rowid] are set as follows:
+**
+** <pre>
+**     data type: "INTEGER"
+**     collation sequence: "BINARY"
+**     not null: 0
+**     primary key: 1
+**     auto increment: 0
+** </pre>)^
+**
+** ^This function causes all database schemas to be read from disk and
+** parsed, if that has not already been done, and returns an error if
+** any errors are encountered while loading the schema.
+*/
+SQLITE_API int sqlite3_table_column_metadata(
+  sqlite3 *db,                /* Connection handle */
+  const char *zDbName,        /* Database name or NULL */
+  const char *zTableName,     /* Table name */
+  const char *zColumnName,    /* Column name */
+  char const **pzDataType,    /* OUTPUT: Declared data type */
+  char const **pzCollSeq,     /* OUTPUT: Collation sequence name */
+  int *pNotNull,              /* OUTPUT: True if NOT NULL constraint exists */
+  int *pPrimaryKey,           /* OUTPUT: True if column part of PK */
+  int *pAutoinc               /* OUTPUT: True if column is auto-increment */
+);
+
+/*
+** CAPI3REF: Load An Extension
+** METHOD: sqlite3
+**
+** ^This interface loads an SQLite extension library from the named file.
+**
+** ^The sqlite3_load_extension() interface attempts to load an
+** [SQLite extension] library contained in the file zFile.  If
+** the file cannot be loaded directly, attempts are made to load
+** with various operating-system specific extensions added.
+** So for example, if "samplelib" cannot be loaded, then names like
+** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might
+** be tried also.
+**
+** ^The entry point is zProc.
+** ^(zProc may be 0, in which case SQLite will try to come up with an
+** entry point name on its own.  It first tries "sqlite3_extension_init".
+** If that does not work, it constructs a name "sqlite3_X_init" where the
+** X is consists of the lower-case equivalent of all ASCII alphabetic
+** characters in the filename from the last "/" to the first following
+** "." and omitting any initial "lib".)^
+** ^The sqlite3_load_extension() interface returns
+** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
+** ^If an error occurs and pzErrMsg is not 0, then the
+** [sqlite3_load_extension()] interface shall attempt to
+** fill *pzErrMsg with error message text stored in memory
+** obtained from [sqlite3_malloc()]. The calling function
+** should free this memory by calling [sqlite3_free()].
+**
+** ^Extension loading must be enabled using
+** [sqlite3_enable_load_extension()] or
+** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
+** prior to calling this API,
+** otherwise an error will be returned.
+**
+** <b>Security warning:</b> It is recommended that the 
+** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
+** interface.  The use of the [sqlite3_enable_load_extension()] interface
+** should be avoided.  This will keep the SQL function [load_extension()]
+** disabled and prevent SQL injections from giving attackers
+** access to extension loading capabilities.
+**
+** See also the [load_extension() SQL function].
+*/
+SQLITE_API int sqlite3_load_extension(
+  sqlite3 *db,          /* Load the extension into this database connection */
+  const char *zFile,    /* Name of the shared library containing extension */
+  const char *zProc,    /* Entry point.  Derived from zFile if 0 */
+  char **pzErrMsg       /* Put error message here if not 0 */
+);
+
+/*
+** CAPI3REF: Enable Or Disable Extension Loading
+** METHOD: sqlite3
+**
+** ^So as not to open security holes in older applications that are
+** unprepared to deal with [extension loading], and as a means of disabling
+** [extension loading] while evaluating user-entered SQL, the following API
+** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
+**
+** ^Extension loading is off by default.
+** ^Call the sqlite3_enable_load_extension() routine with onoff==1
+** to turn extension loading on and call it with onoff==0 to turn
+** it back off again.
+**
+** ^This interface enables or disables both the C-API
+** [sqlite3_load_extension()] and the SQL function [load_extension()].
+** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
+** to enable or disable only the C-API.)^
+**
+** <b>Security warning:</b> It is recommended that extension loading
+** be enabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
+** rather than this interface, so the [load_extension()] SQL function
+** remains disabled. This will prevent SQL injections from giving attackers
+** access to extension loading capabilities.
+*/
+SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
+
+/*
+** CAPI3REF: Automatically Load Statically Linked Extensions
+**
+** ^This interface causes the xEntryPoint() function to be invoked for
+** each new [database connection] that is created.  The idea here is that
+** xEntryPoint() is the entry point for a statically linked [SQLite extension]
+** that is to be automatically loaded into all new database connections.
+**
+** ^(Even though the function prototype shows that xEntryPoint() takes
+** no arguments and returns void, SQLite invokes xEntryPoint() with three
+** arguments and expects an integer result as if the signature of the
+** entry point where as follows:
+**
+** <blockquote><pre>
+** &nbsp;  int xEntryPoint(
+** &nbsp;    sqlite3 *db,
+** &nbsp;    const char **pzErrMsg,
+** &nbsp;    const struct sqlite3_api_routines *pThunk
+** &nbsp;  );
+** </pre></blockquote>)^
+**
+** If the xEntryPoint routine encounters an error, it should make *pzErrMsg
+** point to an appropriate error message (obtained from [sqlite3_mprintf()])
+** and return an appropriate [error code].  ^SQLite ensures that *pzErrMsg
+** is NULL before calling the xEntryPoint().  ^SQLite will invoke
+** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns.  ^If any
+** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()],
+** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail.
+**
+** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
+** on the list of automatic extensions is a harmless no-op. ^No entry point
+** will be called more than once for each database connection that is opened.
+**
+** See also: [sqlite3_reset_auto_extension()]
+** and [sqlite3_cancel_auto_extension()]
+*/
+SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void));
+
+/*
+** CAPI3REF: Cancel Automatic Extension Loading
+**
+** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
+** initialization routine X that was registered using a prior call to
+** [sqlite3_auto_extension(X)].  ^The [sqlite3_cancel_auto_extension(X)]
+** routine returns 1 if initialization routine X was successfully 
+** unregistered and it returns 0 if X was not on the list of initialization
+** routines.
+*/
+SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
+
+/*
+** CAPI3REF: Reset Automatic Extension Loading
+**
+** ^This interface disables all automatic extensions previously
+** registered using [sqlite3_auto_extension()].
+*/
+SQLITE_API void sqlite3_reset_auto_extension(void);
+
+/*
+** The interface to the virtual-table mechanism is currently considered
+** to be experimental.  The interface might change in incompatible ways.
+** If this is a problem for you, do not use the interface at this time.
+**
+** When the virtual-table mechanism stabilizes, we will declare the
+** interface fixed, support it indefinitely, and remove this comment.
+*/
+
+/*
+** Structures used by the virtual table interface
+*/
+typedef struct sqlite3_vtab sqlite3_vtab;
+typedef struct sqlite3_index_info sqlite3_index_info;
+typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor;
+typedef struct sqlite3_module sqlite3_module;
+
+/*
+** CAPI3REF: Virtual Table Object
+** KEYWORDS: sqlite3_module {virtual table module}
+**
+** This structure, sometimes called a "virtual table module", 
+** defines the implementation of a [virtual table].  
+** This structure consists mostly of methods for the module.
+**
+** ^A virtual table module is created by filling in a persistent
+** instance of this structure and passing a pointer to that instance
+** to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
+** ^The registration remains valid until it is replaced by a different
+** module or until the [database connection] closes.  The content
+** of this structure must not change while it is registered with
+** any database connection.
+*/
+struct sqlite3_module {
+  int iVersion;
+  int (*xCreate)(sqlite3*, void *pAux,
+               int argc, const char *const*argv,
+               sqlite3_vtab **ppVTab, char**);
+  int (*xConnect)(sqlite3*, void *pAux,
+               int argc, const char *const*argv,
+               sqlite3_vtab **ppVTab, char**);
+  int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*);
+  int (*xDisconnect)(sqlite3_vtab *pVTab);
+  int (*xDestroy)(sqlite3_vtab *pVTab);
+  int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor);
+  int (*xClose)(sqlite3_vtab_cursor*);
+  int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr,
+                int argc, sqlite3_value **argv);
+  int (*xNext)(sqlite3_vtab_cursor*);
+  int (*xEof)(sqlite3_vtab_cursor*);
+  int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int);
+  int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid);
+  int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *);
+  int (*xBegin)(sqlite3_vtab *pVTab);
+  int (*xSync)(sqlite3_vtab *pVTab);
+  int (*xCommit)(sqlite3_vtab *pVTab);
+  int (*xRollback)(sqlite3_vtab *pVTab);
+  int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
+                       void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
+                       void **ppArg);
+  int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
+  /* The methods above are in version 1 of the sqlite_module object. Those 
+  ** below are for version 2 and greater. */
+  int (*xSavepoint)(sqlite3_vtab *pVTab, int);
+  int (*xRelease)(sqlite3_vtab *pVTab, int);
+  int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
+  /* The methods above are in versions 1 and 2 of the sqlite_module object.
+  ** Those below are for version 3 and greater. */
+  int (*xShadowName)(const char*);
+};
+
+/*
+** CAPI3REF: Virtual Table Indexing Information
+** KEYWORDS: sqlite3_index_info
+**
+** The sqlite3_index_info structure and its substructures is used as part
+** of the [virtual table] interface to
+** pass information into and receive the reply from the [xBestIndex]
+** method of a [virtual table module].  The fields under **Inputs** are the
+** inputs to xBestIndex and are read-only.  xBestIndex inserts its
+** results into the **Outputs** fields.
+**
+** ^(The aConstraint[] array records WHERE clause constraints of the form:
+**
+** <blockquote>column OP expr</blockquote>
+**
+** where OP is =, &lt;, &lt;=, &gt;, or &gt;=.)^  ^(The particular operator is
+** stored in aConstraint[].op using one of the
+** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^
+** ^(The index of the column is stored in
+** aConstraint[].iColumn.)^  ^(aConstraint[].usable is TRUE if the
+** expr on the right-hand side can be evaluated (and thus the constraint
+** is usable) and false if it cannot.)^
+**
+** ^The optimizer automatically inverts terms of the form "expr OP column"
+** and makes other simplifications to the WHERE clause in an attempt to
+** get as many WHERE clause terms into the form shown above as possible.
+** ^The aConstraint[] array only reports WHERE clause terms that are
+** relevant to the particular virtual table being queried.
+**
+** ^Information about the ORDER BY clause is stored in aOrderBy[].
+** ^Each term of aOrderBy records a column of the ORDER BY clause.
+**
+** The colUsed field indicates which columns of the virtual table may be
+** required by the current scan. Virtual table columns are numbered from
+** zero in the order in which they appear within the CREATE TABLE statement
+** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
+** the corresponding bit is set within the colUsed mask if the column may be
+** required by SQLite. If the table has at least 64 columns and any column
+** to the right of the first 63 is required, then bit 63 of colUsed is also
+** set. In other words, column iCol may be required if the expression
+** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to 
+** non-zero.
+**
+** The [xBestIndex] method must fill aConstraintUsage[] with information
+** about what parameters to pass to xFilter.  ^If argvIndex>0 then
+** the right-hand side of the corresponding aConstraint[] is evaluated
+** and becomes the argvIndex-th entry in argv.  ^(If aConstraintUsage[].omit
+** is true, then the constraint is assumed to be fully handled by the
+** virtual table and might not be checked again by the byte code.)^ ^(The
+** aConstraintUsage[].omit flag is an optimization hint. When the omit flag
+** is left in its default setting of false, the constraint will always be
+** checked separately in byte code.  If the omit flag is change to true, then
+** the constraint may or may not be checked in byte code.  In other words,
+** when the omit flag is true there is no guarantee that the constraint will
+** not be checked again using byte code.)^
+**
+** ^The idxNum and idxPtr values are recorded and passed into the
+** [xFilter] method.
+** ^[sqlite3_free()] is used to free idxPtr if and only if
+** needToFreeIdxPtr is true.
+**
+** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
+** the correct order to satisfy the ORDER BY clause so that no separate
+** sorting step is required.
+**
+** ^The estimatedCost value is an estimate of the cost of a particular
+** strategy. A cost of N indicates that the cost of the strategy is similar
+** to a linear scan of an SQLite table with N rows. A cost of log(N) 
+** indicates that the expense of the operation is similar to that of a
+** binary search on a unique indexed field of an SQLite table with N rows.
+**
+** ^The estimatedRows value is an estimate of the number of rows that
+** will be returned by the strategy.
+**
+** The xBestIndex method may optionally populate the idxFlags field with a 
+** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
+** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
+** assumes that the strategy may visit at most one row. 
+**
+** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
+** SQLite also assumes that if a call to the xUpdate() method is made as
+** part of the same statement to delete or update a virtual table row and the
+** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
+** any database changes. In other words, if the xUpdate() returns
+** SQLITE_CONSTRAINT, the database contents must be exactly as they were
+** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
+** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
+** the xUpdate method are automatically rolled back by SQLite.
+**
+** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). 
+** If a virtual table extension is
+** used with an SQLite version earlier than 3.8.2, the results of attempting 
+** to read or write the estimatedRows field are undefined (but are likely 
+** to include crashing the application). The estimatedRows field should
+** therefore only be used if [sqlite3_libversion_number()] returns a
+** value greater than or equal to 3008002. Similarly, the idxFlags field
+** was added for [version 3.9.0] ([dateof:3.9.0]). 
+** It may therefore only be used if
+** sqlite3_libversion_number() returns a value greater than or equal to
+** 3009000.
+*/
+struct sqlite3_index_info {
+  /* Inputs */
+  int nConstraint;           /* Number of entries in aConstraint */
+  struct sqlite3_index_constraint {
+     int iColumn;              /* Column constrained.  -1 for ROWID */
+     unsigned char op;         /* Constraint operator */
+     unsigned char usable;     /* True if this constraint is usable */
+     int iTermOffset;          /* Used internally - xBestIndex should ignore */
+  } *aConstraint;            /* Table of WHERE clause constraints */
+  int nOrderBy;              /* Number of terms in the ORDER BY clause */
+  struct sqlite3_index_orderby {
+     int iColumn;              /* Column number */
+     unsigned char desc;       /* True for DESC.  False for ASC. */
+  } *aOrderBy;               /* The ORDER BY clause */
+  /* Outputs */
+  struct sqlite3_index_constraint_usage {
+    int argvIndex;           /* if >0, constraint is part of argv to xFilter */
+    unsigned char omit;      /* Do not code a test for this constraint */
+  } *aConstraintUsage;
+  int idxNum;                /* Number used to identify the index */
+  char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
+  int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
+  int orderByConsumed;       /* True if output is already ordered */
+  double estimatedCost;           /* Estimated cost of using this index */
+  /* Fields below are only available in SQLite 3.8.2 and later */
+  sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
+  /* Fields below are only available in SQLite 3.9.0 and later */
+  int idxFlags;              /* Mask of SQLITE_INDEX_SCAN_* flags */
+  /* Fields below are only available in SQLite 3.10.0 and later */
+  sqlite3_uint64 colUsed;    /* Input: Mask of columns used by statement */
+};
+
+/*
+** CAPI3REF: Virtual Table Scan Flags
+**
+** Virtual table implementations are allowed to set the 
+** [sqlite3_index_info].idxFlags field to some combination of
+** these bits.
+*/
+#define SQLITE_INDEX_SCAN_UNIQUE      1     /* Scan visits at most 1 row */
+
+/*
+** CAPI3REF: Virtual Table Constraint Operator Codes
+**
+** These macros define the allowed values for the
+** [sqlite3_index_info].aConstraint[].op field.  Each value represents
+** an operator that is part of a constraint term in the wHERE clause of
+** a query that uses a [virtual table].
+*/
+#define SQLITE_INDEX_CONSTRAINT_EQ         2
+#define SQLITE_INDEX_CONSTRAINT_GT         4
+#define SQLITE_INDEX_CONSTRAINT_LE         8
+#define SQLITE_INDEX_CONSTRAINT_LT        16
+#define SQLITE_INDEX_CONSTRAINT_GE        32
+#define SQLITE_INDEX_CONSTRAINT_MATCH     64
+#define SQLITE_INDEX_CONSTRAINT_LIKE      65
+#define SQLITE_INDEX_CONSTRAINT_GLOB      66
+#define SQLITE_INDEX_CONSTRAINT_REGEXP    67
+#define SQLITE_INDEX_CONSTRAINT_NE        68
+#define SQLITE_INDEX_CONSTRAINT_ISNOT     69
+#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
+#define SQLITE_INDEX_CONSTRAINT_ISNULL    71
+#define SQLITE_INDEX_CONSTRAINT_IS        72
+#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
+
+/*
+** CAPI3REF: Register A Virtual Table Implementation
+** METHOD: sqlite3
+**
+** ^These routines are used to register a new [virtual table module] name.
+** ^Module names must be registered before
+** creating a new [virtual table] using the module and before using a
+** preexisting [virtual table] for the module.
+**
+** ^The module name is registered on the [database connection] specified
+** by the first parameter.  ^The name of the module is given by the 
+** second parameter.  ^The third parameter is a pointer to
+** the implementation of the [virtual table module].   ^The fourth
+** parameter is an arbitrary client data pointer that is passed through
+** into the [xCreate] and [xConnect] methods of the virtual table module
+** when a new virtual table is be being created or reinitialized.
+**
+** ^The sqlite3_create_module_v2() interface has a fifth parameter which
+** is a pointer to a destructor for the pClientData.  ^SQLite will
+** invoke the destructor function (if it is not NULL) when SQLite
+** no longer needs the pClientData pointer.  ^The destructor will also
+** be invoked if the call to sqlite3_create_module_v2() fails.
+** ^The sqlite3_create_module()
+** interface is equivalent to sqlite3_create_module_v2() with a NULL
+** destructor.
+**
+** ^If the third parameter (the pointer to the sqlite3_module object) is
+** NULL then no new module is create and any existing modules with the
+** same name are dropped.
+**
+** See also: [sqlite3_drop_modules()]
+*/
+SQLITE_API int sqlite3_create_module(
+  sqlite3 *db,               /* SQLite connection to register module with */
+  const char *zName,         /* Name of the module */
+  const sqlite3_module *p,   /* Methods for the module */
+  void *pClientData          /* Client data for xCreate/xConnect */
+);
+SQLITE_API int sqlite3_create_module_v2(
+  sqlite3 *db,               /* SQLite connection to register module with */
+  const char *zName,         /* Name of the module */
+  const sqlite3_module *p,   /* Methods for the module */
+  void *pClientData,         /* Client data for xCreate/xConnect */
+  void(*xDestroy)(void*)     /* Module destructor function */
+);
+
+/*
+** CAPI3REF: Remove Unnecessary Virtual Table Implementations
+** METHOD: sqlite3
+**
+** ^The sqlite3_drop_modules(D,L) interface removes all virtual
+** table modules from database connection D except those named on list L.
+** The L parameter must be either NULL or a pointer to an array of pointers
+** to strings where the array is terminated by a single NULL pointer.
+** ^If the L parameter is NULL, then all virtual table modules are removed.
+**
+** See also: [sqlite3_create_module()]
+*/
+SQLITE_API int sqlite3_drop_modules(
+  sqlite3 *db,                /* Remove modules from this connection */
+  const char **azKeep         /* Except, do not remove the ones named here */
+);
+
+/*
+** CAPI3REF: Virtual Table Instance Object
+** KEYWORDS: sqlite3_vtab
+**
+** Every [virtual table module] implementation uses a subclass
+** of this object to describe a particular instance
+** of the [virtual table].  Each subclass will
+** be tailored to the specific needs of the module implementation.
+** The purpose of this superclass is to define certain fields that are
+** common to all module implementations.
+**
+** ^Virtual tables methods can set an error message by assigning a
+** string obtained from [sqlite3_mprintf()] to zErrMsg.  The method should
+** take care that any prior string is freed by a call to [sqlite3_free()]
+** prior to assigning a new string to zErrMsg.  ^After the error message
+** is delivered up to the client application, the string will be automatically
+** freed by sqlite3_free() and the zErrMsg field will be zeroed.
+*/
+struct sqlite3_vtab {
+  const sqlite3_module *pModule;  /* The module for this virtual table */
+  int nRef;                       /* Number of open cursors */
+  char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
+  /* Virtual table implementations will typically add additional fields */
+};
+
+/*
+** CAPI3REF: Virtual Table Cursor Object
+** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}
+**
+** Every [virtual table module] implementation uses a subclass of the
+** following structure to describe cursors that point into the
+** [virtual table] and are used
+** to loop through the virtual table.  Cursors are created using the
+** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed
+** by the [sqlite3_module.xClose | xClose] method.  Cursors are used
+** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods
+** of the module.  Each module implementation will define
+** the content of a cursor structure to suit its own needs.
+**
+** This superclass exists in order to define fields of the cursor that
+** are common to all implementations.
+*/
+struct sqlite3_vtab_cursor {
+  sqlite3_vtab *pVtab;      /* Virtual table of this cursor */
+  /* Virtual table implementations will typically add additional fields */
+};
+
+/*
+** CAPI3REF: Declare The Schema Of A Virtual Table
+**
+** ^The [xCreate] and [xConnect] methods of a
+** [virtual table module] call this interface
+** to declare the format (the names and datatypes of the columns) of
+** the virtual tables they implement.
+*/
+SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+
+/*
+** CAPI3REF: Overload A Function For A Virtual Table
+** METHOD: sqlite3
+**
+** ^(Virtual tables can provide alternative implementations of functions
+** using the [xFindFunction] method of the [virtual table module].  
+** But global versions of those functions
+** must exist in order to be overloaded.)^
+**
+** ^(This API makes sure a global version of a function with a particular
+** name and number of parameters exists.  If no such function exists
+** before this API is called, a new function is created.)^  ^The implementation
+** of the new function always causes an exception to be thrown.  So
+** the new function is not good for anything by itself.  Its only
+** purpose is to be a placeholder function that can be overloaded
+** by a [virtual table].
+*/
+SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+
+/*
+** The interface to the virtual-table mechanism defined above (back up
+** to a comment remarkably similar to this one) is currently considered
+** to be experimental.  The interface might change in incompatible ways.
+** If this is a problem for you, do not use the interface at this time.
+**
+** When the virtual-table mechanism stabilizes, we will declare the
+** interface fixed, support it indefinitely, and remove this comment.
+*/
+
+/*
+** CAPI3REF: A Handle To An Open BLOB
+** KEYWORDS: {BLOB handle} {BLOB handles}
+**
+** An instance of this object represents an open BLOB on which
+** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
+** ^Objects of this type are created by [sqlite3_blob_open()]
+** and destroyed by [sqlite3_blob_close()].
+** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces
+** can be used to read or write small subsections of the BLOB.
+** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes.
+*/
+typedef struct sqlite3_blob sqlite3_blob;
+
+/*
+** CAPI3REF: Open A BLOB For Incremental I/O
+** METHOD: sqlite3
+** CONSTRUCTOR: sqlite3_blob
+**
+** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
+** in row iRow, column zColumn, table zTable in database zDb;
+** in other words, the same BLOB that would be selected by:
+**
+** <pre>
+**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
+** </pre>)^
+**
+** ^(Parameter zDb is not the filename that contains the database, but 
+** rather the symbolic name of the database. For attached databases, this is
+** the name that appears after the AS keyword in the [ATTACH] statement.
+** For the main database file, the database name is "main". For TEMP
+** tables, the database name is "temp".)^
+**
+** ^If the flags parameter is non-zero, then the BLOB is opened for read
+** and write access. ^If the flags parameter is zero, the BLOB is opened for
+** read-only access.
+**
+** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
+** in *ppBlob. Otherwise an [error code] is returned and, unless the error
+** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
+** the API is not misused, it is always safe to call [sqlite3_blob_close()] 
+** on *ppBlob after this function it returns.
+**
+** This function fails with SQLITE_ERROR if any of the following are true:
+** <ul>
+**   <li> ^(Database zDb does not exist)^, 
+**   <li> ^(Table zTable does not exist within database zDb)^, 
+**   <li> ^(Table zTable is a WITHOUT ROWID table)^, 
+**   <li> ^(Column zColumn does not exist)^,
+**   <li> ^(Row iRow is not present in the table)^,
+**   <li> ^(The specified column of row iRow contains a value that is not
+**         a TEXT or BLOB value)^,
+**   <li> ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE 
+**         constraint and the blob is being opened for read/write access)^,
+**   <li> ^([foreign key constraints | Foreign key constraints] are enabled, 
+**         column zColumn is part of a [child key] definition and the blob is
+**         being opened for read/write access)^.
+** </ul>
+**
+** ^Unless it returns SQLITE_MISUSE, this function sets the 
+** [database connection] error code and message accessible via 
+** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 
+**
+** A BLOB referenced by sqlite3_blob_open() may be read using the
+** [sqlite3_blob_read()] interface and modified by using
+** [sqlite3_blob_write()].  The [BLOB handle] can be moved to a
+** different row of the same table using the [sqlite3_blob_reopen()]
+** interface.  However, the column, table, or database of a [BLOB handle]
+** cannot be changed after the [BLOB handle] is opened.
+**
+** ^(If the row that a BLOB handle points to is modified by an
+** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
+** then the BLOB handle is marked as "expired".
+** This is true if any column of the row is changed, even a column
+** other than the one the BLOB handle is open on.)^
+** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
+** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
+** ^(Changes written into a BLOB prior to the BLOB expiring are not
+** rolled back by the expiration of the BLOB.  Such changes will eventually
+** commit if the transaction continues to completion.)^
+**
+** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
+** the opened blob.  ^The size of a blob may not be changed by this
+** interface.  Use the [UPDATE] SQL command to change the size of a
+** blob.
+**
+** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
+** and the built-in [zeroblob] SQL function may be used to create a 
+** zero-filled blob to read or write using the incremental-blob interface.
+**
+** To avoid a resource leak, every open [BLOB handle] should eventually
+** be released by a call to [sqlite3_blob_close()].
+**
+** See also: [sqlite3_blob_close()],
+** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
+** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
+*/
+SQLITE_API int sqlite3_blob_open(
+  sqlite3*,
+  const char *zDb,
+  const char *zTable,
+  const char *zColumn,
+  sqlite3_int64 iRow,
+  int flags,
+  sqlite3_blob **ppBlob
+);
+
+/*
+** CAPI3REF: Move a BLOB Handle to a New Row
+** METHOD: sqlite3_blob
+**
+** ^This function is used to move an existing [BLOB handle] so that it points
+** to a different row of the same database table. ^The new row is identified
+** by the rowid value passed as the second argument. Only the row can be
+** changed. ^The database, table and column on which the blob handle is open
+** remain the same. Moving an existing [BLOB handle] to a new row is
+** faster than closing the existing handle and opening a new one.
+**
+** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
+** it must exist and there must be either a blob or text value stored in
+** the nominated column.)^ ^If the new row is not present in the table, or if
+** it does not contain a blob or text value, or if another error occurs, an
+** SQLite error code is returned and the blob handle is considered aborted.
+** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or
+** [sqlite3_blob_reopen()] on an aborted blob handle immediately return
+** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
+** always returns zero.
+**
+** ^This function sets the database handle error code and message.
+*/
+SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+
+/*
+** CAPI3REF: Close A BLOB Handle
+** DESTRUCTOR: sqlite3_blob
+**
+** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
+** unconditionally.  Even if this routine returns an error code, the 
+** handle is still closed.)^
+**
+** ^If the blob handle being closed was opened for read-write access, and if
+** the database is in auto-commit mode and there are no other open read-write
+** blob handles or active write statements, the current transaction is
+** committed. ^If an error occurs while committing the transaction, an error
+** code is returned and the transaction rolled back.
+**
+** Calling this function with an argument that is not a NULL pointer or an
+** open blob handle results in undefined behaviour. ^Calling this routine 
+** with a null pointer (such as would be returned by a failed call to 
+** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
+** is passed a valid open blob handle, the values returned by the 
+** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
+*/
+SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
+
+/*
+** CAPI3REF: Return The Size Of An Open BLOB
+** METHOD: sqlite3_blob
+**
+** ^Returns the size in bytes of the BLOB accessible via the 
+** successfully opened [BLOB handle] in its only argument.  ^The
+** incremental blob I/O routines can only read or overwriting existing
+** blob content; they cannot change the size of a blob.
+**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()].  Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
+*/
+SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
+
+/*
+** CAPI3REF: Read Data From A BLOB Incrementally
+** METHOD: sqlite3_blob
+**
+** ^(This function is used to read data from an open [BLOB handle] into a
+** caller-supplied buffer. N bytes of data are copied into buffer Z
+** from the open BLOB, starting at offset iOffset.)^
+**
+** ^If offset iOffset is less than N bytes from the end of the BLOB,
+** [SQLITE_ERROR] is returned and no data is read.  ^If N or iOffset is
+** less than zero, [SQLITE_ERROR] is returned and no data is read.
+** ^The size of the blob (and hence the maximum value of N+iOffset)
+** can be determined using the [sqlite3_blob_bytes()] interface.
+**
+** ^An attempt to read from an expired [BLOB handle] fails with an
+** error code of [SQLITE_ABORT].
+**
+** ^(On success, sqlite3_blob_read() returns SQLITE_OK.
+** Otherwise, an [error code] or an [extended error code] is returned.)^
+**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()].  Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
+**
+** See also: [sqlite3_blob_write()].
+*/
+SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
+
+/*
+** CAPI3REF: Write Data Into A BLOB Incrementally
+** METHOD: sqlite3_blob
+**
+** ^(This function is used to write data into an open [BLOB handle] from a
+** caller-supplied buffer. N bytes of data are copied from the buffer Z
+** into the open BLOB, starting at offset iOffset.)^
+**
+** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
+** Otherwise, an  [error code] or an [extended error code] is returned.)^
+** ^Unless SQLITE_MISUSE is returned, this function sets the 
+** [database connection] error code and message accessible via 
+** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 
+**
+** ^If the [BLOB handle] passed as the first argument was not opened for
+** writing (the flags parameter to [sqlite3_blob_open()] was zero),
+** this function returns [SQLITE_READONLY].
+**
+** This function may only modify the contents of the BLOB; it is
+** not possible to increase the size of a BLOB using this API.
+** ^If offset iOffset is less than N bytes from the end of the BLOB,
+** [SQLITE_ERROR] is returned and no data is written. The size of the 
+** BLOB (and hence the maximum value of N+iOffset) can be determined 
+** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less 
+** than zero [SQLITE_ERROR] is returned and no data is written.
+**
+** ^An attempt to write to an expired [BLOB handle] fails with an
+** error code of [SQLITE_ABORT].  ^Writes to the BLOB that occurred
+** before the [BLOB handle] expired are not rolled back by the
+** expiration of the handle, though of course those changes might
+** have been overwritten by the statement that expired the BLOB handle
+** or by other independent statements.
+**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()].  Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
+**
+** See also: [sqlite3_blob_read()].
+*/
+SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+
+/*
+** CAPI3REF: Virtual File System Objects
+**
+** A virtual filesystem (VFS) is an [sqlite3_vfs] object
+** that SQLite uses to interact
+** with the underlying operating system.  Most SQLite builds come with a
+** single default VFS that is appropriate for the host computer.
+** New VFSes can be registered and existing VFSes can be unregistered.
+** The following interfaces are provided.
+**
+** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name.
+** ^Names are case sensitive.
+** ^Names are zero-terminated UTF-8 strings.
+** ^If there is no match, a NULL pointer is returned.
+** ^If zVfsName is NULL then the default VFS is returned.
+**
+** ^New VFSes are registered with sqlite3_vfs_register().
+** ^Each new VFS becomes the default VFS if the makeDflt flag is set.
+** ^The same VFS can be registered multiple times without injury.
+** ^To make an existing VFS into the default VFS, register it again
+** with the makeDflt flag set.  If two different VFSes with the
+** same name are registered, the behavior is undefined.  If a
+** VFS is registered with a name that is NULL or an empty string,
+** then the behavior is undefined.
+**
+** ^Unregister a VFS with the sqlite3_vfs_unregister() interface.
+** ^(If the default VFS is unregistered, another VFS is chosen as
+** the default.  The choice for the new VFS is arbitrary.)^
+*/
+SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
+SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
+
+/*
+** CAPI3REF: Mutexes
+**
+** The SQLite core uses these routines for thread
+** synchronization. Though they are intended for internal
+** use by SQLite, code that links against SQLite is
+** permitted to use any of these routines.
+**
+** The SQLite source code contains multiple implementations
+** of these mutex routines.  An appropriate implementation
+** is selected automatically at compile-time.  The following
+** implementations are available in the SQLite core:
+**
+** <ul>
+** <li>   SQLITE_MUTEX_PTHREADS
+** <li>   SQLITE_MUTEX_W32
+** <li>   SQLITE_MUTEX_NOOP
+** </ul>
+**
+** The SQLITE_MUTEX_NOOP implementation is a set of routines
+** that does no real locking and is appropriate for use in
+** a single-threaded application.  The SQLITE_MUTEX_PTHREADS and
+** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
+** and Windows.
+**
+** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
+** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
+** implementation is included with the library. In this case the
+** application must supply a custom mutex implementation using the
+** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
+** before calling sqlite3_initialize() or any other public sqlite3_
+** function that calls sqlite3_initialize().
+**
+** ^The sqlite3_mutex_alloc() routine allocates a new
+** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
+** routine returns NULL if it is unable to allocate the requested
+** mutex.  The argument to sqlite3_mutex_alloc() must one of these
+** integer constants:
+**
+** <ul>
+** <li>  SQLITE_MUTEX_FAST
+** <li>  SQLITE_MUTEX_RECURSIVE
+** <li>  SQLITE_MUTEX_STATIC_MASTER
+** <li>  SQLITE_MUTEX_STATIC_MEM
+** <li>  SQLITE_MUTEX_STATIC_OPEN
+** <li>  SQLITE_MUTEX_STATIC_PRNG
+** <li>  SQLITE_MUTEX_STATIC_LRU
+** <li>  SQLITE_MUTEX_STATIC_PMEM
+** <li>  SQLITE_MUTEX_STATIC_APP1
+** <li>  SQLITE_MUTEX_STATIC_APP2
+** <li>  SQLITE_MUTEX_STATIC_APP3
+** <li>  SQLITE_MUTEX_STATIC_VFS1
+** <li>  SQLITE_MUTEX_STATIC_VFS2
+** <li>  SQLITE_MUTEX_STATIC_VFS3
+** </ul>
+**
+** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
+** cause sqlite3_mutex_alloc() to create
+** a new mutex.  ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
+** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
+** The mutex implementation does not need to make a distinction
+** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
+** not want to.  SQLite will only request a recursive mutex in
+** cases where it really needs one.  If a faster non-recursive mutex
+** implementation is available on the host platform, the mutex subsystem
+** might return such a mutex in response to SQLITE_MUTEX_FAST.
+**
+** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
+** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
+** a pointer to a static preexisting mutex.  ^Nine static mutexes are
+** used by the current version of SQLite.  Future versions of SQLite
+** may add additional static mutexes.  Static mutexes are for internal
+** use by SQLite only.  Applications that use SQLite mutexes should
+** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
+** SQLITE_MUTEX_RECURSIVE.
+**
+** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
+** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
+** returns a different mutex on every call.  ^For the static
+** mutex types, the same mutex is returned on every call that has
+** the same type number.
+**
+** ^The sqlite3_mutex_free() routine deallocates a previously
+** allocated dynamic mutex.  Attempting to deallocate a static
+** mutex results in undefined behavior.
+**
+** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
+** to enter a mutex.  ^If another thread is already within the mutex,
+** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
+** SQLITE_BUSY.  ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
+** upon successful entry.  ^(Mutexes created using
+** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
+** In such cases, the
+** mutex must be exited an equal number of times before another thread
+** can enter.)^  If the same thread tries to enter any mutex other
+** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
+**
+** ^(Some systems (for example, Windows 95) do not support the operation
+** implemented by sqlite3_mutex_try().  On those systems, sqlite3_mutex_try()
+** will always return SQLITE_BUSY. The SQLite core only ever uses
+** sqlite3_mutex_try() as an optimization so this is acceptable 
+** behavior.)^
+**
+** ^The sqlite3_mutex_leave() routine exits a mutex that was
+** previously entered by the same thread.   The behavior
+** is undefined if the mutex is not currently entered by the
+** calling thread or is not currently allocated.
+**
+** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
+** sqlite3_mutex_leave() is a NULL pointer, then all three routines
+** behave as no-ops.
+**
+** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
+*/
+SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
+SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
+
+/*
+** CAPI3REF: Mutex Methods Object
+**
+** An instance of this structure defines the low-level routines
+** used to allocate and use mutexes.
+**
+** Usually, the default mutex implementations provided by SQLite are
+** sufficient, however the application has the option of substituting a custom
+** implementation for specialized deployments or systems for which SQLite
+** does not provide a suitable implementation. In this case, the application
+** creates and populates an instance of this structure to pass
+** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
+** Additionally, an instance of this structure can be used as an
+** output variable when querying the system for the current mutex
+** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
+**
+** ^The xMutexInit method defined by this structure is invoked as
+** part of system initialization by the sqlite3_initialize() function.
+** ^The xMutexInit routine is called by SQLite exactly once for each
+** effective call to [sqlite3_initialize()].
+**
+** ^The xMutexEnd method defined by this structure is invoked as
+** part of system shutdown by the sqlite3_shutdown() function. The
+** implementation of this method is expected to release all outstanding
+** resources obtained by the mutex methods implementation, especially
+** those obtained by the xMutexInit method.  ^The xMutexEnd()
+** interface is invoked exactly once for each call to [sqlite3_shutdown()].
+**
+** ^(The remaining seven methods defined by this structure (xMutexAlloc,
+** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and
+** xMutexNotheld) implement the following interfaces (respectively):
+**
+** <ul>
+**   <li>  [sqlite3_mutex_alloc()] </li>
+**   <li>  [sqlite3_mutex_free()] </li>
+**   <li>  [sqlite3_mutex_enter()] </li>
+**   <li>  [sqlite3_mutex_try()] </li>
+**   <li>  [sqlite3_mutex_leave()] </li>
+**   <li>  [sqlite3_mutex_held()] </li>
+**   <li>  [sqlite3_mutex_notheld()] </li>
+** </ul>)^
+**
+** The only difference is that the public sqlite3_XXX functions enumerated
+** above silently ignore any invocations that pass a NULL pointer instead
+** of a valid mutex handle. The implementations of the methods defined
+** by this structure are not required to handle this case. The results
+** of passing a NULL pointer instead of a valid mutex handle are undefined
+** (i.e. it is acceptable to provide an implementation that segfaults if
+** it is passed a NULL pointer).
+**
+** The xMutexInit() method must be threadsafe.  It must be harmless to
+** invoke xMutexInit() multiple times within the same process and without
+** intervening calls to xMutexEnd().  Second and subsequent calls to
+** xMutexInit() must be no-ops.
+**
+** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
+** and its associates).  Similarly, xMutexAlloc() must not use SQLite memory
+** allocation for a static mutex.  ^However xMutexAlloc() may use SQLite
+** memory allocation for a fast or recursive mutex.
+**
+** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
+** called, but only if the prior call to xMutexInit returned SQLITE_OK.
+** If xMutexInit fails in any way, it is expected to clean up after itself
+** prior to returning.
+*/
+typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
+struct sqlite3_mutex_methods {
+  int (*xMutexInit)(void);
+  int (*xMutexEnd)(void);
+  sqlite3_mutex *(*xMutexAlloc)(int);
+  void (*xMutexFree)(sqlite3_mutex *);
+  void (*xMutexEnter)(sqlite3_mutex *);
+  int (*xMutexTry)(sqlite3_mutex *);
+  void (*xMutexLeave)(sqlite3_mutex *);
+  int (*xMutexHeld)(sqlite3_mutex *);
+  int (*xMutexNotheld)(sqlite3_mutex *);
+};
+
+/*
+** CAPI3REF: Mutex Verification Routines
+**
+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
+** are intended for use inside assert() statements.  The SQLite core
+** never uses these routines except inside an assert() and applications
+** are advised to follow the lead of the core.  The SQLite core only
+** provides implementations for these routines when it is compiled
+** with the SQLITE_DEBUG flag.  External mutex implementations
+** are only required to provide these routines if SQLITE_DEBUG is
+** defined and if NDEBUG is not defined.
+**
+** These routines should return true if the mutex in their argument
+** is held or not held, respectively, by the calling thread.
+**
+** The implementation is not required to provide versions of these
+** routines that actually work. If the implementation does not provide working
+** versions of these routines, it should at least provide stubs that always
+** return true so that one does not get spurious assertion failures.
+**
+** If the argument to sqlite3_mutex_held() is a NULL pointer then
+** the routine should return 1.   This seems counter-intuitive since
+** clearly the mutex cannot be held if it does not exist.  But
+** the reason the mutex does not exist is because the build is not
+** using mutexes.  And we do not want the assert() containing the
+** call to sqlite3_mutex_held() to fail, so a non-zero return is
+** the appropriate thing to do.  The sqlite3_mutex_notheld()
+** interface should also return 1 when given a NULL pointer.
+*/
+#ifndef NDEBUG
+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
+#endif
+
+/*
+** CAPI3REF: Mutex Types
+**
+** The [sqlite3_mutex_alloc()] interface takes a single argument
+** which is one of these integer constants.
+**
+** The set of static mutexes may change from one SQLite release to the
+** next.  Applications that override the built-in mutex logic must be
+** prepared to accommodate additional static mutexes.
+*/
+#define SQLITE_MUTEX_FAST             0
+#define SQLITE_MUTEX_RECURSIVE        1
+#define SQLITE_MUTEX_STATIC_MASTER    2
+#define SQLITE_MUTEX_STATIC_MEM       3  /* sqlite3_malloc() */
+#define SQLITE_MUTEX_STATIC_MEM2      4  /* NOT USED */
+#define SQLITE_MUTEX_STATIC_OPEN      4  /* sqlite3BtreeOpen() */
+#define SQLITE_MUTEX_STATIC_PRNG      5  /* sqlite3_randomness() */
+#define SQLITE_MUTEX_STATIC_LRU       6  /* lru page list */
+#define SQLITE_MUTEX_STATIC_LRU2      7  /* NOT USED */
+#define SQLITE_MUTEX_STATIC_PMEM      7  /* sqlite3PageMalloc() */
+#define SQLITE_MUTEX_STATIC_APP1      8  /* For use by application */
+#define SQLITE_MUTEX_STATIC_APP2      9  /* For use by application */
+#define SQLITE_MUTEX_STATIC_APP3     10  /* For use by application */
+#define SQLITE_MUTEX_STATIC_VFS1     11  /* For use by built-in VFS */
+#define SQLITE_MUTEX_STATIC_VFS2     12  /* For use by extension VFS */
+#define SQLITE_MUTEX_STATIC_VFS3     13  /* For use by application VFS */
+
+/*
+** CAPI3REF: Retrieve the mutex for a database connection
+** METHOD: sqlite3
+**
+** ^This interface returns a pointer the [sqlite3_mutex] object that 
+** serializes access to the [database connection] given in the argument
+** when the [threading mode] is Serialized.
+** ^If the [threading mode] is Single-thread or Multi-thread then this
+** routine returns a NULL pointer.
+*/
+SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
+
+/*
+** CAPI3REF: Low-Level Control Of Database Files
+** METHOD: sqlite3
+** KEYWORDS: {file control}
+**
+** ^The [sqlite3_file_control()] interface makes a direct call to the
+** xFileControl method for the [sqlite3_io_methods] object associated
+** with a particular database identified by the second argument. ^The
+** name of the database is "main" for the main database or "temp" for the
+** TEMP database, or the name that appears after the AS keyword for
+** databases that are added using the [ATTACH] SQL command.
+** ^A NULL pointer can be used in place of "main" to refer to the
+** main database file.
+** ^The third and fourth parameters to this routine
+** are passed directly through to the second and third parameters of
+** the xFileControl method.  ^The return value of the xFileControl
+** method becomes the return value of this routine.
+**
+** A few opcodes for [sqlite3_file_control()] are handled directly
+** by the SQLite core and never invoke the 
+** sqlite3_io_methods.xFileControl method.
+** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
+** a pointer to the underlying [sqlite3_file] object to be written into
+** the space pointed to by the 4th parameter.  The
+** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
+** the [sqlite3_file] object associated with the journal file instead of
+** the main database.  The [SQLITE_FCNTL_VFS_POINTER] opcode returns
+** a pointer to the underlying [sqlite3_vfs] object for the file.
+** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter
+** from the pager.
+**
+** ^If the second parameter (zDbName) does not match the name of any
+** open database file, then SQLITE_ERROR is returned.  ^This error
+** code is not remembered and will not be recalled by [sqlite3_errcode()]
+** or [sqlite3_errmsg()].  The underlying xFileControl method might
+** also return SQLITE_ERROR.  There is no way to distinguish between
+** an incorrect zDbName and an SQLITE_ERROR return from the underlying
+** xFileControl method.
+**
+** See also: [file control opcodes]
+*/
+SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+
+/*
+** CAPI3REF: Testing Interface
+**
+** ^The sqlite3_test_control() interface is used to read out internal
+** state of SQLite and to inject faults into SQLite for testing
+** purposes.  ^The first parameter is an operation code that determines
+** the number, meaning, and operation of all subsequent parameters.
+**
+** This interface is not for use by applications.  It exists solely
+** for verifying the correct operation of the SQLite library.  Depending
+** on how the SQLite library is compiled, this interface might not exist.
+**
+** The details of the operation codes, their meanings, the parameters
+** they take, and what they do are all subject to change without notice.
+** Unlike most of the SQLite API, this function is not guaranteed to
+** operate consistently from one release to the next.
+*/
+SQLITE_API int sqlite3_test_control(int op, ...);
+
+/*
+** CAPI3REF: Testing Interface Operation Codes
+**
+** These constants are the valid operation code parameters used
+** as the first argument to [sqlite3_test_control()].
+**
+** These parameters and their meanings are subject to change
+** without notice.  These values are for testing purposes only.
+** Applications should not use any of these parameters or the
+** [sqlite3_test_control()] interface.
+*/
+#define SQLITE_TESTCTRL_FIRST                    5
+#define SQLITE_TESTCTRL_PRNG_SAVE                5
+#define SQLITE_TESTCTRL_PRNG_RESTORE             6
+#define SQLITE_TESTCTRL_PRNG_RESET               7  /* NOT USED */
+#define SQLITE_TESTCTRL_BITVEC_TEST              8
+#define SQLITE_TESTCTRL_FAULT_INSTALL            9
+#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10
+#define SQLITE_TESTCTRL_PENDING_BYTE            11
+#define SQLITE_TESTCTRL_ASSERT                  12
+#define SQLITE_TESTCTRL_ALWAYS                  13
+#define SQLITE_TESTCTRL_RESERVE                 14  /* NOT USED */
+#define SQLITE_TESTCTRL_OPTIMIZATIONS           15
+#define SQLITE_TESTCTRL_ISKEYWORD               16  /* NOT USED */
+#define SQLITE_TESTCTRL_SCRATCHMALLOC           17  /* NOT USED */
+#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS      17
+#define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
+#define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
+#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD    19
+#define SQLITE_TESTCTRL_NEVER_CORRUPT           20
+#define SQLITE_TESTCTRL_VDBE_COVERAGE           21
+#define SQLITE_TESTCTRL_BYTEORDER               22
+#define SQLITE_TESTCTRL_ISINIT                  23
+#define SQLITE_TESTCTRL_SORTER_MMAP             24
+#define SQLITE_TESTCTRL_IMPOSTER                25
+#define SQLITE_TESTCTRL_PARSER_COVERAGE         26
+#define SQLITE_TESTCTRL_RESULT_INTREAL          27
+#define SQLITE_TESTCTRL_PRNG_SEED               28
+#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS     29
+#define SQLITE_TESTCTRL_LAST                    29  /* Largest TESTCTRL */
+
+/*
+** CAPI3REF: SQL Keyword Checking
+**
+** These routines provide access to the set of SQL language keywords 
+** recognized by SQLite.  Applications can uses these routines to determine
+** whether or not a specific identifier needs to be escaped (for example,
+** by enclosing in double-quotes) so as not to confuse the parser.
+**
+** The sqlite3_keyword_count() interface returns the number of distinct
+** keywords understood by SQLite.
+**
+** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
+** makes *Z point to that keyword expressed as UTF8 and writes the number
+** of bytes in the keyword into *L.  The string that *Z points to is not
+** zero-terminated.  The sqlite3_keyword_name(N,Z,L) routine returns
+** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
+** or L are NULL or invalid pointers then calls to
+** sqlite3_keyword_name(N,Z,L) result in undefined behavior.
+**
+** The sqlite3_keyword_check(Z,L) interface checks to see whether or not
+** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero
+** if it is and zero if not.
+**
+** The parser used by SQLite is forgiving.  It is often possible to use
+** a keyword as an identifier as long as such use does not result in a
+** parsing ambiguity.  For example, the statement
+** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and
+** creates a new table named "BEGIN" with three columns named
+** "REPLACE", "PRAGMA", and "END".  Nevertheless, best practice is to avoid
+** using keywords as identifiers.  Common techniques used to avoid keyword
+** name collisions include:
+** <ul>
+** <li> Put all identifier names inside double-quotes.  This is the official
+**      SQL way to escape identifier names.
+** <li> Put identifier names inside &#91;...&#93;.  This is not standard SQL,
+**      but it is what SQL Server does and so lots of programmers use this
+**      technique.
+** <li> Begin every identifier with the letter "Z" as no SQL keywords start
+**      with "Z".
+** <li> Include a digit somewhere in every identifier name.
+** </ul>
+**
+** Note that the number of keywords understood by SQLite can depend on
+** compile-time options.  For example, "VACUUM" is not a keyword if
+** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option.  Also,
+** new keywords may be added to future releases of SQLite.
+*/
+SQLITE_API int sqlite3_keyword_count(void);
+SQLITE_API int sqlite3_keyword_name(int,const char**,int*);
+SQLITE_API int sqlite3_keyword_check(const char*,int);
+
+/*
+** CAPI3REF: Dynamic String Object
+** KEYWORDS: {dynamic string}
+**
+** An instance of the sqlite3_str object contains a dynamically-sized
+** string under construction.
+**
+** The lifecycle of an sqlite3_str object is as follows:
+** <ol>
+** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].
+** <li> ^Text is appended to the sqlite3_str object using various
+** methods, such as [sqlite3_str_appendf()].
+** <li> ^The sqlite3_str object is destroyed and the string it created
+** is returned using the [sqlite3_str_finish()] interface.
+** </ol>
+*/
+typedef struct sqlite3_str sqlite3_str;
+
+/*
+** CAPI3REF: Create A New Dynamic String Object
+** CONSTRUCTOR: sqlite3_str
+**
+** ^The [sqlite3_str_new(D)] interface allocates and initializes
+** a new [sqlite3_str] object.  To avoid memory leaks, the object returned by
+** [sqlite3_str_new()] must be freed by a subsequent call to 
+** [sqlite3_str_finish(X)].
+**
+** ^The [sqlite3_str_new(D)] interface always returns a pointer to a
+** valid [sqlite3_str] object, though in the event of an out-of-memory
+** error the returned object might be a special singleton that will
+** silently reject new text, always return SQLITE_NOMEM from 
+** [sqlite3_str_errcode()], always return 0 for 
+** [sqlite3_str_length()], and always return NULL from
+** [sqlite3_str_finish(X)].  It is always safe to use the value
+** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter
+** to any of the other [sqlite3_str] methods.
+**
+** The D parameter to [sqlite3_str_new(D)] may be NULL.  If the
+** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum
+** length of the string contained in the [sqlite3_str] object will be
+** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead
+** of [SQLITE_MAX_LENGTH].
+*/
+SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);
+
+/*
+** CAPI3REF: Finalize A Dynamic String
+** DESTRUCTOR: sqlite3_str
+**
+** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
+** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
+** that contains the constructed string.  The calling application should
+** pass the returned value to [sqlite3_free()] to avoid a memory leak.
+** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
+** errors were encountered during construction of the string.  ^The
+** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
+** string in [sqlite3_str] object X is zero bytes long.
+*/
+SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
+
+/*
+** CAPI3REF: Add Content To A Dynamic String
+** METHOD: sqlite3_str
+**
+** These interfaces add content to an sqlite3_str object previously obtained
+** from [sqlite3_str_new()].
+**
+** ^The [sqlite3_str_appendf(X,F,...)] and 
+** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
+** functionality of SQLite to append formatted text onto the end of 
+** [sqlite3_str] object X.
+**
+** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
+** onto the end of the [sqlite3_str] object X.  N must be non-negative.
+** S must contain at least N non-zero bytes of content.  To append a
+** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
+** method instead.
+**
+** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of
+** zero-terminated string S onto the end of [sqlite3_str] object X.
+**
+** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
+** single-byte character C onto the end of [sqlite3_str] object X.
+** ^This method can be used, for example, to add whitespace indentation.
+**
+** ^The [sqlite3_str_reset(X)] method resets the string under construction
+** inside [sqlite3_str] object X back to zero bytes in length.  
+**
+** These methods do not return a result code.  ^If an error occurs, that fact
+** is recorded in the [sqlite3_str] object and can be recovered by a
+** subsequent call to [sqlite3_str_errcode(X)].
+*/
+SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
+SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
+SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
+SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
+SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
+SQLITE_API void sqlite3_str_reset(sqlite3_str*);
+
+/*
+** CAPI3REF: Status Of A Dynamic String
+** METHOD: sqlite3_str
+**
+** These interfaces return the current status of an [sqlite3_str] object.
+**
+** ^If any prior errors have occurred while constructing the dynamic string
+** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
+** an appropriate error code.  ^The [sqlite3_str_errcode(X)] method returns
+** [SQLITE_NOMEM] following any out-of-memory error, or
+** [SQLITE_TOOBIG] if the size of the dynamic string exceeds
+** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
+**
+** ^The [sqlite3_str_length(X)] method returns the current length, in bytes,
+** of the dynamic string under construction in [sqlite3_str] object X.
+** ^The length returned by [sqlite3_str_length(X)] does not include the
+** zero-termination byte.
+**
+** ^The [sqlite3_str_value(X)] method returns a pointer to the current
+** content of the dynamic string under construction in X.  The value
+** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
+** and might be freed or altered by any subsequent method on the same
+** [sqlite3_str] object.  Applications must not used the pointer returned
+** [sqlite3_str_value(X)] after any subsequent method call on the same
+** object.  ^Applications may change the content of the string returned
+** by [sqlite3_str_value(X)] as long as they do not write into any bytes
+** outside the range of 0 to [sqlite3_str_length(X)] and do not read or
+** write any byte after any subsequent sqlite3_str method call.
+*/
+SQLITE_API int sqlite3_str_errcode(sqlite3_str*);
+SQLITE_API int sqlite3_str_length(sqlite3_str*);
+SQLITE_API char *sqlite3_str_value(sqlite3_str*);
+
+/*
+** CAPI3REF: SQLite Runtime Status
+**
+** ^These interfaces are used to retrieve runtime status information
+** about the performance of SQLite, and optionally to reset various
+** highwater marks.  ^The first argument is an integer code for
+** the specific parameter to measure.  ^(Recognized integer codes
+** are of the form [status parameters | SQLITE_STATUS_...].)^
+** ^The current value of the parameter is returned into *pCurrent.
+** ^The highest recorded value is returned in *pHighwater.  ^If the
+** resetFlag is true, then the highest record value is reset after
+** *pHighwater is written.  ^(Some parameters do not record the highest
+** value.  For those parameters
+** nothing is written into *pHighwater and the resetFlag is ignored.)^
+** ^(Other parameters record only the highwater mark and not the current
+** value.  For these latter parameters nothing is written into *pCurrent.)^
+**
+** ^The sqlite3_status() and sqlite3_status64() routines return
+** SQLITE_OK on success and a non-zero [error code] on failure.
+**
+** If either the current value or the highwater mark is too large to
+** be represented by a 32-bit integer, then the values returned by
+** sqlite3_status() are undefined.
+**
+** See also: [sqlite3_db_status()]
+*/
+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int sqlite3_status64(
+  int op,
+  sqlite3_int64 *pCurrent,
+  sqlite3_int64 *pHighwater,
+  int resetFlag
+);
+
+
+/*
+** CAPI3REF: Status Parameters
+** KEYWORDS: {status parameters}
+**
+** These integer constants designate various run-time status parameters
+** that can be returned by [sqlite3_status()].
+**
+** <dl>
+** [[SQLITE_STATUS_MEMORY_USED]] ^(<dt>SQLITE_STATUS_MEMORY_USED</dt>
+** <dd>This parameter is the current amount of memory checked out
+** using [sqlite3_malloc()], either directly or indirectly.  The
+** figure includes calls made to [sqlite3_malloc()] by the application
+** and internal memory usage by the SQLite library.  Auxiliary page-cache
+** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
+** this parameter.  The amount returned is the sum of the allocation
+** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
+**
+** [[SQLITE_STATUS_MALLOC_SIZE]] ^(<dt>SQLITE_STATUS_MALLOC_SIZE</dt>
+** <dd>This parameter records the largest memory allocation request
+** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
+** internal equivalents).  Only the value returned in the
+** *pHighwater parameter to [sqlite3_status()] is of interest.  
+** The value written into the *pCurrent parameter is undefined.</dd>)^
+**
+** [[SQLITE_STATUS_MALLOC_COUNT]] ^(<dt>SQLITE_STATUS_MALLOC_COUNT</dt>
+** <dd>This parameter records the number of separate memory allocations
+** currently checked out.</dd>)^
+**
+** [[SQLITE_STATUS_PAGECACHE_USED]] ^(<dt>SQLITE_STATUS_PAGECACHE_USED</dt>
+** <dd>This parameter returns the number of pages used out of the
+** [pagecache memory allocator] that was configured using 
+** [SQLITE_CONFIG_PAGECACHE].  The
+** value returned is in pages, not in bytes.</dd>)^
+**
+** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] 
+** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
+** <dd>This parameter returns the number of bytes of page cache
+** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE]
+** buffer and where forced to overflow to [sqlite3_malloc()].  The
+** returned value includes allocations that overflowed because they
+** where too large (they were larger than the "sz" parameter to
+** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
+** no space was left in the page cache.</dd>)^
+**
+** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
+** <dd>This parameter records the largest memory allocation request
+** handed to the [pagecache memory allocator].  Only the value returned in the
+** *pHighwater parameter to [sqlite3_status()] is of interest.  
+** The value written into the *pCurrent parameter is undefined.</dd>)^
+**
+** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt>
+** <dd>No longer used.</dd>
+**
+** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
+** <dd>No longer used.</dd>
+**
+** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
+** <dd>No longer used.</dd>
+**
+** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
+** <dd>The *pHighwater parameter records the deepest parser stack. 
+** The *pCurrent value is undefined.  The *pHighwater value is only
+** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
+** </dl>
+**
+** New status parameters may be added from time to time.
+*/
+#define SQLITE_STATUS_MEMORY_USED          0
+#define SQLITE_STATUS_PAGECACHE_USED       1
+#define SQLITE_STATUS_PAGECACHE_OVERFLOW   2
+#define SQLITE_STATUS_SCRATCH_USED         3  /* NOT USED */
+#define SQLITE_STATUS_SCRATCH_OVERFLOW     4  /* NOT USED */
+#define SQLITE_STATUS_MALLOC_SIZE          5
+#define SQLITE_STATUS_PARSER_STACK         6
+#define SQLITE_STATUS_PAGECACHE_SIZE       7
+#define SQLITE_STATUS_SCRATCH_SIZE         8  /* NOT USED */
+#define SQLITE_STATUS_MALLOC_COUNT         9
+
+/*
+** CAPI3REF: Database Connection Status
+** METHOD: sqlite3
+**
+** ^This interface is used to retrieve runtime status information 
+** about a single [database connection].  ^The first argument is the
+** database connection object to be interrogated.  ^The second argument
+** is an integer constant, taken from the set of
+** [SQLITE_DBSTATUS options], that
+** determines the parameter to interrogate.  The set of 
+** [SQLITE_DBSTATUS options] is likely
+** to grow in future releases of SQLite.
+**
+** ^The current value of the requested parameter is written into *pCur
+** and the highest instantaneous value is written into *pHiwtr.  ^If
+** the resetFlg is true, then the highest instantaneous value is
+** reset back down to the current value.
+**
+** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
+** non-zero [error code] on failure.
+**
+** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
+*/
+SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+
+/*
+** CAPI3REF: Status Parameters for database connections
+** KEYWORDS: {SQLITE_DBSTATUS options}
+**
+** These constants are the available integer "verbs" that can be passed as
+** the second argument to the [sqlite3_db_status()] interface.
+**
+** New verbs may be added in future releases of SQLite. Existing verbs
+** might be discontinued. Applications should check the return code from
+** [sqlite3_db_status()] to make sure that the call worked.
+** The [sqlite3_db_status()] interface will return a non-zero error code
+** if a discontinued or unsupported verb is invoked.
+**
+** <dl>
+** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
+** <dd>This parameter returns the number of lookaside memory slots currently
+** checked out.</dd>)^
+**
+** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
+** <dd>This parameter returns the number of malloc attempts that were 
+** satisfied using lookaside memory. Only the high-water value is meaningful;
+** the current value is always zero.)^
+**
+** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]]
+** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt>
+** <dd>This parameter returns the number malloc attempts that might have
+** been satisfied using lookaside memory but failed due to the amount of
+** memory requested being larger than the lookaside slot size.
+** Only the high-water value is meaningful;
+** the current value is always zero.)^
+**
+** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]]
+** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt>
+** <dd>This parameter returns the number malloc attempts that might have
+** been satisfied using lookaside memory but failed due to all lookaside
+** memory already being in use.
+** Only the high-water value is meaningful;
+** the current value is always zero.)^
+**
+** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
+** <dd>This parameter returns the approximate number of bytes of heap
+** memory used by all pager caches associated with the database connection.)^
+** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
+**
+** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] 
+** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt>
+** <dd>This parameter is similar to DBSTATUS_CACHE_USED, except that if a
+** pager cache is shared between two or more connections the bytes of heap
+** memory used by that pager cache is divided evenly between the attached
+** connections.)^  In other words, if none of the pager caches associated
+** with the database connection are shared, this request returns the same
+** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are
+** shared, the value returned by this call will be smaller than that returned
+** by DBSTATUS_CACHE_USED. ^The highwater mark associated with
+** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.
+**
+** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
+** <dd>This parameter returns the approximate number of bytes of heap
+** memory used to store the schema for all databases associated
+** with the connection - main, temp, and any [ATTACH]-ed databases.)^ 
+** ^The full amount of memory used by the schemas is reported, even if the
+** schema memory is shared with other database connections due to
+** [shared cache mode] being enabled.
+** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0.
+**
+** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
+** <dd>This parameter returns the approximate number of bytes of heap
+** and lookaside memory used by all prepared statements associated with
+** the database connection.)^
+** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
+** </dd>
+**
+** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt>
+** <dd>This parameter returns the number of pager cache hits that have
+** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT 
+** is always 0.
+** </dd>
+**
+** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt>
+** <dd>This parameter returns the number of pager cache misses that have
+** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS 
+** is always 0.
+** </dd>
+**
+** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt>
+** <dd>This parameter returns the number of dirty cache entries that have
+** been written to disk. Specifically, the number of pages written to the
+** wal file in wal mode databases, or the number of pages written to the
+** database file in rollback mode databases. Any pages written as part of
+** transaction rollback or database recovery operations are not included.
+** If an IO or other error occurs while writing a page to disk, the effect
+** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
+** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
+** </dd>
+**
+** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt>
+** <dd>This parameter returns the number of dirty cache entries that have
+** been written to disk in the middle of a transaction due to the page
+** cache overflowing. Transactions are more efficient if they are written
+** to disk all at once. When pages spill mid-transaction, that introduces
+** additional overhead. This parameter can be used help identify
+** inefficiencies that can be resolved by increasing the cache size.
+** </dd>
+**
+** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
+** <dd>This parameter returns zero for the current value if and only if
+** all foreign key constraints (deferred or immediate) have been
+** resolved.)^  ^The highwater mark is always 0.
+** </dd>
+** </dl>
+*/
+#define SQLITE_DBSTATUS_LOOKASIDE_USED       0
+#define SQLITE_DBSTATUS_CACHE_USED           1
+#define SQLITE_DBSTATUS_SCHEMA_USED          2
+#define SQLITE_DBSTATUS_STMT_USED            3
+#define SQLITE_DBSTATUS_LOOKASIDE_HIT        4
+#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE  5
+#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL  6
+#define SQLITE_DBSTATUS_CACHE_HIT            7
+#define SQLITE_DBSTATUS_CACHE_MISS           8
+#define SQLITE_DBSTATUS_CACHE_WRITE          9
+#define SQLITE_DBSTATUS_DEFERRED_FKS        10
+#define SQLITE_DBSTATUS_CACHE_USED_SHARED   11
+#define SQLITE_DBSTATUS_CACHE_SPILL         12
+#define SQLITE_DBSTATUS_MAX                 12   /* Largest defined DBSTATUS */
+
+
+/*
+** CAPI3REF: Prepared Statement Status
+** METHOD: sqlite3_stmt
+**
+** ^(Each prepared statement maintains various
+** [SQLITE_STMTSTATUS counters] that measure the number
+** of times it has performed specific operations.)^  These counters can
+** be used to monitor the performance characteristics of the prepared
+** statements.  For example, if the number of table steps greatly exceeds
+** the number of table searches or result rows, that would tend to indicate
+** that the prepared statement is using a full table scan rather than
+** an index.  
+**
+** ^(This interface is used to retrieve and reset counter values from
+** a [prepared statement].  The first argument is the prepared statement
+** object to be interrogated.  The second argument
+** is an integer code for a specific [SQLITE_STMTSTATUS counter]
+** to be interrogated.)^
+** ^The current value of the requested counter is returned.
+** ^If the resetFlg is true, then the counter is reset to zero after this
+** interface call returns.
+**
+** See also: [sqlite3_status()] and [sqlite3_db_status()].
+*/
+SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+
+/*
+** CAPI3REF: Status Parameters for prepared statements
+** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters}
+**
+** These preprocessor macros define integer codes that name counter
+** values associated with the [sqlite3_stmt_status()] interface.
+** The meanings of the various counters are as follows:
+**
+** <dl>
+** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]] <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
+** <dd>^This is the number of times that SQLite has stepped forward in
+** a table as part of a full table scan.  Large numbers for this counter
+** may indicate opportunities for performance improvement through 
+** careful use of indices.</dd>
+**
+** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt>
+** <dd>^This is the number of sort operations that have occurred.
+** A non-zero value in this counter may indicate an opportunity to
+** improvement performance through careful use of indices.</dd>
+**
+** [[SQLITE_STMTSTATUS_AUTOINDEX]] <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt>
+** <dd>^This is the number of rows inserted into transient indices that
+** were created automatically in order to help joins run faster.
+** A non-zero value in this counter may indicate an opportunity to
+** improvement performance by adding permanent indices that do not
+** need to be reinitialized each time the statement is run.</dd>
+**
+** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt>
+** <dd>^This is the number of virtual machine operations executed
+** by the prepared statement if that number is less than or equal
+** to 2147483647.  The number of virtual machine operations can be 
+** used as a proxy for the total work done by the prepared statement.
+** If the number of virtual machine operations exceeds 2147483647
+** then the value returned by this statement status code is undefined.
+**
+** [[SQLITE_STMTSTATUS_REPREPARE]] <dt>SQLITE_STMTSTATUS_REPREPARE</dt>
+** <dd>^This is the number of times that the prepare statement has been
+** automatically regenerated due to schema changes or changes to 
+** [bound parameters] that might affect the query plan.
+**
+** [[SQLITE_STMTSTATUS_RUN]] <dt>SQLITE_STMTSTATUS_RUN</dt>
+** <dd>^This is the number of times that the prepared statement has
+** been run.  A single "run" for the purposes of this counter is one
+** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
+** The counter is incremented on the first [sqlite3_step()] call of each
+** cycle.
+**
+** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
+** <dd>^This is the approximate number of bytes of heap memory
+** used to store the prepared statement.  ^This value is not actually
+** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
+** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
+** </dd>
+** </dl>
+*/
+#define SQLITE_STMTSTATUS_FULLSCAN_STEP     1
+#define SQLITE_STMTSTATUS_SORT              2
+#define SQLITE_STMTSTATUS_AUTOINDEX         3
+#define SQLITE_STMTSTATUS_VM_STEP           4
+#define SQLITE_STMTSTATUS_REPREPARE         5
+#define SQLITE_STMTSTATUS_RUN               6
+#define SQLITE_STMTSTATUS_MEMUSED           99
+
+/*
+** CAPI3REF: Custom Page Cache Object
+**
+** The sqlite3_pcache type is opaque.  It is implemented by
+** the pluggable module.  The SQLite core has no knowledge of
+** its size or internal structure and never deals with the
+** sqlite3_pcache object except by holding and passing pointers
+** to the object.
+**
+** See [sqlite3_pcache_methods2] for additional information.
+*/
+typedef struct sqlite3_pcache sqlite3_pcache;
+
+/*
+** CAPI3REF: Custom Page Cache Object
+**
+** The sqlite3_pcache_page object represents a single page in the
+** page cache.  The page cache will allocate instances of this
+** object.  Various methods of the page cache use pointers to instances
+** of this object as parameters or as their return value.
+**
+** See [sqlite3_pcache_methods2] for additional information.
+*/
+typedef struct sqlite3_pcache_page sqlite3_pcache_page;
+struct sqlite3_pcache_page {
+  void *pBuf;        /* The content of the page */
+  void *pExtra;      /* Extra information associated with the page */
+};
+
+/*
+** CAPI3REF: Application Defined Page Cache.
+** KEYWORDS: {page cache}
+**
+** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can
+** register an alternative page cache implementation by passing in an 
+** instance of the sqlite3_pcache_methods2 structure.)^
+** In many applications, most of the heap memory allocated by 
+** SQLite is used for the page cache.
+** By implementing a 
+** custom page cache using this API, an application can better control
+** the amount of memory consumed by SQLite, the way in which 
+** that memory is allocated and released, and the policies used to 
+** determine exactly which parts of a database file are cached and for 
+** how long.
+**
+** The alternative page cache mechanism is an
+** extreme measure that is only needed by the most demanding applications.
+** The built-in page cache is recommended for most uses.
+**
+** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an
+** internal buffer by SQLite within the call to [sqlite3_config].  Hence
+** the application may discard the parameter after the call to
+** [sqlite3_config()] returns.)^
+**
+** [[the xInit() page cache method]]
+** ^(The xInit() method is called once for each effective 
+** call to [sqlite3_initialize()])^
+** (usually only once during the lifetime of the process). ^(The xInit()
+** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^
+** The intent of the xInit() method is to set up global data structures 
+** required by the custom page cache implementation. 
+** ^(If the xInit() method is NULL, then the 
+** built-in default page cache is used instead of the application defined
+** page cache.)^
+**
+** [[the xShutdown() page cache method]]
+** ^The xShutdown() method is called by [sqlite3_shutdown()].
+** It can be used to clean up 
+** any outstanding resources before process shutdown, if required.
+** ^The xShutdown() method may be NULL.
+**
+** ^SQLite automatically serializes calls to the xInit method,
+** so the xInit method need not be threadsafe.  ^The
+** xShutdown method is only called from [sqlite3_shutdown()] so it does
+** not need to be threadsafe either.  All other methods must be threadsafe
+** in multithreaded applications.
+**
+** ^SQLite will never invoke xInit() more than once without an intervening
+** call to xShutdown().
+**
+** [[the xCreate() page cache methods]]
+** ^SQLite invokes the xCreate() method to construct a new cache instance.
+** SQLite will typically create one cache instance for each open database file,
+** though this is not guaranteed. ^The
+** first parameter, szPage, is the size in bytes of the pages that must
+** be allocated by the cache.  ^szPage will always a power of two.  ^The
+** second parameter szExtra is a number of bytes of extra storage 
+** associated with each page cache entry.  ^The szExtra parameter will
+** a number less than 250.  SQLite will use the
+** extra szExtra bytes on each page to store metadata about the underlying
+** database page on disk.  The value passed into szExtra depends
+** on the SQLite version, the target platform, and how SQLite was compiled.
+** ^The third argument to xCreate(), bPurgeable, is true if the cache being
+** created will be used to cache database pages of a file stored on disk, or
+** false if it is used for an in-memory database. The cache implementation
+** does not have to do anything special based with the value of bPurgeable;
+** it is purely advisory.  ^On a cache where bPurgeable is false, SQLite will
+** never invoke xUnpin() except to deliberately delete a page.
+** ^In other words, calls to xUnpin() on a cache with bPurgeable set to
+** false will always have the "discard" flag set to true.  
+** ^Hence, a cache created with bPurgeable false will
+** never contain any unpinned pages.
+**
+** [[the xCachesize() page cache method]]
+** ^(The xCachesize() method may be called at any time by SQLite to set the
+** suggested maximum cache-size (number of pages stored by) the cache
+** instance passed as the first argument. This is the value configured using
+** the SQLite "[PRAGMA cache_size]" command.)^  As with the bPurgeable
+** parameter, the implementation is not required to do anything with this
+** value; it is advisory only.
+**
+** [[the xPagecount() page cache methods]]
+** The xPagecount() method must return the number of pages currently
+** stored in the cache, both pinned and unpinned.
+** 
+** [[the xFetch() page cache methods]]
+** The xFetch() method locates a page in the cache and returns a pointer to 
+** an sqlite3_pcache_page object associated with that page, or a NULL pointer.
+** The pBuf element of the returned sqlite3_pcache_page object will be a
+** pointer to a buffer of szPage bytes used to store the content of a 
+** single database page.  The pExtra element of sqlite3_pcache_page will be
+** a pointer to the szExtra bytes of extra storage that SQLite has requested
+** for each entry in the page cache.
+**
+** The page to be fetched is determined by the key. ^The minimum key value
+** is 1.  After it has been retrieved using xFetch, the page is considered
+** to be "pinned".
+**
+** If the requested page is already in the page cache, then the page cache
+** implementation must return a pointer to the page buffer with its content
+** intact.  If the requested page is not already in the cache, then the
+** cache implementation should use the value of the createFlag
+** parameter to help it determined what action to take:
+**
+** <table border=1 width=85% align=center>
+** <tr><th> createFlag <th> Behavior when page is not already in cache
+** <tr><td> 0 <td> Do not allocate a new page.  Return NULL.
+** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
+**                 Otherwise return NULL.
+** <tr><td> 2 <td> Make every effort to allocate a new page.  Only return
+**                 NULL if allocating a new page is effectively impossible.
+** </table>
+**
+** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  SQLite
+** will only use a createFlag of 2 after a prior call with a createFlag of 1
+** failed.)^  In between the xFetch() calls, SQLite may
+** attempt to unpin one or more cache pages by spilling the content of
+** pinned pages to disk and synching the operating system disk cache.
+**
+** [[the xUnpin() page cache method]]
+** ^xUnpin() is called by SQLite with a pointer to a currently pinned page
+** as its second argument.  If the third parameter, discard, is non-zero,
+** then the page must be evicted from the cache.
+** ^If the discard parameter is
+** zero, then the page may be discarded or retained at the discretion of
+** page cache implementation. ^The page cache implementation
+** may choose to evict unpinned pages at any time.
+**
+** The cache must not perform any reference counting. A single 
+** call to xUnpin() unpins the page regardless of the number of prior calls 
+** to xFetch().
+**
+** [[the xRekey() page cache methods]]
+** The xRekey() method is used to change the key value associated with the
+** page passed as the second argument. If the cache
+** previously contains an entry associated with newKey, it must be
+** discarded. ^Any prior cache entry associated with newKey is guaranteed not
+** to be pinned.
+**
+** When SQLite calls the xTruncate() method, the cache must discard all
+** existing cache entries with page numbers (keys) greater than or equal
+** to the value of the iLimit parameter passed to xTruncate(). If any
+** of these pages are pinned, they are implicitly unpinned, meaning that
+** they can be safely discarded.
+**
+** [[the xDestroy() page cache method]]
+** ^The xDestroy() method is used to delete a cache allocated by xCreate().
+** All resources associated with the specified cache should be freed. ^After
+** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*]
+** handle invalid, and will not use it with any other sqlite3_pcache_methods2
+** functions.
+**
+** [[the xShrink() page cache method]]
+** ^SQLite invokes the xShrink() method when it wants the page cache to
+** free up as much of heap memory as possible.  The page cache implementation
+** is not obligated to free any memory, but well-behaved implementations should
+** do their best.
+*/
+typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2;
+struct sqlite3_pcache_methods2 {
+  int iVersion;
+  void *pArg;
+  int (*xInit)(void*);
+  void (*xShutdown)(void*);
+  sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable);
+  void (*xCachesize)(sqlite3_pcache*, int nCachesize);
+  int (*xPagecount)(sqlite3_pcache*);
+  sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
+  void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard);
+  void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, 
+      unsigned oldKey, unsigned newKey);
+  void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
+  void (*xDestroy)(sqlite3_pcache*);
+  void (*xShrink)(sqlite3_pcache*);
+};
+
+/*
+** This is the obsolete pcache_methods object that has now been replaced
+** by sqlite3_pcache_methods2.  This object is not used by SQLite.  It is
+** retained in the header file for backwards compatibility only.
+*/
+typedef struct sqlite3_pcache_methods sqlite3_pcache_methods;
+struct sqlite3_pcache_methods {
+  void *pArg;
+  int (*xInit)(void*);
+  void (*xShutdown)(void*);
+  sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable);
+  void (*xCachesize)(sqlite3_pcache*, int nCachesize);
+  int (*xPagecount)(sqlite3_pcache*);
+  void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
+  void (*xUnpin)(sqlite3_pcache*, void*, int discard);
+  void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey);
+  void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
+  void (*xDestroy)(sqlite3_pcache*);
+};
+
+
+/*
+** CAPI3REF: Online Backup Object
+**
+** The sqlite3_backup object records state information about an ongoing
+** online backup operation.  ^The sqlite3_backup object is created by
+** a call to [sqlite3_backup_init()] and is destroyed by a call to
+** [sqlite3_backup_finish()].
+**
+** See Also: [Using the SQLite Online Backup API]
+*/
+typedef struct sqlite3_backup sqlite3_backup;
+
+/*
+** CAPI3REF: Online Backup API.
+**
+** The backup API copies the content of one database into another.
+** It is useful either for creating backups of databases or
+** for copying in-memory databases to or from persistent files. 
+**
+** See Also: [Using the SQLite Online Backup API]
+**
+** ^SQLite holds a write transaction open on the destination database file
+** for the duration of the backup operation.
+** ^The source database is read-locked only while it is being read;
+** it is not locked continuously for the entire backup operation.
+** ^Thus, the backup may be performed on a live source database without
+** preventing other database connections from
+** reading or writing to the source database while the backup is underway.
+** 
+** ^(To perform a backup operation: 
+**   <ol>
+**     <li><b>sqlite3_backup_init()</b> is called once to initialize the
+**         backup, 
+**     <li><b>sqlite3_backup_step()</b> is called one or more times to transfer 
+**         the data between the two databases, and finally
+**     <li><b>sqlite3_backup_finish()</b> is called to release all resources 
+**         associated with the backup operation. 
+**   </ol>)^
+** There should be exactly one call to sqlite3_backup_finish() for each
+** successful call to sqlite3_backup_init().
+**
+** [[sqlite3_backup_init()]] <b>sqlite3_backup_init()</b>
+**
+** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the 
+** [database connection] associated with the destination database 
+** and the database name, respectively.
+** ^The database name is "main" for the main database, "temp" for the
+** temporary database, or the name specified after the AS keyword in
+** an [ATTACH] statement for an attached database.
+** ^The S and M arguments passed to 
+** sqlite3_backup_init(D,N,S,M) identify the [database connection]
+** and database name of the source database, respectively.
+** ^The source and destination [database connections] (parameters S and D)
+** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
+** an error.
+**
+** ^A call to sqlite3_backup_init() will fail, returning NULL, if 
+** there is already a read or read-write transaction open on the 
+** destination database.
+**
+** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
+** returned and an error code and error message are stored in the
+** destination [database connection] D.
+** ^The error code and message for the failed call to sqlite3_backup_init()
+** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
+** [sqlite3_errmsg16()] functions.
+** ^A successful call to sqlite3_backup_init() returns a pointer to an
+** [sqlite3_backup] object.
+** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and
+** sqlite3_backup_finish() functions to perform the specified backup 
+** operation.
+**
+** [[sqlite3_backup_step()]] <b>sqlite3_backup_step()</b>
+**
+** ^Function sqlite3_backup_step(B,N) will copy up to N pages between 
+** the source and destination databases specified by [sqlite3_backup] object B.
+** ^If N is negative, all remaining source pages are copied. 
+** ^If sqlite3_backup_step(B,N) successfully copies N pages and there
+** are still more pages to be copied, then the function returns [SQLITE_OK].
+** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages
+** from source to destination, then it returns [SQLITE_DONE].
+** ^If an error occurs while running sqlite3_backup_step(B,N),
+** then an [error code] is returned. ^As well as [SQLITE_OK] and
+** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY],
+** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
+** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
+**
+** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if
+** <ol>
+** <li> the destination database was opened read-only, or
+** <li> the destination database is using write-ahead-log journaling
+** and the destination and source page sizes differ, or
+** <li> the destination database is an in-memory database and the
+** destination and source page sizes differ.
+** </ol>)^
+**
+** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then
+** the [sqlite3_busy_handler | busy-handler function]
+** is invoked (if one is specified). ^If the 
+** busy-handler returns non-zero before the lock is available, then 
+** [SQLITE_BUSY] is returned to the caller. ^In this case the call to
+** sqlite3_backup_step() can be retried later. ^If the source
+** [database connection]
+** is being used to write to the source database when sqlite3_backup_step()
+** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this
+** case the call to sqlite3_backup_step() can be retried later on. ^(If
+** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or
+** [SQLITE_READONLY] is returned, then 
+** there is no point in retrying the call to sqlite3_backup_step(). These 
+** errors are considered fatal.)^  The application must accept 
+** that the backup operation has failed and pass the backup operation handle 
+** to the sqlite3_backup_finish() to release associated resources.
+**
+** ^The first call to sqlite3_backup_step() obtains an exclusive lock
+** on the destination file. ^The exclusive lock is not released until either 
+** sqlite3_backup_finish() is called or the backup operation is complete 
+** and sqlite3_backup_step() returns [SQLITE_DONE].  ^Every call to
+** sqlite3_backup_step() obtains a [shared lock] on the source database that
+** lasts for the duration of the sqlite3_backup_step() call.
+** ^Because the source database is not locked between calls to
+** sqlite3_backup_step(), the source database may be modified mid-way
+** through the backup process.  ^If the source database is modified by an
+** external process or via a database connection other than the one being
+** used by the backup operation, then the backup will be automatically
+** restarted by the next call to sqlite3_backup_step(). ^If the source 
+** database is modified by the using the same database connection as is used
+** by the backup operation, then the backup database is automatically
+** updated at the same time.
+**
+** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b>
+**
+** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the 
+** application wishes to abandon the backup operation, the application
+** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish().
+** ^The sqlite3_backup_finish() interfaces releases all
+** resources associated with the [sqlite3_backup] object. 
+** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any
+** active write-transaction on the destination database is rolled back.
+** The [sqlite3_backup] object is invalid
+** and may not be used following a call to sqlite3_backup_finish().
+**
+** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no
+** sqlite3_backup_step() errors occurred, regardless or whether or not
+** sqlite3_backup_step() completed.
+** ^If an out-of-memory condition or IO error occurred during any prior
+** sqlite3_backup_step() call on the same [sqlite3_backup] object, then
+** sqlite3_backup_finish() returns the corresponding [error code].
+**
+** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step()
+** is not a permanent error and does not affect the return value of
+** sqlite3_backup_finish().
+**
+** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]]
+** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
+**
+** ^The sqlite3_backup_remaining() routine returns the number of pages still
+** to be backed up at the conclusion of the most recent sqlite3_backup_step().
+** ^The sqlite3_backup_pagecount() routine returns the total number of pages
+** in the source database at the conclusion of the most recent
+** sqlite3_backup_step().
+** ^(The values returned by these functions are only updated by
+** sqlite3_backup_step(). If the source database is modified in a way that
+** changes the size of the source database or the number of pages remaining,
+** those changes are not reflected in the output of sqlite3_backup_pagecount()
+** and sqlite3_backup_remaining() until after the next
+** sqlite3_backup_step().)^
+**
+** <b>Concurrent Usage of Database Handles</b>
+**
+** ^The source [database connection] may be used by the application for other
+** purposes while a backup operation is underway or being initialized.
+** ^If SQLite is compiled and configured to support threadsafe database
+** connections, then the source database connection may be used concurrently
+** from within other threads.
+**
+** However, the application must guarantee that the destination 
+** [database connection] is not passed to any other API (by any thread) after 
+** sqlite3_backup_init() is called and before the corresponding call to
+** sqlite3_backup_finish().  SQLite does not currently check to see
+** if the application incorrectly accesses the destination [database connection]
+** and so no error code is reported, but the operations may malfunction
+** nevertheless.  Use of the destination database connection while a
+** backup is in progress might also also cause a mutex deadlock.
+**
+** If running in [shared cache mode], the application must
+** guarantee that the shared cache used by the destination database
+** is not accessed while the backup is running. In practice this means
+** that the application must guarantee that the disk file being 
+** backed up to is not accessed by any connection within the process,
+** not just the specific connection that was passed to sqlite3_backup_init().
+**
+** The [sqlite3_backup] object itself is partially threadsafe. Multiple 
+** threads may safely make multiple concurrent calls to sqlite3_backup_step().
+** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount()
+** APIs are not strictly speaking threadsafe. If they are invoked at the
+** same time as another thread is invoking sqlite3_backup_step() it is
+** possible that they return invalid values.
+*/
+SQLITE_API sqlite3_backup *sqlite3_backup_init(
+  sqlite3 *pDest,                        /* Destination database handle */
+  const char *zDestName,                 /* Destination database name */
+  sqlite3 *pSource,                      /* Source database handle */
+  const char *zSourceName                /* Source database name */
+);
+SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
+SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
+
+/*
+** CAPI3REF: Unlock Notification
+** METHOD: sqlite3
+**
+** ^When running in shared-cache mode, a database operation may fail with
+** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
+** individual tables within the shared-cache cannot be obtained. See
+** [SQLite Shared-Cache Mode] for a description of shared-cache locking. 
+** ^This API may be used to register a callback that SQLite will invoke 
+** when the connection currently holding the required lock relinquishes it.
+** ^This API is only available if the library was compiled with the
+** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined.
+**
+** See Also: [Using the SQLite Unlock Notification Feature].
+**
+** ^Shared-cache locks are released when a database connection concludes
+** its current transaction, either by committing it or rolling it back. 
+**
+** ^When a connection (known as the blocked connection) fails to obtain a
+** shared-cache lock and SQLITE_LOCKED is returned to the caller, the
+** identity of the database connection (the blocking connection) that
+** has locked the required resource is stored internally. ^After an 
+** application receives an SQLITE_LOCKED error, it may call the
+** sqlite3_unlock_notify() method with the blocked connection handle as 
+** the first argument to register for a callback that will be invoked
+** when the blocking connections current transaction is concluded. ^The
+** callback is invoked from within the [sqlite3_step] or [sqlite3_close]
+** call that concludes the blocking connection's transaction.
+**
+** ^(If sqlite3_unlock_notify() is called in a multi-threaded application,
+** there is a chance that the blocking connection will have already
+** concluded its transaction by the time sqlite3_unlock_notify() is invoked.
+** If this happens, then the specified callback is invoked immediately,
+** from within the call to sqlite3_unlock_notify().)^
+**
+** ^If the blocked connection is attempting to obtain a write-lock on a
+** shared-cache table, and more than one other connection currently holds
+** a read-lock on the same table, then SQLite arbitrarily selects one of 
+** the other connections to use as the blocking connection.
+**
+** ^(There may be at most one unlock-notify callback registered by a 
+** blocked connection. If sqlite3_unlock_notify() is called when the
+** blocked connection already has a registered unlock-notify callback,
+** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is
+** called with a NULL pointer as its second argument, then any existing
+** unlock-notify callback is canceled. ^The blocked connections 
+** unlock-notify callback may also be canceled by closing the blocked
+** connection using [sqlite3_close()].
+**
+** The unlock-notify callback is not reentrant. If an application invokes
+** any sqlite3_xxx API functions from within an unlock-notify callback, a
+** crash or deadlock may be the result.
+**
+** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always
+** returns SQLITE_OK.
+**
+** <b>Callback Invocation Details</b>
+**
+** When an unlock-notify callback is registered, the application provides a 
+** single void* pointer that is passed to the callback when it is invoked.
+** However, the signature of the callback function allows SQLite to pass
+** it an array of void* context pointers. The first argument passed to
+** an unlock-notify callback is a pointer to an array of void* pointers,
+** and the second is the number of entries in the array.
+**
+** When a blocking connection's transaction is concluded, there may be
+** more than one blocked connection that has registered for an unlock-notify
+** callback. ^If two or more such blocked connections have specified the
+** same callback function, then instead of invoking the callback function
+** multiple times, it is invoked once with the set of void* context pointers
+** specified by the blocked connections bundled together into an array.
+** This gives the application an opportunity to prioritize any actions 
+** related to the set of unblocked database connections.
+**
+** <b>Deadlock Detection</b>
+**
+** Assuming that after registering for an unlock-notify callback a 
+** database waits for the callback to be issued before taking any further
+** action (a reasonable assumption), then using this API may cause the
+** application to deadlock. For example, if connection X is waiting for
+** connection Y's transaction to be concluded, and similarly connection
+** Y is waiting on connection X's transaction, then neither connection
+** will proceed and the system may remain deadlocked indefinitely.
+**
+** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock
+** detection. ^If a given call to sqlite3_unlock_notify() would put the
+** system in a deadlocked state, then SQLITE_LOCKED is returned and no
+** unlock-notify callback is registered. The system is said to be in
+** a deadlocked state if connection A has registered for an unlock-notify
+** callback on the conclusion of connection B's transaction, and connection
+** B has itself registered for an unlock-notify callback when connection
+** A's transaction is concluded. ^Indirect deadlock is also detected, so
+** the system is also considered to be deadlocked if connection B has
+** registered for an unlock-notify callback on the conclusion of connection
+** C's transaction, where connection C is waiting on connection A. ^Any
+** number of levels of indirection are allowed.
+**
+** <b>The "DROP TABLE" Exception</b>
+**
+** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost 
+** always appropriate to call sqlite3_unlock_notify(). There is however,
+** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement,
+** SQLite checks if there are any currently executing SELECT statements
+** that belong to the same connection. If there are, SQLITE_LOCKED is
+** returned. In this case there is no "blocking connection", so invoking
+** sqlite3_unlock_notify() results in the unlock-notify callback being
+** invoked immediately. If the application then re-attempts the "DROP TABLE"
+** or "DROP INDEX" query, an infinite loop might be the result.
+**
+** One way around this problem is to check the extended error code returned
+** by an sqlite3_step() call. ^(If there is a blocking connection, then the
+** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in
+** the special "DROP TABLE/INDEX" case, the extended error code is just 
+** SQLITE_LOCKED.)^
+*/
+SQLITE_API int sqlite3_unlock_notify(
+  sqlite3 *pBlocked,                          /* Waiting connection */
+  void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
+  void *pNotifyArg                            /* Argument to pass to xNotify */
+);
+
+
+/*
+** CAPI3REF: String Comparison
+**
+** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications
+** and extensions to compare the contents of two buffers containing UTF-8
+** strings in a case-independent fashion, using the same definition of "case
+** independence" that SQLite uses internally when comparing identifiers.
+*/
+SQLITE_API int sqlite3_stricmp(const char *, const char *);
+SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
+
+/*
+** CAPI3REF: String Globbing
+*
+** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
+** string X matches the [GLOB] pattern P.
+** ^The definition of [GLOB] pattern matching used in
+** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
+** SQL dialect understood by SQLite.  ^The [sqlite3_strglob(P,X)] function
+** is case sensitive.
+**
+** Note that this routine returns zero on a match and non-zero if the strings
+** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
+**
+** See also: [sqlite3_strlike()].
+*/
+SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
+
+/*
+** CAPI3REF: String LIKE Matching
+*
+** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
+** string X matches the [LIKE] pattern P with escape character E.
+** ^The definition of [LIKE] pattern matching used in
+** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
+** operator in the SQL dialect understood by SQLite.  ^For "X LIKE P" without
+** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
+** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
+** insensitive - equivalent upper and lower case ASCII characters match
+** one another.
+**
+** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
+** only ASCII characters are case folded.
+**
+** Note that this routine returns zero on a match and non-zero if the strings
+** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
+**
+** See also: [sqlite3_strglob()].
+*/
+SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
+
+/*
+** CAPI3REF: Error Logging Interface
+**
+** ^The [sqlite3_log()] interface writes a message into the [error log]
+** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()].
+** ^If logging is enabled, the zFormat string and subsequent arguments are
+** used with [sqlite3_snprintf()] to generate the final output string.
+**
+** The sqlite3_log() interface is intended for use by extensions such as
+** virtual tables, collating functions, and SQL functions.  While there is
+** nothing to prevent an application from calling sqlite3_log(), doing so
+** is considered bad form.
+**
+** The zFormat string must not be NULL.
+**
+** To avoid deadlocks and other threading problems, the sqlite3_log() routine
+** will not use dynamically allocated memory.  The log message is stored in
+** a fixed-length buffer on the stack.  If the log message is longer than
+** a few hundred characters, it will be truncated to the length of the
+** buffer.
+*/
+SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
+
+/*
+** CAPI3REF: Write-Ahead Log Commit Hook
+** METHOD: sqlite3
+**
+** ^The [sqlite3_wal_hook()] function is used to register a callback that
+** is invoked each time data is committed to a database in wal mode.
+**
+** ^(The callback is invoked by SQLite after the commit has taken place and 
+** the associated write-lock on the database released)^, so the implementation 
+** may read, write or [checkpoint] the database as required.
+**
+** ^The first parameter passed to the callback function when it is invoked
+** is a copy of the third parameter passed to sqlite3_wal_hook() when
+** registering the callback. ^The second is a copy of the database handle.
+** ^The third parameter is the name of the database that was written to -
+** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
+** is the number of pages currently in the write-ahead log file,
+** including those that were just committed.
+**
+** The callback function should normally return [SQLITE_OK].  ^If an error
+** code is returned, that error will propagate back up through the
+** SQLite code base to cause the statement that provoked the callback
+** to report an error, though the commit will have still occurred. If the
+** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
+** that does not correspond to any valid SQLite error code, the results
+** are undefined.
+**
+** A single database handle may have at most a single write-ahead log callback 
+** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any
+** previously registered write-ahead log callback. ^Note that the
+** [sqlite3_wal_autocheckpoint()] interface and the
+** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
+** overwrite any prior [sqlite3_wal_hook()] settings.
+*/
+SQLITE_API void *sqlite3_wal_hook(
+  sqlite3*, 
+  int(*)(void *,sqlite3*,const char*,int),
+  void*
+);
+
+/*
+** CAPI3REF: Configure an auto-checkpoint
+** METHOD: sqlite3
+**
+** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
+** [sqlite3_wal_hook()] that causes any database on [database connection] D
+** to automatically [checkpoint]
+** after committing a transaction if there are N or
+** more frames in the [write-ahead log] file.  ^Passing zero or 
+** a negative value as the nFrame parameter disables automatic
+** checkpoints entirely.
+**
+** ^The callback registered by this function replaces any existing callback
+** registered using [sqlite3_wal_hook()].  ^Likewise, registering a callback
+** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
+** configured by this function.
+**
+** ^The [wal_autocheckpoint pragma] can be used to invoke this interface
+** from SQL.
+**
+** ^Checkpoints initiated by this mechanism are
+** [sqlite3_wal_checkpoint_v2|PASSIVE].
+**
+** ^Every new [database connection] defaults to having the auto-checkpoint
+** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
+** pages.  The use of this interface
+** is only necessary if the default setting is found to be suboptimal
+** for a particular application.
+*/
+SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
+
+/*
+** CAPI3REF: Checkpoint a database
+** METHOD: sqlite3
+**
+** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
+** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
+**
+** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the 
+** [write-ahead log] for database X on [database connection] D to be
+** transferred into the database file and for the write-ahead log to
+** be reset.  See the [checkpointing] documentation for addition
+** information.
+**
+** This interface used to be the only way to cause a checkpoint to
+** occur.  But then the newer and more powerful [sqlite3_wal_checkpoint_v2()]
+** interface was added.  This interface is retained for backwards
+** compatibility and as a convenience for applications that need to manually
+** start a callback but which do not need the full power (and corresponding
+** complication) of [sqlite3_wal_checkpoint_v2()].
+*/
+SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+
+/*
+** CAPI3REF: Checkpoint a database
+** METHOD: sqlite3
+**
+** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
+** operation on database X of [database connection] D in mode M.  Status
+** information is written back into integers pointed to by L and C.)^
+** ^(The M parameter must be a valid [checkpoint mode]:)^
+**
+** <dl>
+** <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
+**   ^Checkpoint as many frames as possible without waiting for any database 
+**   readers or writers to finish, then sync the database file if all frames 
+**   in the log were checkpointed. ^The [busy-handler callback]
+**   is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode.  
+**   ^On the other hand, passive mode might leave the checkpoint unfinished
+**   if there are concurrent readers or writers.
+**
+** <dt>SQLITE_CHECKPOINT_FULL<dd>
+**   ^This mode blocks (it invokes the
+**   [sqlite3_busy_handler|busy-handler callback]) until there is no
+**   database writer and all readers are reading from the most recent database
+**   snapshot. ^It then checkpoints all frames in the log file and syncs the
+**   database file. ^This mode blocks new database writers while it is pending,
+**   but new database readers are allowed to continue unimpeded.
+**
+** <dt>SQLITE_CHECKPOINT_RESTART<dd>
+**   ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition
+**   that after checkpointing the log file it blocks (calls the 
+**   [busy-handler callback])
+**   until all readers are reading from the database file only. ^This ensures 
+**   that the next writer will restart the log file from the beginning.
+**   ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new
+**   database writer attempts while it is pending, but does not impede readers.
+**
+** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
+**   ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
+**   addition that it also truncates the log file to zero bytes just prior
+**   to a successful return.
+** </dl>
+**
+** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
+** the log file or to -1 if the checkpoint could not run because
+** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
+** NULL,then *pnCkpt is set to the total number of checkpointed frames in the
+** log file (including any that were already checkpointed before the function
+** was called) or to -1 if the checkpoint could not run due to an error or
+** because the database is not in WAL mode. ^Note that upon successful
+** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been
+** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero.
+**
+** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If
+** any other process is running a checkpoint operation at the same time, the 
+** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a 
+** busy-handler configured, it will not be invoked in this case.
+**
+** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the 
+** exclusive "writer" lock on the database file. ^If the writer lock cannot be
+** obtained immediately, and a busy-handler is configured, it is invoked and
+** the writer lock retried until either the busy-handler returns 0 or the lock
+** is successfully obtained. ^The busy-handler is also invoked while waiting for
+** database readers as described above. ^If the busy-handler returns 0 before
+** the writer lock is obtained or while waiting for database readers, the
+** checkpoint operation proceeds from that point in the same way as 
+** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible 
+** without blocking any further. ^SQLITE_BUSY is returned in this case.
+**
+** ^If parameter zDb is NULL or points to a zero length string, then the
+** specified operation is attempted on all WAL databases [attached] to 
+** [database connection] db.  In this case the
+** values written to output parameters *pnLog and *pnCkpt are undefined. ^If 
+** an SQLITE_BUSY error is encountered when processing one or more of the 
+** attached WAL databases, the operation is still attempted on any remaining 
+** attached databases and SQLITE_BUSY is returned at the end. ^If any other 
+** error occurs while processing an attached database, processing is abandoned 
+** and the error code is returned to the caller immediately. ^If no error 
+** (SQLITE_BUSY or otherwise) is encountered while processing the attached 
+** databases, SQLITE_OK is returned.
+**
+** ^If database zDb is the name of an attached database that is not in WAL
+** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If
+** zDb is not NULL (or a zero length string) and is not the name of any
+** attached database, SQLITE_ERROR is returned to the caller.
+**
+** ^Unless it returns SQLITE_MISUSE,
+** the sqlite3_wal_checkpoint_v2() interface
+** sets the error information that is queried by
+** [sqlite3_errcode()] and [sqlite3_errmsg()].
+**
+** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
+** from SQL.
+*/
+SQLITE_API int sqlite3_wal_checkpoint_v2(
+  sqlite3 *db,                    /* Database handle */
+  const char *zDb,                /* Name of attached database (or NULL) */
+  int eMode,                      /* SQLITE_CHECKPOINT_* value */
+  int *pnLog,                     /* OUT: Size of WAL log in frames */
+  int *pnCkpt                     /* OUT: Total number of frames checkpointed */
+);
+
+/*
+** CAPI3REF: Checkpoint Mode Values
+** KEYWORDS: {checkpoint mode}
+**
+** These constants define all valid values for the "checkpoint mode" passed
+** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
+** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
+** meaning of each of these checkpoint modes.
+*/
+#define SQLITE_CHECKPOINT_PASSIVE  0  /* Do as much as possible w/o blocking */
+#define SQLITE_CHECKPOINT_FULL     1  /* Wait for writers, then checkpoint */
+#define SQLITE_CHECKPOINT_RESTART  2  /* Like FULL but wait for for readers */
+#define SQLITE_CHECKPOINT_TRUNCATE 3  /* Like RESTART but also truncate WAL */
+
+/*
+** CAPI3REF: Virtual Table Interface Configuration
+**
+** This function may be called by either the [xConnect] or [xCreate] method
+** of a [virtual table] implementation to configure
+** various facets of the virtual table interface.
+**
+** If this interface is invoked outside the context of an xConnect or
+** xCreate virtual table method then the behavior is undefined.
+**
+** In the call sqlite3_vtab_config(D,C,...) the D parameter is the
+** [database connection] in which the virtual table is being created and
+** which is passed in as the first argument to the [xConnect] or [xCreate]
+** method that is invoking sqlite3_vtab_config().  The C parameter is one
+** of the [virtual table configuration options].  The presence and meaning
+** of parameters after C depend on which [virtual table configuration option]
+** is used.
+*/
+SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
+
+/*
+** CAPI3REF: Virtual Table Configuration Options
+** KEYWORDS: {virtual table configuration options} 
+** KEYWORDS: {virtual table configuration option}
+**
+** These macros define the various options to the
+** [sqlite3_vtab_config()] interface that [virtual table] implementations
+** can use to customize and optimize their behavior.
+**
+** <dl>
+** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
+** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT</dt>
+** <dd>Calls of the form
+** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
+** where X is an integer.  If X is zero, then the [virtual table] whose
+** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
+** support constraints.  In this configuration (which is the default) if
+** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire
+** statement is rolled back as if [ON CONFLICT | OR ABORT] had been
+** specified as part of the users SQL statement, regardless of the actual
+** ON CONFLICT mode specified.
+**
+** If X is non-zero, then the virtual table implementation guarantees
+** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before
+** any modifications to internal or persistent data structures have been made.
+** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite 
+** is able to roll back a statement or database transaction, and abandon
+** or continue processing the current SQL statement as appropriate. 
+** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns
+** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode
+** had been ABORT.
+**
+** Virtual table implementations that are required to handle OR REPLACE
+** must do so within the [xUpdate] method. If a call to the 
+** [sqlite3_vtab_on_conflict()] function indicates that the current ON 
+** CONFLICT policy is REPLACE, the virtual table implementation should 
+** silently replace the appropriate rows within the xUpdate callback and
+** return SQLITE_OK. Or, if this is not possible, it may return
+** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT 
+** constraint handling.
+** </dd>
+**
+** [[SQLITE_VTAB_DIRECTONLY]]<dt>SQLITE_VTAB_DIRECTONLY</dt>
+** <dd>Calls of the form
+** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the
+** the [xConnect] or [xCreate] methods of a [virtual table] implmentation
+** prohibits that virtual table from being used from within triggers and
+** views.
+** </dd>
+**
+** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt>
+** <dd>Calls of the form
+** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the
+** the [xConnect] or [xCreate] methods of a [virtual table] implmentation
+** identify that virtual table as being safe to use from within triggers
+** and views.  Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the
+** virtual table can do no serious harm even if it is controlled by a
+** malicious hacker.  Developers should avoid setting the SQLITE_VTAB_INNOCUOUS
+** flag unless absolutely necessary.
+** </dd>
+** </dl>
+*/
+#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1
+#define SQLITE_VTAB_INNOCUOUS          2
+#define SQLITE_VTAB_DIRECTONLY         3
+
+/*
+** CAPI3REF: Determine The Virtual Table Conflict Policy
+**
+** This function may only be called from within a call to the [xUpdate] method
+** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The
+** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL],
+** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode
+** of the SQL statement that triggered the call to the [xUpdate] method of the
+** [virtual table].
+*/
+SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
+
+/*
+** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
+**
+** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
+** method of a [virtual table], then it returns true if and only if the
+** column is being fetched as part of an UPDATE operation during which the
+** column value will not change.  Applications might use this to substitute
+** a return value that is less expensive to compute and that the corresponding
+** [xUpdate] method understands as a "no-change" value.
+**
+** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
+** the column is not changed by the UPDATE statement, then the xColumn
+** method can optionally return without setting a result, without calling
+** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
+** In that case, [sqlite3_value_nochange(X)] will return true for the
+** same column in the [xUpdate] method.
+*/
+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
+
+/*
+** CAPI3REF: Determine The Collation For a Virtual Table Constraint
+**
+** This function may only be called from within a call to the [xBestIndex]
+** method of a [virtual table]. 
+**
+** The first argument must be the sqlite3_index_info object that is the
+** first parameter to the xBestIndex() method. The second argument must be
+** an index into the aConstraint[] array belonging to the sqlite3_index_info
+** structure passed to xBestIndex. This function returns a pointer to a buffer 
+** containing the name of the collation sequence for the corresponding
+** constraint.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
+
+/*
+** CAPI3REF: Conflict resolution modes
+** KEYWORDS: {conflict resolution mode}
+**
+** These constants are returned by [sqlite3_vtab_on_conflict()] to
+** inform a [virtual table] implementation what the [ON CONFLICT] mode
+** is for the SQL statement being evaluated.
+**
+** Note that the [SQLITE_IGNORE] constant is also used as a potential
+** return value from the [sqlite3_set_authorizer()] callback and that
+** [SQLITE_ABORT] is also a [result code].
+*/
+#define SQLITE_ROLLBACK 1
+/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
+#define SQLITE_FAIL     3
+/* #define SQLITE_ABORT 4  // Also an error code */
+#define SQLITE_REPLACE  5
+
+/*
+** CAPI3REF: Prepared Statement Scan Status Opcodes
+** KEYWORDS: {scanstatus options}
+**
+** The following constants can be used for the T parameter to the
+** [sqlite3_stmt_scanstatus(S,X,T,V)] interface.  Each constant designates a
+** different metric for sqlite3_stmt_scanstatus() to return.
+**
+** When the value returned to V is a string, space to hold that string is
+** managed by the prepared statement S and will be automatically freed when
+** S is finalized.
+**
+** <dl>
+** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
+** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be
+** set to the total number of times that the X-th loop has run.</dd>
+**
+** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
+** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be set
+** to the total number of rows examined by all iterations of the X-th loop.</dd>
+**
+** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
+** <dd>^The "double" variable pointed to by the V parameter will be set to the
+** query planner's estimate for the average number of rows output from each
+** iteration of the X-th loop.  If the query planner's estimates was accurate,
+** then this value will approximate the quotient NVISIT/NLOOP and the
+** product of this value for all prior loops with the same SELECTID will
+** be the NLOOP value for the current loop.
+**
+** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
+** <dd>^The "const char *" variable pointed to by the V parameter will be set
+** to a zero-terminated UTF-8 string containing the name of the index or table
+** used for the X-th loop.
+**
+** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
+** <dd>^The "const char *" variable pointed to by the V parameter will be set
+** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
+** description for the X-th loop.
+**
+** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
+** <dd>^The "int" variable pointed to by the V parameter will be set to the
+** "select-id" for the X-th loop.  The select-id identifies which query or
+** subquery the loop is part of.  The main query has a select-id of zero.
+** The select-id is the same value as is output in the first column
+** of an [EXPLAIN QUERY PLAN] query.
+** </dl>
+*/
+#define SQLITE_SCANSTAT_NLOOP    0
+#define SQLITE_SCANSTAT_NVISIT   1
+#define SQLITE_SCANSTAT_EST      2
+#define SQLITE_SCANSTAT_NAME     3
+#define SQLITE_SCANSTAT_EXPLAIN  4
+#define SQLITE_SCANSTAT_SELECTID 5
+
+/*
+** CAPI3REF: Prepared Statement Scan Status
+** METHOD: sqlite3_stmt
+**
+** This interface returns information about the predicted and measured
+** performance for pStmt.  Advanced applications can use this
+** interface to compare the predicted and the measured performance and
+** issue warnings and/or rerun [ANALYZE] if discrepancies are found.
+**
+** Since this interface is expected to be rarely used, it is only
+** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS]
+** compile-time option.
+**
+** The "iScanStatusOp" parameter determines which status information to return.
+** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
+** of this interface is undefined.
+** ^The requested measurement is written into a variable pointed to by
+** the "pOut" parameter.
+** Parameter "idx" identifies the specific loop to retrieve statistics for.
+** Loops are numbered starting from zero. ^If idx is out of range - less than
+** zero or greater than or equal to the total number of loops used to implement
+** the statement - a non-zero value is returned and the variable that pOut
+** points to is unchanged.
+**
+** ^Statistics might not be available for all loops in all statements. ^In cases
+** where there exist loops with no available statistics, this function behaves
+** as if the loop did not exist - it returns non-zero and leave the variable
+** that pOut points to unchanged.
+**
+** See also: [sqlite3_stmt_scanstatus_reset()]
+*/
+SQLITE_API int sqlite3_stmt_scanstatus(
+  sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
+  int idx,                  /* Index of loop to report on */
+  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
+  void *pOut                /* Result written here */
+);     
+
+/*
+** CAPI3REF: Zero Scan-Status Counters
+** METHOD: sqlite3_stmt
+**
+** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
+**
+** This API is only available if the library is built with pre-processor
+** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
+*/
+SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
+
+/*
+** CAPI3REF: Flush caches to disk mid-transaction
+**
+** ^If a write-transaction is open on [database connection] D when the
+** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
+** pages in the pager-cache that are not currently in use are written out 
+** to disk. A dirty page may be in use if a database cursor created by an
+** active SQL statement is reading from it, or if it is page 1 of a database
+** file (page 1 is always "in use").  ^The [sqlite3_db_cacheflush(D)]
+** interface flushes caches for all schemas - "main", "temp", and
+** any [attached] databases.
+**
+** ^If this function needs to obtain extra database locks before dirty pages 
+** can be flushed to disk, it does so. ^If those locks cannot be obtained 
+** immediately and there is a busy-handler callback configured, it is invoked
+** in the usual manner. ^If the required lock still cannot be obtained, then
+** the database is skipped and an attempt made to flush any dirty pages
+** belonging to the next (if any) database. ^If any databases are skipped
+** because locks cannot be obtained, but no other error occurs, this
+** function returns SQLITE_BUSY.
+**
+** ^If any other error occurs while flushing dirty pages to disk (for
+** example an IO error or out-of-memory condition), then processing is
+** abandoned and an SQLite [error code] is returned to the caller immediately.
+**
+** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
+**
+** ^This function does not set the database handle error code or message
+** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
+*/
+SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
+
+/*
+** CAPI3REF: The pre-update hook.
+**
+** ^These interfaces are only available if SQLite is compiled using the
+** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
+**
+** ^The [sqlite3_preupdate_hook()] interface registers a callback function
+** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
+** on a database table.
+** ^At most one preupdate hook may be registered at a time on a single
+** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
+** the previous setting.
+** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()]
+** with a NULL pointer as the second parameter.
+** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
+** the first parameter to callbacks.
+**
+** ^The preupdate hook only fires for changes to real database tables; the
+** preupdate hook is not invoked for changes to [virtual tables] or to
+** system tables like sqlite_master or sqlite_stat1.
+**
+** ^The second parameter to the preupdate callback is a pointer to
+** the [database connection] that registered the preupdate hook.
+** ^The third parameter to the preupdate callback is one of the constants
+** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the
+** kind of update operation that is about to occur.
+** ^(The fourth parameter to the preupdate callback is the name of the
+** database within the database connection that is being modified.  This
+** will be "main" for the main database or "temp" for TEMP tables or 
+** the name given after the AS keyword in the [ATTACH] statement for attached
+** databases.)^
+** ^The fifth parameter to the preupdate callback is the name of the
+** table that is being modified.
+**
+** For an UPDATE or DELETE operation on a [rowid table], the sixth
+** parameter passed to the preupdate callback is the initial [rowid] of the 
+** row being modified or deleted. For an INSERT operation on a rowid table,
+** or any operation on a WITHOUT ROWID table, the value of the sixth 
+** parameter is undefined. For an INSERT or UPDATE on a rowid table the
+** seventh parameter is the final rowid value of the row being inserted
+** or updated. The value of the seventh parameter passed to the callback
+** function is not defined for operations on WITHOUT ROWID tables, or for
+** INSERT operations on rowid tables.
+**
+** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
+** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
+** provide additional information about a preupdate event. These routines
+** may only be called from within a preupdate callback.  Invoking any of
+** these routines from outside of a preupdate callback or with a
+** [database connection] pointer that is different from the one supplied
+** to the preupdate callback results in undefined and probably undesirable
+** behavior.
+**
+** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns
+** in the row that is being inserted, updated, or deleted.
+**
+** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to
+** a [protected sqlite3_value] that contains the value of the Nth column of
+** the table row before it is updated.  The N parameter must be between 0
+** and one less than the number of columns or the behavior will be
+** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE
+** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the
+** behavior is undefined.  The [sqlite3_value] that P points to
+** will be destroyed when the preupdate callback returns.
+**
+** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to
+** a [protected sqlite3_value] that contains the value of the Nth column of
+** the table row after it is updated.  The N parameter must be between 0
+** and one less than the number of columns or the behavior will be
+** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE
+** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the
+** behavior is undefined.  The [sqlite3_value] that P points to
+** will be destroyed when the preupdate callback returns.
+**
+** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate
+** callback was invoked as a result of a direct insert, update, or delete
+** operation; or 1 for inserts, updates, or deletes invoked by top-level 
+** triggers; or 2 for changes resulting from triggers called by top-level
+** triggers; and so forth.
+**
+** See also:  [sqlite3_update_hook()]
+*/
+#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+SQLITE_API void *sqlite3_preupdate_hook(
+  sqlite3 *db,
+  void(*xPreUpdate)(
+    void *pCtx,                   /* Copy of third arg to preupdate_hook() */
+    sqlite3 *db,                  /* Database handle */
+    int op,                       /* SQLITE_UPDATE, DELETE or INSERT */
+    char const *zDb,              /* Database name */
+    char const *zName,            /* Table name */
+    sqlite3_int64 iKey1,          /* Rowid of row about to be deleted/updated */
+    sqlite3_int64 iKey2           /* New rowid value (for a rowid UPDATE) */
+  ),
+  void*
+);
+SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
+SQLITE_API int sqlite3_preupdate_count(sqlite3 *);
+SQLITE_API int sqlite3_preupdate_depth(sqlite3 *);
+SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
+#endif
+
+/*
+** CAPI3REF: Low-level system error code
+**
+** ^Attempt to return the underlying operating system error code or error
+** number that caused the most recent I/O error or failure to open a file.
+** The return value is OS-dependent.  For example, on unix systems, after
+** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be
+** called to get back the underlying "errno" that caused the problem, such
+** as ENOSPC, EAUTH, EISDIR, and so forth.  
+*/
+SQLITE_API int sqlite3_system_errno(sqlite3*);
+
+/*
+** CAPI3REF: Database Snapshot
+** KEYWORDS: {snapshot} {sqlite3_snapshot}
+**
+** An instance of the snapshot object records the state of a [WAL mode]
+** database for some specific point in history.
+**
+** In [WAL mode], multiple [database connections] that are open on the
+** same database file can each be reading a different historical version
+** of the database file.  When a [database connection] begins a read
+** transaction, that connection sees an unchanging copy of the database
+** as it existed for the point in time when the transaction first started.
+** Subsequent changes to the database from other connections are not seen
+** by the reader until a new read transaction is started.
+**
+** The sqlite3_snapshot object records state information about an historical
+** version of the database file so that it is possible to later open a new read
+** transaction that sees that historical version of the database rather than
+** the most recent version.
+*/
+typedef struct sqlite3_snapshot {
+  unsigned char hidden[48];
+} sqlite3_snapshot;
+
+/*
+** CAPI3REF: Record A Database Snapshot
+** CONSTRUCTOR: sqlite3_snapshot
+**
+** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
+** new [sqlite3_snapshot] object that records the current state of
+** schema S in database connection D.  ^On success, the
+** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
+** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
+** If there is not already a read-transaction open on schema S when
+** this function is called, one is opened automatically. 
+**
+** The following must be true for this function to succeed. If any of
+** the following statements are false when sqlite3_snapshot_get() is
+** called, SQLITE_ERROR is returned. The final value of *P is undefined
+** in this case. 
+**
+** <ul>
+**   <li> The database handle must not be in [autocommit mode].
+**
+**   <li> Schema S of [database connection] D must be a [WAL mode] database.
+**
+**   <li> There must not be a write transaction open on schema S of database
+**        connection D.
+**
+**   <li> One or more transactions must have been written to the current wal
+**        file since it was created on disk (by any connection). This means
+**        that a snapshot cannot be taken on a wal mode database with no wal 
+**        file immediately after it is first opened. At least one transaction
+**        must be written to it first.
+** </ul>
+**
+** This function may also return SQLITE_NOMEM.  If it is called with the
+** database handle in autocommit mode but fails for some other reason, 
+** whether or not a read transaction is opened on schema S is undefined.
+**
+** The [sqlite3_snapshot] object returned from a successful call to
+** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
+** to avoid a memory leak.
+**
+** The [sqlite3_snapshot_get()] interface is only available when the
+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
+  sqlite3 *db,
+  const char *zSchema,
+  sqlite3_snapshot **ppSnapshot
+);
+
+/*
+** CAPI3REF: Start a read transaction on an historical snapshot
+** METHOD: sqlite3_snapshot
+**
+** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read 
+** transaction or upgrades an existing one for schema S of 
+** [database connection] D such that the read transaction refers to 
+** historical [snapshot] P, rather than the most recent change to the 
+** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK 
+** on success or an appropriate [error code] if it fails.
+**
+** ^In order to succeed, the database connection must not be in 
+** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
+** is already a read transaction open on schema S, then the database handle
+** must have no active statements (SELECT statements that have been passed
+** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). 
+** SQLITE_ERROR is returned if either of these conditions is violated, or
+** if schema S does not exist, or if the snapshot object is invalid.
+**
+** ^A call to sqlite3_snapshot_open() will fail to open if the specified
+** snapshot has been overwritten by a [checkpoint]. In this case 
+** SQLITE_ERROR_SNAPSHOT is returned.
+**
+** If there is already a read transaction open when this function is 
+** invoked, then the same read transaction remains open (on the same
+** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT
+** is returned. If another error code - for example SQLITE_PROTOCOL or an
+** SQLITE_IOERR error code - is returned, then the final state of the
+** read transaction is undefined. If SQLITE_OK is returned, then the 
+** read transaction is now open on database snapshot P.
+**
+** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
+** database connection D does not know that the database file for
+** schema S is in [WAL mode].  A database connection might not know
+** that the database file is in [WAL mode] if there has been no prior
+** I/O on that database connection, or if the database entered [WAL mode] 
+** after the most recent I/O on the database connection.)^
+** (Hint: Run "[PRAGMA application_id]" against a newly opened
+** database connection in order to make it ready to use snapshots.)
+**
+** The [sqlite3_snapshot_open()] interface is only available when the
+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
+  sqlite3 *db,
+  const char *zSchema,
+  sqlite3_snapshot *pSnapshot
+);
+
+/*
+** CAPI3REF: Destroy a snapshot
+** DESTRUCTOR: sqlite3_snapshot
+**
+** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
+** The application must eventually free every [sqlite3_snapshot] object
+** using this routine to avoid a memory leak.
+**
+** The [sqlite3_snapshot_free()] interface is only available when the
+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
+
+/*
+** CAPI3REF: Compare the ages of two snapshot handles.
+** METHOD: sqlite3_snapshot
+**
+** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
+** of two valid snapshot handles. 
+**
+** If the two snapshot handles are not associated with the same database 
+** file, the result of the comparison is undefined. 
+**
+** Additionally, the result of the comparison is only valid if both of the
+** snapshot handles were obtained by calling sqlite3_snapshot_get() since the
+** last time the wal file was deleted. The wal file is deleted when the
+** database is changed back to rollback mode or when the number of database
+** clients drops to zero. If either snapshot handle was obtained before the 
+** wal file was last deleted, the value returned by this function 
+** is undefined.
+**
+** Otherwise, this API returns a negative value if P1 refers to an older
+** snapshot than P2, zero if the two handles refer to the same database
+** snapshot, and a positive value if P1 is a newer snapshot than P2.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_SNAPSHOT] option.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
+  sqlite3_snapshot *p1,
+  sqlite3_snapshot *p2
+);
+
+/*
+** CAPI3REF: Recover snapshots from a wal file
+** METHOD: sqlite3_snapshot
+**
+** If a [WAL file] remains on disk after all database connections close
+** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
+** or because the last process to have the database opened exited without
+** calling [sqlite3_close()]) and a new connection is subsequently opened
+** on that database and [WAL file], the [sqlite3_snapshot_open()] interface
+** will only be able to open the last transaction added to the WAL file
+** even though the WAL file contains other valid transactions.
+**
+** This function attempts to scan the WAL file associated with database zDb
+** of database handle db and make all valid snapshots available to
+** sqlite3_snapshot_open(). It is an error if there is already a read
+** transaction open on the database, or if the database is not a WAL mode
+** database.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_SNAPSHOT] option.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
+
+/*
+** CAPI3REF: Serialize a database
+**
+** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
+** that is a serialization of the S database on [database connection] D.
+** If P is not a NULL pointer, then the size of the database in bytes
+** is written into *P.
+**
+** For an ordinary on-disk database file, the serialization is just a
+** copy of the disk file.  For an in-memory database or a "TEMP" database,
+** the serialization is the same sequence of bytes which would be written
+** to disk if that database where backed up to disk.
+**
+** The usual case is that sqlite3_serialize() copies the serialization of
+** the database into memory obtained from [sqlite3_malloc64()] and returns
+** a pointer to that memory.  The caller is responsible for freeing the
+** returned value to avoid a memory leak.  However, if the F argument
+** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations
+** are made, and the sqlite3_serialize() function will return a pointer
+** to the contiguous memory representation of the database that SQLite
+** is currently using for that database, or NULL if the no such contiguous
+** memory representation of the database exists.  A contiguous memory
+** representation of the database will usually only exist if there has
+** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
+** values of D and S.
+** The size of the database is written into *P even if the 
+** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy
+** of the database exists.
+**
+** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
+** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
+** allocation error occurs.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_DESERIALIZE] option.
+*/
+SQLITE_API unsigned char *sqlite3_serialize(
+  sqlite3 *db,           /* The database connection */
+  const char *zSchema,   /* Which DB to serialize. ex: "main", "temp", ... */
+  sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */
+  unsigned int mFlags    /* Zero or more SQLITE_SERIALIZE_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3_serialize
+**
+** Zero or more of the following constants can be OR-ed together for
+** the F argument to [sqlite3_serialize(D,S,P,F)].
+**
+** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return
+** a pointer to contiguous in-memory database that it is currently using,
+** without making a copy of the database.  If SQLite is not currently using
+** a contiguous in-memory database, then this option causes
+** [sqlite3_serialize()] to return a NULL pointer.  SQLite will only be
+** using a contiguous in-memory database if it has been initialized by a
+** prior call to [sqlite3_deserialize()].
+*/
+#define SQLITE_SERIALIZE_NOCOPY 0x001   /* Do no memory allocations */
+
+/*
+** CAPI3REF: Deserialize a database
+**
+** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the 
+** [database connection] D to disconnect from database S and then
+** reopen S as an in-memory database based on the serialization contained
+** in P.  The serialized database P is N bytes in size.  M is the size of
+** the buffer P, which might be larger than N.  If M is larger than N, and
+** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
+** permitted to add content to the in-memory database as long as the total
+** size does not exceed M bytes.
+**
+** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
+** invoke sqlite3_free() on the serialization buffer when the database
+** connection closes.  If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
+** SQLite will try to increase the buffer size using sqlite3_realloc64()
+** if writes on the database cause it to grow larger than M bytes.
+**
+** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
+** database is currently in a read transaction or is involved in a backup
+** operation.
+**
+** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the 
+** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
+** [sqlite3_free()] is invoked on argument P prior to returning.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_DESERIALIZE] option.
+*/
+SQLITE_API int sqlite3_deserialize(
+  sqlite3 *db,            /* The database connection */
+  const char *zSchema,    /* Which DB to reopen with the deserialization */
+  unsigned char *pData,   /* The serialized database content */
+  sqlite3_int64 szDb,     /* Number bytes in the deserialization */
+  sqlite3_int64 szBuf,    /* Total size of buffer pData[] */
+  unsigned mFlags         /* Zero or more SQLITE_DESERIALIZE_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3_deserialize()
+**
+** The following are allowed values for 6th argument (the F argument) to
+** the [sqlite3_deserialize(D,S,P,N,M,F)] interface.
+**
+** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization
+** in the P argument is held in memory obtained from [sqlite3_malloc64()]
+** and that SQLite should take ownership of this memory and automatically
+** free it when it has finished using it.  Without this flag, the caller
+** is responsible for freeing any dynamically allocated memory.
+**
+** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
+** grow the size of the database using calls to [sqlite3_realloc64()].  This
+** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used.
+** Without this flag, the deserialized database cannot increase in size beyond
+** the number of bytes specified by the M parameter.
+**
+** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database
+** should be treated as read-only.
+*/
+#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */
+#define SQLITE_DESERIALIZE_RESIZEABLE  2 /* Resize using sqlite3_realloc64() */
+#define SQLITE_DESERIALIZE_READONLY    4 /* Database is read-only */
+
+/*
+** Undo the hack that converts floating point types to integer for
+** builds on processors without floating point support.
+*/
+#ifdef SQLITE_OMIT_FLOATING_POINT
+# undef double
+#endif
+
+#ifdef __cplusplus
+}  /* End of the 'extern "C"' block */
+#endif
+#endif /* SQLITE3_H */
+
+/******** Begin file sqlite3rtree.h *********/
+/*
+** 2010 August 30
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+*/
+
+#ifndef _SQLITE3RTREE_H_
+#define _SQLITE3RTREE_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
+typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
+
+/* The double-precision datatype used by RTree depends on the
+** SQLITE_RTREE_INT_ONLY compile-time option.
+*/
+#ifdef SQLITE_RTREE_INT_ONLY
+  typedef sqlite3_int64 sqlite3_rtree_dbl;
+#else
+  typedef double sqlite3_rtree_dbl;
+#endif
+
+/*
+** Register a geometry callback named zGeom that can be used as part of an
+** R-Tree geometry query as follows:
+**
+**   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
+*/
+SQLITE_API int sqlite3_rtree_geometry_callback(
+  sqlite3 *db,
+  const char *zGeom,
+  int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
+  void *pContext
+);
+
+
+/*
+** A pointer to a structure of the following type is passed as the first
+** argument to callbacks registered using rtree_geometry_callback().
+*/
+struct sqlite3_rtree_geometry {
+  void *pContext;                 /* Copy of pContext passed to s_r_g_c() */
+  int nParam;                     /* Size of array aParam[] */
+  sqlite3_rtree_dbl *aParam;      /* Parameters passed to SQL geom function */
+  void *pUser;                    /* Callback implementation user data */
+  void (*xDelUser)(void *);       /* Called by SQLite to clean up pUser */
+};
+
+/*
+** Register a 2nd-generation geometry callback named zScore that can be 
+** used as part of an R-Tree geometry query as follows:
+**
+**   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
+*/
+SQLITE_API int sqlite3_rtree_query_callback(
+  sqlite3 *db,
+  const char *zQueryFunc,
+  int (*xQueryFunc)(sqlite3_rtree_query_info*),
+  void *pContext,
+  void (*xDestructor)(void*)
+);
+
+
+/*
+** A pointer to a structure of the following type is passed as the 
+** argument to scored geometry callback registered using
+** sqlite3_rtree_query_callback().
+**
+** Note that the first 5 fields of this structure are identical to
+** sqlite3_rtree_geometry.  This structure is a subclass of
+** sqlite3_rtree_geometry.
+*/
+struct sqlite3_rtree_query_info {
+  void *pContext;                   /* pContext from when function registered */
+  int nParam;                       /* Number of function parameters */
+  sqlite3_rtree_dbl *aParam;        /* value of function parameters */
+  void *pUser;                      /* callback can use this, if desired */
+  void (*xDelUser)(void*);          /* function to free pUser */
+  sqlite3_rtree_dbl *aCoord;        /* Coordinates of node or entry to check */
+  unsigned int *anQueue;            /* Number of pending entries in the queue */
+  int nCoord;                       /* Number of coordinates */
+  int iLevel;                       /* Level of current node or entry */
+  int mxLevel;                      /* The largest iLevel value in the tree */
+  sqlite3_int64 iRowid;             /* Rowid for current entry */
+  sqlite3_rtree_dbl rParentScore;   /* Score of parent node */
+  int eParentWithin;                /* Visibility of parent node */
+  int eWithin;                      /* OUT: Visibility */
+  sqlite3_rtree_dbl rScore;         /* OUT: Write the score here */
+  /* The following fields are only available in 3.8.11 and later */
+  sqlite3_value **apSqlParam;       /* Original SQL values of parameters */
+};
+
+/*
+** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
+*/
+#define NOT_WITHIN       0   /* Object completely outside of query region */
+#define PARTLY_WITHIN    1   /* Object partially overlaps query region */
+#define FULLY_WITHIN     2   /* Object fully contained within query region */
+
+
+#ifdef __cplusplus
+}  /* end of the 'extern "C"' block */
+#endif
+
+#endif  /* ifndef _SQLITE3RTREE_H_ */
+
+/******** End of sqlite3rtree.h *********/
+/******** Begin file sqlite3session.h *********/
+
+#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION)
+#define __SQLITESESSION_H_ 1
+
+/*
+** Make sure we can call this stuff from C++.
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+** CAPI3REF: Session Object Handle
+**
+** An instance of this object is a [session] that can be used to
+** record changes to a database.
+*/
+typedef struct sqlite3_session sqlite3_session;
+
+/*
+** CAPI3REF: Changeset Iterator Handle
+**
+** An instance of this object acts as a cursor for iterating
+** over the elements of a [changeset] or [patchset].
+*/
+typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
+
+/*
+** CAPI3REF: Create A New Session Object
+** CONSTRUCTOR: sqlite3_session
+**
+** Create a new session object attached to database handle db. If successful,
+** a pointer to the new object is written to *ppSession and SQLITE_OK is
+** returned. If an error occurs, *ppSession is set to NULL and an SQLite
+** error code (e.g. SQLITE_NOMEM) is returned.
+**
+** It is possible to create multiple session objects attached to a single
+** database handle.
+**
+** Session objects created using this function should be deleted using the
+** [sqlite3session_delete()] function before the database handle that they
+** are attached to is itself closed. If the database handle is closed before
+** the session object is deleted, then the results of calling any session
+** module function, including [sqlite3session_delete()] on the session object
+** are undefined.
+**
+** Because the session module uses the [sqlite3_preupdate_hook()] API, it
+** is not possible for an application to register a pre-update hook on a
+** database handle that has one or more session objects attached. Nor is
+** it possible to create a session object attached to a database handle for
+** which a pre-update hook is already defined. The results of attempting 
+** either of these things are undefined.
+**
+** The session object will be used to create changesets for tables in
+** database zDb, where zDb is either "main", or "temp", or the name of an
+** attached database. It is not an error if database zDb is not attached
+** to the database when the session object is created.
+*/
+SQLITE_API int sqlite3session_create(
+  sqlite3 *db,                    /* Database handle */
+  const char *zDb,                /* Name of db (e.g. "main") */
+  sqlite3_session **ppSession     /* OUT: New session object */
+);
+
+/*
+** CAPI3REF: Delete A Session Object
+** DESTRUCTOR: sqlite3_session
+**
+** Delete a session object previously allocated using 
+** [sqlite3session_create()]. Once a session object has been deleted, the
+** results of attempting to use pSession with any other session module
+** function are undefined.
+**
+** Session objects must be deleted before the database handle to which they
+** are attached is closed. Refer to the documentation for 
+** [sqlite3session_create()] for details.
+*/
+SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
+
+
+/*
+** CAPI3REF: Enable Or Disable A Session Object
+** METHOD: sqlite3_session
+**
+** Enable or disable the recording of changes by a session object. When
+** enabled, a session object records changes made to the database. When
+** disabled - it does not. A newly created session object is enabled.
+** Refer to the documentation for [sqlite3session_changeset()] for further
+** details regarding how enabling and disabling a session object affects
+** the eventual changesets.
+**
+** Passing zero to this function disables the session. Passing a value
+** greater than zero enables it. Passing a value less than zero is a 
+** no-op, and may be used to query the current state of the session.
+**
+** The return value indicates the final state of the session object: 0 if 
+** the session is disabled, or 1 if it is enabled.
+*/
+SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
+
+/*
+** CAPI3REF: Set Or Clear the Indirect Change Flag
+** METHOD: sqlite3_session
+**
+** Each change recorded by a session object is marked as either direct or
+** indirect. A change is marked as indirect if either:
+**
+** <ul>
+**   <li> The session object "indirect" flag is set when the change is
+**        made, or
+**   <li> The change is made by an SQL trigger or foreign key action 
+**        instead of directly as a result of a users SQL statement.
+** </ul>
+**
+** If a single row is affected by more than one operation within a session,
+** then the change is considered indirect if all operations meet the criteria
+** for an indirect change above, or direct otherwise.
+**
+** This function is used to set, clear or query the session object indirect
+** flag.  If the second argument passed to this function is zero, then the
+** indirect flag is cleared. If it is greater than zero, the indirect flag
+** is set. Passing a value less than zero does not modify the current value
+** of the indirect flag, and may be used to query the current state of the 
+** indirect flag for the specified session object.
+**
+** The return value indicates the final state of the indirect flag: 0 if 
+** it is clear, or 1 if it is set.
+*/
+SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
+
+/*
+** CAPI3REF: Attach A Table To A Session Object
+** METHOD: sqlite3_session
+**
+** If argument zTab is not NULL, then it is the name of a table to attach
+** to the session object passed as the first argument. All subsequent changes 
+** made to the table while the session object is enabled will be recorded. See 
+** documentation for [sqlite3session_changeset()] for further details.
+**
+** Or, if argument zTab is NULL, then changes are recorded for all tables
+** in the database. If additional tables are added to the database (by 
+** executing "CREATE TABLE" statements) after this call is made, changes for 
+** the new tables are also recorded.
+**
+** Changes can only be recorded for tables that have a PRIMARY KEY explicitly
+** defined as part of their CREATE TABLE statement. It does not matter if the 
+** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY
+** KEY may consist of a single column, or may be a composite key.
+** 
+** It is not an error if the named table does not exist in the database. Nor
+** is it an error if the named table does not have a PRIMARY KEY. However,
+** no changes will be recorded in either of these scenarios.
+**
+** Changes are not recorded for individual rows that have NULL values stored
+** in one or more of their PRIMARY KEY columns.
+**
+** SQLITE_OK is returned if the call completes without error. Or, if an error 
+** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
+**
+** <h3>Special sqlite_stat1 Handling</h3>
+**
+** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to 
+** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
+**  <pre>
+**  &nbsp;     CREATE TABLE sqlite_stat1(tbl,idx,stat)  
+**  </pre>
+**
+** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are 
+** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes 
+** are recorded for rows for which (idx IS NULL) is true. However, for such
+** rows a zero-length blob (SQL value X'') is stored in the changeset or
+** patchset instead of a NULL value. This allows such changesets to be
+** manipulated by legacy implementations of sqlite3changeset_invert(),
+** concat() and similar.
+**
+** The sqlite3changeset_apply() function automatically converts the 
+** zero-length blob back to a NULL value when updating the sqlite_stat1
+** table. However, if the application calls sqlite3changeset_new(),
+** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset 
+** iterator directly (including on a changeset iterator passed to a
+** conflict-handler callback) then the X'' value is returned. The application
+** must translate X'' to NULL itself if required.
+**
+** Legacy (older than 3.22.0) versions of the sessions module cannot capture
+** changes made to the sqlite_stat1 table. Legacy versions of the
+** sqlite3changeset_apply() function silently ignore any modifications to the
+** sqlite_stat1 table that are part of a changeset or patchset.
+*/
+SQLITE_API int sqlite3session_attach(
+  sqlite3_session *pSession,      /* Session object */
+  const char *zTab                /* Table name */
+);
+
+/*
+** CAPI3REF: Set a table filter on a Session Object.
+** METHOD: sqlite3_session
+**
+** The second argument (xFilter) is the "filter callback". For changes to rows 
+** in tables that are not attached to the Session object, the filter is called
+** to determine whether changes to the table's rows should be tracked or not. 
+** If xFilter returns 0, changes are not tracked. Note that once a table is 
+** attached, xFilter will not be called again.
+*/
+SQLITE_API void sqlite3session_table_filter(
+  sqlite3_session *pSession,      /* Session object */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of third arg to _filter_table() */
+    const char *zTab              /* Table name */
+  ),
+  void *pCtx                      /* First argument passed to xFilter */
+);
+
+/*
+** CAPI3REF: Generate A Changeset From A Session Object
+** METHOD: sqlite3_session
+**
+** Obtain a changeset containing changes to the tables attached to the 
+** session object passed as the first argument. If successful, 
+** set *ppChangeset to point to a buffer containing the changeset 
+** and *pnChangeset to the size of the changeset in bytes before returning
+** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to
+** zero and return an SQLite error code.
+**
+** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes,
+** each representing a change to a single row of an attached table. An INSERT
+** change contains the values of each field of a new database row. A DELETE
+** contains the original values of each field of a deleted database row. An
+** UPDATE change contains the original values of each field of an updated
+** database row along with the updated values for each updated non-primary-key
+** column. It is not possible for an UPDATE change to represent a change that
+** modifies the values of primary key columns. If such a change is made, it
+** is represented in a changeset as a DELETE followed by an INSERT.
+**
+** Changes are not recorded for rows that have NULL values stored in one or 
+** more of their PRIMARY KEY columns. If such a row is inserted or deleted,
+** no corresponding change is present in the changesets returned by this
+** function. If an existing row with one or more NULL values stored in
+** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL,
+** only an INSERT is appears in the changeset. Similarly, if an existing row
+** with non-NULL PRIMARY KEY values is updated so that one or more of its
+** PRIMARY KEY columns are set to NULL, the resulting changeset contains a
+** DELETE change only.
+**
+** The contents of a changeset may be traversed using an iterator created
+** using the [sqlite3changeset_start()] API. A changeset may be applied to
+** a database with a compatible schema using the [sqlite3changeset_apply()]
+** API.
+**
+** Within a changeset generated by this function, all changes related to a
+** single table are grouped together. In other words, when iterating through
+** a changeset or when applying a changeset to a database, all changes related
+** to a single table are processed before moving on to the next table. Tables
+** are sorted in the same order in which they were attached (or auto-attached)
+** to the sqlite3_session object. The order in which the changes related to
+** a single table are stored is undefined.
+**
+** Following a successful call to this function, it is the responsibility of
+** the caller to eventually free the buffer that *ppChangeset points to using
+** [sqlite3_free()].
+**
+** <h3>Changeset Generation</h3>
+**
+** Once a table has been attached to a session object, the session object
+** records the primary key values of all new rows inserted into the table.
+** It also records the original primary key and other column values of any
+** deleted or updated rows. For each unique primary key value, data is only
+** recorded once - the first time a row with said primary key is inserted,
+** updated or deleted in the lifetime of the session.
+**
+** There is one exception to the previous paragraph: when a row is inserted,
+** updated or deleted, if one or more of its primary key columns contain a
+** NULL value, no record of the change is made.
+**
+** The session object therefore accumulates two types of records - those
+** that consist of primary key values only (created when the user inserts
+** a new record) and those that consist of the primary key values and the
+** original values of other table columns (created when the users deletes
+** or updates a record).
+**
+** When this function is called, the requested changeset is created using
+** both the accumulated records and the current contents of the database
+** file. Specifically:
+**
+** <ul>
+**   <li> For each record generated by an insert, the database is queried
+**        for a row with a matching primary key. If one is found, an INSERT
+**        change is added to the changeset. If no such row is found, no change 
+**        is added to the changeset.
+**
+**   <li> For each record generated by an update or delete, the database is 
+**        queried for a row with a matching primary key. If such a row is
+**        found and one or more of the non-primary key fields have been
+**        modified from their original values, an UPDATE change is added to 
+**        the changeset. Or, if no such row is found in the table, a DELETE 
+**        change is added to the changeset. If there is a row with a matching
+**        primary key in the database, but all fields contain their original
+**        values, no change is added to the changeset.
+** </ul>
+**
+** This means, amongst other things, that if a row is inserted and then later
+** deleted while a session object is active, neither the insert nor the delete
+** will be present in the changeset. Or if a row is deleted and then later a 
+** row with the same primary key values inserted while a session object is
+** active, the resulting changeset will contain an UPDATE change instead of
+** a DELETE and an INSERT.
+**
+** When a session object is disabled (see the [sqlite3session_enable()] API),
+** it does not accumulate records when rows are inserted, updated or deleted.
+** This may appear to have some counter-intuitive effects if a single row
+** is written to more than once during a session. For example, if a row
+** is inserted while a session object is enabled, then later deleted while 
+** the same session object is disabled, no INSERT record will appear in the
+** changeset, even though the delete took place while the session was disabled.
+** Or, if one field of a row is updated while a session is disabled, and 
+** another field of the same row is updated while the session is enabled, the
+** resulting changeset will contain an UPDATE change that updates both fields.
+*/
+SQLITE_API int sqlite3session_changeset(
+  sqlite3_session *pSession,      /* Session object */
+  int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
+  void **ppChangeset              /* OUT: Buffer containing changeset */
+);
+
+/*
+** CAPI3REF: Load The Difference Between Tables Into A Session
+** METHOD: sqlite3_session
+**
+** If it is not already attached to the session object passed as the first
+** argument, this function attaches table zTbl in the same manner as the
+** [sqlite3session_attach()] function. If zTbl does not exist, or if it
+** does not have a primary key, this function is a no-op (but does not return
+** an error).
+**
+** Argument zFromDb must be the name of a database ("main", "temp" etc.)
+** attached to the same database handle as the session object that contains 
+** a table compatible with the table attached to the session by this function.
+** A table is considered compatible if it:
+**
+** <ul>
+**   <li> Has the same name,
+**   <li> Has the same set of columns declared in the same order, and
+**   <li> Has the same PRIMARY KEY definition.
+** </ul>
+**
+** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables
+** are compatible but do not have any PRIMARY KEY columns, it is not an error
+** but no changes are added to the session object. As with other session
+** APIs, tables without PRIMARY KEYs are simply ignored.
+**
+** This function adds a set of changes to the session object that could be
+** used to update the table in database zFrom (call this the "from-table") 
+** so that its content is the same as the table attached to the session 
+** object (call this the "to-table"). Specifically:
+**
+** <ul>
+**   <li> For each row (primary key) that exists in the to-table but not in 
+**     the from-table, an INSERT record is added to the session object.
+**
+**   <li> For each row (primary key) that exists in the to-table but not in 
+**     the from-table, a DELETE record is added to the session object.
+**
+**   <li> For each row (primary key) that exists in both tables, but features 
+**     different non-PK values in each, an UPDATE record is added to the
+**     session.  
+** </ul>
+**
+** To clarify, if this function is called and then a changeset constructed
+** using [sqlite3session_changeset()], then after applying that changeset to 
+** database zFrom the contents of the two compatible tables would be 
+** identical.
+**
+** It an error if database zFrom does not exist or does not contain the
+** required compatible table.
+**
+** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite
+** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
+** may be set to point to a buffer containing an English language error 
+** message. It is the responsibility of the caller to free this buffer using
+** sqlite3_free().
+*/
+SQLITE_API int sqlite3session_diff(
+  sqlite3_session *pSession,
+  const char *zFromDb,
+  const char *zTbl,
+  char **pzErrMsg
+);
+
+
+/*
+** CAPI3REF: Generate A Patchset From A Session Object
+** METHOD: sqlite3_session
+**
+** The differences between a patchset and a changeset are that:
+**
+** <ul>
+**   <li> DELETE records consist of the primary key fields only. The 
+**        original values of other fields are omitted.
+**   <li> The original values of any modified fields are omitted from 
+**        UPDATE records.
+** </ul>
+**
+** A patchset blob may be used with up to date versions of all 
+** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(), 
+** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly,
+** attempting to use a patchset blob with old versions of the
+** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error. 
+**
+** Because the non-primary key "old.*" fields are omitted, no 
+** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset
+** is passed to the sqlite3changeset_apply() API. Other conflict types work
+** in the same way as for changesets.
+**
+** Changes within a patchset are ordered in the same way as for changesets
+** generated by the sqlite3session_changeset() function (i.e. all changes for
+** a single table are grouped together, tables appear in the order in which
+** they were attached to the session object).
+*/
+SQLITE_API int sqlite3session_patchset(
+  sqlite3_session *pSession,      /* Session object */
+  int *pnPatchset,                /* OUT: Size of buffer at *ppPatchset */
+  void **ppPatchset               /* OUT: Buffer containing patchset */
+);
+
+/*
+** CAPI3REF: Test if a changeset has recorded any changes.
+**
+** Return non-zero if no changes to attached tables have been recorded by 
+** the session object passed as the first argument. Otherwise, if one or 
+** more changes have been recorded, return zero.
+**
+** Even if this function returns zero, it is possible that calling
+** [sqlite3session_changeset()] on the session handle may still return a
+** changeset that contains no changes. This can happen when a row in 
+** an attached table is modified and then later on the original values 
+** are restored. However, if this function returns non-zero, then it is
+** guaranteed that a call to sqlite3session_changeset() will return a 
+** changeset containing zero changes.
+*/
+SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
+
+/*
+** CAPI3REF: Create An Iterator To Traverse A Changeset 
+** CONSTRUCTOR: sqlite3_changeset_iter
+**
+** Create an iterator used to iterate through the contents of a changeset.
+** If successful, *pp is set to point to the iterator handle and SQLITE_OK
+** is returned. Otherwise, if an error occurs, *pp is set to zero and an
+** SQLite error code is returned.
+**
+** The following functions can be used to advance and query a changeset 
+** iterator created by this function:
+**
+** <ul>
+**   <li> [sqlite3changeset_next()]
+**   <li> [sqlite3changeset_op()]
+**   <li> [sqlite3changeset_new()]
+**   <li> [sqlite3changeset_old()]
+** </ul>
+**
+** It is the responsibility of the caller to eventually destroy the iterator
+** by passing it to [sqlite3changeset_finalize()]. The buffer containing the
+** changeset (pChangeset) must remain valid until after the iterator is
+** destroyed.
+**
+** Assuming the changeset blob was created by one of the
+** [sqlite3session_changeset()], [sqlite3changeset_concat()] or
+** [sqlite3changeset_invert()] functions, all changes within the changeset 
+** that apply to a single table are grouped together. This means that when 
+** an application iterates through a changeset using an iterator created by 
+** this function, all changes that relate to a single table are visited 
+** consecutively. There is no chance that the iterator will visit a change 
+** the applies to table X, then one for table Y, and then later on visit 
+** another change for table X.
+**
+** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
+** may be modified by passing a combination of
+** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
+**
+** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
+** and therefore subject to change.
+*/
+SQLITE_API int sqlite3changeset_start(
+  sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
+  int nChangeset,                 /* Size of changeset blob in bytes */
+  void *pChangeset                /* Pointer to blob containing changeset */
+);
+SQLITE_API int sqlite3changeset_start_v2(
+  sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
+  int nChangeset,                 /* Size of changeset blob in bytes */
+  void *pChangeset,               /* Pointer to blob containing changeset */
+  int flags                       /* SESSION_CHANGESETSTART_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3changeset_start_v2
+**
+** The following flags may passed via the 4th parameter to
+** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
+**
+** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
+**   Invert the changeset while iterating through it. This is equivalent to
+**   inverting a changeset using sqlite3changeset_invert() before applying it.
+**   It is an error to specify this flag with a patchset.
+*/
+#define SQLITE_CHANGESETSTART_INVERT        0x0002
+
+
+/*
+** CAPI3REF: Advance A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
+**
+** This function may only be used with iterators created by the function
+** [sqlite3changeset_start()]. If it is called on an iterator passed to
+** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
+** is returned and the call has no effect.
+**
+** Immediately after an iterator is created by sqlite3changeset_start(), it
+** does not point to any change in the changeset. Assuming the changeset
+** is not empty, the first call to this function advances the iterator to
+** point to the first change in the changeset. Each subsequent call advances
+** the iterator to point to the next change in the changeset (if any). If
+** no error occurs and the iterator points to a valid change after a call
+** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned. 
+** Otherwise, if all changes in the changeset have already been visited,
+** SQLITE_DONE is returned.
+**
+** If an error occurs, an SQLite error code is returned. Possible error 
+** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or 
+** SQLITE_NOMEM.
+*/
+SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
+
+/*
+** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this
+** is not the case, this function returns [SQLITE_MISUSE].
+**
+** If argument pzTab is not NULL, then *pzTab is set to point to a
+** nul-terminated utf-8 encoded string containing the name of the table
+** affected by the current change. The buffer remains valid until either
+** sqlite3changeset_next() is called on the iterator or until the 
+** conflict-handler function returns. If pnCol is not NULL, then *pnCol is 
+** set to the number of columns in the table affected by the change. If
+** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
+** is an indirect change, or false (0) otherwise. See the documentation for
+** [sqlite3session_indirect()] for a description of direct and indirect
+** changes. Finally, if pOp is not NULL, then *pOp is set to one of 
+** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the 
+** type of change that the iterator currently points to.
+**
+** If no error occurs, SQLITE_OK is returned. If an error does occur, an
+** SQLite error code is returned. The values of the output variables may not
+** be trusted in this case.
+*/
+SQLITE_API int sqlite3changeset_op(
+  sqlite3_changeset_iter *pIter,  /* Iterator object */
+  const char **pzTab,             /* OUT: Pointer to table name */
+  int *pnCol,                     /* OUT: Number of columns in table */
+  int *pOp,                       /* OUT: SQLITE_INSERT, DELETE or UPDATE */
+  int *pbIndirect                 /* OUT: True for an 'indirect' change */
+);
+
+/*
+** CAPI3REF: Obtain The Primary Key Definition Of A Table
+** METHOD: sqlite3_changeset_iter
+**
+** For each modified table, a changeset includes the following:
+**
+** <ul>
+**   <li> The number of columns in the table, and
+**   <li> Which of those columns make up the tables PRIMARY KEY.
+** </ul>
+**
+** This function is used to find which columns comprise the PRIMARY KEY of
+** the table modified by the change that iterator pIter currently points to.
+** If successful, *pabPK is set to point to an array of nCol entries, where
+** nCol is the number of columns in the table. Elements of *pabPK are set to
+** 0x01 if the corresponding column is part of the tables primary key, or
+** 0x00 if it is not.
+**
+** If argument pnCol is not NULL, then *pnCol is set to the number of columns
+** in the table.
+**
+** If this function is called when the iterator does not point to a valid
+** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
+** SQLITE_OK is returned and the output variables populated as described
+** above.
+*/
+SQLITE_API int sqlite3changeset_pk(
+  sqlite3_changeset_iter *pIter,  /* Iterator object */
+  unsigned char **pabPK,          /* OUT: Array of boolean - true for PK cols */
+  int *pnCol                      /* OUT: Number of entries in output array */
+);
+
+/*
+** CAPI3REF: Obtain old.* Values From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise,
+** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the vector of 
+** original row values stored as part of the UPDATE or DELETE change and
+** returns SQLITE_OK. The name of the function comes from the fact that this 
+** is similar to the "old.*" columns available to update or delete triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+SQLITE_API int sqlite3changeset_old(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Column number */
+  sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
+);
+
+/*
+** CAPI3REF: Obtain new.* Values From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
+**
+** The pIter argument passed to this function may either be an iterator
+** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+** created by [sqlite3changeset_start()]. In the latter case, the most recent
+** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. 
+** Furthermore, it may only be called if the type of change that the iterator
+** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise,
+** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the vector of 
+** new row values stored as part of the UPDATE or INSERT change and
+** returns SQLITE_OK. If the change is an UPDATE and does not include
+** a new value for the requested column, *ppValue is set to NULL and 
+** SQLITE_OK returned. The name of the function comes from the fact that 
+** this is similar to the "new.*" columns available to update or delete 
+** triggers.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+SQLITE_API int sqlite3changeset_new(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Column number */
+  sqlite3_value **ppValue         /* OUT: New value (or NULL pointer) */
+);
+
+/*
+** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
+**
+** This function should only be used with iterator objects passed to a
+** conflict-handler callback by [sqlite3changeset_apply()] with either
+** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function
+** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue
+** is set to NULL.
+**
+** Argument iVal must be greater than or equal to 0, and less than the number
+** of columns in the table affected by the current change. Otherwise,
+** [SQLITE_RANGE] is returned and *ppValue is set to NULL.
+**
+** If successful, this function sets *ppValue to point to a protected
+** sqlite3_value object containing the iVal'th value from the 
+** "conflicting row" associated with the current conflict-handler callback
+** and returns SQLITE_OK.
+**
+** If some other error occurs (e.g. an OOM condition), an SQLite error code
+** is returned and *ppValue is set to NULL.
+*/
+SQLITE_API int sqlite3changeset_conflict(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int iVal,                       /* Column number */
+  sqlite3_value **ppValue         /* OUT: Value from conflicting row */
+);
+
+/*
+** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
+** METHOD: sqlite3_changeset_iter
+**
+** This function may only be called with an iterator passed to an
+** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
+** it sets the output variable to the total number of known foreign key
+** violations in the destination database and returns SQLITE_OK.
+**
+** In all other cases this function returns SQLITE_MISUSE.
+*/
+SQLITE_API int sqlite3changeset_fk_conflicts(
+  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
+  int *pnOut                      /* OUT: Number of FK violations */
+);
+
+
+/*
+** CAPI3REF: Finalize A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
+**
+** This function is used to finalize an iterator allocated with
+** [sqlite3changeset_start()].
+**
+** This function should only be called on iterators created using the
+** [sqlite3changeset_start()] function. If an application calls this
+** function with an iterator passed to a conflict-handler by
+** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the
+** call has no effect.
+**
+** If an error was encountered within a call to an sqlite3changeset_xxx()
+** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an 
+** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding
+** to that error is returned by this function. Otherwise, SQLITE_OK is
+** returned. This is to allow the following pattern (pseudo-code):
+**
+** <pre>
+**   sqlite3changeset_start();
+**   while( SQLITE_ROW==sqlite3changeset_next() ){
+**     // Do something with change.
+**   }
+**   rc = sqlite3changeset_finalize();
+**   if( rc!=SQLITE_OK ){
+**     // An error has occurred 
+**   }
+** </pre>
+*/
+SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
+
+/*
+** CAPI3REF: Invert A Changeset
+**
+** This function is used to "invert" a changeset object. Applying an inverted
+** changeset to a database reverses the effects of applying the uninverted
+** changeset. Specifically:
+**
+** <ul>
+**   <li> Each DELETE change is changed to an INSERT, and
+**   <li> Each INSERT change is changed to a DELETE, and
+**   <li> For each UPDATE change, the old.* and new.* values are exchanged.
+** </ul>
+**
+** This function does not change the order in which changes appear within
+** the changeset. It merely reverses the sense of each individual change.
+**
+** If successful, a pointer to a buffer containing the inverted changeset
+** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and
+** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are
+** zeroed and an SQLite error code returned.
+**
+** It is the responsibility of the caller to eventually call sqlite3_free()
+** on the *ppOut pointer to free the buffer allocation following a successful 
+** call to this function.
+**
+** WARNING/TODO: This function currently assumes that the input is a valid
+** changeset. If it is not, the results are undefined.
+*/
+SQLITE_API int sqlite3changeset_invert(
+  int nIn, const void *pIn,       /* Input changeset */
+  int *pnOut, void **ppOut        /* OUT: Inverse of input */
+);
+
+/*
+** CAPI3REF: Concatenate Two Changeset Objects
+**
+** This function is used to concatenate two changesets, A and B, into a 
+** single changeset. The result is a changeset equivalent to applying
+** changeset A followed by changeset B. 
+**
+** This function combines the two input changesets using an 
+** sqlite3_changegroup object. Calling it produces similar results as the
+** following code fragment:
+**
+** <pre>
+**   sqlite3_changegroup *pGrp;
+**   rc = sqlite3_changegroup_new(&pGrp);
+**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
+**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
+**   if( rc==SQLITE_OK ){
+**     rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
+**   }else{
+**     *ppOut = 0;
+**     *pnOut = 0;
+**   }
+** </pre>
+**
+** Refer to the sqlite3_changegroup documentation below for details.
+*/
+SQLITE_API int sqlite3changeset_concat(
+  int nA,                         /* Number of bytes in buffer pA */
+  void *pA,                       /* Pointer to buffer containing changeset A */
+  int nB,                         /* Number of bytes in buffer pB */
+  void *pB,                       /* Pointer to buffer containing changeset B */
+  int *pnOut,                     /* OUT: Number of bytes in output changeset */
+  void **ppOut                    /* OUT: Buffer containing output changeset */
+);
+
+
+/*
+** CAPI3REF: Changegroup Handle
+**
+** A changegroup is an object used to combine two or more 
+** [changesets] or [patchsets]
+*/
+typedef struct sqlite3_changegroup sqlite3_changegroup;
+
+/*
+** CAPI3REF: Create A New Changegroup Object
+** CONSTRUCTOR: sqlite3_changegroup
+**
+** An sqlite3_changegroup object is used to combine two or more changesets
+** (or patchsets) into a single changeset (or patchset). A single changegroup
+** object may combine changesets or patchsets, but not both. The output is
+** always in the same format as the input.
+**
+** If successful, this function returns SQLITE_OK and populates (*pp) with
+** a pointer to a new sqlite3_changegroup object before returning. The caller
+** should eventually free the returned object using a call to 
+** sqlite3changegroup_delete(). If an error occurs, an SQLite error code
+** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL.
+**
+** The usual usage pattern for an sqlite3_changegroup object is as follows:
+**
+** <ul>
+**   <li> It is created using a call to sqlite3changegroup_new().
+**
+**   <li> Zero or more changesets (or patchsets) are added to the object
+**        by calling sqlite3changegroup_add().
+**
+**   <li> The result of combining all input changesets together is obtained 
+**        by the application via a call to sqlite3changegroup_output().
+**
+**   <li> The object is deleted using a call to sqlite3changegroup_delete().
+** </ul>
+**
+** Any number of calls to add() and output() may be made between the calls to
+** new() and delete(), and in any order.
+**
+** As well as the regular sqlite3changegroup_add() and 
+** sqlite3changegroup_output() functions, also available are the streaming
+** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().
+*/
+SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
+
+/*
+** CAPI3REF: Add A Changeset To A Changegroup
+** METHOD: sqlite3_changegroup
+**
+** Add all changes within the changeset (or patchset) in buffer pData (size
+** nData bytes) to the changegroup. 
+**
+** If the buffer contains a patchset, then all prior calls to this function
+** on the same changegroup object must also have specified patchsets. Or, if
+** the buffer contains a changeset, so must have the earlier calls to this
+** function. Otherwise, SQLITE_ERROR is returned and no changes are added
+** to the changegroup.
+**
+** Rows within the changeset and changegroup are identified by the values in
+** their PRIMARY KEY columns. A change in the changeset is considered to
+** apply to the same row as a change already present in the changegroup if
+** the two rows have the same primary key.
+**
+** Changes to rows that do not already appear in the changegroup are
+** simply copied into it. Or, if both the new changeset and the changegroup
+** contain changes that apply to a single row, the final contents of the
+** changegroup depends on the type of each change, as follows:
+**
+** <table border=1 style="margin-left:8ex;margin-right:8ex">
+**   <tr><th style="white-space:pre">Existing Change  </th>
+**       <th style="white-space:pre">New Change       </th>
+**       <th>Output Change
+**   <tr><td>INSERT <td>INSERT <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+**   <tr><td>INSERT <td>UPDATE <td>
+**       The INSERT change remains in the changegroup. The values in the 
+**       INSERT change are modified as if the row was inserted by the
+**       existing change and then updated according to the new change.
+**   <tr><td>INSERT <td>DELETE <td>
+**       The existing INSERT is removed from the changegroup. The DELETE is
+**       not added.
+**   <tr><td>UPDATE <td>INSERT <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+**   <tr><td>UPDATE <td>UPDATE <td>
+**       The existing UPDATE remains within the changegroup. It is amended 
+**       so that the accompanying values are as if the row was updated once 
+**       by the existing change and then again by the new change.
+**   <tr><td>UPDATE <td>DELETE <td>
+**       The existing UPDATE is replaced by the new DELETE within the
+**       changegroup.
+**   <tr><td>DELETE <td>INSERT <td>
+**       If one or more of the column values in the row inserted by the
+**       new change differ from those in the row deleted by the existing 
+**       change, the existing DELETE is replaced by an UPDATE within the
+**       changegroup. Otherwise, if the inserted row is exactly the same 
+**       as the deleted row, the existing DELETE is simply discarded.
+**   <tr><td>DELETE <td>UPDATE <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+**   <tr><td>DELETE <td>DELETE <td>
+**       The new change is ignored. This case does not occur if the new
+**       changeset was recorded immediately after the changesets already
+**       added to the changegroup.
+** </table>
+**
+** If the new changeset contains changes to a table that is already present
+** in the changegroup, then the number of columns and the position of the
+** primary key columns for the table must be consistent. If this is not the
+** case, this function fails with SQLITE_SCHEMA. If the input changeset
+** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
+** returned. Or, if an out-of-memory condition occurs during processing, this
+** function returns SQLITE_NOMEM. In all cases, if an error occurs the state
+** of the final contents of the changegroup is undefined.
+**
+** If no error occurs, SQLITE_OK is returned.
+*/
+SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+
+/*
+** CAPI3REF: Obtain A Composite Changeset From A Changegroup
+** METHOD: sqlite3_changegroup
+**
+** Obtain a buffer containing a changeset (or patchset) representing the
+** current contents of the changegroup. If the inputs to the changegroup
+** were themselves changesets, the output is a changeset. Or, if the
+** inputs were patchsets, the output is also a patchset.
+**
+** As with the output of the sqlite3session_changeset() and
+** sqlite3session_patchset() functions, all changes related to a single
+** table are grouped together in the output of this function. Tables appear
+** in the same order as for the very first changeset added to the changegroup.
+** If the second or subsequent changesets added to the changegroup contain
+** changes for tables that do not appear in the first changeset, they are
+** appended onto the end of the output changeset, again in the order in
+** which they are first encountered.
+**
+** If an error occurs, an SQLite error code is returned and the output
+** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK
+** is returned and the output variables are set to the size of and a 
+** pointer to the output buffer, respectively. In this case it is the
+** responsibility of the caller to eventually free the buffer using a
+** call to sqlite3_free().
+*/
+SQLITE_API int sqlite3changegroup_output(
+  sqlite3_changegroup*,
+  int *pnData,                    /* OUT: Size of output buffer in bytes */
+  void **ppData                   /* OUT: Pointer to output buffer */
+);
+
+/*
+** CAPI3REF: Delete A Changegroup Object
+** DESTRUCTOR: sqlite3_changegroup
+*/
+SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
+
+/*
+** CAPI3REF: Apply A Changeset To A Database
+**
+** Apply a changeset or patchset to a database. These functions attempt to
+** update the "main" database attached to handle db with the changes found in
+** the changeset passed via the second and third arguments. 
+**
+** The fourth argument (xFilter) passed to these functions is the "filter
+** callback". If it is not NULL, then for each table affected by at least one
+** change in the changeset, the filter callback is invoked with
+** the table name as the second argument, and a copy of the context pointer
+** passed as the sixth argument as the first. If the "filter callback"
+** returns zero, then no attempt is made to apply any changes to the table.
+** Otherwise, if the return value is non-zero or the xFilter argument to
+** is NULL, all changes related to the table are attempted.
+**
+** For each table that is not excluded by the filter callback, this function 
+** tests that the target database contains a compatible table. A table is 
+** considered compatible if all of the following are true:
+**
+** <ul>
+**   <li> The table has the same name as the name recorded in the 
+**        changeset, and
+**   <li> The table has at least as many columns as recorded in the 
+**        changeset, and
+**   <li> The table has primary key columns in the same position as 
+**        recorded in the changeset.
+** </ul>
+**
+** If there is no compatible table, it is not an error, but none of the
+** changes associated with the table are applied. A warning message is issued
+** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most
+** one such warning is issued for each table in the changeset.
+**
+** For each change for which there is a compatible table, an attempt is made 
+** to modify the table contents according to the UPDATE, INSERT or DELETE 
+** change. If a change cannot be applied cleanly, the conflict handler 
+** function passed as the fifth argument to sqlite3changeset_apply() may be 
+** invoked. A description of exactly when the conflict handler is invoked for 
+** each type of change is below.
+**
+** Unlike the xFilter argument, xConflict may not be passed NULL. The results
+** of passing anything other than a valid function pointer as the xConflict
+** argument are undefined.
+**
+** Each time the conflict handler function is invoked, it must return one
+** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or 
+** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned
+** if the second argument passed to the conflict handler is either
+** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler
+** returns an illegal value, any changes already made are rolled back and
+** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different 
+** actions are taken by sqlite3changeset_apply() depending on the value
+** returned by each invocation of the conflict-handler function. Refer to
+** the documentation for the three 
+** [SQLITE_CHANGESET_OMIT|available return values] for details.
+**
+** <dl>
+** <dt>DELETE Changes<dd>
+**   For each DELETE change, the function checks if the target database 
+**   contains a row with the same primary key value (or values) as the 
+**   original row values stored in the changeset. If it does, and the values 
+**   stored in all non-primary key columns also match the values stored in 
+**   the changeset the row is deleted from the target database.
+**
+**   If a row with matching primary key values is found, but one or more of
+**   the non-primary key fields contains a value different from the original
+**   row value stored in the changeset, the conflict-handler function is
+**   invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the
+**   database table has more columns than are recorded in the changeset,
+**   only the values of those non-primary key fields are compared against
+**   the current database contents - any trailing database table columns
+**   are ignored.
+**
+**   If no row with matching primary key values is found in the database,
+**   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
+**   passed as the second argument.
+**
+**   If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT
+**   (which can only happen if a foreign key constraint is violated), the
+**   conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT]
+**   passed as the second argument. This includes the case where the DELETE
+**   operation is attempted because an earlier call to the conflict handler
+**   function returned [SQLITE_CHANGESET_REPLACE].
+**
+** <dt>INSERT Changes<dd>
+**   For each INSERT change, an attempt is made to insert the new row into
+**   the database. If the changeset row contains fewer fields than the
+**   database table, the trailing fields are populated with their default
+**   values.
+**
+**   If the attempt to insert the row fails because the database already 
+**   contains a row with the same primary key values, the conflict handler
+**   function is invoked with the second argument set to 
+**   [SQLITE_CHANGESET_CONFLICT].
+**
+**   If the attempt to insert the row fails because of some other constraint
+**   violation (e.g. NOT NULL or UNIQUE), the conflict handler function is 
+**   invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT].
+**   This includes the case where the INSERT operation is re-attempted because 
+**   an earlier call to the conflict handler function returned 
+**   [SQLITE_CHANGESET_REPLACE].
+**
+** <dt>UPDATE Changes<dd>
+**   For each UPDATE change, the function checks if the target database 
+**   contains a row with the same primary key value (or values) as the 
+**   original row values stored in the changeset. If it does, and the values 
+**   stored in all modified non-primary key columns also match the values
+**   stored in the changeset the row is updated within the target database.
+**
+**   If a row with matching primary key values is found, but one or more of
+**   the modified non-primary key fields contains a value different from an
+**   original row value stored in the changeset, the conflict-handler function
+**   is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
+**   UPDATE changes only contain values for non-primary key fields that are
+**   to be modified, only those fields need to match the original values to
+**   avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
+**
+**   If no row with matching primary key values is found in the database,
+**   the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
+**   passed as the second argument.
+**
+**   If the UPDATE operation is attempted, but SQLite returns 
+**   SQLITE_CONSTRAINT, the conflict-handler function is invoked with 
+**   [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument.
+**   This includes the case where the UPDATE operation is attempted after 
+**   an earlier call to the conflict handler function returned
+**   [SQLITE_CHANGESET_REPLACE].  
+** </dl>
+**
+** It is safe to execute SQL statements, including those that write to the
+** table that the callback related to, from within the xConflict callback.
+** This can be used to further customize the application's conflict
+** resolution strategy.
+**
+** All changes made by these functions are enclosed in a savepoint transaction.
+** If any other error (aside from a constraint failure when attempting to
+** write to the target database) occurs, then the savepoint transaction is
+** rolled back, restoring the target database to its original state, and an 
+** SQLite error code returned.
+**
+** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
+** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
+** may set (*ppRebase) to point to a "rebase" that may be used with the 
+** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
+** is set to the size of the buffer in bytes. It is the responsibility of the
+** caller to eventually free any such buffer using sqlite3_free(). The buffer
+** is only allocated and populated if one or more conflicts were encountered
+** while applying the patchset. See comments surrounding the sqlite3_rebaser
+** APIs for further details.
+**
+** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent
+** may be modified by passing a combination of
+** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter.
+**
+** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b>
+** and therefore subject to change.
+*/
+SQLITE_API int sqlite3changeset_apply(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  int nChangeset,                 /* Size of changeset in bytes */
+  void *pChangeset,               /* Changeset blob */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    const char *zTab              /* Table name */
+  ),
+  int(*xConflict)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+  ),
+  void *pCtx                      /* First argument passed to xConflict */
+);
+SQLITE_API int sqlite3changeset_apply_v2(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  int nChangeset,                 /* Size of changeset in bytes */
+  void *pChangeset,               /* Changeset blob */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    const char *zTab              /* Table name */
+  ),
+  int(*xConflict)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+  ),
+  void *pCtx,                     /* First argument passed to xConflict */
+  void **ppRebase, int *pnRebase, /* OUT: Rebase data */
+  int flags                       /* SESSION_CHANGESETAPPLY_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3changeset_apply_v2
+**
+** The following flags may passed via the 9th parameter to
+** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]:
+**
+** <dl>
+** <dt>SQLITE_CHANGESETAPPLY_NOSAVEPOINT <dd>
+**   Usually, the sessions module encloses all operations performed by
+**   a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The
+**   SAVEPOINT is committed if the changeset or patchset is successfully
+**   applied, or rolled back if an error occurs. Specifying this flag
+**   causes the sessions module to omit this savepoint. In this case, if the
+**   caller has an open transaction or savepoint when apply_v2() is called, 
+**   it may revert the partially applied changeset by rolling it back.
+**
+** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
+**   Invert the changeset before applying it. This is equivalent to inverting
+**   a changeset using sqlite3changeset_invert() before applying it. It is
+**   an error to specify this flag with a patchset.
+*/
+#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT   0x0001
+#define SQLITE_CHANGESETAPPLY_INVERT        0x0002
+
+/* 
+** CAPI3REF: Constants Passed To The Conflict Handler
+**
+** Values that may be passed as the second argument to a conflict-handler.
+**
+** <dl>
+** <dt>SQLITE_CHANGESET_DATA<dd>
+**   The conflict handler is invoked with CHANGESET_DATA as the second argument
+**   when processing a DELETE or UPDATE change if a row with the required
+**   PRIMARY KEY fields is present in the database, but one or more other 
+**   (non primary-key) fields modified by the update do not contain the 
+**   expected "before" values.
+** 
+**   The conflicting row, in this case, is the database row with the matching
+**   primary key.
+** 
+** <dt>SQLITE_CHANGESET_NOTFOUND<dd>
+**   The conflict handler is invoked with CHANGESET_NOTFOUND as the second
+**   argument when processing a DELETE or UPDATE change if a row with the
+**   required PRIMARY KEY fields is not present in the database.
+** 
+**   There is no conflicting row in this case. The results of invoking the
+**   sqlite3changeset_conflict() API are undefined.
+** 
+** <dt>SQLITE_CHANGESET_CONFLICT<dd>
+**   CHANGESET_CONFLICT is passed as the second argument to the conflict
+**   handler while processing an INSERT change if the operation would result 
+**   in duplicate primary key values.
+** 
+**   The conflicting row in this case is the database row with the matching
+**   primary key.
+**
+** <dt>SQLITE_CHANGESET_FOREIGN_KEY<dd>
+**   If foreign key handling is enabled, and applying a changeset leaves the
+**   database in a state containing foreign key violations, the conflict 
+**   handler is invoked with CHANGESET_FOREIGN_KEY as the second argument
+**   exactly once before the changeset is committed. If the conflict handler
+**   returns CHANGESET_OMIT, the changes, including those that caused the
+**   foreign key constraint violation, are committed. Or, if it returns
+**   CHANGESET_ABORT, the changeset is rolled back.
+**
+**   No current or conflicting row information is provided. The only function
+**   it is possible to call on the supplied sqlite3_changeset_iter handle
+**   is sqlite3changeset_fk_conflicts().
+** 
+** <dt>SQLITE_CHANGESET_CONSTRAINT<dd>
+**   If any other constraint violation occurs while applying a change (i.e. 
+**   a UNIQUE, CHECK or NOT NULL constraint), the conflict handler is 
+**   invoked with CHANGESET_CONSTRAINT as the second argument.
+** 
+**   There is no conflicting row in this case. The results of invoking the
+**   sqlite3changeset_conflict() API are undefined.
+**
+** </dl>
+*/
+#define SQLITE_CHANGESET_DATA        1
+#define SQLITE_CHANGESET_NOTFOUND    2
+#define SQLITE_CHANGESET_CONFLICT    3
+#define SQLITE_CHANGESET_CONSTRAINT  4
+#define SQLITE_CHANGESET_FOREIGN_KEY 5
+
+/* 
+** CAPI3REF: Constants Returned By The Conflict Handler
+**
+** A conflict handler callback must return one of the following three values.
+**
+** <dl>
+** <dt>SQLITE_CHANGESET_OMIT<dd>
+**   If a conflict handler returns this value no special action is taken. The
+**   change that caused the conflict is not applied. The session module 
+**   continues to the next change in the changeset.
+**
+** <dt>SQLITE_CHANGESET_REPLACE<dd>
+**   This value may only be returned if the second argument to the conflict
+**   handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this
+**   is not the case, any changes applied so far are rolled back and the 
+**   call to sqlite3changeset_apply() returns SQLITE_MISUSE.
+**
+**   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict
+**   handler, then the conflicting row is either updated or deleted, depending
+**   on the type of change.
+**
+**   If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict
+**   handler, then the conflicting row is removed from the database and a
+**   second attempt to apply the change is made. If this second attempt fails,
+**   the original row is restored to the database before continuing.
+**
+** <dt>SQLITE_CHANGESET_ABORT<dd>
+**   If this value is returned, any changes applied so far are rolled back 
+**   and the call to sqlite3changeset_apply() returns SQLITE_ABORT.
+** </dl>
+*/
+#define SQLITE_CHANGESET_OMIT       0
+#define SQLITE_CHANGESET_REPLACE    1
+#define SQLITE_CHANGESET_ABORT      2
+
+/* 
+** CAPI3REF: Rebasing changesets
+** EXPERIMENTAL
+**
+** Suppose there is a site hosting a database in state S0. And that
+** modifications are made that move that database to state S1 and a
+** changeset recorded (the "local" changeset). Then, a changeset based
+** on S0 is received from another site (the "remote" changeset) and 
+** applied to the database. The database is then in state 
+** (S1+"remote"), where the exact state depends on any conflict
+** resolution decisions (OMIT or REPLACE) made while applying "remote".
+** Rebasing a changeset is to update it to take those conflict 
+** resolution decisions into account, so that the same conflicts
+** do not have to be resolved elsewhere in the network. 
+**
+** For example, if both the local and remote changesets contain an
+** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)":
+**
+**   local:  INSERT INTO t1 VALUES(1, 'v1');
+**   remote: INSERT INTO t1 VALUES(1, 'v2');
+**
+** and the conflict resolution is REPLACE, then the INSERT change is
+** removed from the local changeset (it was overridden). Or, if the
+** conflict resolution was "OMIT", then the local changeset is modified
+** to instead contain:
+**
+**           UPDATE t1 SET b = 'v2' WHERE a=1;
+**
+** Changes within the local changeset are rebased as follows:
+**
+** <dl>
+** <dt>Local INSERT<dd>
+**   This may only conflict with a remote INSERT. If the conflict 
+**   resolution was OMIT, then add an UPDATE change to the rebased
+**   changeset. Or, if the conflict resolution was REPLACE, add
+**   nothing to the rebased changeset.
+**
+** <dt>Local DELETE<dd>
+**   This may conflict with a remote UPDATE or DELETE. In both cases the
+**   only possible resolution is OMIT. If the remote operation was a
+**   DELETE, then add no change to the rebased changeset. If the remote
+**   operation was an UPDATE, then the old.* fields of change are updated
+**   to reflect the new.* values in the UPDATE.
+**
+** <dt>Local UPDATE<dd>
+**   This may conflict with a remote UPDATE or DELETE. If it conflicts
+**   with a DELETE, and the conflict resolution was OMIT, then the update
+**   is changed into an INSERT. Any undefined values in the new.* record
+**   from the update change are filled in using the old.* values from
+**   the conflicting DELETE. Or, if the conflict resolution was REPLACE,
+**   the UPDATE change is simply omitted from the rebased changeset.
+**
+**   If conflict is with a remote UPDATE and the resolution is OMIT, then
+**   the old.* values are rebased using the new.* values in the remote
+**   change. Or, if the resolution is REPLACE, then the change is copied
+**   into the rebased changeset with updates to columns also updated by
+**   the conflicting remote UPDATE removed. If this means no columns would 
+**   be updated, the change is omitted.
+** </dl>
+**
+** A local change may be rebased against multiple remote changes 
+** simultaneously. If a single key is modified by multiple remote 
+** changesets, they are combined as follows before the local changeset
+** is rebased:
+**
+** <ul>
+**    <li> If there has been one or more REPLACE resolutions on a
+**         key, it is rebased according to a REPLACE.
+**
+**    <li> If there have been no REPLACE resolutions on a key, then
+**         the local changeset is rebased according to the most recent
+**         of the OMIT resolutions.
+** </ul>
+**
+** Note that conflict resolutions from multiple remote changesets are 
+** combined on a per-field basis, not per-row. This means that in the 
+** case of multiple remote UPDATE operations, some fields of a single 
+** local change may be rebased for REPLACE while others are rebased for 
+** OMIT.
+**
+** In order to rebase a local changeset, the remote changeset must first
+** be applied to the local database using sqlite3changeset_apply_v2() and
+** the buffer of rebase information captured. Then:
+**
+** <ol>
+**   <li> An sqlite3_rebaser object is created by calling 
+**        sqlite3rebaser_create().
+**   <li> The new object is configured with the rebase buffer obtained from
+**        sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure().
+**        If the local changeset is to be rebased against multiple remote
+**        changesets, then sqlite3rebaser_configure() should be called
+**        multiple times, in the same order that the multiple
+**        sqlite3changeset_apply_v2() calls were made.
+**   <li> Each local changeset is rebased by calling sqlite3rebaser_rebase().
+**   <li> The sqlite3_rebaser object is deleted by calling
+**        sqlite3rebaser_delete().
+** </ol>
+*/
+typedef struct sqlite3_rebaser sqlite3_rebaser;
+
+/*
+** CAPI3REF: Create a changeset rebaser object.
+** EXPERIMENTAL
+**
+** Allocate a new changeset rebaser object. If successful, set (*ppNew) to
+** point to the new object and return SQLITE_OK. Otherwise, if an error
+** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew) 
+** to NULL. 
+*/
+SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew);
+
+/*
+** CAPI3REF: Configure a changeset rebaser object.
+** EXPERIMENTAL
+**
+** Configure the changeset rebaser object to rebase changesets according
+** to the conflict resolutions described by buffer pRebase (size nRebase
+** bytes), which must have been obtained from a previous call to
+** sqlite3changeset_apply_v2().
+*/
+SQLITE_API int sqlite3rebaser_configure(
+  sqlite3_rebaser*, 
+  int nRebase, const void *pRebase
+); 
+
+/*
+** CAPI3REF: Rebase a changeset
+** EXPERIMENTAL
+**
+** Argument pIn must point to a buffer containing a changeset nIn bytes
+** in size. This function allocates and populates a buffer with a copy
+** of the changeset rebased according to the configuration of the
+** rebaser object passed as the first argument. If successful, (*ppOut)
+** is set to point to the new buffer containing the rebased changeset and 
+** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
+** responsibility of the caller to eventually free the new buffer using
+** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
+** are set to zero and an SQLite error code returned.
+*/
+SQLITE_API int sqlite3rebaser_rebase(
+  sqlite3_rebaser*,
+  int nIn, const void *pIn, 
+  int *pnOut, void **ppOut 
+);
+
+/*
+** CAPI3REF: Delete a changeset rebaser object.
+** EXPERIMENTAL
+**
+** Delete the changeset rebaser object and all associated resources. There
+** should be one call to this function for each successful invocation
+** of sqlite3rebaser_create().
+*/
+SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p); 
+
+/*
+** CAPI3REF: Streaming Versions of API functions.
+**
+** The six streaming API xxx_strm() functions serve similar purposes to the 
+** corresponding non-streaming API functions:
+**
+** <table border=1 style="margin-left:8ex;margin-right:8ex">
+**   <tr><th>Streaming function<th>Non-streaming equivalent</th>
+**   <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply] 
+**   <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2] 
+**   <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat] 
+**   <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert] 
+**   <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start] 
+**   <tr><td>sqlite3session_changeset_strm<td>[sqlite3session_changeset] 
+**   <tr><td>sqlite3session_patchset_strm<td>[sqlite3session_patchset] 
+** </table>
+**
+** Non-streaming functions that accept changesets (or patchsets) as input
+** require that the entire changeset be stored in a single buffer in memory. 
+** Similarly, those that return a changeset or patchset do so by returning 
+** a pointer to a single large buffer allocated using sqlite3_malloc(). 
+** Normally this is convenient. However, if an application running in a 
+** low-memory environment is required to handle very large changesets, the
+** large contiguous memory allocations required can become onerous.
+**
+** In order to avoid this problem, instead of a single large buffer, input
+** is passed to a streaming API functions by way of a callback function that
+** the sessions module invokes to incrementally request input data as it is
+** required. In all cases, a pair of API function parameters such as
+**
+**  <pre>
+**  &nbsp;     int nChangeset,
+**  &nbsp;     void *pChangeset,
+**  </pre>
+**
+** Is replaced by:
+**
+**  <pre>
+**  &nbsp;     int (*xInput)(void *pIn, void *pData, int *pnData),
+**  &nbsp;     void *pIn,
+**  </pre>
+**
+** Each time the xInput callback is invoked by the sessions module, the first
+** argument passed is a copy of the supplied pIn context pointer. The second 
+** argument, pData, points to a buffer (*pnData) bytes in size. Assuming no 
+** error occurs the xInput method should copy up to (*pnData) bytes of data 
+** into the buffer and set (*pnData) to the actual number of bytes copied 
+** before returning SQLITE_OK. If the input is completely exhausted, (*pnData) 
+** should be set to zero to indicate this. Or, if an error occurs, an SQLite 
+** error code should be returned. In all cases, if an xInput callback returns
+** an error, all processing is abandoned and the streaming API function
+** returns a copy of the error code to the caller.
+**
+** In the case of sqlite3changeset_start_strm(), the xInput callback may be
+** invoked by the sessions module at any point during the lifetime of the
+** iterator. If such an xInput callback returns an error, the iterator enters
+** an error state, whereby all subsequent calls to iterator functions 
+** immediately fail with the same error code as returned by xInput.
+**
+** Similarly, streaming API functions that return changesets (or patchsets)
+** return them in chunks by way of a callback function instead of via a
+** pointer to a single large buffer. In this case, a pair of parameters such
+** as:
+**
+**  <pre>
+**  &nbsp;     int *pnChangeset,
+**  &nbsp;     void **ppChangeset,
+**  </pre>
+**
+** Is replaced by:
+**
+**  <pre>
+**  &nbsp;     int (*xOutput)(void *pOut, const void *pData, int nData),
+**  &nbsp;     void *pOut
+**  </pre>
+**
+** The xOutput callback is invoked zero or more times to return data to
+** the application. The first parameter passed to each call is a copy of the
+** pOut pointer supplied by the application. The second parameter, pData,
+** points to a buffer nData bytes in size containing the chunk of output
+** data being returned. If the xOutput callback successfully processes the
+** supplied data, it should return SQLITE_OK to indicate success. Otherwise,
+** it should return some other SQLite error code. In this case processing
+** is immediately abandoned and the streaming API function returns a copy
+** of the xOutput error code to the application.
+**
+** The sessions module never invokes an xOutput callback with the third 
+** parameter set to a value less than or equal to zero. Other than this,
+** no guarantees are made as to the size of the chunks of data returned.
+*/
+SQLITE_API int sqlite3changeset_apply_strm(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
+  void *pIn,                                          /* First arg for xInput */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    const char *zTab              /* Table name */
+  ),
+  int(*xConflict)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+  ),
+  void *pCtx                      /* First argument passed to xConflict */
+);
+SQLITE_API int sqlite3changeset_apply_v2_strm(
+  sqlite3 *db,                    /* Apply change to "main" db of this handle */
+  int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
+  void *pIn,                                          /* First arg for xInput */
+  int(*xFilter)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    const char *zTab              /* Table name */
+  ),
+  int(*xConflict)(
+    void *pCtx,                   /* Copy of sixth arg to _apply() */
+    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+  ),
+  void *pCtx,                     /* First argument passed to xConflict */
+  void **ppRebase, int *pnRebase,
+  int flags
+);
+SQLITE_API int sqlite3changeset_concat_strm(
+  int (*xInputA)(void *pIn, void *pData, int *pnData),
+  void *pInA,
+  int (*xInputB)(void *pIn, void *pData, int *pnData),
+  void *pInB,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+SQLITE_API int sqlite3changeset_invert_strm(
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+SQLITE_API int sqlite3changeset_start_strm(
+  sqlite3_changeset_iter **pp,
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn
+);
+SQLITE_API int sqlite3changeset_start_v2_strm(
+  sqlite3_changeset_iter **pp,
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn,
+  int flags
+);
+SQLITE_API int sqlite3session_changeset_strm(
+  sqlite3_session *pSession,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+SQLITE_API int sqlite3session_patchset_strm(
+  sqlite3_session *pSession,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*, 
+    int (*xInput)(void *pIn, void *pData, int *pnData),
+    void *pIn
+);
+SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
+    int (*xOutput)(void *pOut, const void *pData, int nData), 
+    void *pOut
+);
+SQLITE_API int sqlite3rebaser_rebase_strm(
+  sqlite3_rebaser *pRebaser,
+  int (*xInput)(void *pIn, void *pData, int *pnData),
+  void *pIn,
+  int (*xOutput)(void *pOut, const void *pData, int nData),
+  void *pOut
+);
+
+/*
+** CAPI3REF: Configure global parameters
+**
+** The sqlite3session_config() interface is used to make global configuration
+** changes to the sessions module in order to tune it to the specific needs 
+** of the application.
+**
+** The sqlite3session_config() interface is not threadsafe. If it is invoked
+** while any other thread is inside any other sessions method then the
+** results are undefined. Furthermore, if it is invoked after any sessions
+** related objects have been created, the results are also undefined. 
+**
+** The first argument to the sqlite3session_config() function must be one
+** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The 
+** interpretation of the (void*) value passed as the second parameter and
+** the effect of calling this function depends on the value of the first
+** parameter.
+**
+** <dl>
+** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
+**    By default, the sessions module streaming interfaces attempt to input
+**    and output data in approximately 1 KiB chunks. This operand may be used
+**    to set and query the value of this configuration setting. The pointer
+**    passed as the second argument must point to a value of type (int).
+**    If this value is greater than 0, it is used as the new streaming data
+**    chunk size for both input and output. Before returning, the (int) value
+**    pointed to by pArg is set to the final value of the streaming interface
+**    chunk size.
+** </dl>
+**
+** This function returns SQLITE_OK if successful, or an SQLite error code
+** otherwise.
+*/
+SQLITE_API int sqlite3session_config(int op, void *pArg);
+
+/*
+** CAPI3REF: Values for sqlite3session_config().
+*/
+#define SQLITE_SESSION_CONFIG_STRMSIZE 1
+
+/*
+** Make sure we can call this stuff from C++.
+*/
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */
+
+/******** End of sqlite3session.h *********/
+/******** Begin file fts5.h *********/
+/*
+** 2014 May 31
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** Interfaces to extend FTS5. Using the interfaces defined in this file, 
+** FTS5 may be extended with:
+**
+**     * custom tokenizers, and
+**     * custom auxiliary functions.
+*/
+
+
+#ifndef _FTS5_H
+#define _FTS5_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*************************************************************************
+** CUSTOM AUXILIARY FUNCTIONS
+**
+** Virtual table implementations may overload SQL functions by implementing
+** the sqlite3_module.xFindFunction() method.
+*/
+
+typedef struct Fts5ExtensionApi Fts5ExtensionApi;
+typedef struct Fts5Context Fts5Context;
+typedef struct Fts5PhraseIter Fts5PhraseIter;
+
+typedef void (*fts5_extension_function)(
+  const Fts5ExtensionApi *pApi,   /* API offered by current FTS version */
+  Fts5Context *pFts,              /* First arg to pass to pApi functions */
+  sqlite3_context *pCtx,          /* Context for returning result/error */
+  int nVal,                       /* Number of values in apVal[] array */
+  sqlite3_value **apVal           /* Array of trailing arguments */
+);
+
+struct Fts5PhraseIter {
+  const unsigned char *a;
+  const unsigned char *b;
+};
+
+/*
+** EXTENSION API FUNCTIONS
+**
+** xUserData(pFts):
+**   Return a copy of the context pointer the extension function was 
+**   registered with.
+**
+** xColumnTotalSize(pFts, iCol, pnToken):
+**   If parameter iCol is less than zero, set output variable *pnToken
+**   to the total number of tokens in the FTS5 table. Or, if iCol is
+**   non-negative but less than the number of columns in the table, return
+**   the total number of tokens in column iCol, considering all rows in 
+**   the FTS5 table.
+**
+**   If parameter iCol is greater than or equal to the number of columns
+**   in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+**   an OOM condition or IO error), an appropriate SQLite error code is 
+**   returned.
+**
+** xColumnCount(pFts):
+**   Return the number of columns in the table.
+**
+** xColumnSize(pFts, iCol, pnToken):
+**   If parameter iCol is less than zero, set output variable *pnToken
+**   to the total number of tokens in the current row. Or, if iCol is
+**   non-negative but less than the number of columns in the table, set
+**   *pnToken to the number of tokens in column iCol of the current row.
+**
+**   If parameter iCol is greater than or equal to the number of columns
+**   in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+**   an OOM condition or IO error), an appropriate SQLite error code is 
+**   returned.
+**
+**   This function may be quite inefficient if used with an FTS5 table
+**   created with the "columnsize=0" option.
+**
+** xColumnText:
+**   This function attempts to retrieve the text of column iCol of the
+**   current document. If successful, (*pz) is set to point to a buffer
+**   containing the text in utf-8 encoding, (*pn) is set to the size in bytes
+**   (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
+**   if an error occurs, an SQLite error code is returned and the final values
+**   of (*pz) and (*pn) are undefined.
+**
+** xPhraseCount:
+**   Returns the number of phrases in the current query expression.
+**
+** xPhraseSize:
+**   Returns the number of tokens in phrase iPhrase of the query. Phrases
+**   are numbered starting from zero.
+**
+** xInstCount:
+**   Set *pnInst to the total number of occurrences of all phrases within
+**   the query within the current row. Return SQLITE_OK if successful, or
+**   an error code (i.e. SQLITE_NOMEM) if an error occurs.
+**
+**   This API can be quite slow if used with an FTS5 table created with the
+**   "detail=none" or "detail=column" option. If the FTS5 table is created 
+**   with either "detail=none" or "detail=column" and "content=" option 
+**   (i.e. if it is a contentless table), then this API always returns 0.
+**
+** xInst:
+**   Query for the details of phrase match iIdx within the current row.
+**   Phrase matches are numbered starting from zero, so the iIdx argument
+**   should be greater than or equal to zero and smaller than the value
+**   output by xInstCount().
+**
+**   Usually, output parameter *piPhrase is set to the phrase number, *piCol
+**   to the column in which it occurs and *piOff the token offset of the
+**   first token of the phrase. Returns SQLITE_OK if successful, or an error
+**   code (i.e. SQLITE_NOMEM) if an error occurs.
+**
+**   This API can be quite slow if used with an FTS5 table created with the
+**   "detail=none" or "detail=column" option. 
+**
+** xRowid:
+**   Returns the rowid of the current row.
+**
+** xTokenize:
+**   Tokenize text using the tokenizer belonging to the FTS5 table.
+**
+** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
+**   This API function is used to query the FTS table for phrase iPhrase
+**   of the current query. Specifically, a query equivalent to:
+**
+**       ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
+**
+**   with $p set to a phrase equivalent to the phrase iPhrase of the
+**   current query is executed. Any column filter that applies to
+**   phrase iPhrase of the current query is included in $p. For each 
+**   row visited, the callback function passed as the fourth argument 
+**   is invoked. The context and API objects passed to the callback 
+**   function may be used to access the properties of each matched row.
+**   Invoking Api.xUserData() returns a copy of the pointer passed as 
+**   the third argument to pUserData.
+**
+**   If the callback function returns any value other than SQLITE_OK, the
+**   query is abandoned and the xQueryPhrase function returns immediately.
+**   If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
+**   Otherwise, the error code is propagated upwards.
+**
+**   If the query runs to completion without incident, SQLITE_OK is returned.
+**   Or, if some error occurs before the query completes or is aborted by
+**   the callback, an SQLite error code is returned.
+**
+**
+** xSetAuxdata(pFts5, pAux, xDelete)
+**
+**   Save the pointer passed as the second argument as the extension function's 
+**   "auxiliary data". The pointer may then be retrieved by the current or any
+**   future invocation of the same fts5 extension function made as part of
+**   the same MATCH query using the xGetAuxdata() API.
+**
+**   Each extension function is allocated a single auxiliary data slot for
+**   each FTS query (MATCH expression). If the extension function is invoked 
+**   more than once for a single FTS query, then all invocations share a 
+**   single auxiliary data context.
+**
+**   If there is already an auxiliary data pointer when this function is
+**   invoked, then it is replaced by the new pointer. If an xDelete callback
+**   was specified along with the original pointer, it is invoked at this
+**   point.
+**
+**   The xDelete callback, if one is specified, is also invoked on the
+**   auxiliary data pointer after the FTS5 query has finished.
+**
+**   If an error (e.g. an OOM condition) occurs within this function,
+**   the auxiliary data is set to NULL and an error code returned. If the
+**   xDelete parameter was not NULL, it is invoked on the auxiliary data
+**   pointer before returning.
+**
+**
+** xGetAuxdata(pFts5, bClear)
+**
+**   Returns the current auxiliary data pointer for the fts5 extension 
+**   function. See the xSetAuxdata() method for details.
+**
+**   If the bClear argument is non-zero, then the auxiliary data is cleared
+**   (set to NULL) before this function returns. In this case the xDelete,
+**   if any, is not invoked.
+**
+**
+** xRowCount(pFts5, pnRow)
+**
+**   This function is used to retrieve the total number of rows in the table.
+**   In other words, the same value that would be returned by:
+**
+**        SELECT count(*) FROM ftstable;
+**
+** xPhraseFirst()
+**   This function is used, along with type Fts5PhraseIter and the xPhraseNext
+**   method, to iterate through all instances of a single query phrase within
+**   the current row. This is the same information as is accessible via the
+**   xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
+**   to use, this API may be faster under some circumstances. To iterate 
+**   through instances of phrase iPhrase, use the following code:
+**
+**       Fts5PhraseIter iter;
+**       int iCol, iOff;
+**       for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
+**           iCol>=0;
+**           pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
+**       ){
+**         // An instance of phrase iPhrase at offset iOff of column iCol
+**       }
+**
+**   The Fts5PhraseIter structure is defined above. Applications should not
+**   modify this structure directly - it should only be used as shown above
+**   with the xPhraseFirst() and xPhraseNext() API methods (and by
+**   xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
+**
+**   This API can be quite slow if used with an FTS5 table created with the
+**   "detail=none" or "detail=column" option. If the FTS5 table is created 
+**   with either "detail=none" or "detail=column" and "content=" option 
+**   (i.e. if it is a contentless table), then this API always iterates
+**   through an empty set (all calls to xPhraseFirst() set iCol to -1).
+**
+** xPhraseNext()
+**   See xPhraseFirst above.
+**
+** xPhraseFirstColumn()
+**   This function and xPhraseNextColumn() are similar to the xPhraseFirst()
+**   and xPhraseNext() APIs described above. The difference is that instead
+**   of iterating through all instances of a phrase in the current row, these
+**   APIs are used to iterate through the set of columns in the current row
+**   that contain one or more instances of a specified phrase. For example:
+**
+**       Fts5PhraseIter iter;
+**       int iCol;
+**       for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
+**           iCol>=0;
+**           pApi->xPhraseNextColumn(pFts, &iter, &iCol)
+**       ){
+**         // Column iCol contains at least one instance of phrase iPhrase
+**       }
+**
+**   This API can be quite slow if used with an FTS5 table created with the
+**   "detail=none" option. If the FTS5 table is created with either 
+**   "detail=none" "content=" option (i.e. if it is a contentless table), 
+**   then this API always iterates through an empty set (all calls to 
+**   xPhraseFirstColumn() set iCol to -1).
+**
+**   The information accessed using this API and its companion
+**   xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
+**   (or xInst/xInstCount). The chief advantage of this API is that it is
+**   significantly more efficient than those alternatives when used with
+**   "detail=column" tables.  
+**
+** xPhraseNextColumn()
+**   See xPhraseFirstColumn above.
+*/
+struct Fts5ExtensionApi {
+  int iVersion;                   /* Currently always set to 3 */
+
+  void *(*xUserData)(Fts5Context*);
+
+  int (*xColumnCount)(Fts5Context*);
+  int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
+  int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
+
+  int (*xTokenize)(Fts5Context*, 
+    const char *pText, int nText, /* Text to tokenize */
+    void *pCtx,                   /* Context passed to xToken() */
+    int (*xToken)(void*, int, const char*, int, int, int)       /* Callback */
+  );
+
+  int (*xPhraseCount)(Fts5Context*);
+  int (*xPhraseSize)(Fts5Context*, int iPhrase);
+
+  int (*xInstCount)(Fts5Context*, int *pnInst);
+  int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
+
+  sqlite3_int64 (*xRowid)(Fts5Context*);
+  int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
+  int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
+
+  int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
+    int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
+  );
+  int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
+  void *(*xGetAuxdata)(Fts5Context*, int bClear);
+
+  int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
+  void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
+
+  int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
+  void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
+};
+
+/* 
+** CUSTOM AUXILIARY FUNCTIONS
+*************************************************************************/
+
+/*************************************************************************
+** CUSTOM TOKENIZERS
+**
+** Applications may also register custom tokenizer types. A tokenizer 
+** is registered by providing fts5 with a populated instance of the 
+** following structure. All structure methods must be defined, setting
+** any member of the fts5_tokenizer struct to NULL leads to undefined
+** behaviour. The structure methods are expected to function as follows:
+**
+** xCreate:
+**   This function is used to allocate and initialize a tokenizer instance.
+**   A tokenizer instance is required to actually tokenize text.
+**
+**   The first argument passed to this function is a copy of the (void*)
+**   pointer provided by the application when the fts5_tokenizer object
+**   was registered with FTS5 (the third argument to xCreateTokenizer()). 
+**   The second and third arguments are an array of nul-terminated strings
+**   containing the tokenizer arguments, if any, specified following the
+**   tokenizer name as part of the CREATE VIRTUAL TABLE statement used
+**   to create the FTS5 table.
+**
+**   The final argument is an output variable. If successful, (*ppOut) 
+**   should be set to point to the new tokenizer handle and SQLITE_OK
+**   returned. If an error occurs, some value other than SQLITE_OK should
+**   be returned. In this case, fts5 assumes that the final value of *ppOut 
+**   is undefined.
+**
+** xDelete:
+**   This function is invoked to delete a tokenizer handle previously
+**   allocated using xCreate(). Fts5 guarantees that this function will
+**   be invoked exactly once for each successful call to xCreate().
+**
+** xTokenize:
+**   This function is expected to tokenize the nText byte string indicated 
+**   by argument pText. pText may or may not be nul-terminated. The first
+**   argument passed to this function is a pointer to an Fts5Tokenizer object
+**   returned by an earlier call to xCreate().
+**
+**   The second argument indicates the reason that FTS5 is requesting
+**   tokenization of the supplied text. This is always one of the following
+**   four values:
+**
+**   <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
+**            or removed from the FTS table. The tokenizer is being invoked to
+**            determine the set of tokens to add to (or delete from) the
+**            FTS index.
+**
+**       <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed 
+**            against the FTS index. The tokenizer is being called to tokenize 
+**            a bareword or quoted string specified as part of the query.
+**
+**       <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
+**            FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
+**            followed by a "*" character, indicating that the last token
+**            returned by the tokenizer will be treated as a token prefix.
+**
+**       <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to 
+**            satisfy an fts5_api.xTokenize() request made by an auxiliary
+**            function. Or an fts5_api.xColumnSize() request made by the same
+**            on a columnsize=0 database.  
+**   </ul>
+**
+**   For each token in the input string, the supplied callback xToken() must
+**   be invoked. The first argument to it should be a copy of the pointer
+**   passed as the second argument to xTokenize(). The third and fourth
+**   arguments are a pointer to a buffer containing the token text, and the
+**   size of the token in bytes. The 4th and 5th arguments are the byte offsets
+**   of the first byte of and first byte immediately following the text from
+**   which the token is derived within the input.
+**
+**   The second argument passed to the xToken() callback ("tflags") should
+**   normally be set to 0. The exception is if the tokenizer supports 
+**   synonyms. In this case see the discussion below for details.
+**
+**   FTS5 assumes the xToken() callback is invoked for each token in the 
+**   order that they occur within the input text.
+**
+**   If an xToken() callback returns any value other than SQLITE_OK, then
+**   the tokenization should be abandoned and the xTokenize() method should
+**   immediately return a copy of the xToken() return value. Or, if the
+**   input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
+**   if an error occurs with the xTokenize() implementation itself, it
+**   may abandon the tokenization and return any error code other than
+**   SQLITE_OK or SQLITE_DONE.
+**
+** SYNONYM SUPPORT
+**
+**   Custom tokenizers may also support synonyms. Consider a case in which a
+**   user wishes to query for a phrase such as "first place". Using the 
+**   built-in tokenizers, the FTS5 query 'first + place' will match instances
+**   of "first place" within the document set, but not alternative forms
+**   such as "1st place". In some applications, it would be better to match
+**   all instances of "first place" or "1st place" regardless of which form
+**   the user specified in the MATCH query text.
+**
+**   There are several ways to approach this in FTS5:
+**
+**   <ol><li> By mapping all synonyms to a single token. In this case, using
+**            the above example, this means that the tokenizer returns the
+**            same token for inputs "first" and "1st". Say that token is in
+**            fact "first", so that when the user inserts the document "I won
+**            1st place" entries are added to the index for tokens "i", "won",
+**            "first" and "place". If the user then queries for '1st + place',
+**            the tokenizer substitutes "first" for "1st" and the query works
+**            as expected.
+**
+**       <li> By querying the index for all synonyms of each query term
+**            separately. In this case, when tokenizing query text, the
+**            tokenizer may provide multiple synonyms for a single term 
+**            within the document. FTS5 then queries the index for each 
+**            synonym individually. For example, faced with the query:
+**
+**   <codeblock>
+**     ... MATCH 'first place'</codeblock>
+**
+**            the tokenizer offers both "1st" and "first" as synonyms for the
+**            first token in the MATCH query and FTS5 effectively runs a query 
+**            similar to:
+**
+**   <codeblock>
+**     ... MATCH '(first OR 1st) place'</codeblock>
+**
+**            except that, for the purposes of auxiliary functions, the query
+**            still appears to contain just two phrases - "(first OR 1st)" 
+**            being treated as a single phrase.
+**
+**       <li> By adding multiple synonyms for a single term to the FTS index.
+**            Using this method, when tokenizing document text, the tokenizer
+**            provides multiple synonyms for each token. So that when a 
+**            document such as "I won first place" is tokenized, entries are
+**            added to the FTS index for "i", "won", "first", "1st" and
+**            "place".
+**
+**            This way, even if the tokenizer does not provide synonyms
+**            when tokenizing query text (it should not - to do so would be
+**            inefficient), it doesn't matter if the user queries for 
+**            'first + place' or '1st + place', as there are entries in the
+**            FTS index corresponding to both forms of the first token.
+**   </ol>
+**
+**   Whether it is parsing document or query text, any call to xToken that
+**   specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
+**   is considered to supply a synonym for the previous token. For example,
+**   when parsing the document "I won first place", a tokenizer that supports
+**   synonyms would call xToken() 5 times, as follows:
+**
+**   <codeblock>
+**       xToken(pCtx, 0, "i",                      1,  0,  1);
+**       xToken(pCtx, 0, "won",                    3,  2,  5);
+**       xToken(pCtx, 0, "first",                  5,  6, 11);
+**       xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3,  6, 11);
+**       xToken(pCtx, 0, "place",                  5, 12, 17);
+**</codeblock>
+**
+**   It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
+**   xToken() is called. Multiple synonyms may be specified for a single token
+**   by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence. 
+**   There is no limit to the number of synonyms that may be provided for a
+**   single token.
+**
+**   In many cases, method (1) above is the best approach. It does not add 
+**   extra data to the FTS index or require FTS5 to query for multiple terms,
+**   so it is efficient in terms of disk space and query speed. However, it
+**   does not support prefix queries very well. If, as suggested above, the
+**   token "first" is substituted for "1st" by the tokenizer, then the query:
+**
+**   <codeblock>
+**     ... MATCH '1s*'</codeblock>
+**
+**   will not match documents that contain the token "1st" (as the tokenizer
+**   will probably not map "1s" to any prefix of "first").
+**
+**   For full prefix support, method (3) may be preferred. In this case, 
+**   because the index contains entries for both "first" and "1st", prefix
+**   queries such as 'fi*' or '1s*' will match correctly. However, because
+**   extra entries are added to the FTS index, this method uses more space
+**   within the database.
+**
+**   Method (2) offers a midpoint between (1) and (3). Using this method,
+**   a query such as '1s*' will match documents that contain the literal 
+**   token "1st", but not "first" (assuming the tokenizer is not able to
+**   provide synonyms for prefixes). However, a non-prefix query like '1st'
+**   will match against "1st" and "first". This method does not require
+**   extra disk space, as no extra entries are added to the FTS index. 
+**   On the other hand, it may require more CPU cycles to run MATCH queries,
+**   as separate queries of the FTS index are required for each synonym.
+**
+**   When using methods (2) or (3), it is important that the tokenizer only
+**   provide synonyms when tokenizing document text (method (2)) or query
+**   text (method (3)), not both. Doing so will not cause any errors, but is
+**   inefficient.
+*/
+typedef struct Fts5Tokenizer Fts5Tokenizer;
+typedef struct fts5_tokenizer fts5_tokenizer;
+struct fts5_tokenizer {
+  int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
+  void (*xDelete)(Fts5Tokenizer*);
+  int (*xTokenize)(Fts5Tokenizer*, 
+      void *pCtx,
+      int flags,            /* Mask of FTS5_TOKENIZE_* flags */
+      const char *pText, int nText, 
+      int (*xToken)(
+        void *pCtx,         /* Copy of 2nd argument to xTokenize() */
+        int tflags,         /* Mask of FTS5_TOKEN_* flags */
+        const char *pToken, /* Pointer to buffer containing token */
+        int nToken,         /* Size of token in bytes */
+        int iStart,         /* Byte offset of token within input text */
+        int iEnd            /* Byte offset of end of token within input text */
+      )
+  );
+};
+
+/* Flags that may be passed as the third argument to xTokenize() */
+#define FTS5_TOKENIZE_QUERY     0x0001
+#define FTS5_TOKENIZE_PREFIX    0x0002
+#define FTS5_TOKENIZE_DOCUMENT  0x0004
+#define FTS5_TOKENIZE_AUX       0x0008
+
+/* Flags that may be passed by the tokenizer implementation back to FTS5
+** as the third argument to the supplied xToken callback. */
+#define FTS5_TOKEN_COLOCATED    0x0001      /* Same position as prev. token */
+
+/*
+** END OF CUSTOM TOKENIZERS
+*************************************************************************/
+
+/*************************************************************************
+** FTS5 EXTENSION REGISTRATION API
+*/
+typedef struct fts5_api fts5_api;
+struct fts5_api {
+  int iVersion;                   /* Currently always set to 2 */
+
+  /* Create a new tokenizer */
+  int (*xCreateTokenizer)(
+    fts5_api *pApi,
+    const char *zName,
+    void *pContext,
+    fts5_tokenizer *pTokenizer,
+    void (*xDestroy)(void*)
+  );
+
+  /* Find an existing tokenizer */
+  int (*xFindTokenizer)(
+    fts5_api *pApi,
+    const char *zName,
+    void **ppContext,
+    fts5_tokenizer *pTokenizer
+  );
+
+  /* Create a new auxiliary function */
+  int (*xCreateFunction)(
+    fts5_api *pApi,
+    const char *zName,
+    void *pContext,
+    fts5_extension_function xFunction,
+    void (*xDestroy)(void*)
+  );
+};
+
+/*
+** END OF REGISTRATION API
+*************************************************************************/
+
+#ifdef __cplusplus
+}  /* end of the 'extern "C"' block */
+#endif
+
+#endif /* _FTS5_H */
+
+/******** End of fts5.h *********/
diff --git a/pkgs/ffigen/tool/coverage.sh b/pkgs/ffigen/tool/coverage.sh
new file mode 100755
index 0000000..02c8e2f
--- /dev/null
+++ b/pkgs/ffigen/tool/coverage.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Fast fail the script on failures.
+set -e
+
+# Gather coverage.
+dart pub global activate coverage
+# Generate coverage report.
+dart run --pause-isolates-on-exit --disable-service-auth-codes --enable-vm-service=3000 test &
+dart pub global run coverage:collect_coverage --wait-paused --uri=http://127.0.0.1:3000/ -o coverage.json --resume-isolates --scope-output=ffigen
+dart pub global run coverage:format_coverage --packages=.dart_tool/package_config.json --lcov -i coverage.json -o lcov.info
diff --git a/pkgs/ffigen/tool/generate_json_schema.dart b/pkgs/ffigen/tool/generate_json_schema.dart
new file mode 100644
index 0000000..7a5a030
--- /dev/null
+++ b/pkgs/ffigen/tool/generate_json_schema.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// ================== GENERATING JSON SCHEMA =====================
+//    cd to project's root, and run -
+//    dart generate_json_schema.dart
+// ===============================================================
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:ffigen/ffigen.dart';
+import 'package:ffigen/src/strings.dart' as strings;
+
+void main() async {
+  final actualJsonSchema =
+      JsonEncoder.withIndent(strings.ffigenJsonSchemaIndent).convert(
+    Config.getsRootConfigSpec().generateJsonSchema(strings.ffigenJsonSchemaId),
+  );
+
+  final file = File(strings.ffigenJsonSchemaFileName);
+  if (!await file.exists()) {
+    throw Exception("File '${file.absolute.path}' does not exist.");
+  }
+  await file.writeAsString(actualJsonSchema);
+
+  print("Generated json schema: ${file.absolute.path}");
+}
diff --git a/pkgs/ffigen/tool/libclang_config.yaml b/pkgs/ffigen/tool/libclang_config.yaml
new file mode 100644
index 0000000..f569afd
--- /dev/null
+++ b/pkgs/ffigen/tool/libclang_config.yaml
@@ -0,0 +1,127 @@
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Config file for generating the libclang bindings used by this package.
+
+# ===================== GENERATING BINDINGS =====================
+#    cd to project's root, and run -
+#    dart run ffigen --config tool/libclang_config.yaml
+# ===============================================================
+
+# yaml-language-server: $schema=../ffigen.schema.json
+
+name: Clang
+description: Holds bindings to LibClang.
+output: '../lib/src/header_parser/clang_bindings/clang_bindings.dart'
+compiler-opts:
+  - '-Ithird_party/libclang/include'
+  - '-Wno-nullability-completeness'
+headers:
+  entry-points:
+    - '../third_party/libclang/include/clang-c/Index.h'
+  include-directives:
+    - '**wrapper.c'
+    - '**Index.h'
+    - '**CXString.h'
+
+preamble: |
+  // Part of the LLVM Project, under the Apache License v2.0 with LLVM
+  // Exceptions.
+  // See https://llvm.org/LICENSE.txt for license information.
+  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+  // ignore_for_file: camel_case_types, non_constant_identifier_names
+
+enums:
+  include:
+    - CXChildVisitResult
+    - CXCursorKind
+    - CXTypeKind
+    - CXDiagnosticDisplayOptions
+    - CXTranslationUnit_Flags
+    - CXEvalResultKind
+    - CXObjCPropertyAttrKind
+    - CXTypeNullabilityKind
+    - CXTypeLayoutError
+
+structs:
+  include:
+    - CXCursor
+    - CXType
+    - CXSourceLocation
+    - CXString
+    - CXTranslationUnitImpl
+    - CXUnsavedFile
+    - CXSourceRange
+
+functions:
+  include:
+    - clang_createIndex
+    - clang_disposeIndex
+    - clang_getNumDiagnostics
+    - clang_getDiagnostic
+    - clang_disposeDiagnostic
+    - clang_parseTranslationUnit
+    - clang_disposeTranslationUnit
+    - clang_EvalResult_getKind
+    - clang_EvalResult_getAsInt
+    - clang_EvalResult_getAsLongLong
+    - clang_EvalResult_getAsDouble
+    - clang_EvalResult_getAsStr
+    - clang_EvalResult_dispose
+    - clang_getCString
+    - clang_disposeString
+    - clang_getCursorKind
+    - clang_getCursorKindSpelling
+    - clang_getCursorType
+    - clang_getTypeSpelling
+    - clang_getTypeKindSpelling
+    - clang_getResultType
+    - clang_getTypedefName
+    - clang_getPointeeType
+    - clang_getCanonicalType
+    - clang_Type_getNamedType
+    - clang_Type_getAlignOf
+    - clang_getTypeDeclaration
+    - clang_getTypedefDeclUnderlyingType
+    - clang_getCursorSpelling
+    - clang_getTranslationUnitCursor
+    - clang_formatDiagnostic
+    - clang_visitChildren
+    - clang_Cursor_getNumArguments
+    - clang_Cursor_getArgument
+    - clang_getNumArgTypes
+    - clang_getArgType
+    - clang_isFunctionTypeVariadic
+    - clang_Cursor_getStorageClass
+    - clang_getCursorResultType
+    - clang_getEnumConstantDeclValue
+    - clang_equalRanges
+    - clang_Cursor_getCommentRange
+    - clang_Cursor_getRawCommentText
+    - clang_Cursor_getBriefCommentText
+    - clang_getCursorLocation
+    - clang_getFileLocation
+    - clang_getFileName
+    - clang_getNumElements
+    - clang_getArrayElementType
+    - clang_Cursor_isMacroFunctionLike
+    - clang_Cursor_isMacroBuiltin
+    - clang_Cursor_Evaluate
+    - clang_Cursor_isAnonymous
+    - clang_Cursor_isAnonymousRecordDecl
+    - clang_getCursorUSR
+    - clang_getFieldDeclBitWidth
+    - clang_Cursor_isFunctionInlined
+    - clang_getCursorDefinition
+    - clang_Cursor_isNull
+    - clang_Cursor_hasAttrs
+    - clang_Type_getObjCObjectBaseType
+    - clang_Cursor_getObjCPropertyAttributes
+    - clang_Cursor_getObjCPropertyGetterName
+    - clang_Cursor_getObjCPropertySetterName
+    - clang_Type_getNullability
+    - clang_Type_getModifiedType
+    - clang_Location_isInSystemHeader
+    - clang_getClangVersion
diff --git a/pkgs/native_assets_builder/.gitignore b/pkgs/native_assets_builder/.gitignore
new file mode 100644
index 0000000..9fa208d
--- /dev/null
+++ b/pkgs/native_assets_builder/.gitignore
@@ -0,0 +1,11 @@
+# Please keep consistent with .pubignore.
+
+# https://dart.dev/guides/libraries/private-files
+# Created by `dart pub`
+.dart_tool/
+
+# Avoid committing pubspec.lock for library packages; see
+# https://dart.dev/guides/libraries/private-files#pubspeclock.
+pubspec.lock
+
+coverage/
diff --git a/pkgs/native_assets_builder/.pubignore b/pkgs/native_assets_builder/.pubignore
new file mode 100644
index 0000000..1d80e79
--- /dev/null
+++ b/pkgs/native_assets_builder/.pubignore
@@ -0,0 +1,14 @@
+# Please keep consistent with .gitignore.
+
+# https://dart.dev/guides/libraries/private-files
+# Created by `dart pub`
+.dart_tool/
+
+# Avoid committing pubspec.lock for library packages; see
+# https://dart.dev/guides/libraries/private-files#pubspeclock.
+pubspec.lock
+
+coverage/
+
+# Woraround https://github.com/dart-lang/pub/issues/3982
+test/
diff --git a/pkgs/native_assets_builder/CHANGELOG.md b/pkgs/native_assets_builder/CHANGELOG.md
new file mode 100644
index 0000000..5700d5d
--- /dev/null
+++ b/pkgs/native_assets_builder/CHANGELOG.md
@@ -0,0 +1,38 @@
+## 0.3.0
+
+- Bump `package:native_assets_cli` to 0.3.0
+  ([#142](https://github.com/dart-lang/native/issues/142)).
+
+## 0.2.3
+
+- Quicker build planning for 0 or 1 packages with native assets
+  ([#128](https://github.com/dart-lang/native/issues/128)).
+
+## 0.2.2
+
+- Take a `PackageLayout` argument for `build` and `dryRun`
+  ([flutter#134427](https://github.com/flutter/flutter/issues/134427)).
+
+## 0.2.1
+
+- Provide a `PackageLayout` constructor for already parsed `PackageConfig`
+  ([flutter#134427](https://github.com/flutter/flutter/issues/134427)).
+
+## 0.2.0
+
+- **Breaking change** `NativeAssetsBuildRunner`s methods now return an object
+  ([#105](https://github.com/dart-lang/native/issues/105)).
+- **Breaking change** `NativeAssetsBuildRunner`s methods now return value now
+  contain a success bool instead of throwing
+  ([#106](https://github.com/dart-lang/native/issues/106)). Error messages are
+  streamed to the logger.
+- Use an `out/` sub directory for building native assets
+  ([#98](https://github.com/dart-lang/native/issues/98)).
+- Check asset ids on having having a package uri with the owning package
+  ([#96](https://github.com/dart-lang/native/issues/96)).
+- `NativeAssetsBuildRunner` now supports multiple calls
+  ([#102](https://github.com/dart-lang/native/issues/102)).
+
+## 0.1.0
+
+- Initial version.
diff --git a/pkgs/native_assets_builder/LICENSE b/pkgs/native_assets_builder/LICENSE
new file mode 100644
index 0000000..4fd5739
--- /dev/null
+++ b/pkgs/native_assets_builder/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2023, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google LLC nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkgs/native_assets_builder/README.md b/pkgs/native_assets_builder/README.md
new file mode 100644
index 0000000..dfdc0e8
--- /dev/null
+++ b/pkgs/native_assets_builder/README.md
@@ -0,0 +1,19 @@
+[![dart](https://github.com/dart-lang/native/actions/workflows/native.yaml/badge.svg)](https://github.com/dart-lang/native/actions/workflows/native.yaml)
+[![Coverage Status](https://coveralls.io/repos/github/dart-lang/native/badge.svg?branch=main)](https://coveralls.io/github/dart-lang/native?branch=main)
+[![pub package](https://img.shields.io/pub/v/native_assets_builder.svg)](https://pub.dev/packages/native_assets_builder)
+[![package publisher](https://img.shields.io/pub/publisher/native_assets_builder.svg)](https://pub.dev/packages/native_assets_builder/publisher)
+
+This package contains the shared logic for invoking [native assets CLI]s.
+
+## Audience
+
+This package is not intended for users, rather it is shared logic for Dart
+launchers to invoke the native assets CLIs of packages.
+Known Dart launchers using this shared logic: [dartdev] and [flutter_tools].
+
+For more information on how to use native assets as a user see 
+package [native assets CLI].
+
+[native assets CLI]: https://github.com/dart-lang/native/tree/main/pkgs/native_assets_cli
+[dartdev]: https://github.com/dart-lang/sdk/tree/main/pkg/dartdev
+[flutter_tools]: https://github.com/flutter/flutter/tree/master/packages/flutter_tools
diff --git a/pkgs/native_assets_builder/analysis_options.yaml b/pkgs/native_assets_builder/analysis_options.yaml
new file mode 100644
index 0000000..89ab6f0
--- /dev/null
+++ b/pkgs/native_assets_builder/analysis_options.yaml
@@ -0,0 +1,15 @@
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+analyzer:
+  language:
+    strict-raw-types: true
+  exclude:
+    # TODO(https://github.com/dart-lang/ecosystem/issues/150): Remove this.
+    - test/data/
+
+linter:
+  rules:
+    - prefer_const_declarations
+    - prefer_expression_function_bodies
+    - prefer_final_in_for_each
+    - prefer_final_locals
diff --git a/pkgs/native_assets_builder/dart_test.yaml b/pkgs/native_assets_builder/dart_test.yaml
new file mode 100644
index 0000000..c1c8a57
--- /dev/null
+++ b/pkgs/native_assets_builder/dart_test.yaml
@@ -0,0 +1,2 @@
+paths:
+  - test/build_runner/
diff --git a/pkgs/native_assets_builder/lib/native_assets_builder.dart b/pkgs/native_assets_builder/lib/native_assets_builder.dart
new file mode 100644
index 0000000..3ff29ab
--- /dev/null
+++ b/pkgs/native_assets_builder/lib/native_assets_builder.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'package:native_assets_builder/src/build_runner/build_runner.dart';
+export 'package:native_assets_builder/src/package_layout/package_layout.dart';
diff --git a/pkgs/native_assets_builder/lib/src/build_runner/build_planner.dart b/pkgs/native_assets_builder/lib/src/build_runner/build_planner.dart
new file mode 100644
index 0000000..24c533a
--- /dev/null
+++ b/pkgs/native_assets_builder/lib/src/build_runner/build_planner.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:graphs/graphs.dart' as graphs;
+import 'package:logging/logging.dart';
+import 'package:package_config/package_config.dart';
+
+class NativeAssetsBuildPlanner {
+  final PackageGraph packageGraph;
+  final List<Package> packagesWithNativeAssets;
+  final Uri dartExecutable;
+  final Logger logger;
+
+  NativeAssetsBuildPlanner({
+    required this.packageGraph,
+    required this.packagesWithNativeAssets,
+    required this.dartExecutable,
+    required this.logger,
+  });
+
+  static Future<NativeAssetsBuildPlanner> fromRootPackageRoot({
+    required Uri rootPackageRoot,
+    required List<Package> packagesWithNativeAssets,
+    required Uri dartExecutable,
+    required Logger logger,
+  }) async {
+    final result = await Process.run(
+      dartExecutable.toFilePath(),
+      [
+        'pub',
+        'deps',
+        '--json',
+      ],
+      workingDirectory: rootPackageRoot.toFilePath(),
+    );
+    final packageGraph =
+        PackageGraph.fromPubDepsJsonString(result.stdout as String);
+    return NativeAssetsBuildPlanner(
+      packageGraph: packageGraph,
+      packagesWithNativeAssets: packagesWithNativeAssets,
+      dartExecutable: dartExecutable,
+      logger: logger,
+    );
+  }
+
+  (List<Package> packages, bool success) plan() {
+    final packageMap = {
+      for (final package in packagesWithNativeAssets) package.name: package
+    };
+    final packagesToBuild = packageMap.keys.toSet();
+    final stronglyConnectedComponents = packageGraph.computeStrongComponents();
+    final result = <Package>[];
+    var success = true;
+    for (final stronglyConnectedComponent in stronglyConnectedComponents) {
+      final stronglyConnectedComponentWithNativeAssets = [
+        for (final packageName in stronglyConnectedComponent)
+          if (packagesToBuild.contains(packageName)) packageName
+      ];
+      if (stronglyConnectedComponentWithNativeAssets.length > 1) {
+        logger.severe(
+          'Cyclic dependency for native asset builds in the following '
+          'packages: $stronglyConnectedComponentWithNativeAssets.',
+        );
+        success = false;
+      } else if (stronglyConnectedComponentWithNativeAssets.length == 1) {
+        result.add(
+            packageMap[stronglyConnectedComponentWithNativeAssets.single]!);
+      }
+    }
+    return (result, success);
+  }
+}
+
+class PackageGraph {
+  final Map<String, List<String>> map;
+
+  PackageGraph(this.map);
+
+  /// Construct a graph from the JSON produced by `dart pub deps --json`.
+  factory PackageGraph.fromPubDepsJsonString(String json) =>
+      PackageGraph.fromPubDepsJson(jsonDecode(json) as Map<dynamic, dynamic>);
+
+  /// Construct a graph from the JSON produced by `dart pub deps --json`.
+  factory PackageGraph.fromPubDepsJson(Map<dynamic, dynamic> map) {
+    final result = <String, List<String>>{};
+    final packages = map['packages'] as List<dynamic>;
+    for (final package in packages) {
+      final package_ = package as Map<dynamic, dynamic>;
+      final name = package_['name'] as String;
+      final dependencies = (package_['dependencies'] as List<dynamic>)
+          .whereType<String>()
+          .toList();
+      result[name] = dependencies;
+    }
+    return PackageGraph(result);
+  }
+
+  Iterable<String> neighborsOf(String vertex) => map[vertex] ?? [];
+
+  Iterable<String> get vertices => map.keys;
+
+  List<List<String>> computeStrongComponents() =>
+      graphs.stronglyConnectedComponents(vertices, neighborsOf);
+}
diff --git a/pkgs/native_assets_builder/lib/src/build_runner/build_runner.dart b/pkgs/native_assets_builder/lib/src/build_runner/build_runner.dart
new file mode 100644
index 0000000..579855c
--- /dev/null
+++ b/pkgs/native_assets_builder/lib/src/build_runner/build_runner.dart
@@ -0,0 +1,478 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:package_config/package_config.dart';
+
+import '../package_layout/package_layout.dart';
+import '../utils/run_process.dart';
+import 'build_planner.dart';
+
+typedef DependencyMetadata = Map<String, Metadata>;
+
+/// The programmatic API to be used by Dart launchers to invoke native builds.
+///
+/// These methods are invoked by launchers such as dartdev (for `dart run`)
+/// and flutter_tools (for `flutter run` and `flutter build`).
+class NativeAssetsBuildRunner {
+  final Logger logger;
+  final Uri dartExecutable;
+
+  NativeAssetsBuildRunner({
+    required this.logger,
+    required this.dartExecutable,
+  });
+
+  /// [workingDirectory] is expected to contain `.dart_tool`.
+  ///
+  /// This method is invoked by launchers such as dartdev (for `dart run`) and
+  /// flutter_tools (for `flutter run` and `flutter build`).
+  ///
+  /// Completes the future with an error if the build fails.
+  Future<BuildResult> build({
+    required LinkModePreference linkModePreference,
+    required Target target,
+    required Uri workingDirectory,
+    required BuildMode buildMode,
+    CCompilerConfig? cCompilerConfig,
+    IOSSdk? targetIOSSdk,
+    int? targetAndroidNdkApi,
+    required bool includeParentEnvironment,
+    PackageLayout? packageLayout,
+  }) async {
+    packageLayout ??= await PackageLayout.fromRootPackageRoot(workingDirectory);
+    final packagesWithNativeAssets =
+        await packageLayout.packagesWithNativeAssets;
+    final List<Package> buildPlan;
+    final PackageGraph packageGraph;
+    if (packagesWithNativeAssets.length <= 1) {
+      buildPlan = packagesWithNativeAssets;
+      packageGraph = PackageGraph({
+        for (final p in packagesWithNativeAssets) p.name: [],
+      });
+    } else {
+      final planner = await NativeAssetsBuildPlanner.fromRootPackageRoot(
+        rootPackageRoot: packageLayout.rootPackageRoot,
+        packagesWithNativeAssets: packagesWithNativeAssets,
+        dartExecutable: Uri.file(Platform.resolvedExecutable),
+        logger: logger,
+      );
+      final (plan, planSuccess) = planner.plan();
+      if (!planSuccess) {
+        return _BuildResultImpl(
+          assets: [],
+          dependencies: [],
+          success: false,
+        );
+      }
+      buildPlan = plan;
+      packageGraph = planner.packageGraph;
+    }
+    final assets = <Asset>[];
+    final dependencies = <Uri>[];
+    final metadata = <String, Metadata>{};
+    var success = true;
+    for (final package in buildPlan) {
+      final dependencyMetadata = _metadataForPackage(
+        packageGraph: packageGraph,
+        packageName: package.name,
+        targetMetadata: metadata,
+      );
+      final config = await _cliConfig(
+        packageName: package.name,
+        packageRoot: packageLayout.packageRoot(package.name),
+        target: target,
+        buildMode: buildMode,
+        linkMode: linkModePreference,
+        buildParentDir: packageLayout.dartToolNativeAssetsBuilder,
+        dependencyMetadata: dependencyMetadata,
+        cCompilerConfig: cCompilerConfig,
+        targetIOSSdk: targetIOSSdk,
+        targetAndroidNdkApi: targetAndroidNdkApi,
+      );
+      final (
+        packageAssets,
+        packageDependencies,
+        packageMetadata,
+        packageSuccess,
+      ) = await _buildPackageCached(
+        config,
+        packageLayout.packageConfigUri,
+        workingDirectory,
+        includeParentEnvironment,
+      );
+      assets.addAll(packageAssets);
+      dependencies.addAll(packageDependencies);
+      success &= packageSuccess;
+      if (packageMetadata != null) {
+        metadata[config.packageName] = packageMetadata;
+      }
+    }
+    return _BuildResultImpl(
+      assets: assets,
+      dependencies: dependencies..sort(_uriCompare),
+      success: success,
+    );
+  }
+
+  /// [workingDirectory] is expected to contain `.dart_tool`.
+  ///
+  /// This method is invoked by launchers such as dartdev (for `dart run`) and
+  /// flutter_tools (for `flutter run` and `flutter build`).
+  ///
+  /// Completes the future with an error if the build fails.
+  Future<DryRunResult> dryRun({
+    required LinkModePreference linkModePreference,
+    required OS targetOs,
+    required Uri workingDirectory,
+    required bool includeParentEnvironment,
+    PackageLayout? packageLayout,
+  }) async {
+    packageLayout ??= await PackageLayout.fromRootPackageRoot(workingDirectory);
+    final packagesWithNativeAssets =
+        await packageLayout.packagesWithNativeAssets;
+    final List<Package> buildPlan;
+    if (packagesWithNativeAssets.length <= 1) {
+      buildPlan = packagesWithNativeAssets;
+    } else {
+      final planner = await NativeAssetsBuildPlanner.fromRootPackageRoot(
+        rootPackageRoot: packageLayout.rootPackageRoot,
+        packagesWithNativeAssets: packagesWithNativeAssets,
+        dartExecutable: Uri.file(Platform.resolvedExecutable),
+        logger: logger,
+      );
+      final (plan, planSuccess) = planner.plan();
+      if (!planSuccess) {
+        return _DryRunResultImpl(
+          assets: [],
+          success: false,
+        );
+      }
+      buildPlan = plan;
+    }
+    final assets = <Asset>[];
+    var success = true;
+    for (final package in buildPlan) {
+      final config = await _cliConfigDryRun(
+        packageName: package.name,
+        packageRoot: packageLayout.packageRoot(package.name),
+        targetOs: targetOs,
+        linkMode: linkModePreference,
+        buildParentDir: packageLayout.dartToolNativeAssetsBuilder,
+      );
+      final (packageAssets, _, _, packageSuccess) = await _buildPackage(
+        config,
+        packageLayout.packageConfigUri,
+        workingDirectory,
+        includeParentEnvironment,
+        dryRun: true,
+      );
+      assets.addAll(packageAssets);
+      success &= packageSuccess;
+    }
+    return _DryRunResultImpl(
+      assets: assets,
+      success: success,
+    );
+  }
+
+  Future<_PackageBuildRecord> _buildPackageCached(
+    BuildConfig config,
+    Uri packageConfigUri,
+    Uri workingDirectory,
+    bool includeParentEnvironment,
+  ) async {
+    final packageName = config.packageName;
+    final outDir = config.outDir;
+    if (!await Directory.fromUri(outDir).exists()) {
+      await Directory.fromUri(outDir).create(recursive: true);
+    }
+
+    final buildOutput = await BuildOutput.readFromFile(outDir: outDir);
+    final lastBuilt = buildOutput?.timestamp.roundDownToSeconds() ??
+        DateTime.fromMillisecondsSinceEpoch(0);
+    final dependencies = buildOutput?.dependencies;
+    final lastChange = await dependencies?.lastModified() ?? DateTime.now();
+
+    if (lastBuilt.isAfter(lastChange)) {
+      logger.info('Skipping build for $packageName in $outDir. '
+          'Last build on $lastBuilt, last input change on $lastChange.');
+      // All build flags go into [outDir]. Therefore we do not have to check
+      // here whether the config is equal.
+      final assets = buildOutput!.assets;
+      final dependencies = buildOutput.dependencies.dependencies;
+      final metadata = buildOutput.metadata;
+      return (assets, dependencies, metadata, true);
+    }
+
+    return await _buildPackage(
+      config,
+      packageConfigUri,
+      workingDirectory,
+      includeParentEnvironment,
+      dryRun: false,
+    );
+  }
+
+  Future<_PackageBuildRecord> _buildPackage(
+    BuildConfig config,
+    Uri packageConfigUri,
+    Uri workingDirectory,
+    bool includeParentEnvironment, {
+    required bool dryRun,
+  }) async {
+    final outDir = config.outDir;
+    final configFile = outDir.resolve('../config.yaml');
+    final buildDotDart = config.packageRoot.resolve('build.dart');
+    final configFileContents = config.toYamlString();
+    logger.info('config.yaml contents: $configFileContents');
+    await File.fromUri(configFile).writeAsString(configFileContents);
+    final buildOutputFile = File.fromUri(outDir.resolve(BuildOutput.fileName));
+    if (await buildOutputFile.exists()) {
+      // Ensure we'll never read outdated build results.
+      await buildOutputFile.delete();
+    }
+    final arguments = [
+      '--packages=${packageConfigUri.toFilePath()}',
+      buildDotDart.toFilePath(),
+      '--config=${configFile.toFilePath()}',
+    ];
+    final result = await runProcess(
+      workingDirectory: workingDirectory,
+      executable: dartExecutable,
+      arguments: arguments,
+      logger: logger,
+      includeParentEnvironment: includeParentEnvironment,
+    );
+    var success = true;
+    if (result.exitCode != 0) {
+      final printWorkingDir = workingDirectory != Directory.current.uri;
+      final commandString = [
+        if (printWorkingDir) '(cd ${workingDirectory.toFilePath()};',
+        dartExecutable.toFilePath(),
+        ...arguments.map((a) => a.contains(' ') ? "'$a'" : a),
+        if (printWorkingDir) ')',
+      ].join(' ');
+      logger.severe(
+        '''
+Building native assets for package:${config.packageName} failed.
+build.dart returned with exit code: ${result.exitCode}.
+To reproduce run:
+$commandString
+stderr:
+${result.stderr}
+stdout:
+${result.stdout}
+        ''',
+      );
+      success = false;
+    }
+
+    try {
+      final buildOutput = await BuildOutput.readFromFile(outDir: outDir);
+      final assets = buildOutput?.assets ?? [];
+      success &= validateAssetsPackage(assets, config.packageName);
+      final dependencies = buildOutput?.dependencies.dependencies ?? [];
+      final metadata = dryRun ? null : buildOutput?.metadata;
+      return (assets, dependencies, metadata, success);
+    } on FormatException catch (e) {
+      logger.severe('''
+Building native assets for package:${config.packageName} failed.
+build_output.yaml contained a format error.
+${e.message}
+        ''');
+      success = false;
+      return (<Asset>[], <Uri>[], const Metadata({}), false);
+      // TODO(https://github.com/dart-lang/native/issues/109): Stop throwing
+      // type errors in native_assets_cli, release a new version of that package
+      // and then remove this.
+      // ignore: avoid_catching_errors
+    } on TypeError {
+      logger.severe('''
+Building native assets for package:${config.packageName} failed.
+build_output.yaml contained a format error.
+        ''');
+      success = false;
+      return (<Asset>[], <Uri>[], const Metadata({}), false);
+    } finally {
+      if (!success) {
+        final buildOutputFile =
+            File.fromUri(outDir.resolve(BuildOutput.fileName));
+        if (await buildOutputFile.exists()) {
+          await buildOutputFile.delete();
+        }
+      }
+    }
+  }
+
+  static Future<BuildConfig> _cliConfig({
+    required String packageName,
+    required Uri packageRoot,
+    required Target target,
+    IOSSdk? targetIOSSdk,
+    int? targetAndroidNdkApi,
+    required BuildMode buildMode,
+    required LinkModePreference linkMode,
+    required Uri buildParentDir,
+    CCompilerConfig? cCompilerConfig,
+    DependencyMetadata? dependencyMetadata,
+  }) async {
+    final buildDirName = BuildConfig.checksum(
+      packageName: packageName,
+      packageRoot: packageRoot,
+      targetOs: target.os,
+      targetArchitecture: target.architecture,
+      buildMode: buildMode,
+      linkModePreference: linkMode,
+      targetIOSSdk: targetIOSSdk,
+      cCompiler: cCompilerConfig,
+      dependencyMetadata: dependencyMetadata,
+      targetAndroidNdkApi: targetAndroidNdkApi,
+    );
+    final outDirUri = buildParentDir.resolve('$buildDirName/out/');
+    final outDir = Directory.fromUri(outDirUri);
+    if (!await outDir.exists()) {
+      // TODO(https://dartbug.com/50565): Purge old or unused folders.
+      await outDir.create(recursive: true);
+    }
+    return BuildConfig(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: packageRoot,
+      targetOs: target.os,
+      targetArchitecture: target.architecture,
+      buildMode: buildMode,
+      linkModePreference: linkMode,
+      targetIOSSdk: targetIOSSdk,
+      cCompiler: cCompilerConfig,
+      dependencyMetadata: dependencyMetadata,
+      targetAndroidNdkApi: targetAndroidNdkApi,
+    );
+  }
+
+  static Future<BuildConfig> _cliConfigDryRun({
+    required String packageName,
+    required Uri packageRoot,
+    required OS targetOs,
+    required LinkModePreference linkMode,
+    required Uri buildParentDir,
+  }) async {
+    final buildDirName = 'dry_run_${targetOs}_$linkMode';
+    final outDirUri = buildParentDir.resolve('$buildDirName/out/');
+    final outDir = Directory.fromUri(outDirUri);
+    if (!await outDir.exists()) {
+      await outDir.create(recursive: true);
+    }
+    return BuildConfig.dryRun(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: packageRoot,
+      targetOs: targetOs,
+      linkModePreference: linkMode,
+    );
+  }
+
+  DependencyMetadata? _metadataForPackage({
+    required PackageGraph packageGraph,
+    required String packageName,
+    DependencyMetadata? targetMetadata,
+  }) {
+    if (targetMetadata == null) {
+      return null;
+    }
+    final dependencies = packageGraph.neighborsOf(packageName).toSet();
+    return {
+      for (final entry in targetMetadata.entries)
+        if (dependencies.contains(entry.key)) entry.key: entry.value,
+    };
+  }
+
+  bool validateAssetsPackage(List<Asset> assets, String packageName) {
+    final invalidAssetIds = assets
+        .map((a) => a.id)
+        .where((n) => !n.startsWith('package:$packageName/'))
+        .toSet()
+        .toList()
+      ..sort();
+    final success = invalidAssetIds.isEmpty;
+    if (!success) {
+      logger.severe(
+        '`package:$packageName` declares the following assets which do not '
+        'start with `package:$packageName/`: ${invalidAssetIds.join(', ')}.',
+      );
+    }
+    return success;
+  }
+}
+
+typedef _PackageBuildRecord = (
+  List<Asset>,
+  List<Uri> dependencies,
+  Metadata?,
+  bool success,
+);
+
+/// The result from a [NativeAssetsBuildRunner.dryRun].
+abstract interface class DryRunResult {
+  /// The native assets for all [Target]s for the build or dry run.
+  List<Asset> get assets;
+
+  /// Whether all builds completed without errors.
+  ///
+  /// All error messages are streamed to [NativeAssetsBuildRunner.logger].
+  bool get success;
+}
+
+final class _DryRunResultImpl implements DryRunResult {
+  @override
+  final List<Asset> assets;
+
+  @override
+  final bool success;
+
+  _DryRunResultImpl({
+    required this.assets,
+    required this.success,
+  });
+}
+
+/// The result from a [NativeAssetsBuildRunner.build].
+abstract class BuildResult implements DryRunResult {
+  /// All the files used for building the native assets of all packages.
+  ///
+  /// This aggregated list can be used to determine whether the
+  /// [NativeAssetsBuildRunner] needs to be invoked again. The
+  /// [NativeAssetsBuildRunner] determines per package with native assets
+  /// if it needs to run the build again.
+  List<Uri> get dependencies;
+}
+
+final class _BuildResultImpl implements BuildResult {
+  @override
+  final List<Asset> assets;
+
+  @override
+  final List<Uri> dependencies;
+
+  @override
+  final bool success;
+
+  _BuildResultImpl({
+    required this.assets,
+    required this.dependencies,
+    required this.success,
+  });
+}
+
+extension on DateTime {
+  DateTime roundDownToSeconds() =>
+      DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch -
+          millisecondsSinceEpoch % const Duration(seconds: 1).inMilliseconds);
+}
+
+int _uriCompare(Uri u1, Uri u2) => u1.toString().compareTo(u2.toString());
diff --git a/pkgs/native_assets_builder/lib/src/package_layout/package_layout.dart b/pkgs/native_assets_builder/lib/src/package_layout/package_layout.dart
new file mode 100644
index 0000000..00b97d2
--- /dev/null
+++ b/pkgs/native_assets_builder/lib/src/package_layout/package_layout.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:package_config/package_config.dart';
+
+/// Directory layout for dealing with native assets.
+///
+/// Build scripts for native assets will be run from the context of another
+/// root package.
+///
+/// The directory layout follows pub's convention for caching:
+/// https://dart.dev/tools/pub/package-layout#project-specific-caching-for-tools
+class PackageLayout {
+  /// The root folder of the current dart invocation root package.
+  ///
+  /// `$rootPackageRoot`.
+  final Uri rootPackageRoot;
+
+  /// Package config containing the information of where to foot the root [Uri]s
+  /// of other packages.
+  ///
+  /// Can be `null` to enable quick construction of a
+  /// [PackageLayout].
+  final PackageConfig packageConfig;
+
+  final Uri packageConfigUri;
+
+  PackageLayout._(
+      this.rootPackageRoot, this.packageConfig, this.packageConfigUri);
+
+  factory PackageLayout.fromPackageConfig(
+    PackageConfig packageConfig,
+    Uri packageConfigUri,
+  ) {
+    assert(File.fromUri(packageConfigUri).existsSync());
+    packageConfigUri = packageConfigUri.normalizePath();
+    final rootPackageRoot = packageConfigUri.resolve('../');
+    return PackageLayout._(rootPackageRoot, packageConfig, packageConfigUri);
+  }
+
+  static Future<PackageLayout> fromRootPackageRoot(Uri rootPackageRoot) async {
+    rootPackageRoot = rootPackageRoot.normalizePath();
+    final packageConfigUri =
+        rootPackageRoot.resolve('.dart_tool/package_config.json');
+    assert(await File.fromUri(packageConfigUri).exists());
+    final packageConfig = await loadPackageConfigUri(packageConfigUri);
+    return PackageLayout._(rootPackageRoot, packageConfig, packageConfigUri);
+  }
+
+  /// The .dart_tool directory is used to store built artifacts and caches.
+  ///
+  /// `$rootPackageRoot/.dart_tool/`.
+  ///
+  /// Each package should only modify the subfolder of `.dart_tool/` with its
+  /// own name.
+  /// https://dart.dev/tools/pub/package-layout#project-specific-caching-for-tools
+  late final Uri dartTool = rootPackageRoot.resolve('.dart_tool/');
+
+  /// The directory where `package:native_assets_builder` stores all persistent
+  /// information.
+  ///
+  /// This folder is owned by `package:native_assets_builder`, no other package
+  /// should read or modify it.
+  /// https://dart.dev/tools/pub/package-layout#project-specific-caching-for-tools
+  ///
+  /// `$rootPackageRoot/.dart_tool/native_assets_builder/`.
+  late final Uri dartToolNativeAssetsBuilder =
+      dartTool.resolve('native_assets_builder/');
+
+  /// The root of `package:$packageName`.
+  ///
+  /// `$packageName/`.
+  ///
+  /// This folder is owned by pub, and should _never_ be written to.
+  Uri packageRoot(String packageName) {
+    final package = packageConfig[packageName];
+    if (package == null) {
+      throw StateError('Package $packageName not found in packageConfig.');
+    }
+    return package.root;
+  }
+
+  /// All packages in [packageConfig] with native assets.
+  ///
+  /// Whether a package has native assets is defined by whether it contains
+  /// a `build.dart`.
+  ///
+  /// `package:native` itself is excluded.
+  late final Future<List<Package>> packagesWithNativeAssets = () async {
+    final result = <Package>[];
+    for (final package in packageConfig.packages) {
+      final packageRoot = package.root;
+      if (packageRoot.scheme == 'file') {
+        if (await File.fromUri(packageRoot.resolve('build.dart')).exists()) {
+          result.add(package);
+        }
+      }
+    }
+    return result;
+  }();
+}
diff --git a/pkgs/native_assets_builder/lib/src/utils/run_process.dart b/pkgs/native_assets_builder/lib/src/utils/run_process.dart
new file mode 100644
index 0000000..cb989c7
--- /dev/null
+++ b/pkgs/native_assets_builder/lib/src/utils/run_process.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:logging/logging.dart';
+
+/// Runs a [Process].
+///
+/// If [logger] is provided, stream stdout and stderr to it.
+///
+/// If [captureOutput], captures stdout and stderr.
+// TODO(dacoharkes): Share between package:native_toolchain_c and here.
+Future<RunProcessResult> runProcess({
+  required Uri executable,
+  List<String> arguments = const [],
+  Uri? workingDirectory,
+  Map<String, String>? environment,
+  bool includeParentEnvironment = true,
+  required Logger? logger,
+  bool captureOutput = true,
+  int expectedExitCode = 0,
+  bool throwOnUnexpectedExitCode = false,
+}) async {
+  if (Platform.isWindows && !includeParentEnvironment) {
+    const winEnvKeys = [
+      'SYSTEMROOT',
+      'TEMP',
+      'TMP',
+    ];
+    environment = {
+      for (final winEnvKey in winEnvKeys)
+        winEnvKey: Platform.environment[winEnvKey]!,
+      ...?environment,
+    };
+  }
+
+  final printWorkingDir =
+      workingDirectory != null && workingDirectory != Directory.current.uri;
+  final commandString = [
+    if (printWorkingDir) '(cd ${workingDirectory.toFilePath()};',
+    ...?environment?.entries.map((entry) => '${entry.key}=${entry.value}'),
+    executable.toFilePath(),
+    ...arguments.map((a) => a.contains(' ') ? "'$a'" : a),
+    if (printWorkingDir) ')',
+  ].join(' ');
+  logger?.info('Running `$commandString`.');
+
+  final stdoutBuffer = StringBuffer();
+  final stderrBuffer = StringBuffer();
+  final process = await Process.start(
+    executable.toFilePath(),
+    arguments,
+    workingDirectory: workingDirectory?.toFilePath(),
+    environment: environment,
+    includeParentEnvironment: includeParentEnvironment,
+    runInShell: Platform.isWindows &&
+        (!includeParentEnvironment || workingDirectory != null),
+  );
+
+  final stdoutSub = process.stdout
+      .transform(utf8.decoder)
+      .transform(const LineSplitter())
+      .listen(captureOutput
+          ? (s) {
+              logger?.fine(s);
+              stdoutBuffer.writeln(s);
+            }
+          : logger?.fine);
+  final stderrSub = process.stderr
+      .transform(utf8.decoder)
+      .transform(const LineSplitter())
+      .listen(captureOutput
+          ? (s) {
+              logger?.severe(s);
+              stderrBuffer.writeln(s);
+            }
+          : logger?.severe);
+
+  final (exitCode, _, _) = await (
+    process.exitCode,
+    stdoutSub.asFuture<void>(),
+    stderrSub.asFuture<void>()
+  ).wait;
+  final result = RunProcessResult(
+    pid: process.pid,
+    command: commandString,
+    exitCode: exitCode,
+    stdout: stdoutBuffer.toString(),
+    stderr: stderrBuffer.toString(),
+  );
+  if (throwOnUnexpectedExitCode && expectedExitCode != exitCode) {
+    throw ProcessException(
+      executable.toFilePath(),
+      arguments,
+      "Full command string: '$commandString'.\n"
+      "Exit code: '$exitCode'.\n"
+      'For the output of the process check the logger output.',
+    );
+  }
+  return result;
+}
+
+/// Drop in replacement of [ProcessResult].
+class RunProcessResult {
+  final int pid;
+
+  final String command;
+
+  final int exitCode;
+
+  final String stderr;
+
+  final String stdout;
+
+  RunProcessResult({
+    required this.pid,
+    required this.command,
+    required this.exitCode,
+    required this.stderr,
+    required this.stdout,
+  });
+
+  @override
+  String toString() => '''command: $command
+exitCode: $exitCode
+stdout: $stdout
+stderr: $stderr''';
+}
diff --git a/pkgs/native_assets_builder/pubspec.yaml b/pkgs/native_assets_builder/pubspec.yaml
new file mode 100644
index 0000000..af8c48e
--- /dev/null
+++ b/pkgs/native_assets_builder/pubspec.yaml
@@ -0,0 +1,20 @@
+name: native_assets_builder
+description: >-
+  This package is the backend that invokes top-level `build.dart` scripts.
+version: 0.3.0
+repository: https://github.com/dart-lang/native/tree/main/pkgs/native_assets_builder
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  graphs: ^2.3.1
+  logging: ^1.2.0
+  native_assets_cli: ^0.3.0
+  package_config: ^2.1.0
+
+dev_dependencies:
+  dart_flutter_team_lints: ^2.1.1
+  file_testing: ^3.0.0
+  test: ^1.24.3
+  yaml: ^3.1.2
diff --git a/pkgs/native_assets_builder/test/build_runner/build_dependencies_test.dart b/pkgs/native_assets_builder/test/build_runner/build_dependencies_test.dart
new file mode 100644
index 0000000..4e5de91
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/build_dependencies_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  test('dart_app build dependencies', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('dart_app/');
+
+      // First, run `pub get`, we need pub to resolve our dependencies.
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+
+      // Trigger a build, should invoke build for libraries with native assets.
+      {
+        final logMessages = <String>[];
+        final result = await build(packageUri, logger, dartExecutable,
+            capturedLogs: logMessages);
+        expect(
+          logMessages.join('\n'),
+          stringContainsInOrder(
+            [
+              'native_add${Platform.pathSeparator}build.dart',
+              'native_subtract${Platform.pathSeparator}build.dart'
+            ],
+          ),
+        );
+        expect(result.assets.length, 2);
+        expect(
+          result.dependencies,
+          [
+            tempUri.resolve('native_add/').resolve('build.dart'),
+            tempUri.resolve('native_add/').resolve('src/native_add.c'),
+            tempUri.resolve('native_subtract/').resolve('build.dart'),
+            tempUri
+                .resolve('native_subtract/')
+                .resolve('src/native_subtract.c'),
+          ],
+        );
+      }
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/build_planner_test.dart b/pkgs/native_assets_builder/test/build_runner/build_planner_test.dart
new file mode 100644
index 0000000..48daae3
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/build_planner_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_assets_builder/native_assets_builder.dart';
+import 'package:native_assets_builder/src/build_runner/build_planner.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+void main() async {
+  test('build dependency graph from pub', () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final nativeAddUri = tempUri.resolve('native_add/');
+
+      // First, run `pub get`, we need pub to resolve our dependencies.
+      await runPubGet(workingDirectory: nativeAddUri, logger: logger);
+
+      final result = await runProcess(
+        executable: Uri.file(Platform.resolvedExecutable),
+        arguments: [
+          'pub',
+          'deps',
+          '--json',
+        ],
+        workingDirectory: nativeAddUri,
+        logger: logger,
+      );
+      expect(result.exitCode, 0);
+
+      final graph = PackageGraph.fromPubDepsJsonString(result.stdout);
+
+      final packageLayout =
+          await PackageLayout.fromRootPackageRoot(nativeAddUri);
+      final packagesWithNativeAssets =
+          await packageLayout.packagesWithNativeAssets;
+
+      final planner = NativeAssetsBuildPlanner(
+        packageGraph: graph,
+        packagesWithNativeAssets: packagesWithNativeAssets,
+        dartExecutable: Uri.file(Platform.resolvedExecutable),
+        logger: logger,
+      );
+      final (buildPlan, _) = planner.plan();
+      expect(buildPlan.length, 1);
+      expect(buildPlan.single.name, 'native_add');
+    });
+  });
+  test('build dependency graph fromPackageRoot', () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final nativeAddUri = tempUri.resolve('native_add/');
+
+      // First, run `pub get`, we need pub to resolve our dependencies.
+      await runPubGet(workingDirectory: nativeAddUri, logger: logger);
+
+      final packageLayout =
+          await PackageLayout.fromRootPackageRoot(nativeAddUri);
+      final packagesWithNativeAssets =
+          await packageLayout.packagesWithNativeAssets;
+      final nativeAssetsBuildPlanner =
+          await NativeAssetsBuildPlanner.fromRootPackageRoot(
+        rootPackageRoot: nativeAddUri,
+        packagesWithNativeAssets: packagesWithNativeAssets,
+        dartExecutable: Uri.file(Platform.resolvedExecutable),
+        logger: logger,
+      );
+      final (buildPlan, _) = nativeAssetsBuildPlanner.plan();
+      expect(buildPlan.length, 1);
+      expect(buildPlan.single.name, 'native_add');
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/build_runner_asset_id_test.dart b/pkgs/native_assets_builder/test/build_runner/build_runner_asset_id_test.dart
new file mode 100644
index 0000000..19ad319
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/build_runner_asset_id_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  test('wrong asset id', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('wrong_namespace_asset/');
+
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+
+      {
+        final logMessages = <String>[];
+        final result = await build(
+          packageUri,
+          createCapturingLogger(logMessages, level: Level.SEVERE),
+          dartExecutable,
+        );
+        final fullLog = logMessages.join('\n');
+        expect(result.success, false);
+        expect(
+          fullLog,
+          contains(
+            '`package:wrong_namespace_asset` declares the following assets '
+            'which do not start with `package:wrong_namespace_asset/`:',
+          ),
+        );
+      }
+    });
+  });
+
+  test('right asset id but other directory', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      final packageUri = tempUri.resolve('different_root_dir/');
+      await copyTestProjects(
+        sourceUri: testDataUri.resolve('native_add/'),
+        targetUri: packageUri,
+      );
+
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+
+      {
+        final result = await build(
+          packageUri,
+          logger,
+          dartExecutable,
+        );
+        expect(result.success, true);
+      }
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/build_runner_build_output_format_test.dart b/pkgs/native_assets_builder/test/build_runner/build_runner_build_output_format_test.dart
new file mode 100644
index 0000000..21f15f9
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/build_runner_build_output_format_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  for (final package in [
+    'wrong_build_output',
+    'wrong_build_output_2',
+    'wrong_build_output_3',
+  ]) {
+    test('wrong build output $package', timeout: longTimeout, () async {
+      await inTempDir((tempUri) async {
+        await copyTestProjects(targetUri: tempUri);
+        final packageUri = tempUri.resolve('$package/');
+
+        await runPubGet(
+          workingDirectory: packageUri,
+          logger: logger,
+        );
+
+        // Run twice, failures should not be cached and return the same errors.
+        for (final _ in [1, 2]) {
+          final logMessages = <String>[];
+          final result = await build(
+            packageUri,
+            createCapturingLogger(logMessages, level: Level.SEVERE),
+            dartExecutable,
+          );
+          final fullLog = logMessages.join('\n');
+          expect(result.success, false);
+          if (package == 'wrong_build_output_3') {
+            // Should re-execute the process on second run.
+            expect(
+              fullLog,
+              contains('build.dart returned with exit code: 1.'),
+            );
+          } else {
+            expect(
+              fullLog,
+              contains('build_output.yaml contained a format error.'),
+            );
+          }
+        }
+      });
+    });
+  }
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/build_runner_caching_test.dart b/pkgs/native_assets_builder/test/build_runner/build_runner_caching_test.dart
new file mode 100644
index 0000000..2749e53
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/build_runner_caching_test.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  test('cached build', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('native_add/');
+
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+
+      {
+        final logMessages = <String>[];
+        final result = await build(packageUri, logger, dartExecutable,
+            capturedLogs: logMessages);
+        expect(
+          logMessages.join('\n'),
+          contains('native_add${Platform.pathSeparator}build.dart'),
+        );
+        expect(
+          result.dependencies,
+          [
+            packageUri.resolve('build.dart'),
+            packageUri.resolve('src/native_add.c'),
+          ],
+        );
+      }
+
+      {
+        final logMessages = <String>[];
+        final result = await build(packageUri, logger, dartExecutable,
+            capturedLogs: logMessages);
+        expect(
+          logMessages.join('\n'),
+          contains('Skipping build for native_add'),
+        );
+        expect(
+          logMessages.join('\n'),
+          isNot(contains('native_add${Platform.pathSeparator}build.dart')),
+        );
+        expect(
+          result.dependencies,
+          [
+            packageUri.resolve('build.dart'),
+            packageUri.resolve('src/native_add.c'),
+          ],
+        );
+      }
+    });
+  });
+
+  test('modify C file', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('native_add/');
+
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+
+      {
+        final result = await build(packageUri, logger, dartExecutable);
+        await expectSymbols(asset: result.assets.single, symbols: ['add']);
+      }
+
+      await copyTestProjects(
+        sourceUri: testDataUri.resolve('native_add_add_symbol/'),
+        targetUri: packageUri,
+      );
+
+      {
+        final result = await build(packageUri, logger, dartExecutable);
+        await expectSymbols(
+          asset: result.assets.single,
+          symbols: ['add', 'subtract'],
+        );
+      }
+    });
+  });
+
+  test('add C file, modify script', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('native_add/');
+
+      await runPubGet(workingDirectory: packageUri, logger: logger);
+
+      {
+        final result = await build(packageUri, logger, dartExecutable);
+        await expectSymbols(asset: result.assets.single, symbols: ['add']);
+      }
+
+      await copyTestProjects(
+          sourceUri: testDataUri.resolve('native_add_add_source/'),
+          targetUri: packageUri);
+
+      {
+        final result = await build(packageUri, logger, dartExecutable);
+        await expectSymbols(
+            asset: result.assets.single, symbols: ['add', 'multiply']);
+      }
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/build_runner_cycle_test.dart b/pkgs/native_assets_builder/test/build_runner/build_runner_cycle_test.dart
new file mode 100644
index 0000000..94a09c7
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/build_runner_cycle_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  test('cycle', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('cyclic_package_1/');
+
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+      {
+        final logMessages = <String>[];
+        final result = await dryRun(
+          packageUri,
+          createCapturingLogger(logMessages, level: Level.SEVERE),
+          dartExecutable,
+        );
+        final fullLog = logMessages.join('\n');
+        expect(result.success, false);
+        expect(
+          fullLog,
+          contains(
+            'Cyclic dependency for native asset builds in the following '
+            'packages: [cyclic_package_1, cyclic_package_2]',
+          ),
+        );
+      }
+
+      {
+        final logMessages = <String>[];
+        final result = await build(
+          packageUri,
+          createCapturingLogger(logMessages, level: Level.SEVERE),
+          dartExecutable,
+        );
+        final fullLog = logMessages.join('\n');
+        expect(result.success, false);
+        expect(
+          fullLog,
+          contains(
+            'Cyclic dependency for native asset builds in the following '
+            'packages: [cyclic_package_1, cyclic_package_2]',
+          ),
+        );
+      }
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/build_runner_dry_run_test.dart b/pkgs/native_assets_builder/test/build_runner/build_runner_dry_run_test.dart
new file mode 100644
index 0000000..be4f817
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/build_runner_dry_run_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:file_testing/file_testing.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  test('dry_run', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('native_add/');
+
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+
+      final dryRunAssets = (await dryRun(packageUri, logger, dartExecutable))
+          .assets
+          .where((element) => element.target == Target.current)
+          .toList();
+      final result = await build(packageUri, logger, dartExecutable);
+
+      expect(dryRunAssets.length, result.assets.length);
+      for (var i = 0; i < dryRunAssets.length; i++) {
+        final dryRunAsset = dryRunAssets[0];
+        final buildAsset = result.assets[0];
+        expect(dryRunAsset.linkMode, buildAsset.linkMode);
+        expect(dryRunAsset.id, buildAsset.id);
+        expect(dryRunAsset.target, buildAsset.target);
+        // The target folders are different, so the paths are different.
+      }
+
+      final dryRunDir = packageUri.resolve(
+          '.dart_tool/native_assets_builder/dry_run_${Target.current.os}_dynamic/');
+      expect(File.fromUri(dryRunDir.resolve('config.yaml')), exists);
+      expect(File.fromUri(dryRunDir.resolve('out/build_output.yaml')), exists);
+      //
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/build_runner_failure_test.dart b/pkgs/native_assets_builder/test/build_runner/build_runner_failure_test.dart
new file mode 100644
index 0000000..c844be2
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/build_runner_failure_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:logging/logging.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  test('break build', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('native_add/');
+
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+
+      {
+        final result = await build(packageUri, logger, dartExecutable);
+        expect(result.assets.length, 1);
+        await expectSymbols(asset: result.assets.single, symbols: ['add']);
+        expect(
+          result.dependencies,
+          [
+            packageUri.resolve('build.dart'),
+            packageUri.resolve('src/native_add.c'),
+          ],
+        );
+      }
+
+      await copyTestProjects(
+        sourceUri: testDataUri.resolve('native_add_break_build/'),
+        targetUri: packageUri,
+      );
+
+      {
+        final logMessages = <String>[];
+        final result = await build(
+          packageUri,
+          createCapturingLogger(logMessages, level: Level.SEVERE),
+          dartExecutable,
+        );
+        final fullLog = logMessages.join('\n');
+        expect(result.success, false);
+        expect(fullLog, contains('To reproduce run:'));
+        final reproCommand = fullLog
+            .split('\n')
+            .skipWhile((l) => l != 'To reproduce run:')
+            .skip(1)
+            .first;
+        final reproResult =
+            await Process.run(reproCommand, [], runInShell: true);
+        expect(reproResult.exitCode, isNot(0));
+      }
+
+      await copyTestProjects(
+        sourceUri: testDataUri.resolve('native_add_fix_build/'),
+        targetUri: packageUri,
+      );
+
+      {
+        final result = await build(packageUri, logger, dartExecutable);
+        expect(result.assets.length, 1);
+        await expectSymbols(asset: result.assets.single, symbols: ['add']);
+        expect(
+          result.dependencies,
+          [
+            packageUri.resolve('build.dart'),
+            packageUri.resolve('src/native_add.c'),
+          ],
+        );
+      }
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/build_runner_reusability_test.dart b/pkgs/native_assets_builder/test/build_runner/build_runner_reusability_test.dart
new file mode 100644
index 0000000..f4313cd
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/build_runner_reusability_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_assets_builder/src/build_runner/build_runner.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  test('multiple dryRun and build invocations', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('package_reading_metadata/');
+
+      // First, run `pub get`, we need pub to resolve our dependencies.
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+
+      final buildRunner = NativeAssetsBuildRunner(
+        logger: logger,
+        dartExecutable: dartExecutable,
+      );
+
+      await buildRunner.dryRun(
+        targetOs: Target.current.os,
+        linkModePreference: LinkModePreference.dynamic,
+        workingDirectory: packageUri,
+        includeParentEnvironment: true,
+      );
+      await buildRunner.dryRun(
+        targetOs: Target.current.os,
+        linkModePreference: LinkModePreference.dynamic,
+        workingDirectory: packageUri,
+        includeParentEnvironment: true,
+      );
+      await buildRunner.build(
+        buildMode: BuildMode.release,
+        linkModePreference: LinkModePreference.dynamic,
+        target: Target.current,
+        workingDirectory: packageUri,
+        includeParentEnvironment: true,
+      );
+      await buildRunner.build(
+        buildMode: BuildMode.release,
+        linkModePreference: LinkModePreference.dynamic,
+        target: Target.current,
+        workingDirectory: packageUri,
+        includeParentEnvironment: true,
+      );
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/build_runner_run_in_isolation_test.dart b/pkgs/native_assets_builder/test/build_runner/build_runner_run_in_isolation_test.dart
new file mode 100644
index 0000000..ffcbdc0
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/build_runner_run_in_isolation_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  String unparseKey(String key) => key.replaceAll('.', '__').toUpperCase();
+  final arKey = unparseKey(CCompilerConfig.arConfigKeyFull);
+  final ccKey = unparseKey(CCompilerConfig.ccConfigKeyFull);
+  final ldKey = unparseKey(CCompilerConfig.ldConfigKeyFull);
+  final envScriptKey = unparseKey(CCompilerConfig.envScriptConfigKeyFull);
+  final envScriptArgsKey =
+      unparseKey(CCompilerConfig.envScriptArgsConfigKeyFull);
+
+  final cc = Platform.environment[ccKey]?.fileUri;
+
+  if (cc == null) {
+    // We don't set any compiler paths on the GitHub CI.
+    // We neither set compiler paths on MacOS on the Dart SDK CI
+    // in pkg/test_runner/lib/src/configuration.dart
+    // nativeCompilerEnvironmentVariables.
+    //
+    // We could potentially run this test if we default to some compilers
+    // we find on the path before running the test. However, the logic for
+    // discovering compilers is currently hidden inside
+    // package:native_toolchain_c.
+    return;
+  }
+
+  test('run in isolation', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('native_add/');
+
+      await runPubGet(workingDirectory: packageUri, logger: logger);
+
+      printOnFailure(
+          'Platform.environment[ccKey]: ${Platform.environment[ccKey]}');
+      printOnFailure('cc: $cc');
+
+      final result = await build(
+        packageUri,
+        logger,
+        dartExecutable,
+        // Manually pass in a compiler.
+        cCompilerConfig: CCompilerConfig(
+          ar: Platform.environment[arKey]?.fileUri,
+          cc: cc,
+          envScript: Platform.environment[envScriptKey]?.fileUri,
+          envScriptArgs: Platform.environment[envScriptArgsKey]?.split(' '),
+          ld: Platform.environment[ldKey]?.fileUri,
+        ),
+        // Prevent any other environment variables.
+        includeParentEnvironment: false,
+      );
+      expect(result.assets.length, 1);
+    });
+  });
+}
+
+extension on String {
+  Uri get fileUri => Uri.file(this);
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/build_runner_test.dart b/pkgs/native_assets_builder/test/build_runner/build_runner_test.dart
new file mode 100644
index 0000000..f6fff2c
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/build_runner_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_assets_builder/native_assets_builder.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  test('native_add build', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('native_add/');
+
+      // First, run `pub get`, we need pub to resolve our dependencies.
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+
+      // Trigger a build, should invoke build for libraries with native assets.
+      {
+        final logMessages = <String>[];
+        final result = await build(packageUri, logger, dartExecutable,
+            capturedLogs: logMessages);
+        expect(
+            logMessages.join('\n'),
+            stringContainsInOrder(
+                ['native_add${Platform.pathSeparator}build.dart']));
+        expect(result.assets.length, 1);
+      }
+
+      // Trigger a build, should not invoke anything.
+      for (final passPackageLayout in [true, false]) {
+        PackageLayout? packageLayout;
+        if (passPackageLayout) {
+          packageLayout = await PackageLayout.fromRootPackageRoot(packageUri);
+        }
+        final logMessages = <String>[];
+        final result = await build(
+          packageUri,
+          logger,
+          dartExecutable,
+          capturedLogs: logMessages,
+          packageLayout: packageLayout,
+        );
+        expect(
+          false,
+          logMessages
+              .join('\n')
+              .contains('native_add${Platform.pathSeparator}build.dart'),
+        );
+        expect(result.assets.length, 1);
+      }
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/helpers.dart b/pkgs/native_assets_builder/test/build_runner/helpers.dart
new file mode 100644
index 0000000..9609c1c
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/helpers.dart
@@ -0,0 +1,138 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:file_testing/file_testing.dart';
+import 'package:logging/logging.dart';
+import 'package:native_assets_builder/native_assets_builder.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+Future<void> runPubGet({
+  required Uri workingDirectory,
+  required Logger logger,
+}) async {
+  final result = await runProcess(
+    executable: Uri.file(Platform.resolvedExecutable),
+    arguments: [
+      'pub',
+      '--suppress-analytics', // Prevent extra log entries.
+      'get',
+    ],
+    workingDirectory: workingDirectory,
+    logger: logger,
+  );
+  expect(result.exitCode, 0);
+}
+
+Future<BuildResult> build(
+  Uri packageUri,
+  Logger logger,
+  Uri dartExecutable, {
+  LinkModePreference linkModePreference = LinkModePreference.dynamic,
+  CCompilerConfig? cCompilerConfig,
+  bool includeParentEnvironment = true,
+  List<String>? capturedLogs,
+  PackageLayout? packageLayout,
+}) async {
+  StreamSubscription<LogRecord>? subscription;
+  if (capturedLogs != null) {
+    subscription =
+        logger.onRecord.listen((event) => capturedLogs.add(event.message));
+  }
+
+  final result = await NativeAssetsBuildRunner(
+    logger: logger,
+    dartExecutable: dartExecutable,
+  ).build(
+    buildMode: BuildMode.release,
+    linkModePreference: linkModePreference,
+    target: Target.current,
+    workingDirectory: packageUri,
+    cCompilerConfig: cCompilerConfig,
+    includeParentEnvironment: includeParentEnvironment,
+    packageLayout: packageLayout,
+  );
+  if (result.success) {
+    await expectAssetsExist(result.assets);
+  }
+
+  if (subscription != null) {
+    await subscription.cancel();
+  }
+
+  return result;
+}
+
+Future<DryRunResult> dryRun(
+  Uri packageUri,
+  Logger logger,
+  Uri dartExecutable, {
+  LinkModePreference linkModePreference = LinkModePreference.dynamic,
+  CCompilerConfig? cCompilerConfig,
+  bool includeParentEnvironment = true,
+  List<String>? capturedLogs,
+  PackageLayout? packageLayout,
+}) async {
+  StreamSubscription<LogRecord>? subscription;
+  if (capturedLogs != null) {
+    subscription =
+        logger.onRecord.listen((event) => capturedLogs.add(event.message));
+  }
+
+  final result = await NativeAssetsBuildRunner(
+    logger: logger,
+    dartExecutable: dartExecutable,
+  ).dryRun(
+    linkModePreference: linkModePreference,
+    targetOs: Target.current.os,
+    workingDirectory: packageUri,
+    includeParentEnvironment: includeParentEnvironment,
+    packageLayout: packageLayout,
+  );
+
+  if (subscription != null) {
+    await subscription.cancel();
+  }
+
+  return result;
+}
+
+Future<void> expectAssetsExist(List<Asset> assets) async {
+  for (final asset in assets) {
+    final uri = (asset.path as AssetAbsolutePath).uri;
+    expect(
+        uri.toFilePath(),
+        contains('${Platform.pathSeparator}.dart_tool${Platform.pathSeparator}'
+            'native_assets_builder${Platform.pathSeparator}'));
+    final file = File.fromUri(uri);
+    expect(file, exists);
+  }
+}
+
+Future<void> expectSymbols({
+  required Asset asset,
+  required List<String> symbols,
+}) async {
+  if (Platform.isLinux) {
+    final assetUri = (asset.path as AssetAbsolutePath).uri;
+    final nmResult = await runProcess(
+      executable: Uri(path: 'nm'),
+      arguments: [
+        '-D',
+        assetUri.toFilePath(),
+      ],
+      logger: logger,
+    );
+
+    expect(
+      nmResult.stdout,
+      stringContainsInOrder(symbols),
+    );
+  }
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/metadata_test.dart b/pkgs/native_assets_builder/test/build_runner/metadata_test.dart
new file mode 100644
index 0000000..12e9461
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/metadata_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  test('get dependency metadata', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('package_reading_metadata/');
+
+      // First, run `pub get`, we need pub to resolve our dependencies.
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+
+      // Trigger a build, should invoke build for libraries with native assets.
+      {
+        final logMessages = <String>[];
+        await build(packageUri, logger, dartExecutable,
+            capturedLogs: logMessages);
+        expect(
+            logMessages.join('\n'),
+            stringContainsInOrder([
+              'package_with_metadata${Platform.pathSeparator}build.dart',
+              'package_reading_metadata${Platform.pathSeparator}build.dart',
+              '{some_int: 3, some_key: some_value}',
+            ]));
+      }
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/package_layout_test.dart b/pkgs/native_assets_builder/test/build_runner/package_layout_test.dart
new file mode 100644
index 0000000..a92992f
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/package_layout_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_assets_builder/native_assets_builder.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+void main() async {
+  test('fromRootPackageRoot', () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final nativeAddUri = tempUri.resolve('native_add/');
+
+      // First, run `pub get`, we need pub to resolve our dependencies.
+      await runPubGet(workingDirectory: nativeAddUri, logger: logger);
+
+      final packageLayout =
+          await PackageLayout.fromRootPackageRoot(nativeAddUri);
+      final packageLayout2 = PackageLayout.fromPackageConfig(
+        packageLayout.packageConfig,
+        packageLayout.packageConfigUri,
+      );
+      expect(packageLayout.rootPackageRoot, packageLayout2.rootPackageRoot);
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/build_runner/packaging_preference_test.dart b/pkgs/native_assets_builder/test/build_runner/packaging_preference_test.dart
new file mode 100644
index 0000000..e1fefee
--- /dev/null
+++ b/pkgs/native_assets_builder/test/build_runner/packaging_preference_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+import 'helpers.dart';
+
+const Timeout longTimeout = Timeout(Duration(minutes: 5));
+
+void main() async {
+  test('link mode preference', timeout: longTimeout, () async {
+    await inTempDir((tempUri) async {
+      await copyTestProjects(targetUri: tempUri);
+      final packageUri = tempUri.resolve('native_add/');
+
+      // First, run `pub get`, we need pub to resolve our dependencies.
+      await runPubGet(
+        workingDirectory: packageUri,
+        logger: logger,
+      );
+
+      final resultDynamic = await build(
+        packageUri,
+        logger,
+        dartExecutable,
+        linkModePreference: LinkModePreference.dynamic,
+      );
+
+      final resultPreferDynamic = await build(
+        packageUri,
+        logger,
+        dartExecutable,
+        linkModePreference: LinkModePreference.preferDynamic,
+      );
+
+      final resultStatic = await build(
+        packageUri,
+        logger,
+        dartExecutable,
+        linkModePreference: LinkModePreference.static,
+      );
+
+      final resultPreferStatic = await build(
+        packageUri,
+        logger,
+        dartExecutable,
+        linkModePreference: LinkModePreference.preferStatic,
+      );
+
+      // This package honors preferences.
+      expect(resultDynamic.assets.single.linkMode, LinkMode.dynamic);
+      expect(resultPreferDynamic.assets.single.linkMode, LinkMode.dynamic);
+      expect(resultStatic.assets.single.linkMode, LinkMode.static);
+      expect(resultPreferStatic.assets.single.linkMode, LinkMode.static);
+    });
+  });
+}
diff --git a/pkgs/native_assets_builder/test/data/README.md b/pkgs/native_assets_builder/test/data/README.md
new file mode 100644
index 0000000..311839a
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/README.md
@@ -0,0 +1,6 @@
+The `dart_app` depends on multiple packages with native assets.
+
+`manifest.yaml` contains a list of all the files of the test projects.
+This is used to copy the test projects to temporary folders when running tests,
+to prevent tests accidentally using temporary files or interferring with each
+other.
diff --git a/pkgs/native_assets_builder/test/data/cyclic_package_1/build.dart b/pkgs/native_assets_builder/test/data/cyclic_package_1/build.dart
new file mode 100644
index 0000000..2479e4e
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/cyclic_package_1/build.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+void main(List<String> args) async {
+  final buildConfig = await BuildConfig.fromArgs(args);
+  final buildOutput = BuildOutput();
+  await buildOutput.writeToFile(outDir: buildConfig.outDir);
+}
diff --git a/pkgs/native_assets_builder/test/data/cyclic_package_1/pubspec.yaml b/pkgs/native_assets_builder/test/data/cyclic_package_1/pubspec.yaml
new file mode 100644
index 0000000..ad3302f
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/cyclic_package_1/pubspec.yaml
@@ -0,0 +1,19 @@
+name: cyclic_package_1
+description: Part of two packages with native assets that have a cycle.
+version: 0.1.0
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  cyclic_package_2:
+    path: ../cyclic_package_2
+  native_assets_cli: ^0.3.0
+  yaml: ^3.1.1
+  yaml_edit: ^2.1.0
+
+dev_dependencies:
+  lints: ^3.0.0
diff --git a/pkgs/native_assets_builder/test/data/cyclic_package_2/build.dart b/pkgs/native_assets_builder/test/data/cyclic_package_2/build.dart
new file mode 100644
index 0000000..2479e4e
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/cyclic_package_2/build.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+void main(List<String> args) async {
+  final buildConfig = await BuildConfig.fromArgs(args);
+  final buildOutput = BuildOutput();
+  await buildOutput.writeToFile(outDir: buildConfig.outDir);
+}
diff --git a/pkgs/native_assets_builder/test/data/cyclic_package_2/pubspec.yaml b/pkgs/native_assets_builder/test/data/cyclic_package_2/pubspec.yaml
new file mode 100644
index 0000000..1bf06f4
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/cyclic_package_2/pubspec.yaml
@@ -0,0 +1,19 @@
+name: cyclic_package_2
+description: Part of two packages with native assets that have a cycle.
+version: 0.1.0
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  cyclic_package_1:
+    path: ../cyclic_package_1
+  native_assets_cli: ^0.3.0
+  yaml: ^3.1.1
+  yaml_edit: ^2.1.0
+
+dev_dependencies:
+  lints: ^3.0.0
diff --git a/pkgs/native_assets_builder/test/data/dart_app/.gitignore b/pkgs/native_assets_builder/test/data/dart_app/.gitignore
new file mode 100644
index 0000000..2a9e6b8
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/dart_app/.gitignore
@@ -0,0 +1,2 @@
+.dart_tool
+bin/dart_app/
diff --git a/pkgs/native_assets_builder/test/data/dart_app/bin/dart_app.dart b/pkgs/native_assets_builder/test/data/dart_app/bin/dart_app.dart
new file mode 100644
index 0000000..4e9dc84
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/dart_app/bin/dart_app.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_add/native_add.dart';
+import 'package:native_subtract/native_subtract.dart';
+
+void main() {
+  testNativeAdd();
+  testNativeSubtract();
+}
+
+void testNativeAdd() {
+  final answer = add(5, 6);
+  if (answer != 5 + 6) {
+    throw 'Wrong answer';
+  }
+  print('add(5, 6) = $answer');
+}
+
+void testNativeSubtract() {
+  final answer = subtract(5, 6);
+  if (answer != 5 - 6) {
+    throw 'Wrong answer';
+  }
+  print('subtract(5, 6) = $answer');
+}
diff --git a/pkgs/native_assets_builder/test/data/dart_app/pubspec.yaml b/pkgs/native_assets_builder/test/data/dart_app/pubspec.yaml
new file mode 100644
index 0000000..1ead5cb
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/dart_app/pubspec.yaml
@@ -0,0 +1,12 @@
+name: dart_app
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  native_add:
+    path: ../native_add
+  native_subtract:
+    path: ../native_subtract
diff --git a/pkgs/native_assets_builder/test/data/manifest.yaml b/pkgs/native_assets_builder/test/data/manifest.yaml
new file mode 100644
index 0000000..c52f500
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/manifest.yaml
@@ -0,0 +1,37 @@
+# The list of files to copy to a temporary folder to ensure running tests from
+# a completely clean setup.
+- cyclic_package_1/build.dart
+- cyclic_package_1/pubspec.yaml
+- cyclic_package_2/build.dart
+- cyclic_package_2/pubspec.yaml
+- dart_app/bin/dart_app.dart
+- dart_app/pubspec.yaml
+- native_add/build.dart
+- native_add/ffigen.yaml
+- native_add/lib/native_add.dart
+- native_add/lib/src/native_add_bindings_generated.dart
+- native_add/lib/src/native_add.dart
+- native_add/pubspec.yaml
+- native_add/src/native_add.c
+- native_add/src/native_add.h
+- native_add/test/native_add_test.dart
+- native_subtract/build.dart
+- native_subtract/ffigen.yaml
+- native_subtract/lib/native_subtract.dart
+- native_subtract/lib/src/native_subtract_bindings_generated.dart
+- native_subtract/lib/src/native_subtract.dart
+- native_subtract/pubspec.yaml
+- native_subtract/src/native_subtract.c
+- native_subtract/src/native_subtract.h
+- package_reading_metadata/build.dart
+- package_reading_metadata/pubspec.yaml
+- package_with_metadata/build.dart
+- package_with_metadata/pubspec.yaml
+- wrong_build_output/build.dart
+- wrong_build_output/pubspec.yaml
+- wrong_build_output_2/build.dart
+- wrong_build_output_2/pubspec.yaml
+- wrong_build_output_3/build.dart
+- wrong_build_output_3/pubspec.yaml
+- wrong_namespace_asset/build.dart
+- wrong_namespace_asset/pubspec.yaml
diff --git a/pkgs/native_assets_builder/test/data/native_add/build.dart b/pkgs/native_assets_builder/test/data/native_add/build.dart
new file mode 100644
index 0000000..69bbb9e
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add/build.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+
+const packageName = 'native_add';
+
+void main(List<String> args) async {
+  final buildConfig = await BuildConfig.fromArgs(args);
+  final buildOutput = BuildOutput();
+  final cbuilder = CBuilder.library(
+    name: packageName,
+    assetId: 'package:$packageName/src/${packageName}_bindings_generated.dart',
+    sources: [
+      'src/$packageName.c',
+    ],
+  );
+  await cbuilder.run(
+    buildConfig: buildConfig,
+    buildOutput: buildOutput,
+    logger: Logger('')
+      ..level = Level.ALL
+      ..onRecord.listen((record) {
+        print('${record.level.name}: ${record.time}: ${record.message}');
+      }),
+  );
+  await buildOutput.writeToFile(outDir: buildConfig.outDir);
+}
diff --git a/pkgs/native_assets_builder/test/data/native_add/ffigen.yaml b/pkgs/native_assets_builder/test/data/native_add/ffigen.yaml
new file mode 100644
index 0000000..b8716bd
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add/ffigen.yaml
@@ -0,0 +1,20 @@
+# Run with `flutter pub run ffigen --config ffigen.yaml`.
+name: NativeAddBindings
+description: |
+  Bindings for `src/native_add.h`.
+
+  Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`.
+output: "lib/src/native_add_bindings_generated.dart"
+headers:
+  entry-points:
+    - "src/native_add.h"
+  include-directives:
+    - "src/native_add.h"
+preamble: |
+  // Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+  // for details. All rights reserved. Use of this source code is governed by a
+  // BSD-style license that can be found in the LICENSE file.
+comments:
+  style: any
+  length: full
+ffi-native:
diff --git a/pkgs/native_assets_builder/test/data/native_add/lib/native_add.dart b/pkgs/native_assets_builder/test/data/native_add/lib/native_add.dart
new file mode 100644
index 0000000..9eda681
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add/lib/native_add.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'src/native_add.dart';
diff --git a/pkgs/native_assets_builder/test/data/native_add/lib/src/native_add.dart b/pkgs/native_assets_builder/test/data/native_add/lib/src/native_add.dart
new file mode 100644
index 0000000..9c8a43b
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add/lib/src/native_add.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'native_add_bindings_generated.dart' as bindings;
+
+int add(int a, int b) => bindings.add(a, b);
diff --git a/pkgs/native_assets_builder/test/data/native_add/lib/src/native_add_bindings_generated.dart b/pkgs/native_assets_builder/test/data/native_add/lib/src/native_add_bindings_generated.dart
new file mode 100644
index 0000000..4d1e803
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add/lib/src/native_add_bindings_generated.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+@ffi.Native<ffi.Int32 Function(ffi.Int32, ffi.Int32)>(symbol: 'add')
+external int add(
+  int a,
+  int b,
+);
diff --git a/pkgs/native_assets_builder/test/data/native_add/manifest.yaml b/pkgs/native_assets_builder/test/data/native_add/manifest.yaml
new file mode 100644
index 0000000..e922db8
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add/manifest.yaml
@@ -0,0 +1,9 @@
+- build.dart
+- ffigen.yaml
+- lib/native_add.dart
+- lib/src/native_add_bindings_generated.dart
+- lib/src/native_add.dart
+- pubspec.yaml
+- src/native_add.c
+- src/native_add.h
+- test/native_add_test.dart
diff --git a/pkgs/native_assets_builder/test/data/native_add/pubspec.yaml b/pkgs/native_assets_builder/test/data/native_add/pubspec.yaml
new file mode 100644
index 0000000..67632a6
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add/pubspec.yaml
@@ -0,0 +1,19 @@
+name: native_add
+description: Sums two numbers with native code.
+version: 0.1.0
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  logging: ^1.1.1
+  native_assets_cli: ^0.3.0
+  native_toolchain_c: ^0.3.0
+
+dev_dependencies:
+  ffigen: ^8.0.2
+  lints: ^3.0.0
+  test: ^1.23.1
diff --git a/pkgs/native_assets_builder/test/data/native_add/src/native_add.c b/pkgs/native_assets_builder/test/data/native_add/src/native_add.c
new file mode 100644
index 0000000..cf21076
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add/src/native_add.c
@@ -0,0 +1,9 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "native_add.h"
+
+int32_t add(int32_t a, int32_t b) {
+   return a + b;
+}
diff --git a/pkgs/native_assets_builder/test/data/native_add/src/native_add.h b/pkgs/native_assets_builder/test/data/native_add/src/native_add.h
new file mode 100644
index 0000000..5824f98
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add/src/native_add.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdint.h>
+
+#if _WIN32
+#define MYLIB_EXPORT __declspec(dllexport)
+#else
+#define MYLIB_EXPORT
+#endif
+
+MYLIB_EXPORT int32_t add(int32_t a, int32_t b);
diff --git a/pkgs/native_assets_builder/test/data/native_add/test/native_add_test.dart b/pkgs/native_assets_builder/test/data/native_add/test/native_add_test.dart
new file mode 100644
index 0000000..7531a62
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add/test/native_add_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_add/native_add.dart';
+import 'package:test/test.dart';
+
+void main() {
+  test('native add test', () {
+    final result = add(4, 6);
+    expect(result, equals(10));
+  });
+}
diff --git a/pkgs/native_assets_builder/test/data/native_add_add_source/README.md b/pkgs/native_assets_builder/test/data/native_add_add_source/README.md
new file mode 100644
index 0000000..5a1b807
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_add_source/README.md
@@ -0,0 +1 @@
+Used in automated testing to modify the native_add project.
diff --git a/pkgs/native_assets_builder/test/data/native_add_add_source/build.dart b/pkgs/native_assets_builder/test/data/native_add_add_source/build.dart
new file mode 100644
index 0000000..3fcb30e
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_add_source/build.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+
+const packageName = 'native_add';
+
+void main(List<String> args) async {
+  final buildConfig = await BuildConfig.fromArgs(args);
+  final buildOutput = BuildOutput();
+  final cbuilder = CBuilder.library(
+    name: packageName,
+    assetId: 'package:$packageName/src/${packageName}_bindings_generated.dart',
+    sources: [
+      'src/$packageName.c',
+      'src/native_multiply.c',
+    ],
+  );
+  await cbuilder.run(
+    buildConfig: buildConfig,
+    buildOutput: buildOutput,
+    logger: Logger('')
+      ..level = Level.ALL
+      ..onRecord.listen((record) {
+        print('${record.level.name}: ${record.time}: ${record.message}');
+      }),
+  );
+  await buildOutput.writeToFile(outDir: buildConfig.outDir);
+}
diff --git a/pkgs/native_assets_builder/test/data/native_add_add_source/manifest.yaml b/pkgs/native_assets_builder/test/data/native_add_add_source/manifest.yaml
new file mode 100644
index 0000000..3a2f6c3
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_add_source/manifest.yaml
@@ -0,0 +1,3 @@
+- build.dart
+- src/native_multiply.c
+- src/native_multiply.h
diff --git a/pkgs/native_assets_builder/test/data/native_add_add_source/pubspec.yaml b/pkgs/native_assets_builder/test/data/native_add_add_source/pubspec.yaml
new file mode 100644
index 0000000..67632a6
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_add_source/pubspec.yaml
@@ -0,0 +1,19 @@
+name: native_add
+description: Sums two numbers with native code.
+version: 0.1.0
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  logging: ^1.1.1
+  native_assets_cli: ^0.3.0
+  native_toolchain_c: ^0.3.0
+
+dev_dependencies:
+  ffigen: ^8.0.2
+  lints: ^3.0.0
+  test: ^1.23.1
diff --git a/pkgs/native_assets_builder/test/data/native_add_add_source/src/native_multiply.c b/pkgs/native_assets_builder/test/data/native_add_add_source/src/native_multiply.c
new file mode 100644
index 0000000..7801f65
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_add_source/src/native_multiply.c
@@ -0,0 +1,9 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "native_multiply.h"
+
+MYLIB_EXPORT intptr_t multiply(intptr_t a, intptr_t b) {
+  return a * b;
+}
diff --git a/pkgs/native_assets_builder/test/data/native_add_add_source/src/native_multiply.h b/pkgs/native_assets_builder/test/data/native_add_add_source/src/native_multiply.h
new file mode 100644
index 0000000..0827571
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_add_source/src/native_multiply.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdint.h>
+
+#if _WIN32
+#define MYLIB_EXPORT __declspec(dllexport)
+#else
+#define MYLIB_EXPORT
+#endif
+
+MYLIB_EXPORT intptr_t multiply(intptr_t a, intptr_t b);
diff --git a/pkgs/native_assets_builder/test/data/native_add_add_symbol/README.md b/pkgs/native_assets_builder/test/data/native_add_add_symbol/README.md
new file mode 100644
index 0000000..5a1b807
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_add_symbol/README.md
@@ -0,0 +1 @@
+Used in automated testing to modify the native_add project.
diff --git a/pkgs/native_assets_builder/test/data/native_add_add_symbol/manifest.yaml b/pkgs/native_assets_builder/test/data/native_add_add_symbol/manifest.yaml
new file mode 100644
index 0000000..adc0539
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_add_symbol/manifest.yaml
@@ -0,0 +1,2 @@
+- src/native_add.c
+- src/native_add.h
diff --git a/pkgs/native_assets_builder/test/data/native_add_add_symbol/src/native_add.c b/pkgs/native_assets_builder/test/data/native_add_add_symbol/src/native_add.c
new file mode 100644
index 0000000..a493add
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_add_symbol/src/native_add.c
@@ -0,0 +1,14 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "native_add.h"
+
+MYLIB_EXPORT int32_t add(int32_t a, int32_t b) {
+   return a + b;
+}
+
+
+MYLIB_EXPORT intptr_t subtract(intptr_t a, intptr_t b) {
+  return a - b;
+}
diff --git a/pkgs/native_assets_builder/test/data/native_add_add_symbol/src/native_add.h b/pkgs/native_assets_builder/test/data/native_add_add_symbol/src/native_add.h
new file mode 100644
index 0000000..37d53b6
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_add_symbol/src/native_add.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdint.h>
+
+#if _WIN32
+#define MYLIB_EXPORT __declspec(dllexport)
+#else
+#define MYLIB_EXPORT
+#endif
+
+MYLIB_EXPORT int32_t add(int32_t a, int32_t b);
+
+MYLIB_EXPORT intptr_t subtract(intptr_t a, intptr_t b);
diff --git a/pkgs/native_assets_builder/test/data/native_add_break_build/README.md b/pkgs/native_assets_builder/test/data/native_add_break_build/README.md
new file mode 100644
index 0000000..5a1b807
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_break_build/README.md
@@ -0,0 +1 @@
+Used in automated testing to modify the native_add project.
diff --git a/pkgs/native_assets_builder/test/data/native_add_break_build/manifest.yaml b/pkgs/native_assets_builder/test/data/native_add_break_build/manifest.yaml
new file mode 100644
index 0000000..a475918
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_break_build/manifest.yaml
@@ -0,0 +1 @@
+- src/native_add.c
diff --git a/pkgs/native_assets_builder/test/data/native_add_break_build/src/native_add.c b/pkgs/native_assets_builder/test/data/native_add_break_build/src/native_add.c
new file mode 100644
index 0000000..ba06d8b
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_break_build/src/native_add.c
@@ -0,0 +1,9 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "native_add.h"
+
+MYLIB_EXPORT int32_t add(int32_t different_parameters) {
+   return a + b;
+}
\ No newline at end of file
diff --git a/pkgs/native_assets_builder/test/data/native_add_fix_build/README.md b/pkgs/native_assets_builder/test/data/native_add_fix_build/README.md
new file mode 100644
index 0000000..5a1b807
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_fix_build/README.md
@@ -0,0 +1 @@
+Used in automated testing to modify the native_add project.
diff --git a/pkgs/native_assets_builder/test/data/native_add_fix_build/manifest.yaml b/pkgs/native_assets_builder/test/data/native_add_fix_build/manifest.yaml
new file mode 100644
index 0000000..a475918
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_fix_build/manifest.yaml
@@ -0,0 +1 @@
+- src/native_add.c
diff --git a/pkgs/native_assets_builder/test/data/native_add_fix_build/src/native_add.c b/pkgs/native_assets_builder/test/data/native_add_fix_build/src/native_add.c
new file mode 100644
index 0000000..cf21076
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_add_fix_build/src/native_add.c
@@ -0,0 +1,9 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "native_add.h"
+
+int32_t add(int32_t a, int32_t b) {
+   return a + b;
+}
diff --git a/pkgs/native_assets_builder/test/data/native_subtract/build.dart b/pkgs/native_assets_builder/test/data/native_subtract/build.dart
new file mode 100644
index 0000000..66b62ea
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_subtract/build.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+
+const packageName = 'native_subtract';
+
+void main(List<String> args) async {
+  final buildConfig = await BuildConfig.fromArgs(args);
+  final buildOutput = BuildOutput();
+  final cbuilder = CBuilder.library(
+    name: packageName,
+    assetId: 'package:$packageName/src/${packageName}_bindings_generated.dart',
+    sources: [
+      'src/$packageName.c',
+    ],
+  );
+  await cbuilder.run(
+    buildConfig: buildConfig,
+    buildOutput: buildOutput,
+    logger: Logger('')
+      ..level = Level.ALL
+      ..onRecord.listen((record) {
+        print('${record.level.name}: ${record.time}: ${record.message}');
+      }),
+  );
+  await buildOutput.writeToFile(outDir: buildConfig.outDir);
+}
diff --git a/pkgs/native_assets_builder/test/data/native_subtract/ffigen.yaml b/pkgs/native_assets_builder/test/data/native_subtract/ffigen.yaml
new file mode 100644
index 0000000..5f79dbe
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_subtract/ffigen.yaml
@@ -0,0 +1,20 @@
+# Run with `flutter pub run ffigen --config ffigen.yaml`.
+name: NativeAddBindings
+description: |
+  Bindings for `src/native_subtract.h`.
+
+  Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`.
+output: "lib/src/native_subtract_bindings_generated.dart"
+headers:
+  entry-points:
+    - "src/native_subtract.h"
+  include-directives:
+    - "src/native_subtract.h"
+preamble: |
+  // Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+  // for details. All rights reserved. Use of this source code is governed by a
+  // BSD-style license that can be found in the LICENSE file.
+comments:
+  style: any
+  length: full
+ffi-native:
diff --git a/pkgs/native_assets_builder/test/data/native_subtract/lib/native_subtract.dart b/pkgs/native_assets_builder/test/data/native_subtract/lib/native_subtract.dart
new file mode 100644
index 0000000..a283156
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_subtract/lib/native_subtract.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'src/native_subtract.dart';
diff --git a/pkgs/native_assets_builder/test/data/native_subtract/lib/src/native_subtract.dart b/pkgs/native_assets_builder/test/data/native_subtract/lib/src/native_subtract.dart
new file mode 100644
index 0000000..3d77e75
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_subtract/lib/src/native_subtract.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'native_subtract_bindings_generated.dart' as bindings;
+
+int subtract(int a, int b) => bindings.subtract(a, b);
diff --git a/pkgs/native_assets_builder/test/data/native_subtract/lib/src/native_subtract_bindings_generated.dart b/pkgs/native_assets_builder/test/data/native_subtract/lib/src/native_subtract_bindings_generated.dart
new file mode 100644
index 0000000..1a952fe
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_subtract/lib/src/native_subtract_bindings_generated.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+@ffi.Native<ffi.Int32 Function(ffi.Int32, ffi.Int32)>(symbol: 'subtract')
+external int subtract(
+  int a,
+  int b,
+);
diff --git a/pkgs/native_assets_builder/test/data/native_subtract/pubspec.yaml b/pkgs/native_assets_builder/test/data/native_subtract/pubspec.yaml
new file mode 100644
index 0000000..de93ce0
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_subtract/pubspec.yaml
@@ -0,0 +1,19 @@
+name: native_subtract
+description: Subtracts two numbers with native code.
+version: 0.1.0
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  logging: ^1.1.1
+  native_assets_cli: ^0.3.0
+  native_toolchain_c: ^0.3.0
+
+dev_dependencies:
+  ffigen: ^8.0.2
+  lints: ^3.0.0
+  test: ^1.23.1
diff --git a/pkgs/native_assets_builder/test/data/native_subtract/src/native_subtract.c b/pkgs/native_assets_builder/test/data/native_subtract/src/native_subtract.c
new file mode 100644
index 0000000..6562ae6
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_subtract/src/native_subtract.c
@@ -0,0 +1,9 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "native_subtract.h"
+
+int32_t subtract(int32_t a, int32_t b) {
+   return a - b;
+}
diff --git a/pkgs/native_assets_builder/test/data/native_subtract/src/native_subtract.h b/pkgs/native_assets_builder/test/data/native_subtract/src/native_subtract.h
new file mode 100644
index 0000000..407fc5d
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/native_subtract/src/native_subtract.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdint.h>
+
+#if _WIN32
+#define MYLIB_EXPORT __declspec(dllexport)
+#else
+#define MYLIB_EXPORT
+#endif
+
+MYLIB_EXPORT int32_t subtract(int32_t a, int32_t b);
diff --git a/pkgs/native_assets_builder/test/data/package_reading_metadata/build.dart b/pkgs/native_assets_builder/test/data/package_reading_metadata/build.dart
new file mode 100644
index 0000000..e8009db
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/package_reading_metadata/build.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:cli_config/cli_config.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+void main(List<String> args) async {
+  final config = await Config.fromArgs(args: args);
+  final buildConfig = BuildConfig.fromConfig(config);
+  if (!buildConfig.dryRun) {
+    final metadata =
+        buildConfig.dependencyMetadata!['package_with_metadata']!.metadata;
+    final someValue = metadata['some_key'];
+    assert(someValue != null);
+    final someInt = metadata['some_int'];
+    assert(someInt != null);
+    print(metadata);
+  } else {
+    print('meta data not available in dry run');
+  }
+}
diff --git a/pkgs/native_assets_builder/test/data/package_reading_metadata/pubspec.yaml b/pkgs/native_assets_builder/test/data/package_reading_metadata/pubspec.yaml
new file mode 100644
index 0000000..43f2318
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/package_reading_metadata/pubspec.yaml
@@ -0,0 +1,19 @@
+name: package_reading_metadata
+description: Reads some metadata in its build.dart
+version: 0.1.0
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  native_assets_cli: ^0.3.0
+  package_with_metadata:
+    path: ../package_with_metadata/
+  yaml: ^3.1.1
+  yaml_edit: ^2.1.0
+
+dev_dependencies:
+  lints: ^3.0.0
diff --git a/pkgs/native_assets_builder/test/data/package_with_metadata/build.dart b/pkgs/native_assets_builder/test/data/package_with_metadata/build.dart
new file mode 100644
index 0000000..a5e908a
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/package_with_metadata/build.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+void main(List<String> args) async {
+  final buildConfig = await BuildConfig.fromArgs(args);
+  final buildOutput = BuildOutput(
+    metadata: Metadata({
+      'some_key': 'some_value',
+      'some_int': 3,
+    }),
+  );
+  await buildOutput.writeToFile(outDir: buildConfig.outDir);
+}
diff --git a/pkgs/native_assets_builder/test/data/package_with_metadata/pubspec.yaml b/pkgs/native_assets_builder/test/data/package_with_metadata/pubspec.yaml
new file mode 100644
index 0000000..bca9ddd
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/package_with_metadata/pubspec.yaml
@@ -0,0 +1,17 @@
+name: package_with_metadata
+description: Sets some metadata in its build.dart
+version: 0.1.0
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  native_assets_cli: ^0.3.0
+  yaml: ^3.1.1
+  yaml_edit: ^2.1.0
+
+dev_dependencies:
+  lints: ^3.0.0
diff --git a/pkgs/native_assets_builder/test/data/wrong_build_output/build.dart b/pkgs/native_assets_builder/test/data/wrong_build_output/build.dart
new file mode 100644
index 0000000..a34dbd0
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/wrong_build_output/build.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+void main(List<String> args) async {
+  final buildConfig = await BuildConfig.fromArgs(args);
+  await File.fromUri(buildConfig.outDir.resolve(BuildOutput.fileName))
+      .writeAsString(_wrongContents);
+}
+
+const _wrongContents = '''
+timestamp: 2023-07-28 14:22:45.000
+assets: []
+dependencies: []
+metadata: {}
+version: 9001.0.0
+''';
diff --git a/pkgs/native_assets_builder/test/data/wrong_build_output/pubspec.yaml b/pkgs/native_assets_builder/test/data/wrong_build_output/pubspec.yaml
new file mode 100644
index 0000000..e6b5419
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/wrong_build_output/pubspec.yaml
@@ -0,0 +1,17 @@
+name: wrong_build_output
+description: Package that tries to add an asset with an id not prefixed by its package name.
+version: 0.1.0
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  native_assets_cli: ^0.3.0
+  yaml: ^3.1.1
+  yaml_edit: ^2.1.0
+
+dev_dependencies:
+  lints: ^3.0.0
diff --git a/pkgs/native_assets_builder/test/data/wrong_build_output_2/build.dart b/pkgs/native_assets_builder/test/data/wrong_build_output_2/build.dart
new file mode 100644
index 0000000..331cd2d
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/wrong_build_output_2/build.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+void main(List<String> args) async {
+  final buildConfig = await BuildConfig.fromArgs(args);
+  await File.fromUri(buildConfig.outDir.resolve(BuildOutput.fileName))
+      .writeAsString(_wrongContents);
+}
+
+const _wrongContents = '''
+timestamp: 2023-07-28 14:22:45.000
+assets:
+  foo: 123
+dependencies: []
+metadata: {}
+version: 1.0.0
+''';
diff --git a/pkgs/native_assets_builder/test/data/wrong_build_output_2/pubspec.yaml b/pkgs/native_assets_builder/test/data/wrong_build_output_2/pubspec.yaml
new file mode 100644
index 0000000..9e87ed9
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/wrong_build_output_2/pubspec.yaml
@@ -0,0 +1,17 @@
+name: wrong_build_output_2
+description: Package that tries to add an asset with an id not prefixed by its package name.
+version: 0.1.0
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  native_assets_cli: ^0.3.0
+  yaml: ^3.1.1
+  yaml_edit: ^2.1.0
+
+dev_dependencies:
+  lints: ^3.0.0
diff --git a/pkgs/native_assets_builder/test/data/wrong_build_output_3/build.dart b/pkgs/native_assets_builder/test/data/wrong_build_output_3/build.dart
new file mode 100644
index 0000000..307dfff
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/wrong_build_output_3/build.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+void main(List<String> args) async {
+  final buildConfig = await BuildConfig.fromArgs(args);
+  await File.fromUri(buildConfig.outDir.resolve(BuildOutput.fileName))
+      .writeAsString(_rightContents);
+  exit(1);
+}
+
+const _rightContents = '''
+timestamp: 2023-07-28 14:22:45.000
+assets: []
+dependencies: []
+metadata: {}
+version: 1.0.0
+''';
diff --git a/pkgs/native_assets_builder/test/data/wrong_build_output_3/pubspec.yaml b/pkgs/native_assets_builder/test/data/wrong_build_output_3/pubspec.yaml
new file mode 100644
index 0000000..1cdc5b2
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/wrong_build_output_3/pubspec.yaml
@@ -0,0 +1,17 @@
+name: wrong_build_output_3
+description: Package that outputs a valid build_output.yaml but a non-zero exit code.
+version: 0.1.0
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  native_assets_cli: ^0.3.0
+  yaml: ^3.1.1
+  yaml_edit: ^2.1.0
+
+dev_dependencies:
+  lints: ^3.0.0
diff --git a/pkgs/native_assets_builder/test/data/wrong_namespace_asset/build.dart b/pkgs/native_assets_builder/test/data/wrong_namespace_asset/build.dart
new file mode 100644
index 0000000..457aa90
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/wrong_namespace_asset/build.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+void main(List<String> args) async {
+  final buildConfig = await BuildConfig.fromArgs(args);
+  final buildOutput = BuildOutput(
+    assets: [
+      Asset(
+        id: 'package:other_package/foo',
+        linkMode: LinkMode.dynamic,
+        target: Target.current,
+        path: AssetAbsolutePath(
+          buildConfig.outDir.resolve(
+            Target.current.os.dylibFileName('foo'),
+          ),
+        ),
+      ),
+    ],
+  );
+  await buildOutput.writeToFile(outDir: buildConfig.outDir);
+}
diff --git a/pkgs/native_assets_builder/test/data/wrong_namespace_asset/pubspec.yaml b/pkgs/native_assets_builder/test/data/wrong_namespace_asset/pubspec.yaml
new file mode 100644
index 0000000..fc6b9e8
--- /dev/null
+++ b/pkgs/native_assets_builder/test/data/wrong_namespace_asset/pubspec.yaml
@@ -0,0 +1,17 @@
+name: wrong_namespace_asset
+description: Package that tries to add an asset with an id not prefixed by its package name.
+version: 0.1.0
+
+publish_to: none
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  native_assets_cli: ^0.3.0
+  yaml: ^3.1.1
+  yaml_edit: ^2.1.0
+
+dev_dependencies:
+  lints: ^3.0.0
diff --git a/pkgs/native_assets_builder/test/helpers.dart b/pkgs/native_assets_builder/test/helpers.dart
new file mode 100644
index 0000000..522aa97
--- /dev/null
+++ b/pkgs/native_assets_builder/test/helpers.dart
@@ -0,0 +1,188 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:logging/logging.dart';
+import 'package:native_assets_builder/src/utils/run_process.dart'
+    as run_process;
+import 'package:test/test.dart';
+import 'package:yaml/yaml.dart';
+
+extension UriExtension on Uri {
+  Uri get parent => File(toFilePath()).parent.uri;
+}
+
+const keepTempKey = 'KEEP_TEMPORARY_DIRECTORIES';
+
+Future<void> inTempDir(
+  Future<void> Function(Uri tempUri) fun, {
+  String? prefix,
+  bool keepTemp = false,
+}) async {
+  final tempDir = await Directory.systemTemp.createTemp(prefix);
+  // Deal with Windows temp folder aliases.
+  final tempUri =
+      Directory(await tempDir.resolveSymbolicLinks()).uri.normalizePath();
+  try {
+    await fun(tempUri);
+  } finally {
+    if ((!Platform.environment.containsKey(keepTempKey) ||
+            Platform.environment[keepTempKey]!.isEmpty) &&
+        !keepTemp) {
+      await tempDir.delete(recursive: true);
+    }
+  }
+}
+
+/// Runs a [Process].
+///
+/// If [logger] is provided, stream stdout and stderr to it.
+///
+/// If [captureOutput], captures stdout and stderr.
+Future<run_process.RunProcessResult> runProcess({
+  required Uri executable,
+  List<String> arguments = const [],
+  Uri? workingDirectory,
+  Map<String, String>? environment,
+  bool includeParentEnvironment = true,
+  required Logger? logger,
+  bool captureOutput = true,
+  int expectedExitCode = 0,
+  bool throwOnUnexpectedExitCode = false,
+}) =>
+    run_process.runProcess(
+      executable: executable,
+      arguments: arguments,
+      workingDirectory: workingDirectory,
+      environment: environment,
+      includeParentEnvironment: includeParentEnvironment,
+      logger: logger,
+      captureOutput: captureOutput,
+      expectedExitCode: expectedExitCode,
+      throwOnUnexpectedExitCode: throwOnUnexpectedExitCode,
+    );
+
+/// Test files are run in a variety of ways, find this package root in all.
+///
+/// Test files can be run from source from any working directory. The Dart SDK
+/// `tools/test.py` runs them from the root of the SDK for example.
+///
+/// Test files can be run from dill from the root of package. `package:test`
+/// does this.
+///
+/// https://github.com/dart-lang/test/issues/110
+Uri findPackageRoot(String packageName) {
+  final script = Platform.script;
+  final fileName = script.name;
+  if (fileName.endsWith('_test.dart')) {
+    // We're likely running from source.
+    var directory = script.resolve('.');
+    while (true) {
+      final dirName = directory.name;
+      if (dirName == packageName) {
+        return directory;
+      }
+      final parent = directory.resolve('..');
+      if (parent == directory) break;
+      directory = parent;
+    }
+  } else if (fileName.endsWith('.dill')) {
+    final cwd = Directory.current.uri;
+    final dirName = cwd.name;
+    if (dirName == packageName) {
+      return cwd;
+    }
+  }
+  throw StateError("Could not find package root for package '$packageName'. "
+      'Tried finding the package root via Platform.script '
+      "'${Platform.script.toFilePath()}' and Directory.current "
+      "'${Directory.current.uri.toFilePath()}'.");
+}
+
+final pkgNativeAssetsBuilderUri = findPackageRoot('native_assets_builder');
+
+final testDataUri = pkgNativeAssetsBuilderUri.resolve('test/data/');
+
+extension on Uri {
+  String get name => pathSegments.where((e) => e != '').last;
+}
+
+Future<void> copyTestProjects({
+  Uri? sourceUri,
+  required Uri targetUri,
+}) async {
+  sourceUri ??= testDataUri;
+  final manifestUri = sourceUri.resolve('manifest.yaml');
+  final manifestFile = File.fromUri(manifestUri);
+  final manifestString = await manifestFile.readAsString();
+  final manifestYaml = loadYamlDocument(manifestString);
+  final manifest = [
+    for (final path in manifestYaml.contents as YamlList)
+      Uri(path: path as String)
+  ];
+  final filesToCopy =
+      manifest.where((e) => e.pathSegments.last != 'pubspec.yaml').toList();
+  final filesToModify =
+      manifest.where((e) => e.pathSegments.last == 'pubspec.yaml').toList();
+
+  for (final pathToCopy in filesToCopy) {
+    final sourceFile = File.fromUri(sourceUri.resolveUri(pathToCopy));
+    final targetFileUri = targetUri.resolveUri(pathToCopy);
+    final targetDirUri = targetFileUri.parent;
+    final targetDir = Directory.fromUri(targetDirUri);
+    if (!(await targetDir.exists())) {
+      await targetDir.create(recursive: true);
+    }
+
+    // Copying files on MacOS and Windows preserves the source timestamps.
+    // The builder will use the cached build if the timestamps are equal.
+    // So just write the file instead.
+    final targetFile = File.fromUri(targetFileUri);
+    await targetFile.writeAsBytes(await sourceFile.readAsBytes());
+  }
+  for (final pathToModify in filesToModify) {
+    final sourceFile = File.fromUri(sourceUri.resolveUri(pathToModify));
+    final targetFileUri = targetUri.resolveUri(pathToModify);
+    final sourceString = await sourceFile.readAsString();
+    final modifiedString = sourceString.replaceAll(
+      'path: ../../../',
+      'path: ${pkgNativeAssetsBuilderUri.toFilePath().replaceAll('\\', '/')}',
+    );
+    await File.fromUri(targetFileUri)
+        .writeAsString(modifiedString, flush: true);
+  }
+}
+
+/// Logger that outputs the full trace when a test fails.
+Logger get logger => _logger ??= () {
+      // A new logger is lazily created for each test so that the messages
+      // captured by printOnFailure are scoped to the correct test.
+      addTearDown(() => _logger = null);
+      return _createTestLogger();
+    }();
+
+Logger? _logger;
+
+Logger createCapturingLogger(
+  List<String> capturedMessages, {
+  Level level = Level.ALL,
+}) =>
+    _createTestLogger(capturedMessages: capturedMessages, level: level);
+
+Logger _createTestLogger({
+  List<String>? capturedMessages,
+  Level level = Level.ALL,
+}) =>
+    Logger.detached('')
+      ..level = level
+      ..onRecord.listen((record) {
+        printOnFailure(
+          '${record.level.name}: ${record.time}: ${record.message}',
+        );
+        capturedMessages?.add(record.message);
+      });
+
+final dartExecutable = File(Platform.resolvedExecutable).uri;
diff --git a/pkgs/native_assets_cli/.gitignore b/pkgs/native_assets_cli/.gitignore
new file mode 100644
index 0000000..ef8a06e
--- /dev/null
+++ b/pkgs/native_assets_cli/.gitignore
@@ -0,0 +1,14 @@
+# https://dart.dev/guides/libraries/private-files
+# Created by `dart pub`
+.dart_tool/
+
+# Avoid committing pubspec.lock for library packages; see
+# https://dart.dev/guides/libraries/private-files#pubspeclock.
+pubspec.lock
+
+coverage/
+
+*.dll
+*.dylib
+*.exe
+*.so
diff --git a/pkgs/native_assets_cli/CHANGELOG.md b/pkgs/native_assets_cli/CHANGELOG.md
new file mode 100644
index 0000000..0159aab
--- /dev/null
+++ b/pkgs/native_assets_cli/CHANGELOG.md
@@ -0,0 +1,26 @@
+## 0.3.2
+
+- Fixed an issue where `Depenendencies.dependencies` could not be
+  modified when expected to.
+
+## 0.3.1
+
+- Added `Target.androidRiscv64`.
+
+## 0.3.0
+
+- **Breaking change** Add required `BuildConfig.packageName`
+  ([#142](https://github.com/dart-lang/native/issues/142)).
+
+## 0.2.0
+
+- **Breaking change** Rename `Asset.name` to `Asset.id`
+  ([#100](https://github.com/dart-lang/native/issues/100)).
+- Added topics.
+- Fixed metadata example.
+- Throws `FormatException`s instead of `TypeError`s when failing to parse Yaml
+  ([#109](https://github.com/dart-lang/native/issues/109)).
+
+## 0.1.0
+
+- Initial version.
diff --git a/pkgs/native_assets_cli/LICENSE b/pkgs/native_assets_cli/LICENSE
new file mode 100644
index 0000000..4fd5739
--- /dev/null
+++ b/pkgs/native_assets_cli/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2023, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google LLC nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkgs/native_assets_cli/README.md b/pkgs/native_assets_cli/README.md
new file mode 100644
index 0000000..7a336e0
--- /dev/null
+++ b/pkgs/native_assets_cli/README.md
@@ -0,0 +1,54 @@
+[![package:native_assets_cli](https://github.com/dart-lang/native/actions/workflows/native.yaml/badge.svg)](https://github.com/dart-lang/native/actions/workflows/native.yaml)
+[![Coverage Status](https://coveralls.io/repos/github/dart-lang/native/badge.svg?branch=main)](https://coveralls.io/github/dart-lang/native?branch=main)
+[![pub package](https://img.shields.io/pub/v/native_assets_cli.svg)](https://pub.dev/packages/native_assets_cli)
+[![package publisher](https://img.shields.io/pub/publisher/native_assets_cli.svg)](https://pub.dev/packages/native_assets_cli/publisher)
+
+This library contains the CLI specification and a default implementation
+for bundling native code with Dart packages.
+
+## Status: Experimental
+
+**NOTE**: This package is currently experimental and published under the
+[labs.dart.dev](https://dart.dev/dart-team-packages) pub publisher in order to
+solicit feedback. 
+
+For packages in the labs.dart.dev publisher we generally plan to either graduate
+the package into a supported publisher (dart.dev, tools.dart.dev) after a period
+of feedback and iteration, or discontinue the package. These packages have a
+much higher expected rate of API and breaking changes.
+
+Your feedback is valuable and will help us evolve this package. 
+For bugs, please file an issue in the 
+[bug tracker](https://github.com/dart-lang/native/issues).
+For general feedback and suggestions for the native assets feature in Dart and
+Flutter, please comment in [dart-lang#50565] or [flutter#129757].
+
+## Example
+
+A typical layout of a package with native code is:
+
+* `lib/` contains Dart code which uses [`dart:ffi`] and [`package:ffigen`]
+  to call into native code.
+* `src/` contains C/C++/Rust code which is invoked through `dart:ffi`.
+* `build.dart` implements the CLI that communicates which native assets
+  to build/bundle with the Dart/Flutter SDK. This file uses the
+  protocol specified in this package.
+
+An example can be found in [example/](example/).
+
+## Usage
+
+Using the native assets feature requires passing
+`--enable-experiment=native-assets` in Dart on a dev build.
+
+The native assets feature is not yet available in Flutter.
+
+## Development
+
+The development of the feature can be tracked in [dart-lang#50565],
+[flutter#129757], and in the issue tracker on this repository.
+
+[`dart:ffi`]: https://api.dart.dev/stable/dart-ffi/dart-ffi-library.html
+[`package:ffigen`]: https://pub.dev/packages/ffigen
+[dart-lang#50565]: https://github.com/dart-lang/sdk/issues/50565
+[flutter#129757]: https://github.com/flutter/flutter/issues/129757
diff --git a/pkgs/native_assets_cli/analysis_options.yaml b/pkgs/native_assets_cli/analysis_options.yaml
new file mode 100644
index 0000000..dd3dcda
--- /dev/null
+++ b/pkgs/native_assets_cli/analysis_options.yaml
@@ -0,0 +1,12 @@
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+analyzer:
+  language:
+    strict-raw-types: true
+
+linter:
+  rules:
+    - prefer_const_declarations
+    - prefer_expression_function_bodies
+    - prefer_final_in_for_each
+    - prefer_final_locals
diff --git a/pkgs/native_assets_cli/example/README.md b/pkgs/native_assets_cli/example/README.md
new file mode 100644
index 0000000..1be681f
--- /dev/null
+++ b/pkgs/native_assets_cli/example/README.md
@@ -0,0 +1,9 @@
+The examples in this folder illustrate how native code is built and bundled
+in Dart and Flutter apps.
+
+* [native_add_app/](native_add_app/) has a dependency with C code.
+  This app should declare nothing special. Dart and Flutter should check
+  all dependencies for native code.
+* [native_add_library/](native_add_library/) contains a library with C code.
+  When Dart code in this library or dependent on this library is invoked, the
+  C code must be built and bundled so that it can be used by the Dart code.
diff --git a/pkgs/native_assets_cli/example/native_add_app/README.md b/pkgs/native_assets_cli/example/native_add_app/README.md
new file mode 100644
index 0000000..50a8bc0
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_app/README.md
@@ -0,0 +1,10 @@
+An example application to show invocation of native code bundled with the native
+assets feature.
+
+## Usage
+
+Run application with `dart --enable-experiment=native-assets run`.
+
+Run tests with `dart --enable-experiment=native-assets test`.
+
+Release application with `dart --enable-experiment=native-assets build bin/native_add_app`. (Run with `./bin/native_add_app/native_add_app.exe`.)
diff --git a/pkgs/native_assets_cli/example/native_add_app/bin/native_add_app.dart b/pkgs/native_assets_cli/example/native_add_app/bin/native_add_app.dart
new file mode 100644
index 0000000..40bd133
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_app/bin/native_add_app.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_add_library/native_add_library.dart';
+
+void main() {
+  print('Invoking a native function to calculate 1 + 2.');
+  final result = add(1, 2);
+  print('Invocation success: 1 + 2 = $result.');
+}
diff --git a/pkgs/native_assets_cli/example/native_add_app/pubspec.yaml b/pkgs/native_assets_cli/example/native_add_app/pubspec.yaml
new file mode 100644
index 0000000..68f3d8e
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_app/pubspec.yaml
@@ -0,0 +1,17 @@
+publish_to: none
+
+name: native_add_app
+description: Invokes a package with native assets.
+version: 0.1.0
+repository: https://github.com/dart-lang/native/tree/main/pkgs/native_assets_cli/example/native_add_app
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  native_add_library:
+    path: ../native_add_library/
+
+dev_dependencies:
+  lints: ^3.0.0
+  test: ^1.21.0
diff --git a/pkgs/native_assets_cli/example/native_add_app/test/native_add_library_test.dart b/pkgs/native_assets_cli/example/native_add_app/test/native_add_library_test.dart
new file mode 100644
index 0000000..692446e
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_app/test/native_add_library_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_add_library/native_add_library.dart';
+import 'package:test/test.dart';
+
+void main() {
+  test('invoke native function', () {
+    expect(add(24, 18), 42);
+  });
+}
diff --git a/pkgs/native_assets_cli/example/native_add_library/README.md b/pkgs/native_assets_cli/example/native_add_library/README.md
new file mode 100644
index 0000000..180cb02
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_library/README.md
@@ -0,0 +1,16 @@
+An example library containing native code that should be bundled with Dart and
+Flutter applications.
+
+## Usage
+
+Run tests with `dart --enable-experiment=native-assets test`.
+
+## Code organization
+
+A typical layout of a package with native code is:
+
+* `lib/` contains Dart code which uses [`dart:ffi`] and [`package:ffigen`]
+  to call into native code.
+* `src/` contains C code which is built and then invoked through `dart:ffi`.
+* `build.dart` implements the CLI that communicates which native assets
+  to build/bundle with the Dart/Flutter SDK.
diff --git a/pkgs/native_assets_cli/example/native_add_library/build.dart b/pkgs/native_assets_cli/example/native_add_library/build.dart
new file mode 100644
index 0000000..ae39cdc
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_library/build.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+
+const packageName = 'native_add_library';
+
+/// Implements the protocol from `package:native_assets_cli` by building
+/// the C code in `src/` and reporting what native assets it built.
+void main(List<String> args) async {
+  // Parse the build configuration passed to this CLI from Dart or Flutter.
+  final buildConfig = await BuildConfig.fromArgs(args);
+  final buildOutput = BuildOutput();
+
+  // Configure `package:native_toolchain_c` to build the C code for us.
+  final cbuilder = CBuilder.library(
+    name: packageName,
+    assetId: 'package:$packageName/${packageName}.dart',
+    sources: [
+      'src/$packageName.c',
+    ],
+  );
+  await cbuilder.run(
+    buildConfig: buildConfig,
+    // `package:native_toolchain_c` will output the dynamic or static libraries it built,
+    // what files it accessed (for caching the build), etc.
+    buildOutput: buildOutput,
+    logger: Logger('')
+      ..level = Level.ALL
+      ..onRecord.listen((record) => print(record.message)),
+  );
+
+  // Write the output according to the native assets protocol so that Dart or
+  // Flutter can find the native assets produced by this script.
+  await buildOutput.writeToFile(outDir: buildConfig.outDir);
+}
diff --git a/pkgs/native_assets_cli/example/native_add_library/ffigen.yaml b/pkgs/native_assets_cli/example/native_add_library/ffigen.yaml
new file mode 100644
index 0000000..4b32465
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_library/ffigen.yaml
@@ -0,0 +1,20 @@
+# Run with `flutter pub run ffigen --config ffigen.yaml`.
+name: NativeAddBindings
+description: |
+  Bindings for `src/native_add.h`.
+
+  Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`.
+output: 'lib/native_add_library.dart'
+headers:
+  entry-points:
+    - 'src/native_add_library.h'
+  include-directives:
+    - 'src/native_add_library.h'
+preamble: |
+  // Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+  // for details. All rights reserved. Use of this source code is governed by a
+  // BSD-style license that can be found in the LICENSE file.
+comments:
+  style: any
+  length: full
+ffi-native:
diff --git a/pkgs/native_assets_cli/example/native_add_library/lib/native_add_library.dart b/pkgs/native_assets_cli/example/native_add_library/lib/native_add_library.dart
new file mode 100644
index 0000000..4d1e803
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_library/lib/native_add_library.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// AUTO GENERATED FILE, DO NOT EDIT.
+//
+// Generated by `package:ffigen`.
+// ignore_for_file: type=lint
+import 'dart:ffi' as ffi;
+
+@ffi.Native<ffi.Int32 Function(ffi.Int32, ffi.Int32)>(symbol: 'add')
+external int add(
+  int a,
+  int b,
+);
diff --git a/pkgs/native_assets_cli/example/native_add_library/pubspec.yaml b/pkgs/native_assets_cli/example/native_add_library/pubspec.yaml
new file mode 100644
index 0000000..02f8219
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_library/pubspec.yaml
@@ -0,0 +1,20 @@
+publish_to: none
+
+name: native_add_library
+description: Sums two numbers with native code.
+version: 0.1.0
+repository: https://github.com/dart-lang/native/tree/main/pkgs/native_assets_cli/example/native_add_library
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  logging: ^1.1.1
+  native_assets_cli: ^0.3.0
+  native_toolchain_c: ^0.3.0
+
+dev_dependencies:
+  ffigen: ^8.0.2
+  lints: ^3.0.0
+  test: ^1.21.0
diff --git a/pkgs/native_assets_cli/example/native_add_library/src/native_add_library.c b/pkgs/native_assets_cli/example/native_add_library/src/native_add_library.c
new file mode 100644
index 0000000..cf68dd3
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_library/src/native_add_library.c
@@ -0,0 +1,16 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "native_add_library.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+int32_t add(int32_t a, int32_t b) {
+#ifdef DEBUG
+  printf("Adding %i and %i.\n", a, b);
+#endif
+  return a + b;
+}
diff --git a/pkgs/native_assets_cli/example/native_add_library/src/native_add_library.h b/pkgs/native_assets_cli/example/native_add_library/src/native_add_library.h
new file mode 100644
index 0000000..5824f98
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_library/src/native_add_library.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdint.h>
+
+#if _WIN32
+#define MYLIB_EXPORT __declspec(dllexport)
+#else
+#define MYLIB_EXPORT
+#endif
+
+MYLIB_EXPORT int32_t add(int32_t a, int32_t b);
diff --git a/pkgs/native_assets_cli/example/native_add_library/test/native_add_library_test.dart b/pkgs/native_assets_cli/example/native_add_library/test/native_add_library_test.dart
new file mode 100644
index 0000000..692446e
--- /dev/null
+++ b/pkgs/native_assets_cli/example/native_add_library/test/native_add_library_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_add_library/native_add_library.dart';
+import 'package:test/test.dart';
+
+void main() {
+  test('invoke native function', () {
+    expect(add(24, 18), 42);
+  });
+}
diff --git a/pkgs/native_assets_cli/lib/native_assets_cli.dart b/pkgs/native_assets_cli/lib/native_assets_cli.dart
new file mode 100644
index 0000000..8ee3d30
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/native_assets_cli.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A library that contains the argument and file formats for implementing a
+/// native assets CLI.
+library native_assets_cli;
+
+export 'src/model/asset.dart';
+export 'src/model/build_config.dart';
+export 'src/model/build_mode.dart';
+export 'src/model/build_output.dart';
+export 'src/model/dependencies.dart';
+export 'src/model/ios_sdk.dart';
+export 'src/model/link_mode.dart';
+export 'src/model/link_mode_preference.dart';
+export 'src/model/metadata.dart';
+export 'src/model/target.dart';
diff --git a/pkgs/native_assets_cli/lib/src/model/asset.dart b/pkgs/native_assets_cli/lib/src/model/asset.dart
new file mode 100644
index 0000000..616688f
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/model/asset.dart
@@ -0,0 +1,323 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:yaml/yaml.dart';
+
+import '../utils/uri.dart';
+import '../utils/yaml.dart';
+import 'link_mode.dart';
+import 'target.dart';
+
+abstract class AssetPath {
+  factory AssetPath(String pathType, Uri? uri) {
+    switch (pathType) {
+      case AssetAbsolutePath._pathTypeValue:
+        return AssetAbsolutePath(uri!);
+      case AssetRelativePath._pathTypeValue:
+        return AssetRelativePath(uri!);
+      case AssetSystemPath._pathTypeValue:
+        return AssetSystemPath(uri!);
+      case AssetInExecutable._pathTypeValue:
+        return AssetInExecutable();
+      case AssetInProcess._pathTypeValue:
+        return AssetInProcess();
+    }
+    throw FormatException('Unknown pathType: $pathType.');
+  }
+
+  factory AssetPath.fromYaml(YamlMap yamlMap) {
+    final pathType = as<String>(yamlMap[_pathTypeKey]);
+    final uriString = as<String?>(yamlMap[_uriKey]);
+    final uri = uriString != null ? Uri(path: uriString) : null;
+    return AssetPath(pathType, uri);
+  }
+
+  Map<String, Object> toYaml();
+  List<String> toDartConst();
+
+  static const _pathTypeKey = 'path_type';
+  static const _uriKey = 'uri';
+
+  Future<bool> exists();
+}
+
+/// Asset at absolute path [uri].
+class AssetAbsolutePath implements AssetPath {
+  final Uri uri;
+
+  AssetAbsolutePath(this.uri);
+
+  static const _pathTypeValue = 'absolute';
+
+  @override
+  Map<String, Object> toYaml() => {
+        AssetPath._pathTypeKey: _pathTypeValue,
+        AssetPath._uriKey: uri.toFilePath(),
+      };
+
+  @override
+  List<String> toDartConst() => [_pathTypeValue, uri.toFilePath()];
+
+  @override
+  int get hashCode => Object.hash(uri, 133711);
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! AssetAbsolutePath) {
+      return false;
+    }
+    return uri == other.uri;
+  }
+
+  @override
+  Future<bool> exists() => uri.fileSystemEntity.exists();
+}
+
+/// Asset is avaliable on a relative path.
+///
+/// If [LinkMode] of an [Asset] is [LinkMode.dynamic],
+/// `Platform.script.resolve(uri)` will be used to load the asset at runtime.
+class AssetRelativePath implements AssetPath {
+  final Uri uri;
+
+  AssetRelativePath(this.uri);
+
+  static const _pathTypeValue = 'relative';
+
+  @override
+  Map<String, Object> toYaml() => {
+        AssetPath._pathTypeKey: _pathTypeValue,
+        AssetPath._uriKey: uri.toFilePath(),
+      };
+
+  @override
+  List<String> toDartConst() => [_pathTypeValue, uri.toFilePath()];
+
+  @override
+  int get hashCode => Object.hash(uri, 133717);
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! AssetRelativePath) {
+      return false;
+    }
+    return uri == other.uri;
+  }
+
+  @override
+  Future<bool> exists() => uri.fileSystemEntity.exists();
+}
+
+/// Asset is avaliable on the system `PATH`.
+///
+/// [uri] only contains a file name.
+class AssetSystemPath implements AssetPath {
+  final Uri uri;
+
+  AssetSystemPath(this.uri);
+
+  static const _pathTypeValue = 'system';
+
+  @override
+  Map<String, Object> toYaml() => {
+        AssetPath._pathTypeKey: _pathTypeValue,
+        AssetPath._uriKey: uri.toFilePath(),
+      };
+
+  @override
+  List<String> toDartConst() => [_pathTypeValue, uri.toFilePath()];
+
+  @override
+  int get hashCode => Object.hash(uri, 133723);
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! AssetSystemPath) {
+      return false;
+    }
+    return uri == other.uri;
+  }
+
+  @override
+  Future<bool> exists() => Future.value(true);
+}
+
+/// Asset is loaded in the process and symbols are available through
+/// `DynamicLibrary.process()`.
+class AssetInProcess implements AssetPath {
+  AssetInProcess._();
+
+  static final AssetInProcess _singleton = AssetInProcess._();
+
+  factory AssetInProcess() => _singleton;
+
+  static const _pathTypeValue = 'process';
+
+  @override
+  Map<String, Object> toYaml() => {
+        AssetPath._pathTypeKey: _pathTypeValue,
+      };
+
+  @override
+  List<String> toDartConst() => [_pathTypeValue];
+
+  @override
+  Future<bool> exists() => Future.value(true);
+}
+
+/// Asset is embedded in executable and symbols are available through
+/// `DynamicLibrary.executable()`.
+class AssetInExecutable implements AssetPath {
+  AssetInExecutable._();
+
+  static final AssetInExecutable _singleton = AssetInExecutable._();
+
+  factory AssetInExecutable() => _singleton;
+
+  static const _pathTypeValue = 'executable';
+
+  @override
+  Map<String, Object> toYaml() => {
+        AssetPath._pathTypeKey: _pathTypeValue,
+      };
+
+  @override
+  List<String> toDartConst() => [_pathTypeValue];
+
+  @override
+  Future<bool> exists() => Future.value(true);
+}
+
+class Asset {
+  final LinkMode linkMode;
+  final String id;
+  final Target target;
+  final AssetPath path;
+
+  Asset({
+    required this.id,
+    required this.linkMode,
+    required this.target,
+    required this.path,
+  });
+
+  factory Asset.fromYaml(YamlMap yamlMap) => Asset(
+        id: as<String>(yamlMap[_idKey]),
+        path: AssetPath.fromYaml(as<YamlMap>(yamlMap[_pathKey])),
+        target: Target.fromString(as<String>(yamlMap[_targetKey])),
+        linkMode: LinkMode.fromName(as<String>(yamlMap[_linkModeKey])),
+      );
+
+  static List<Asset> listFromYamlString(String yaml) {
+    final yamlObject = loadYaml(yaml);
+    if (yamlObject == null) {
+      return [];
+    }
+    return [
+      for (final yamlElement in as<YamlList>(yamlObject))
+        Asset.fromYaml(as<YamlMap>(yamlElement)),
+    ];
+  }
+
+  static List<Asset> listFromYamlList(YamlList yamlList) => [
+        for (final yamlElement in yamlList)
+          Asset.fromYaml(as<YamlMap>(yamlElement)),
+      ];
+
+  Asset copyWith({
+    LinkMode? linkMode,
+    String? id,
+    Target? target,
+    AssetPath? path,
+  }) =>
+      Asset(
+        id: id ?? this.id,
+        linkMode: linkMode ?? this.linkMode,
+        target: target ?? this.target,
+        path: path ?? this.path,
+      );
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! Asset) {
+      return false;
+    }
+    return other.id == id &&
+        other.linkMode == linkMode &&
+        other.target == target &&
+        other.path == path;
+  }
+
+  @override
+  int get hashCode => Object.hash(id, linkMode, target, path);
+
+  Map<String, Object> toYaml() => {
+        _idKey: id,
+        _linkModeKey: linkMode.name,
+        _pathKey: path.toYaml(),
+        _targetKey: target.toString(),
+      };
+
+  Map<String, List<String>> toDartConst() => {
+        id: path.toDartConst(),
+      };
+
+  String toYamlString() => yamlEncode(toYaml());
+
+  static const _idKey = 'id';
+  static const _linkModeKey = 'link_mode';
+  static const _pathKey = 'path';
+  static const _targetKey = 'target';
+
+  Future<bool> exists() => path.exists();
+
+  @override
+  String toString() => 'Asset(${toYaml()})';
+}
+
+extension AssetIterable on Iterable<Asset> {
+  List<Object> toYaml() => [for (final item in this) item.toYaml()];
+
+  String toYamlString() => yamlEncode(toYaml());
+
+  Iterable<Asset> whereLinkMode(LinkMode linkMode) =>
+      where((e) => e.linkMode == linkMode);
+
+  Map<Target, List<Asset>> get assetsPerTarget {
+    final result = <Target, List<Asset>>{};
+    for (final asset in this) {
+      final assets = result[asset.target] ?? [];
+      assets.add(asset);
+      result[asset.target] = assets;
+    }
+    return result;
+  }
+
+  Map<String, Map<String, List<String>>> toDartConst() => {
+        for (final entry in assetsPerTarget.entries)
+          entry.key.toString():
+              _combineMaps(entry.value.map((e) => e.toDartConst()).toList())
+      };
+
+  Map<Object, Object> toNativeAssetsFileEncoding() => {
+        'format-version': [1, 0, 0],
+        'native-assets': toDartConst(),
+      };
+
+  String toNativeAssetsFile() => yamlEncode(toNativeAssetsFileEncoding());
+
+  Future<bool> allExist() async {
+    final allResults = await Future.wait(map((e) => e.exists()));
+    final missing = allResults.contains(false);
+    return !missing;
+  }
+}
+
+Map<X, Y> _combineMaps<X, Y>(Iterable<Map<X, Y>> maps) {
+  final result = <X, Y>{};
+  for (final map in maps) {
+    result.addAll(map);
+  }
+  return result;
+}
diff --git a/pkgs/native_assets_cli/lib/src/model/build_config.dart b/pkgs/native_assets_cli/lib/src/model/build_config.dart
new file mode 100644
index 0000000..93e0d9d
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/model/build_config.dart
@@ -0,0 +1,658 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:cli_config/cli_config.dart';
+import 'package:collection/collection.dart';
+import 'package:crypto/crypto.dart';
+import 'package:pub_semver/pub_semver.dart';
+
+import '../utils/map.dart';
+import '../utils/yaml.dart';
+import 'build_mode.dart';
+import 'ios_sdk.dart';
+import 'link_mode_preference.dart';
+import 'metadata.dart';
+import 'target.dart';
+
+class BuildConfig {
+  /// The folder in which all output and intermediate artifacts should be
+  /// placed.
+  Uri get outDir => _outDir;
+  late final Uri _outDir;
+
+  /// The name of the package the native assets are built for.
+  String get packageName => _packageName;
+  late final String _packageName;
+
+  /// The root of the package the native assets are built for.
+  ///
+  /// Often a package's native assets are built because a package is a
+  /// dependency of another. For this it is convenient to know the packageRoot.
+  Uri get packageRoot => _packageRoot;
+  late final Uri _packageRoot;
+
+  /// The target being compiled for.
+  ///
+  /// Not available in [dryRun].
+  late final Target target =
+      Target.fromArchitectureAndOs(targetArchitecture, targetOs);
+
+  /// The architecture being compiled for.
+  ///
+  /// Not available in [dryRun].
+  Architecture get targetArchitecture {
+    _ensureNotDryRun();
+    return _targetArchitecture;
+  }
+
+  late final Architecture _targetArchitecture;
+
+  /// The operating system being compiled for.
+  OS get targetOs => _targetOs;
+  late final OS _targetOs;
+
+  /// When compiling for iOS, whether to target device or simulator.
+  ///
+  /// Required when [targetOs] equals [OS.iOS].
+  ///
+  /// Not available in [dryRun].s
+  IOSSdk? get targetIOSSdk {
+    _ensureNotDryRun();
+    return _targetIOSSdk;
+  }
+
+  late final IOSSdk? _targetIOSSdk;
+
+  /// When compiling for Android, the minimum Android SDK API version to that
+  /// the compiled code will be compatible with.
+  ///
+  /// Required when [targetOs] equals [OS.android].
+  ///
+  /// Not available in [dryRun].
+  ///
+  /// For more information about the Android API version, refer to
+  /// [`minSdkVersion`](https://developer.android.com/ndk/guides/sdk-versions#minsdkversion)
+  /// in the Android documentation.
+  int? get targetAndroidNdkApi {
+    _ensureNotDryRun();
+    return _targetAndroidNdkApi;
+  }
+
+  late final int? _targetAndroidNdkApi;
+
+  /// Preferred linkMode method for library.
+  LinkModePreference get linkModePreference => _linkModePreference;
+  late final LinkModePreference _linkModePreference;
+
+  /// Metadata from direct dependencies.
+  ///
+  /// The key in the map is the package name of the dependency.
+  ///
+  /// The key in the nested map is the key for the metadata from the dependency.
+  ///
+  /// Not available in [dryRun].
+  Map<String, Metadata>? get dependencyMetadata {
+    _ensureNotDryRun();
+    return _dependencyMetadata;
+  }
+
+  late final Map<String, Metadata>? _dependencyMetadata;
+
+  /// The configuration for invoking the C compiler.
+  ///
+  /// Not available in [dryRun].
+  CCompilerConfig get cCompiler {
+    _ensureNotDryRun();
+    return _cCompiler;
+  }
+
+  late final CCompilerConfig _cCompiler;
+
+  /// Don't run the build, only report the native assets produced.
+  bool get dryRun => _dryRun ?? false;
+  late final bool? _dryRun;
+
+  /// The build mode that the code should be compiled in.
+  ///
+  /// Not available in [dryRun].
+  BuildMode get buildMode {
+    _ensureNotDryRun();
+    return _buildMode;
+  }
+
+  late final BuildMode _buildMode;
+
+  /// The underlying config.
+  ///
+  /// Can be used for easier access to values on [dependencyMetadata].
+  Config get config => _config;
+  late final Config _config;
+
+  factory BuildConfig({
+    required Uri outDir,
+    required String packageName,
+    required Uri packageRoot,
+    required BuildMode buildMode,
+    required Architecture targetArchitecture,
+    required OS targetOs,
+    IOSSdk? targetIOSSdk,
+    int? targetAndroidNdkApi,
+    CCompilerConfig? cCompiler,
+    required LinkModePreference linkModePreference,
+    Map<String, Metadata>? dependencyMetadata,
+  }) {
+    final nonValidated = BuildConfig._()
+      .._outDir = outDir
+      .._packageName = packageName
+      .._packageRoot = packageRoot
+      .._buildMode = buildMode
+      .._targetArchitecture = targetArchitecture
+      .._targetOs = targetOs
+      .._targetIOSSdk = targetIOSSdk
+      .._targetAndroidNdkApi = targetAndroidNdkApi
+      .._cCompiler = cCompiler ?? CCompilerConfig()
+      .._linkModePreference = linkModePreference
+      .._dependencyMetadata = dependencyMetadata
+      .._dryRun = false;
+    final parsedConfigFile = nonValidated.toYaml();
+    final config = Config(fileParsed: parsedConfigFile);
+    return BuildConfig.fromConfig(config);
+  }
+
+  factory BuildConfig.dryRun({
+    required Uri outDir,
+    required String packageName,
+    required Uri packageRoot,
+    required OS targetOs,
+    required LinkModePreference linkModePreference,
+  }) {
+    final nonValidated = BuildConfig._()
+      .._outDir = outDir
+      .._packageName = packageName
+      .._packageRoot = packageRoot
+      .._targetOs = targetOs
+      .._linkModePreference = linkModePreference
+      .._cCompiler = CCompilerConfig()
+      .._dryRun = true;
+    final parsedConfigFile = nonValidated.toYaml();
+    final config = Config(fileParsed: parsedConfigFile);
+    return BuildConfig.fromConfig(config);
+  }
+
+  /// Constructs a checksum for a [BuildConfig] based on the fields
+  /// of a buildconfig that influence the build.
+  ///
+  /// This can be used for an [outDir], but should not be used for dry-runs.
+  ///
+  /// In particular, it only takes the package name from [packageRoot],
+  /// so that the hash is equal across checkouts and ignores [outDir] itself.
+  static String checksum({
+    required String packageName,
+    required Uri packageRoot,
+    required Architecture targetArchitecture,
+    required OS targetOs,
+    required BuildMode buildMode,
+    IOSSdk? targetIOSSdk,
+    int? targetAndroidNdkApi,
+    CCompilerConfig? cCompiler,
+    required LinkModePreference linkModePreference,
+    Map<String, Metadata>? dependencyMetadata,
+  }) {
+    final input = [
+      packageName,
+      targetArchitecture.toString(),
+      targetOs.toString(),
+      targetIOSSdk.toString(),
+      targetAndroidNdkApi.toString(),
+      buildMode.toString(),
+      linkModePreference.toString(),
+      cCompiler?.ar.toString(),
+      cCompiler?.cc.toString(),
+      cCompiler?.envScript.toString(),
+      cCompiler?.envScriptArgs.toString(),
+      cCompiler?.ld.toString(),
+      if (dependencyMetadata != null)
+        for (final entry in dependencyMetadata.entries) ...[
+          entry.key,
+          json.encode(entry.value.toYaml()),
+        ]
+    ].join('###');
+    final sha256String = sha256.convert(utf8.encode(input)).toString();
+    // 256 bit hashes lead to 64 hex character strings.
+    // To avoid overflowing file paths limits, only use 32.
+    // Using 16 hex characters would also be unlikely to have collisions.
+    const nameLength = 32;
+    return sha256String.substring(0, nameLength);
+  }
+
+  BuildConfig._();
+
+  /// The version of [BuildConfig].
+  ///
+  /// This class is used in the protocol between the Dart and Flutter SDKs
+  /// and packages through `build.dart` invocations.
+  ///
+  /// If we ever were to make breaking changes, it would be useful to give
+  /// proper error messages rather than just fail to parse the YAML
+  /// representation in the protocol.
+  static Version version = Version(1, 0, 0);
+
+  factory BuildConfig.fromConfig(Config config) {
+    final result = BuildConfig._().._cCompiler = CCompilerConfig._();
+    final configExceptions = <Object>[];
+    for (final f in result._readFieldsFromConfig()) {
+      try {
+        f(config);
+      } on FormatException catch (e, st) {
+        configExceptions.add(e);
+        configExceptions.add(st);
+      }
+    }
+
+    if (configExceptions.isNotEmpty) {
+      throw FormatException('Configuration is not in the right format. '
+          'FormatExceptions: $configExceptions');
+    }
+
+    return result;
+  }
+
+  /// Constructs a config by parsing CLI arguments and loading the config file.
+  ///
+  /// The [args] must be commandline arguments.
+  ///
+  /// If provided, [environment] must be a map containing environment variables.
+  /// If not provided, [environment] defaults to [Platform.environment].
+  ///
+  /// If provided, [workingDirectory] is used to resolves paths inside
+  /// [environment].
+  /// If not provided, [workingDirectory] defaults to [Directory.current].
+  ///
+  /// This async constructor is intended to be used directly in CLI files.
+  static Future<BuildConfig> fromArgs(
+    List<String> args, {
+    Map<String, String>? environment,
+    Uri? workingDirectory,
+  }) async {
+    final config = await Config.fromArgs(
+      args: args,
+      environment: environment,
+      workingDirectory: workingDirectory,
+    );
+    return BuildConfig.fromConfig(config);
+  }
+
+  static const outDirConfigKey = 'out_dir';
+  static const packageNameConfigKey = 'package_name';
+  static const packageRootConfigKey = 'package_root';
+  static const dependencyMetadataConfigKey = 'dependency_metadata';
+  static const _versionKey = 'version';
+  static const targetAndroidNdkApiConfigKey = 'target_android_ndk_api';
+  static const dryRunConfigKey = 'dry_run';
+
+  List<void Function(Config)> _readFieldsFromConfig() {
+    var osSet = false;
+    var ccSet = false;
+    return [
+      (config) {
+        final configVersion = Version.parse(config.string('version'));
+        if (configVersion.major > version.major) {
+          throw FormatException(
+            'The config version $configVersion is newer than this '
+            'package:native_assets_cli config version $version, '
+            'please update native_assets_cli.',
+          );
+        }
+        if (configVersion.major < version.major) {
+          throw FormatException(
+            'The config version $configVersion is newer than this '
+            'package:native_assets_cli config version $version, '
+            'please update the Dart or Flutter SDK.',
+          );
+        }
+      },
+      (config) => _config = config,
+      (config) => _dryRun = config.optionalBool(dryRunConfigKey),
+      (config) => _outDir = config.path(outDirConfigKey, mustExist: true),
+      (config) => _packageName = config.string(packageNameConfigKey),
+      (config) =>
+          _packageRoot = config.path(packageRootConfigKey, mustExist: true),
+      (config) {
+        if (dryRun) {
+          _throwIfNotNullInDryRun<String>(BuildMode.configKey);
+        } else {
+          _buildMode = BuildMode.fromString(
+            config.string(
+              BuildMode.configKey,
+              validValues: BuildMode.values.map((e) => '$e'),
+            ),
+          );
+        }
+      },
+      (config) {
+        _targetOs = OS.fromString(
+          config.string(
+            OS.configKey,
+            validValues: OS.values.map((e) => '$e'),
+          ),
+        );
+        osSet = true;
+      },
+      (config) {
+        if (dryRun) {
+          _throwIfNotNullInDryRun<String>(Architecture.configKey);
+        } else {
+          final validArchitectures = [
+            if (!osSet)
+              ...Architecture.values
+            else
+              for (final target in Target.values)
+                if (target.os == _targetOs) target.architecture
+          ];
+          _targetArchitecture = Architecture.fromString(
+            config.string(
+              Architecture.configKey,
+              validValues: validArchitectures.map((e) => '$e'),
+            ),
+          );
+        }
+      },
+      (config) {
+        if (dryRun) {
+          _throwIfNotNullInDryRun<String>(IOSSdk.configKey);
+        } else {
+          _targetIOSSdk = (osSet && _targetOs == OS.iOS)
+              ? IOSSdk.fromString(
+                  config.string(
+                    IOSSdk.configKey,
+                    validValues: IOSSdk.values.map((e) => '$e'),
+                  ),
+                )
+              : null;
+        }
+      },
+      (config) {
+        if (dryRun) {
+          _throwIfNotNullInDryRun<int>(targetAndroidNdkApiConfigKey);
+        } else {
+          _targetAndroidNdkApi = (osSet && _targetOs == OS.android)
+              ? config.int(targetAndroidNdkApiConfigKey)
+              : null;
+        }
+      },
+      (config) {
+        if (dryRun) {
+          _throwIfNotNullInDryRun<int>(CCompilerConfig.arConfigKeyFull);
+        } else {
+          cCompiler._ar = config.optionalPath(
+            CCompilerConfig.arConfigKeyFull,
+            mustExist: true,
+          );
+        }
+      },
+      (config) {
+        if (dryRun) {
+          _throwIfNotNullInDryRun<int>(CCompilerConfig.ccConfigKeyFull);
+        } else {
+          cCompiler._cc = config.optionalPath(
+            CCompilerConfig.ccConfigKeyFull,
+            mustExist: true,
+          );
+          ccSet = true;
+        }
+      },
+      (config) {
+        if (dryRun) {
+          _throwIfNotNullInDryRun<int>(CCompilerConfig.ccConfigKeyFull);
+        } else {
+          cCompiler._ld = config.optionalPath(
+            CCompilerConfig.ldConfigKeyFull,
+            mustExist: true,
+          );
+        }
+      },
+      (config) {
+        if (dryRun) {
+          _throwIfNotNullInDryRun<int>(CCompilerConfig.ccConfigKeyFull);
+        } else {
+          cCompiler._envScript = (ccSet &&
+                  cCompiler.cc != null &&
+                  cCompiler.cc!.toFilePath().endsWith('cl.exe'))
+              ? config.path(CCompilerConfig.envScriptConfigKeyFull,
+                  mustExist: true)
+              : null;
+        }
+      },
+      (config) {
+        if (dryRun) {
+          _throwIfNotNullInDryRun<int>(CCompilerConfig.ccConfigKeyFull);
+        } else {
+          cCompiler._envScriptArgs = config.optionalStringList(
+            CCompilerConfig.envScriptArgsConfigKeyFull,
+            splitEnvironmentPattern: ' ',
+          );
+        }
+      },
+      (config) {
+        _linkModePreference = LinkModePreference.fromString(
+          config.string(
+            LinkModePreference.configKey,
+            validValues: LinkModePreference.values.map((e) => '$e'),
+          ),
+        );
+      },
+      (config) {
+        _dependencyMetadata = _readDependencyMetadataFromConfig(config);
+      },
+    ];
+  }
+
+  Map<String, Metadata>? _readDependencyMetadataFromConfig(Config config) {
+    final fileValue =
+        config.valueOf<Map<Object?, Object?>?>(dependencyMetadataConfigKey);
+    if (fileValue == null) {
+      return null;
+    }
+    final result = <String, Metadata>{};
+    for (final entry in fileValue.entries) {
+      final packageName = as<String>(entry.key);
+      final defines = entry.value;
+      if (defines is! Map) {
+        throw FormatException("Unexpected value '$defines' for key "
+            "'$dependencyMetadataConfigKey.$packageName' in config file. "
+            'Expected a Map.');
+      }
+      final packageResult = <String, Object>{};
+      for (final entry2 in defines.entries) {
+        final key = as<String>(entry2.key);
+        final value = as<Object>(entry2.value);
+        packageResult[key] = value;
+      }
+      result[packageName] = Metadata(packageResult.sortOnKey());
+    }
+    return result.sortOnKey();
+  }
+
+  Map<String, Object> toYaml() {
+    late Map<String, Object> cCompilerYaml;
+    if (!dryRun) {
+      cCompilerYaml = _cCompiler.toYaml();
+    }
+
+    return {
+      outDirConfigKey: _outDir.toFilePath(),
+      packageNameConfigKey: _packageName,
+      packageRootConfigKey: _packageRoot.toFilePath(),
+      OS.configKey: _targetOs.toString(),
+      LinkModePreference.configKey: _linkModePreference.toString(),
+      _versionKey: version.toString(),
+      if (dryRun) dryRunConfigKey: dryRun,
+      if (!dryRun) ...{
+        BuildMode.configKey: _buildMode.toString(),
+        Architecture.configKey: _targetArchitecture.toString(),
+        if (_targetIOSSdk != null) IOSSdk.configKey: _targetIOSSdk.toString(),
+        if (_targetAndroidNdkApi != null)
+          targetAndroidNdkApiConfigKey: _targetAndroidNdkApi!,
+        if (cCompilerYaml.isNotEmpty) CCompilerConfig.configKey: cCompilerYaml,
+        if (_dependencyMetadata != null)
+          dependencyMetadataConfigKey: {
+            for (final entry in _dependencyMetadata!.entries)
+              entry.key: entry.value.toYaml(),
+          },
+      },
+    }.sortOnKey();
+  }
+
+  String toYamlString() => yamlEncode(toYaml());
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! BuildConfig) {
+      return false;
+    }
+    if (other.outDir != outDir) return false;
+    if (other.packageName != packageName) return false;
+    if (other.packageRoot != packageRoot) return false;
+    if (other.dryRun != dryRun) return false;
+    if (other.targetOs != targetOs) return false;
+    if (other.linkModePreference != linkModePreference) return false;
+    if (!dryRun) {
+      if (other.buildMode != buildMode) return false;
+      if (other.targetArchitecture != targetArchitecture) return false;
+      if (other.targetIOSSdk != targetIOSSdk) return false;
+      if (other.targetAndroidNdkApi != targetAndroidNdkApi) return false;
+      if (other.cCompiler != cCompiler) return false;
+      if (!const DeepCollectionEquality()
+          .equals(other.dependencyMetadata, _dependencyMetadata)) return false;
+    }
+    return true;
+  }
+
+  @override
+  int get hashCode => Object.hashAll([
+        outDir,
+        packageName,
+        packageRoot,
+        targetOs,
+        linkModePreference,
+        dryRun,
+        if (!dryRun) ...[
+          buildMode,
+          const DeepCollectionEquality().hash(dependencyMetadata),
+          targetArchitecture,
+          targetIOSSdk,
+          targetAndroidNdkApi,
+          cCompiler,
+        ],
+      ]);
+
+  @override
+  String toString() => 'BuildConfig(${toYaml()})';
+
+  void _ensureNotDryRun() {
+    if (dryRun) {
+      throw StateError('''This field is not available in dry runs.
+In Flutter projects, native builds are generated per OS which target multiple
+architectures, build modes, etc. Therefore, the list of native assets produced
+can _only_ depend on OS.''');
+    }
+  }
+
+  void _throwIfNotNullInDryRun<T>(String key) {
+    final object = config.valueOf<T?>(key);
+    if (object != null) {
+      throw const FormatException('''This field is not available in dry runs.
+In Flutter projects, native builds are generated per OS which target multiple
+architectures, build modes, etc. Therefore, the list of native assets produced
+can _only_ depend on OS.''');
+    }
+  }
+}
+
+class CCompilerConfig {
+  /// Path to a C compiler.
+  Uri? get cc => _cc;
+  late final Uri? _cc;
+
+  /// Path to a native linker.
+  Uri? get ld => _ld;
+  late final Uri? _ld;
+
+  /// Path to a native archiver.
+  Uri? get ar => _ar;
+  late final Uri? _ar;
+
+  /// Path to script that sets environment variables for [cc], [ld], and [ar].
+  Uri? get envScript => _envScript;
+  late final Uri? _envScript;
+
+  /// Arguments for [envScript].
+  List<String>? get envScriptArgs => _envScriptArgs;
+  late final List<String>? _envScriptArgs;
+
+  factory CCompilerConfig({
+    Uri? ar,
+    Uri? cc,
+    Uri? ld,
+    Uri? envScript,
+    List<String>? envScriptArgs,
+  }) =>
+      CCompilerConfig._()
+        .._ar = ar
+        .._cc = cc
+        .._ld = ld
+        .._envScript = envScript
+        .._envScriptArgs = envScriptArgs;
+
+  CCompilerConfig._();
+
+  static const configKey = 'c_compiler';
+  static const arConfigKey = 'ar';
+  static const arConfigKeyFull = '$configKey.$arConfigKey';
+  static const ccConfigKey = 'cc';
+  static const ccConfigKeyFull = '$configKey.$ccConfigKey';
+  static const ldConfigKey = 'ld';
+  static const ldConfigKeyFull = '$configKey.$ldConfigKey';
+  static const envScriptConfigKey = 'env_script';
+  static const envScriptConfigKeyFull = '$configKey.$envScriptConfigKey';
+  static const envScriptArgsConfigKey = 'env_script_arguments';
+  static const envScriptArgsConfigKeyFull =
+      '$configKey.$envScriptArgsConfigKey';
+
+  Map<String, Object> toYaml() => {
+        if (_ar != null) arConfigKey: _ar!.toFilePath(),
+        if (_cc != null) ccConfigKey: _cc!.toFilePath(),
+        if (_ld != null) ldConfigKey: _ld!.toFilePath(),
+        if (_envScript != null) envScriptConfigKey: _envScript!.toFilePath(),
+        if (_envScriptArgs != null) envScriptArgsConfigKey: _envScriptArgs!,
+      }.sortOnKey();
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! CCompilerConfig) {
+      return false;
+    }
+    if (other.ar != ar) return false;
+    if (other.cc != cc) return false;
+    if (other.ld != ld) return false;
+    if (other.envScript != envScript) return false;
+    if (!const ListEquality<String>()
+        .equals(other.envScriptArgs, envScriptArgs)) {
+      return false;
+    }
+    return true;
+  }
+
+  @override
+  int get hashCode => Object.hash(
+        _ar,
+        _cc,
+        _ld,
+        _envScript,
+        const ListEquality<String>().hash(envScriptArgs),
+      );
+}
diff --git a/pkgs/native_assets_cli/lib/src/model/build_mode.dart b/pkgs/native_assets_cli/lib/src/model/build_mode.dart
new file mode 100644
index 0000000..8b8cd3c
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/model/build_mode.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class BuildMode {
+  final String name;
+
+  const BuildMode._(this.name);
+
+  static const debug = BuildMode._('debug');
+  static const release = BuildMode._('release');
+
+  static const values = [
+    debug,
+    release,
+  ];
+
+  factory BuildMode.fromString(String target) =>
+      values.firstWhere((e) => e.name == target);
+
+  /// The `package:config` key preferably used.
+  static const String configKey = 'build_mode';
+
+  @override
+  String toString() => name;
+}
diff --git a/pkgs/native_assets_cli/lib/src/model/build_output.dart b/pkgs/native_assets_cli/lib/src/model/build_output.dart
new file mode 100644
index 0000000..6f88407
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/model/build_output.dart
@@ -0,0 +1,138 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:collection/collection.dart';
+import 'package:pub_semver/pub_semver.dart';
+import 'package:yaml/yaml.dart';
+
+import '../utils/datetime.dart';
+import '../utils/file.dart';
+import '../utils/map.dart';
+import '../utils/yaml.dart';
+import 'asset.dart';
+import 'dependencies.dart';
+import 'metadata.dart';
+
+class BuildOutput {
+  /// Time the build this output belongs to started.
+  ///
+  /// Rounded down to whole seconds, because [File.lastModified] is rounded
+  /// to whole seconds and caching logic compares these timestamps.
+  final DateTime timestamp;
+  final List<Asset> assets;
+  final Dependencies dependencies;
+  final Metadata metadata;
+
+  BuildOutput({
+    DateTime? timestamp,
+    List<Asset>? assets,
+    Dependencies? dependencies,
+    Metadata? metadata,
+  })  : timestamp = (timestamp ?? DateTime.now()).roundDownToSeconds(),
+        assets = assets ?? [],
+        // ignore: prefer_const_constructors
+        dependencies = dependencies ?? Dependencies([]),
+        // ignore: prefer_const_constructors
+        metadata = metadata ?? Metadata({});
+
+  static const _assetsKey = 'assets';
+  static const _dependenciesKey = 'dependencies';
+  static const _metadataKey = 'metadata';
+  static const _timestampKey = 'timestamp';
+  static const _versionKey = 'version';
+
+  factory BuildOutput.fromYamlString(String yaml) {
+    final yamlObject = loadYaml(yaml);
+    return BuildOutput.fromYaml(as<YamlMap>(yamlObject));
+  }
+
+  factory BuildOutput.fromYaml(YamlMap yamlMap) {
+    final outputVersion = Version.parse(as<String>(yamlMap['version']));
+    if (outputVersion.major > version.major) {
+      throw FormatException(
+        'The output version $outputVersion is newer than the '
+        'package:native_assets_cli config version $version in Dart or Flutter, '
+        'please update the Dart or Flutter SDK.',
+      );
+    }
+    if (outputVersion.major < version.major) {
+      throw FormatException(
+        'The output version $outputVersion is newer than this '
+        'package:native_assets_cli config version $version in Dart or Flutter, '
+        'please update native_assets_cli.',
+      );
+    }
+
+    return BuildOutput(
+      timestamp: DateTime.parse(as<String>(yamlMap[_timestampKey])),
+      assets: Asset.listFromYamlList(as<YamlList>(yamlMap[_assetsKey])),
+      dependencies:
+          Dependencies.fromYaml(as<YamlList?>(yamlMap[_dependenciesKey])),
+      metadata: Metadata.fromYaml(as<YamlMap?>(yamlMap[_metadataKey])),
+    );
+  }
+
+  Map<String, Object> toYaml() => {
+        _timestampKey: timestamp.toString(),
+        _assetsKey: assets.toYaml(),
+        _dependenciesKey: dependencies.toYaml(),
+        _metadataKey: metadata.toYaml(),
+        _versionKey: version.toString(),
+      }..sortOnKey();
+
+  String toYamlString() => yamlEncode(toYaml());
+
+  /// The version of [BuildOutput].
+  ///
+  /// This class is used in the protocol between the Dart and Flutter SDKs
+  /// and packages through `build.dart` invocations.
+  ///
+  /// If we ever were to make breaking changes, it would be useful to give
+  /// proper error messages rather than just fail to parse the YAML
+  /// representation in the protocol.
+  static Version version = Version(1, 0, 0);
+
+  static const fileName = 'build_output.yaml';
+
+  /// Writes the YAML file from [outDir]/[fileName].
+  static Future<BuildOutput?> readFromFile({required Uri outDir}) async {
+    final buildOutputUri = outDir.resolve(fileName);
+    final buildOutputFile = File.fromUri(buildOutputUri);
+    if (!await buildOutputFile.exists()) {
+      return null;
+    }
+    return BuildOutput.fromYamlString(await buildOutputFile.readAsString());
+  }
+
+  /// Writes the [toYamlString] to [outDir]/[fileName].
+  Future<void> writeToFile({required Uri outDir}) async {
+    final buildOutputUri = outDir.resolve(fileName);
+    await File.fromUri(buildOutputUri)
+        .writeAsStringCreateDirectory(toYamlString());
+  }
+
+  @override
+  String toString() => toYamlString();
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! BuildOutput) {
+      return false;
+    }
+    return other.timestamp == timestamp &&
+        const ListEquality<Asset>().equals(other.assets, assets) &&
+        other.dependencies == dependencies &&
+        other.metadata == metadata;
+  }
+
+  @override
+  int get hashCode => Object.hash(
+        timestamp.hashCode,
+        const ListEquality<Asset>().hash(assets),
+        dependencies,
+        metadata,
+      );
+}
diff --git a/pkgs/native_assets_cli/lib/src/model/dependencies.dart b/pkgs/native_assets_cli/lib/src/model/dependencies.dart
new file mode 100644
index 0000000..9ecc2cb
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/model/dependencies.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:collection/collection.dart';
+import 'package:yaml/yaml.dart';
+
+import '../utils/file.dart';
+import '../utils/uri.dart';
+import '../utils/yaml.dart';
+
+class Dependencies {
+  /// The dependencies a build relied on.
+  final List<Uri> dependencies;
+
+  const Dependencies(this.dependencies);
+
+  factory Dependencies.fromYamlString(String yamlString) {
+    final yaml = loadYaml(yamlString);
+    if (yaml is YamlList) {
+      return Dependencies.fromYaml(yaml);
+    }
+    // ignore: prefer_const_constructors
+    return Dependencies([]);
+  }
+
+  factory Dependencies.fromYaml(YamlList? yamlList) => Dependencies([
+        if (yamlList != null)
+          for (final dependency in yamlList)
+            fileSystemPathToUri(as<String>(dependency)),
+      ]);
+
+  List<String> toYaml() => [
+        for (final dependency in dependencies) dependency.toFilePath(),
+      ];
+
+  String toYamlString() => yamlEncode(toYaml());
+
+  @override
+  String toString() => toYamlString();
+
+  Future<DateTime> lastModified() =>
+      dependencies.map((u) => u.fileSystemEntity).lastModified();
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! Dependencies) {
+      return false;
+    }
+    return const ListEquality<Uri>().equals(other.dependencies, dependencies);
+  }
+
+  @override
+  int get hashCode => const ListEquality<Uri>().hash(dependencies);
+}
diff --git a/pkgs/native_assets_cli/lib/src/model/ios_sdk.dart b/pkgs/native_assets_cli/lib/src/model/ios_sdk.dart
new file mode 100644
index 0000000..7d3deeb
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/model/ios_sdk.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// For an iOS target, a build is either done for the device or the simulator.
+///
+/// Only fat binaries or xcframeworks can contain both targets.
+class IOSSdk {
+  final String xcodebuildSdk;
+
+  const IOSSdk._(this.xcodebuildSdk);
+
+  static const iPhoneOs = IOSSdk._('iphoneos');
+  static const iPhoneSimulator = IOSSdk._('iphonesimulator');
+
+  static const values = [
+    iPhoneOs,
+    iPhoneSimulator,
+  ];
+
+  factory IOSSdk.fromString(String target) =>
+      values.firstWhere((e) => e.xcodebuildSdk == target);
+
+  /// The `package:config` key preferably used.
+  static const String configKey = 'target_ios_sdk';
+
+  @override
+  String toString() => xcodebuildSdk;
+}
diff --git a/pkgs/native_assets_cli/lib/src/model/link_mode.dart b/pkgs/native_assets_cli/lib/src/model/link_mode.dart
new file mode 100644
index 0000000..a7f4d3d
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/model/link_mode.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class LinkMode {
+  final String name;
+
+  const LinkMode._(this.name);
+
+  static const LinkMode dynamic = LinkMode._('dynamic');
+  static const LinkMode static = LinkMode._('static');
+
+  /// Known values for [LinkMode].
+  static const List<LinkMode> values = [
+    dynamic,
+    static,
+  ];
+
+  factory LinkMode.fromName(String name) =>
+      values.where((element) => element.name == name).first;
+
+  @override
+  String toString() => name;
+}
diff --git a/pkgs/native_assets_cli/lib/src/model/link_mode_preference.dart b/pkgs/native_assets_cli/lib/src/model/link_mode_preference.dart
new file mode 100644
index 0000000..89a72ce
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/model/link_mode_preference.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'link_mode.dart';
+
+class LinkModePreference {
+  final String name;
+  final String description;
+  final LinkMode preferredLinkMode;
+  final List<LinkMode> potentialLinkMode;
+
+  const LinkModePreference(
+    this.name,
+    this.description, {
+    required this.preferredLinkMode,
+    required this.potentialLinkMode,
+  });
+
+  factory LinkModePreference.fromString(String name) =>
+      values.where((element) => element.name == name).first;
+
+  static const dynamic = LinkModePreference(
+    'dynamic',
+    '''Provide native assets as dynamic libraries.
+Fails if not all native assets can only be provided as static library.
+Required to run Dart in JIT mode.''',
+    preferredLinkMode: LinkMode.dynamic,
+    potentialLinkMode: [LinkMode.dynamic],
+  );
+
+  static const static = LinkModePreference(
+    'static',
+    '''Provide native assets as static libraries.
+Fails if not all native assets can only be provided as dynamic library.
+Required for potential link-time tree-shaking of native code.
+Therefore, preferred to in Dart AOT mode.''',
+    preferredLinkMode: LinkMode.static,
+    potentialLinkMode: [LinkMode.static],
+  );
+
+  static const preferDynamic = LinkModePreference(
+    'prefer-dynamic',
+    '''Provide native assets as dynamic libraries, if possible.
+Otherwise, build native assets as static libraries.''',
+    preferredLinkMode: LinkMode.dynamic,
+    potentialLinkMode: LinkMode.values,
+  );
+
+  static const preferStatic = LinkModePreference(
+    'prefer-static',
+    '''Provide native assets as static libraries, if possible.
+Otherwise, build native assets as dynamic libraries.
+Preferred for AOT compilation, if there are any native assets which can only be
+provided as dynamic libraries.''',
+    preferredLinkMode: LinkMode.static,
+    potentialLinkMode: LinkMode.values,
+  );
+
+  static const values = [
+    dynamic,
+    static,
+    preferDynamic,
+    preferStatic,
+  ];
+
+  /// The `package:config` key preferably used.
+  static const String configKey = 'link_mode_preference';
+
+  @override
+  String toString() => name;
+}
diff --git a/pkgs/native_assets_cli/lib/src/model/metadata.dart b/pkgs/native_assets_cli/lib/src/model/metadata.dart
new file mode 100644
index 0000000..34949b1
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/model/metadata.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:collection/collection.dart';
+import 'package:yaml/yaml.dart';
+
+import '../utils/map.dart';
+import '../utils/yaml.dart';
+
+class Metadata {
+  final Map<String, Object> metadata;
+
+  const Metadata(this.metadata);
+
+  factory Metadata.fromYaml(YamlMap? yamlMap) =>
+      Metadata(yamlMap?.formatCast<String, Object>() ?? {});
+
+  factory Metadata.fromYamlString(String yaml) {
+    final yamlObject = as<YamlMap>(loadYaml(yaml));
+    return Metadata.fromYaml(yamlObject);
+  }
+
+  Map<String, Object> toYaml() => metadata..sortOnKey();
+
+  String toYamlString() => yamlEncode(toYaml());
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! Metadata) {
+      return false;
+    }
+    return const DeepCollectionEquality().equals(other.metadata, metadata);
+  }
+
+  @override
+  int get hashCode => const DeepCollectionEquality().hash(metadata);
+
+  @override
+  String toString() => 'Metadata(${toYaml()})';
+}
diff --git a/pkgs/native_assets_cli/lib/src/model/target.dart b/pkgs/native_assets_cli/lib/src/model/target.dart
new file mode 100644
index 0000000..db61c62
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/model/target.dart
@@ -0,0 +1,372 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi' show Abi;
+import 'dart:io';
+
+import 'link_mode.dart';
+
+/// The hardware architectures the Dart VM runs on.
+class Architecture {
+  /// This architecture as used in [Platform.version].
+  final String dartPlatform;
+
+  const Architecture._(this.dartPlatform);
+
+  factory Architecture.fromAbi(Abi abi) => _abiToArch[abi]!;
+
+  static const Architecture arm = Architecture._('arm');
+  static const Architecture arm64 = Architecture._('arm64');
+  static const Architecture ia32 = Architecture._('ia32');
+  static const Architecture riscv32 = Architecture._('riscv32');
+  static const Architecture riscv64 = Architecture._('riscv64');
+  static const Architecture x64 = Architecture._('x64');
+
+  /// Known values for [Architecture].
+  static const List<Architecture> values = [
+    arm,
+    arm64,
+    ia32,
+    riscv32,
+    riscv64,
+    x64,
+  ];
+
+  static const _abiToArch = {
+    Abi.androidArm: Architecture.arm,
+    Abi.androidArm64: Architecture.arm64,
+    Abi.androidIA32: Architecture.ia32,
+    Abi.androidX64: Architecture.x64,
+    Abi.androidRiscv64: Architecture.riscv64,
+    Abi.fuchsiaArm64: Architecture.arm64,
+    Abi.fuchsiaX64: Architecture.x64,
+    Abi.iosArm: Architecture.arm,
+    Abi.iosArm64: Architecture.arm64,
+    Abi.iosX64: Architecture.x64,
+    Abi.linuxArm: Architecture.arm,
+    Abi.linuxArm64: Architecture.arm64,
+    Abi.linuxIA32: Architecture.ia32,
+    Abi.linuxRiscv32: Architecture.riscv32,
+    Abi.linuxRiscv64: Architecture.riscv64,
+    Abi.linuxX64: Architecture.x64,
+    Abi.macosArm64: Architecture.arm64,
+    Abi.macosX64: Architecture.x64,
+    Abi.windowsArm64: Architecture.arm64,
+    Abi.windowsIA32: Architecture.ia32,
+    Abi.windowsX64: Architecture.x64,
+  };
+
+  /// The `package:config` key preferably used.
+  static const String configKey = 'target_architecture';
+
+  @override
+  String toString() => dartPlatform;
+
+  /// Mapping from strings as used in [Architecture.toString] to
+  /// [Architecture]s.
+  static final Map<String, Architecture> _stringToArchitecture =
+      Map.fromEntries(Architecture.values.map(
+          (architecture) => MapEntry(architecture.toString(), architecture)));
+
+  factory Architecture.fromString(String target) =>
+      _stringToArchitecture[target]!;
+
+  /// The current [Architecture].
+  ///
+  /// Read from the [Platform.version] string.
+  static final Architecture current = Target.current.architecture;
+}
+
+/// The operating systems the Dart VM runs on.
+class OS {
+  /// This OS as used in [Platform.version]
+  final String dartPlatform;
+
+  const OS._(this.dartPlatform);
+
+  factory OS.fromAbi(Abi abi) => _abiToOS[abi]!;
+
+  static const OS android = OS._('android');
+  static const OS fuchsia = OS._('fuchsia');
+  static const OS iOS = OS._('ios');
+  static const OS linux = OS._('linux');
+  static const OS macOS = OS._('macos');
+  static const OS windows = OS._('windows');
+
+  /// Known values for [OS].
+  static const List<OS> values = [
+    android,
+    fuchsia,
+    iOS,
+    linux,
+    macOS,
+    windows,
+  ];
+
+  static const _abiToOS = {
+    Abi.androidArm: OS.android,
+    Abi.androidArm64: OS.android,
+    Abi.androidIA32: OS.android,
+    Abi.androidX64: OS.android,
+    Abi.androidRiscv64: OS.android,
+    Abi.fuchsiaArm64: OS.fuchsia,
+    Abi.fuchsiaX64: OS.fuchsia,
+    Abi.iosArm: OS.iOS,
+    Abi.iosArm64: OS.iOS,
+    Abi.iosX64: OS.iOS,
+    Abi.linuxArm: OS.linux,
+    Abi.linuxArm64: OS.linux,
+    Abi.linuxIA32: OS.linux,
+    Abi.linuxRiscv32: OS.linux,
+    Abi.linuxRiscv64: OS.linux,
+    Abi.linuxX64: OS.linux,
+    Abi.macosArm64: OS.macOS,
+    Abi.macosX64: OS.macOS,
+    Abi.windowsArm64: OS.windows,
+    Abi.windowsIA32: OS.windows,
+    Abi.windowsX64: OS.windows,
+  };
+
+  /// Typical cross compilation between OSes.
+  static const _osCrossCompilationDefault = {
+    OS.macOS: [OS.macOS, OS.iOS, OS.android],
+    OS.linux: [OS.linux, OS.android],
+    OS.windows: [OS.windows, OS.android],
+  };
+
+  /// The default dynamic library file name on this [OS].
+  String dylibFileName(String name) {
+    final prefix = _dylibPrefix[this]!;
+    final extension = _dylibExtension[this]!;
+    return '$prefix$name.$extension';
+  }
+
+  /// The default static library file name on this [OS].
+  String staticlibFileName(String name) {
+    final prefix = _staticlibPrefix[this]!;
+    final extension = _staticlibExtension[this]!;
+    return '$prefix$name.$extension';
+  }
+
+  String libraryFileName(String name, LinkMode linkMode) {
+    if (linkMode == LinkMode.dynamic) {
+      return dylibFileName(name);
+    }
+    assert(linkMode == LinkMode.static);
+    return staticlibFileName(name);
+  }
+
+  /// The default executable file name on this [OS].
+  String executableFileName(String name) {
+    final extension = _executableExtension[this]!;
+    final dot = extension.isNotEmpty ? '.' : '';
+    return '$name$dot$extension';
+  }
+
+  /// The default name prefix for dynamic libraries per [OS].
+  static const _dylibPrefix = {
+    OS.android: 'lib',
+    OS.fuchsia: 'lib',
+    OS.iOS: 'lib',
+    OS.linux: 'lib',
+    OS.macOS: 'lib',
+    OS.windows: '',
+  };
+
+  /// The default extension for dynamic libraries per [OS].
+  static const _dylibExtension = {
+    OS.android: 'so',
+    OS.fuchsia: 'so',
+    OS.iOS: 'dylib',
+    OS.linux: 'so',
+    OS.macOS: 'dylib',
+    OS.windows: 'dll',
+  };
+
+  /// The default name prefix for static libraries per [OS].
+  static const _staticlibPrefix = _dylibPrefix;
+
+  /// The default extension for static libraries per [OS].
+  static const _staticlibExtension = {
+    OS.android: 'a',
+    OS.fuchsia: 'a',
+    OS.iOS: 'a',
+    OS.linux: 'a',
+    OS.macOS: 'a',
+    OS.windows: 'lib',
+  };
+
+  /// The default extension for executables per [OS].
+  static const _executableExtension = {
+    OS.android: '',
+    OS.fuchsia: '',
+    OS.iOS: '',
+    OS.linux: '',
+    OS.macOS: '',
+    OS.windows: 'exe',
+  };
+
+  /// The `package:config` key preferably used.
+  static const String configKey = 'target_os';
+
+  @override
+  String toString() => dartPlatform;
+
+  /// Mapping from strings as used in [OS.toString] to
+  /// [OS]s.
+  static final Map<String, OS> _stringToOS =
+      Map.fromEntries(OS.values.map((os) => MapEntry(os.toString(), os)));
+
+  factory OS.fromString(String target) => _stringToOS[target]!;
+
+  /// The current [OS].
+  ///
+  /// Read from the [Platform.version] string.
+  static final OS current = Target.current.os;
+}
+
+/// Application binary interface.
+///
+/// The Dart VM can run on a variety of [Target]s, see [Target.values].
+class Target implements Comparable<Target> {
+  final Abi abi;
+
+  const Target._(this.abi);
+
+  factory Target.fromString(String target) => _stringToTarget[target]!;
+
+  /// The [Target] corresponding the substring of [Platform.version]
+  /// describing the [Target].
+  ///
+  /// The [Platform.version] strings are formatted as follows:
+  /// `<version> (<date>) on "<Target>"`.
+  factory Target.fromDartPlatform(String versionStringFull) {
+    final split = versionStringFull.split('"');
+    if (split.length < 2) {
+      throw FormatException(
+          "Unknown version from Platform.version '$versionStringFull'.");
+    }
+    final versionString = split[1];
+    final target = _dartVMstringToTarget[versionString];
+    if (target == null) {
+      throw FormatException("Unknown ABI '$versionString' from Platform.version"
+          " '$versionStringFull'.");
+    }
+    return target;
+  }
+
+  factory Target.fromArchitectureAndOs(Architecture architecture, OS os) {
+    for (final value in values) {
+      if (value.os == os && value.architecture == architecture) {
+        return value;
+      }
+    }
+    throw ArgumentError('Unsupported combination of OS and architecture: '
+        "'${os}_$architecture'");
+  }
+
+  static const androidArm = Target._(Abi.androidArm);
+  static const androidArm64 = Target._(Abi.androidArm64);
+  static const androidIA32 = Target._(Abi.androidIA32);
+  static const androidX64 = Target._(Abi.androidX64);
+  static const androidRiscv64 = Target._(Abi.androidRiscv64);
+  static const fuchsiaArm64 = Target._(Abi.fuchsiaArm64);
+  static const fuchsiaX64 = Target._(Abi.fuchsiaX64);
+  static const iOSArm = Target._(Abi.iosArm);
+  static const iOSArm64 = Target._(Abi.iosArm64);
+  static const iOSX64 = Target._(Abi.iosX64);
+  static const linuxArm = Target._(Abi.linuxArm);
+  static const linuxArm64 = Target._(Abi.linuxArm64);
+  static const linuxIA32 = Target._(Abi.linuxIA32);
+  static const linuxRiscv32 = Target._(Abi.linuxRiscv32);
+  static const linuxRiscv64 = Target._(Abi.linuxRiscv64);
+  static const linuxX64 = Target._(Abi.linuxX64);
+  static const macOSArm64 = Target._(Abi.macosArm64);
+  static const macOSX64 = Target._(Abi.macosX64);
+  static const windowsArm64 = Target._(Abi.windowsArm64);
+  static const windowsIA32 = Target._(Abi.windowsIA32);
+  static const windowsX64 = Target._(Abi.windowsX64);
+
+  /// All Targets that we can build for.
+  ///
+  /// Note that for some of these a Dart SDK is not available and they are only
+  /// used as target architectures for Flutter apps.
+  static const values = {
+    androidArm,
+    androidArm64,
+    androidIA32,
+    androidX64,
+    androidRiscv64,
+    fuchsiaArm64,
+    fuchsiaX64,
+    iOSArm,
+    iOSArm64,
+    iOSX64,
+    linuxArm,
+    linuxArm64,
+    linuxIA32,
+    linuxRiscv32,
+    linuxRiscv64,
+    linuxX64,
+    macOSArm64,
+    macOSX64,
+    windowsArm64,
+    windowsIA32,
+    windowsX64,
+    // TODO(dacoharkes): Add support for `wasm`.
+  };
+
+  /// Mapping from strings as used in [Target.toString] to [Target]s.
+  static final Map<String, Target> _stringToTarget = Map.fromEntries(
+      Target.values.map((target) => MapEntry(target.toString(), target)));
+
+  /// Mapping from lowercased strings as used in [Platform.version] to
+  /// [Target]s.
+  static final Map<String, Target> _dartVMstringToTarget = Map.fromEntries(
+      Target.values.map((target) => MapEntry(target.dartVMToString(), target)));
+
+  /// The current [Target].
+  ///
+  /// Read from the [Platform.version] string.
+  static final Target current = Target.fromDartPlatform(Platform.version);
+
+  Architecture get architecture => Architecture.fromAbi(abi);
+
+  OS get os => OS.fromAbi(abi);
+
+  String get _architectureString => architecture.dartPlatform;
+
+  String get _osString => os.dartPlatform;
+
+  /// A string representation of this object.
+  @override
+  String toString() => dartVMToString();
+
+  /// As used in [Platform.version].
+  String dartVMToString() => '${_osString}_$_architectureString';
+
+  /// Compares `this` to [other].
+  ///
+  /// If [other] is also an [Target], consistent with sorting on [toString].
+  @override
+  int compareTo(Target other) => toString().compareTo(other.toString());
+
+  /// A list of supported target [Target]s from this host [os].
+  List<Target> supportedTargetTargets(
+          {Map<OS, List<OS>> osCrossCompilation =
+              OS._osCrossCompilationDefault}) =>
+      Target.values
+          .where((target) =>
+              // Only valid cross compilation.
+              osCrossCompilation[os]!.contains(target.os) &&
+              // And no deprecated architectures.
+              target != Target.iOSArm)
+          .sorted;
+}
+
+/// Common methods for manipulating iterables of [Target]s.
+extension TargetList on Iterable<Target> {
+  /// The [Target]s in `this` sorted by name alphabetically.
+  List<Target> get sorted => [for (final target in this) target]..sort();
+}
diff --git a/pkgs/native_assets_cli/lib/src/utils/datetime.dart b/pkgs/native_assets_cli/lib/src/utils/datetime.dart
new file mode 100644
index 0000000..11cda00
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/utils/datetime.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+extension DateTimeExtension on DateTime {
+  DateTime roundDownToSeconds() =>
+      DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch -
+          millisecondsSinceEpoch % const Duration(seconds: 1).inMilliseconds);
+}
diff --git a/pkgs/native_assets_cli/lib/src/utils/file.dart b/pkgs/native_assets_cli/lib/src/utils/file.dart
new file mode 100644
index 0000000..703f601
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/utils/file.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+extension FileExtension on File {
+  Future<File> writeAsStringCreateDirectory(String contents,
+      {FileMode mode = FileMode.write,
+      Encoding encoding = utf8,
+      bool flush = false}) async {
+    if (!await parent.exists()) {
+      await parent.create(recursive: true);
+    }
+    return await writeAsString(contents,
+        mode: mode, encoding: encoding, flush: flush);
+  }
+}
+
+extension FileSystemEntityExtension on FileSystemEntity {
+  Future<DateTime> lastModified() async {
+    final this_ = this;
+    if (this_ is Link || await FileSystemEntity.isLink(this_.path)) {
+      // Don't follow links.
+      return DateTime.fromMicrosecondsSinceEpoch(0);
+    }
+    if (this_ is File) {
+      if (!await this_.exists()) {
+        // If the file was deleted, regard it is modified recently.
+        return DateTime.now();
+      }
+      return await this_.lastModified();
+    }
+    assert(this_ is Directory);
+    this_ as Directory;
+    return await this_.lastModified();
+  }
+}
+
+extension FileSystemEntityIterable on Iterable<FileSystemEntity> {
+  Future<DateTime> lastModified() async {
+    var last = DateTime.fromMillisecondsSinceEpoch(0);
+    for (final entity in this) {
+      final entityTimestamp = await entity.lastModified();
+      if (entityTimestamp.isAfter(last)) {
+        last = entityTimestamp;
+      }
+    }
+    return last;
+  }
+}
+
+extension DirectoryExtension on Directory {
+  Future<DateTime> lastModified() async {
+    var last = DateTime.fromMillisecondsSinceEpoch(0);
+    await for (final entity in list()) {
+      final entityTimestamp = await entity.lastModified();
+      if (entityTimestamp.isAfter(last)) {
+        last = entityTimestamp;
+      }
+    }
+    return last;
+  }
+}
diff --git a/pkgs/native_assets_cli/lib/src/utils/map.dart b/pkgs/native_assets_cli/lib/src/utils/map.dart
new file mode 100644
index 0000000..bb767ed
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/utils/map.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+extension MapSorting<K extends Comparable<K>, V extends Object> on Map<K, V> {
+  Map<K, V> sortOnKey() {
+    final result = <K, V>{};
+    final keysSorted = keys.toList()..sort();
+    for (final key in keysSorted) {
+      final value = this[key]!;
+      result[key] = value;
+    }
+    return result;
+  }
+}
diff --git a/pkgs/native_assets_cli/lib/src/utils/uri.dart b/pkgs/native_assets_cli/lib/src/utils/uri.dart
new file mode 100644
index 0000000..ee4fd03
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/utils/uri.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+extension UriExtension on Uri {
+  FileSystemEntity get fileSystemEntity {
+    if (path.endsWith(Platform.pathSeparator) || path.endsWith('/')) {
+      return Directory.fromUri(this);
+    }
+    return File.fromUri(this);
+  }
+}
+
+Uri fileSystemPathToUri(String path) {
+  if (path.endsWith(Platform.pathSeparator) || path.endsWith('/')) {
+    return Uri.directory(path);
+  }
+  return Uri.file(path);
+}
diff --git a/pkgs/native_assets_cli/lib/src/utils/yaml.dart b/pkgs/native_assets_cli/lib/src/utils/yaml.dart
new file mode 100644
index 0000000..6e1b9e3
--- /dev/null
+++ b/pkgs/native_assets_cli/lib/src/utils/yaml.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:yaml/yaml.dart';
+import 'package:yaml_edit/yaml_edit.dart';
+
+String yamlEncode(Object yamlEncoding) {
+  final editor = YamlEditor('');
+  editor.update(
+    [],
+    wrapAsYamlNode(
+      yamlEncoding,
+      collectionStyle: CollectionStyle.BLOCK,
+    ),
+  );
+  return editor.toString();
+}
+
+T as<T>(Object? object) {
+  if (object is T) {
+    return object;
+  }
+  throw FormatException(
+    "Unexpected value '$object' in YAML. Expected a $T.",
+  );
+}
+
+extension YamlMapCast on YamlMap {
+  Map<K, V> formatCast<K, V>() => <K, V>{
+        for (final e in entries) as<K>(e.key): as<V>(e.value),
+      };
+}
diff --git a/pkgs/native_assets_cli/pubspec.yaml b/pkgs/native_assets_cli/pubspec.yaml
new file mode 100644
index 0000000..1c944d7
--- /dev/null
+++ b/pkgs/native_assets_cli/pubspec.yaml
@@ -0,0 +1,26 @@
+name: native_assets_cli
+description: >-
+  A library that contains the argument and file formats for implementing a
+  native assets CLI.
+version: 0.3.2
+repository: https://github.com/dart-lang/native/tree/main/pkgs/native_assets_cli
+
+topics:
+  - ffi
+  - interop
+  - native-assets
+
+environment:
+  sdk: '>=3.0.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  collection: ^1.17.1
+  crypto: ^3.0.3
+  pub_semver: ^2.1.3
+  yaml: ^3.1.1
+  yaml_edit: ^2.1.0
+
+dev_dependencies:
+  dart_flutter_team_lints: ^2.1.1
+  test: ^1.21.0
diff --git a/pkgs/native_assets_cli/test/example/native_add_library_test.dart b/pkgs/native_assets_cli/test/example/native_add_library_test.dart
new file mode 100644
index 0000000..34da58d
--- /dev/null
+++ b/pkgs/native_assets_cli/test/example/native_add_library_test.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@OnPlatform({
+  'mac-os': Timeout.factor(2),
+  'windows': Timeout.factor(10),
+})
+library;
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() async {
+  late Uri tempUri;
+  const name = 'native_add_library';
+
+  setUp(() async {
+    tempUri = (await Directory.systemTemp.createTemp()).uri;
+  });
+
+  tearDown(() async {
+    await Directory.fromUri(tempUri).delete(recursive: true);
+  });
+
+  for (final dryRun in [true, false]) {
+    final testSuffix = dryRun ? ' dry_run' : '';
+    test('native_add build$testSuffix', () async {
+      final testTempUri = tempUri.resolve('test1/');
+      await Directory.fromUri(testTempUri).create();
+      final testPackageUri = packageUri.resolve('example/$name/');
+      final dartUri = Uri.file(Platform.resolvedExecutable);
+
+      final processResult = await Process.run(
+        dartUri.toFilePath(),
+        [
+          'build.dart',
+          '-Dout_dir=${tempUri.toFilePath()}',
+          '-Dpackage_name=$name',
+          '-Dpackage_root=${testPackageUri.toFilePath()}',
+          '-Dtarget_os=${OS.current}',
+          '-Dversion=${BuildConfig.version}',
+          '-Dlink_mode_preference=dynamic',
+          '-Ddry_run=$dryRun',
+          if (!dryRun) ...[
+            '-Dtarget_architecture=${Architecture.current}',
+            '-Dbuild_mode=debug',
+            if (cc != null) '-Dcc=${cc!.toFilePath()}',
+            if (envScript != null)
+              '-D${CCompilerConfig.envScriptConfigKeyFull}='
+                  '${envScript!.toFilePath()}',
+            if (envScriptArgs != null)
+              '-D${CCompilerConfig.envScriptArgsConfigKeyFull}='
+                  '${envScriptArgs!.join(' ')}',
+          ],
+        ],
+        workingDirectory: testPackageUri.toFilePath(),
+      );
+      if (processResult.exitCode != 0) {
+        print(processResult.stdout);
+        print(processResult.stderr);
+        print(processResult.exitCode);
+      }
+      expect(processResult.exitCode, 0);
+
+      final buildOutputUri = tempUri.resolve('build_output.yaml');
+      final buildOutput = BuildOutput.fromYamlString(
+          await File.fromUri(buildOutputUri).readAsString());
+      final assets = buildOutput.assets;
+      final dependencies = buildOutput.dependencies;
+      if (dryRun) {
+        expect(assets.length, greaterThanOrEqualTo(1));
+        expect(await assets.first.exists(), false);
+        expect(dependencies.dependencies, <Uri>[]);
+      } else {
+        expect(assets.length, 1);
+        expect(await assets.allExist(), true);
+        expect(
+          dependencies.dependencies,
+          [
+            testPackageUri.resolve('src/$name.c'),
+            testPackageUri.resolve('build.dart'),
+          ],
+        );
+      }
+    });
+  }
+}
diff --git a/pkgs/native_assets_cli/test/helpers.dart b/pkgs/native_assets_cli/test/helpers.dart
new file mode 100644
index 0000000..2bd2742
--- /dev/null
+++ b/pkgs/native_assets_cli/test/helpers.dart
@@ -0,0 +1,105 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_assets_cli/src/model/build_config.dart';
+
+const keepTempKey = 'KEEP_TEMPORARY_DIRECTORIES';
+
+Future<void> inTempDir(
+  Future<void> Function(Uri tempUri) fun, {
+  String? prefix,
+  bool keepTemp = false,
+}) async {
+  final tempDir = await Directory.systemTemp.createTemp(prefix);
+  // Deal with Windows temp folder aliases.
+  final tempUri =
+      Directory(await tempDir.resolveSymbolicLinks()).uri.normalizePath();
+  try {
+    await fun(tempUri);
+  } finally {
+    if ((!Platform.environment.containsKey(keepTempKey) ||
+            Platform.environment[keepTempKey]!.isEmpty) &&
+        !keepTemp) {
+      await tempDir.delete(recursive: true);
+    }
+  }
+}
+
+/// Test files are run in a variety of ways, find this package root in all.
+///
+/// Test files can be run from source from any working directory. The Dart SDK
+/// `tools/test.py` runs them from the root of the SDK for example.
+///
+/// Test files can be run from dill from the root of package. `package:test`
+/// does this.
+///
+/// https://github.com/dart-lang/test/issues/110
+Uri findPackageRoot(String packageName) {
+  final script = Platform.script;
+  final fileName = script.name;
+  if (fileName.endsWith('_test.dart')) {
+    // We're likely running from source.
+    var directory = script.resolve('.');
+    while (true) {
+      final dirName = directory.name;
+      if (dirName == packageName) {
+        return directory;
+      }
+      final parent = directory.resolve('..');
+      if (parent == directory) break;
+      directory = parent;
+    }
+  } else if (fileName.endsWith('.dill')) {
+    final cwd = Directory.current.uri;
+    final dirName = cwd.name;
+    if (dirName == packageName) {
+      return cwd;
+    }
+  }
+  throw StateError("Could not find package root for package '$packageName'. "
+      'Tried finding the package root via Platform.script '
+      "'${Platform.script.toFilePath()}' and Directory.current "
+      "'${Directory.current.uri.toFilePath()}'.");
+}
+
+Uri packageUri = findPackageRoot('native_assets_cli');
+
+extension on Uri {
+  String get name => pathSegments.where((e) => e != '').last;
+}
+
+String unparseKey(String key) => key.replaceAll('.', '__').toUpperCase();
+
+/// Archiver provided by the environment.
+final Uri? ar = Platform
+    .environment[unparseKey(CCompilerConfig.arConfigKeyFull)]
+    ?.asFileUri();
+
+/// Compiler provided by the environment.
+final Uri? cc = Platform
+    .environment[unparseKey(CCompilerConfig.ccConfigKeyFull)]
+    ?.asFileUri();
+
+/// Linker provided by the environment.
+final Uri? ld = Platform
+    .environment[unparseKey(CCompilerConfig.ldConfigKeyFull)]
+    ?.asFileUri();
+
+/// Path to script that sets environment variables for [cc], [ld], and [ar].
+///
+/// Provided by environment.
+final Uri? envScript = Platform
+    .environment[unparseKey(CCompilerConfig.envScriptConfigKeyFull)]
+    ?.asFileUri();
+
+/// Arguments for [envScript] provided by environment.
+final List<String>? envScriptArgs = Platform
+    .environment[unparseKey(CCompilerConfig.envScriptArgsConfigKeyFull)]
+    ?.split(' ');
+
+extension on String {
+  Uri asFileUri() => Uri.file(this);
+}
diff --git a/pkgs/native_assets_cli/test/model/asset_test.dart b/pkgs/native_assets_cli/test/model/asset_test.dart
new file mode 100644
index 0000000..c9f2e9f
--- /dev/null
+++ b/pkgs/native_assets_cli/test/model/asset_test.dart
@@ -0,0 +1,196 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:collection/collection.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+void main() {
+  final fooUri = Uri.file('path/to/libfoo.so');
+  final foo2Uri = Uri.file('path/to/libfoo2.so');
+  final foo3Uri = Uri(path: 'libfoo3.so');
+  final barUri = Uri(path: 'path/to/libbar.a');
+  final blaUri = Uri(path: 'path/with spaces/bla.dll');
+  final assets = [
+    Asset(
+      id: 'foo',
+      path: AssetAbsolutePath(fooUri),
+      target: Target.androidX64,
+      linkMode: LinkMode.dynamic,
+    ),
+    Asset(
+      id: 'foo2',
+      path: AssetRelativePath(foo2Uri),
+      target: Target.androidX64,
+      linkMode: LinkMode.dynamic,
+    ),
+    Asset(
+      id: 'foo3',
+      path: AssetSystemPath(foo3Uri),
+      target: Target.androidX64,
+      linkMode: LinkMode.dynamic,
+    ),
+    Asset(
+      id: 'foo4',
+      path: AssetInExecutable(),
+      target: Target.androidX64,
+      linkMode: LinkMode.dynamic,
+    ),
+    Asset(
+      id: 'foo5',
+      path: AssetInProcess(),
+      target: Target.androidX64,
+      linkMode: LinkMode.dynamic,
+    ),
+    Asset(
+      id: 'bar',
+      path: AssetAbsolutePath(barUri),
+      target: Target.linuxArm64,
+      linkMode: LinkMode.static,
+    ),
+    Asset(
+      id: 'bla',
+      path: AssetAbsolutePath(blaUri),
+      target: Target.windowsX64,
+      linkMode: LinkMode.dynamic,
+    ),
+  ];
+
+  final assetsYamlEncoding = '''- id: foo
+  link_mode: dynamic
+  path:
+    path_type: absolute
+    uri: ${fooUri.toFilePath()}
+  target: android_x64
+- id: foo2
+  link_mode: dynamic
+  path:
+    path_type: relative
+    uri: ${foo2Uri.toFilePath()}
+  target: android_x64
+- id: foo3
+  link_mode: dynamic
+  path:
+    path_type: system
+    uri: ${foo3Uri.toFilePath()}
+  target: android_x64
+- id: foo4
+  link_mode: dynamic
+  path:
+    path_type: executable
+  target: android_x64
+- id: foo5
+  link_mode: dynamic
+  path:
+    path_type: process
+  target: android_x64
+- id: bar
+  link_mode: static
+  path:
+    path_type: absolute
+    uri: ${barUri.toFilePath()}
+  target: linux_arm64
+- id: bla
+  link_mode: dynamic
+  path:
+    path_type: absolute
+    uri: ${blaUri.toFilePath()}
+  target: windows_x64''';
+
+  final assetsDartEncoding = '''format-version:
+  - 1
+  - 0
+  - 0
+native-assets:
+  android_x64:
+    foo:
+      - absolute
+      - ${fooUri.toFilePath()}
+    foo2:
+      - relative
+      - ${foo2Uri.toFilePath()}
+    foo3:
+      - system
+      - ${foo3Uri.toFilePath()}
+    foo4:
+      - executable
+    foo5:
+      - process
+  linux_arm64:
+    bar:
+      - absolute
+      - ${barUri.toFilePath()}
+  windows_x64:
+    bla:
+      - absolute
+      - ${blaUri.toFilePath()}''';
+
+  test('asset yaml', () {
+    final yaml = assets.toYamlString();
+    expect(yaml, assetsYamlEncoding);
+    final assets2 = Asset.listFromYamlString(yaml);
+    expect(assets, assets2);
+  });
+
+  test('asset yaml', () async {
+    final fileContents = assets.toNativeAssetsFile();
+    expect(fileContents, assetsDartEncoding);
+  });
+
+  test('AssetPath factory', () async {
+    expect(
+      () => AssetPath('wrong', null),
+      throwsA(predicate(
+        (e) => e is FormatException && e.message.contains('Unknown pathType'),
+      )),
+    );
+  });
+
+  test('Asset hashCode copyWith', () async {
+    final asset = assets.first;
+    final asset2 = asset.copyWith(id: 'foo321');
+    expect(asset.hashCode != asset2.hashCode, true);
+
+    final asset3 = asset.copyWith();
+    expect(asset.hashCode, asset3.hashCode);
+  });
+
+  test('List<Asset> hashCode', () async {
+    final assets2 = assets.take(3).toList();
+    const equality = ListEquality<Asset>();
+    expect(equality.hash(assets) != equality.hash(assets2), true);
+  });
+
+  test('List<Asset> whereLinkMode', () async {
+    final assets2 = assets.whereLinkMode(LinkMode.dynamic);
+    expect(assets2.length, 6);
+  });
+
+  test('Asset toString', () async {
+    assets.toString();
+  });
+
+  test('Asset toString', () async {
+    expect(await assets.allExist(), false);
+  });
+
+  test('Asset toYaml', () async {
+    expect(
+        assets.first.toYamlString(),
+        '''
+id: foo
+link_mode: dynamic
+path:
+  path_type: absolute
+  uri: ${fooUri.toFilePath()}
+target: android_x64
+'''
+            .trim());
+  });
+
+  test('Asset listFromYamlString', () async {
+    final assets = Asset.listFromYamlString('');
+    expect(assets, <Asset>[]);
+  });
+}
diff --git a/pkgs/native_assets_cli/test/model/build_config_test.dart b/pkgs/native_assets_cli/test/model/build_config_test.dart
new file mode 100644
index 0000000..9566913
--- /dev/null
+++ b/pkgs/native_assets_cli/test/model/build_config_test.dart
@@ -0,0 +1,593 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:cli_config/cli_config.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() async {
+  late Uri tempUri;
+  late Uri outDirUri;
+  late Uri outDir2Uri;
+  late String packageName;
+  late Uri packageRootUri;
+  late Uri fakeClang;
+  late Uri fakeLd;
+  late Uri fakeAr;
+  late Uri fakeCl;
+  late Uri fakeVcVars;
+
+  setUp(() async {
+    tempUri = (await Directory.systemTemp.createTemp()).uri;
+    outDirUri = tempUri.resolve('out1/');
+    await Directory.fromUri(outDirUri).create();
+    outDir2Uri = tempUri.resolve('out2/');
+    packageName = 'my_package';
+    await Directory.fromUri(outDir2Uri).create();
+    packageRootUri = tempUri.resolve('$packageName/');
+    await Directory.fromUri(packageRootUri).create();
+    fakeClang = tempUri.resolve('fake_clang');
+    await File.fromUri(fakeClang).create();
+    fakeLd = tempUri.resolve('fake_ld');
+    await File.fromUri(fakeLd).create();
+    fakeAr = tempUri.resolve('fake_ar');
+    await File.fromUri(fakeAr).create();
+    fakeCl = tempUri.resolve('cl.exe');
+    await File.fromUri(fakeCl).create();
+    fakeVcVars = tempUri.resolve('vcvarsall.bat');
+    await File.fromUri(fakeVcVars).create();
+  });
+
+  tearDown(() async {
+    await Directory.fromUri(tempUri).delete(recursive: true);
+  });
+
+  test('BuildConfig ==', () {
+    final config1 = BuildConfig(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.arm64,
+      targetOs: OS.iOS,
+      targetIOSSdk: IOSSdk.iPhoneOs,
+      cCompiler: CCompilerConfig(
+        cc: fakeClang,
+        ld: fakeLd,
+        ar: fakeAr,
+      ),
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.preferStatic,
+    );
+
+    final config2 = BuildConfig(
+      outDir: outDir2Uri,
+      packageName: packageName,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.arm64,
+      targetOs: OS.android,
+      targetAndroidNdkApi: 30,
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.preferStatic,
+    );
+
+    expect(config1, equals(config1));
+    expect(config1 == config2, false);
+    expect(config1.outDir != config2.outDir, true);
+    expect(config1.packageRoot, config2.packageRoot);
+    expect(config1.targetArchitecture == config2.targetArchitecture, true);
+    expect(config1.targetOs != config2.targetOs, true);
+    expect(config1.targetIOSSdk != config2.targetIOSSdk, true);
+    expect(config1.cCompiler.cc != config2.cCompiler.cc, true);
+    expect(config1.cCompiler.ld != config2.cCompiler.ld, true);
+    expect(config1.cCompiler.ar != config2.cCompiler.ar, true);
+    expect(config1.cCompiler.envScript == config2.cCompiler.envScript, true);
+    expect(config1.cCompiler.envScriptArgs == config2.cCompiler.envScriptArgs,
+        true);
+    expect(config1.cCompiler != config2.cCompiler, true);
+    expect(config1.linkModePreference, config2.linkModePreference);
+    expect(config1.dependencyMetadata, config2.dependencyMetadata);
+  });
+
+  test('BuildConfig fromConfig', () {
+    final buildConfig2 = BuildConfig(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: packageRootUri,
+      targetArchitecture: Architecture.arm64,
+      targetOs: OS.android,
+      targetAndroidNdkApi: 30,
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.preferStatic,
+    );
+
+    final config = Config(fileParsed: {
+      'build_mode': 'release',
+      'dry_run': false,
+      'link_mode_preference': 'prefer-static',
+      'out_dir': outDirUri.toFilePath(),
+      'package_name': packageName,
+      'package_root': packageRootUri.toFilePath(),
+      'target_android_ndk_api': 30,
+      'target_architecture': 'arm64',
+      'target_os': 'android',
+      'version': BuildOutput.version.toString(),
+    });
+
+    final fromConfig = BuildConfig.fromConfig(config);
+    expect(fromConfig, equals(buildConfig2));
+  });
+
+  test('BuildConfig.dryRun', () {
+    final buildConfig2 = BuildConfig.dryRun(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: packageRootUri,
+      targetOs: OS.android,
+      linkModePreference: LinkModePreference.preferStatic,
+    );
+
+    final config = Config(fileParsed: {
+      'dry_run': true,
+      'link_mode_preference': 'prefer-static',
+      'out_dir': outDirUri.toFilePath(),
+      'package_name': packageName,
+      'package_root': packageRootUri.toFilePath(),
+      'target_os': 'android',
+      'version': BuildOutput.version.toString(),
+    });
+
+    final fromConfig = BuildConfig.fromConfig(config);
+    expect(fromConfig, equals(buildConfig2));
+  });
+
+  test('BuildConfig toYaml fromConfig', () {
+    final buildConfig1 = BuildConfig(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: packageRootUri,
+      targetArchitecture: Architecture.arm64,
+      targetOs: OS.iOS,
+      targetIOSSdk: IOSSdk.iPhoneOs,
+      cCompiler: CCompilerConfig(
+        cc: fakeClang,
+        ld: fakeLd,
+      ),
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.preferStatic,
+    );
+
+    final configFile = buildConfig1.toYaml();
+    final config = Config(fileParsed: configFile);
+    final fromConfig = BuildConfig.fromConfig(config);
+    expect(fromConfig, equals(buildConfig1));
+  });
+
+  test('BuildConfig == dependency metadata', () {
+    final buildConfig1 = BuildConfig(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.arm64,
+      targetOs: OS.android,
+      targetAndroidNdkApi: 30,
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.preferStatic,
+      dependencyMetadata: {
+        'bar': const Metadata({
+          'key': 'value',
+          'foo': ['asdf', 'fdsa'],
+        }),
+        'foo': const Metadata({
+          'key': 321,
+        }),
+      },
+    );
+
+    final buildConfig2 = BuildConfig(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.arm64,
+      targetOs: OS.android,
+      targetAndroidNdkApi: 30,
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.preferStatic,
+      dependencyMetadata: {
+        'bar': const Metadata({
+          'key': 'value',
+        }),
+        'foo': const Metadata({
+          'key': 123,
+        }),
+      },
+    );
+
+    expect(buildConfig1, equals(buildConfig1));
+    expect(buildConfig1 == buildConfig2, false);
+    expect(buildConfig1.hashCode == buildConfig2.hashCode, false);
+  });
+
+  test('BuildConfig toYaml fromYaml', () {
+    final outDir = outDirUri;
+    final buildConfig1 = BuildConfig(
+      outDir: outDir,
+      packageName: packageName,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.arm64,
+      targetOs: OS.iOS,
+      targetIOSSdk: IOSSdk.iPhoneOs,
+      cCompiler: CCompilerConfig(
+        cc: fakeClang,
+        ld: fakeLd,
+      ),
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.preferStatic,
+      // This map should be sorted on key for two layers.
+      dependencyMetadata: {
+        'foo': const Metadata({
+          'z': ['z', 'a'],
+          'a': 321,
+        }),
+        'bar': const Metadata({
+          'key': 'value',
+        }),
+      },
+    );
+    final yamlString = buildConfig1.toYamlString();
+    final expectedYamlString = '''build_mode: release
+c_compiler:
+  cc: ${fakeClang.toFilePath()}
+  ld: ${fakeLd.toFilePath()}
+dependency_metadata:
+  bar:
+    key: value
+  foo:
+    a: 321
+    z:
+      - z
+      - a
+link_mode_preference: prefer-static
+out_dir: ${outDir.toFilePath()}
+package_name: $packageName
+package_root: ${tempUri.toFilePath()}
+target_architecture: arm64
+target_ios_sdk: iphoneos
+target_os: ios
+version: ${BuildConfig.version}''';
+    expect(yamlString, equals(expectedYamlString));
+
+    final buildConfig2 = BuildConfig.fromConfig(
+      Config.fromConfigFileContents(
+        fileContents: yamlString,
+      ),
+    );
+    expect(buildConfig2, buildConfig1);
+  });
+
+  test('BuildConfig FormatExceptions', () {
+    expect(
+      () => BuildConfig.fromConfig(Config(fileParsed: {})),
+      throwsA(predicate(
+        (e) =>
+            e is FormatException &&
+            e.message.contains(
+              'No value was provided for required key: build_mode',
+            ),
+      )),
+    );
+    expect(
+      () => BuildConfig.fromConfig(Config(fileParsed: {
+        'version': BuildConfig.version.toString(),
+        'package_name': packageName,
+        'package_root': packageRootUri.toFilePath(),
+        'target_architecture': 'arm64',
+        'target_os': 'android',
+        'target_android_ndk_api': 30,
+        'link_mode_preference': 'prefer-static',
+      })),
+      throwsA(predicate(
+        (e) =>
+            e is FormatException &&
+            e.message.contains(
+              'No value was provided for required key: out_dir',
+            ),
+      )),
+    );
+    expect(
+      () => BuildConfig.fromConfig(Config(fileParsed: {
+        'version': BuildConfig.version.toString(),
+        'out_dir': outDirUri.toFilePath(),
+        'package_name': packageName,
+        'package_root': packageRootUri.toFilePath(),
+        'target_architecture': 'arm64',
+        'target_os': 'android',
+        'target_android_ndk_api': 30,
+        'link_mode_preference': 'prefer-static',
+        'dependency_metadata': {
+          'bar': {'key': 'value'},
+          'foo': <int>[],
+        },
+      })),
+      throwsA(predicate(
+        (e) =>
+            e is FormatException &&
+            e.message.contains(
+              "Unexpected value '[]' for key 'dependency_metadata.foo' in "
+              'config file. Expected a Map.',
+            ),
+      )),
+    );
+    expect(
+      () => BuildConfig.fromConfig(Config(fileParsed: {
+        'out_dir': outDirUri.toFilePath(),
+        'version': BuildConfig.version.toString(),
+        'package_name': packageName,
+        'package_root': packageRootUri.toFilePath(),
+        'target_architecture': 'arm64',
+        'target_os': 'android',
+        'link_mode_preference': 'prefer-static',
+      })),
+      throwsA(predicate(
+        (e) =>
+            e is FormatException &&
+            e.message.contains(
+              'No value was provided for required key: target_android_ndk_api',
+            ),
+      )),
+    );
+  });
+
+  test('FormatExceptions contain full stack trace of wrapped exception', () {
+    try {
+      BuildConfig.fromConfig(Config(fileParsed: {
+        'out_dir': outDirUri.toFilePath(),
+        'package_root': packageRootUri.toFilePath(),
+        'target': [1, 2, 3, 4, 5],
+        'link_mode_preference': 'prefer-static',
+      }));
+    } on FormatException catch (e) {
+      expect(e.toString(), stringContainsInOrder(['Config.string']));
+    }
+  });
+
+  test('BuildConfig toString', () {
+    final config = BuildConfig(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.arm64,
+      targetOs: OS.iOS,
+      targetIOSSdk: IOSSdk.iPhoneOs,
+      cCompiler: CCompilerConfig(
+        cc: fakeClang,
+        ld: fakeLd,
+      ),
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.preferStatic,
+    );
+    config.toString();
+  });
+
+  test('BuildConfig fromArgs', () async {
+    final buildConfig = BuildConfig(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.arm64,
+      targetOs: OS.android,
+      targetAndroidNdkApi: 30,
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.preferStatic,
+    );
+    final configFileContents = buildConfig.toYamlString();
+    final configUri = tempUri.resolve('config.yaml');
+    final configFile = File.fromUri(configUri);
+    await configFile.writeAsString(configFileContents);
+    final buildConfig2 = await BuildConfig.fromArgs(
+      ['--config', configUri.toFilePath()],
+      environment: {}, // Don't inherit the test environment.
+    );
+    expect(buildConfig2, buildConfig);
+  });
+
+  test('dependency metadata via config accessor', () {
+    final buildConfig1 = BuildConfig(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.arm64,
+      targetOs: OS.android,
+      targetAndroidNdkApi: 30,
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.preferStatic,
+      dependencyMetadata: {
+        'bar': const Metadata({
+          'key': {'key2': 'value'},
+        }),
+      },
+    );
+    // Useful for doing `path(..., exists: true)`.
+    expect(
+      buildConfig1.config.string([
+        BuildConfig.dependencyMetadataConfigKey,
+        'bar',
+        'key',
+        'key2'
+      ].join('.')),
+      'value',
+    );
+  });
+
+  test('envScript', () {
+    final buildConfig1 = BuildConfig(
+      outDir: outDirUri,
+      packageName: packageName,
+      packageRoot: packageRootUri,
+      targetArchitecture: Architecture.x64,
+      targetOs: OS.windows,
+      cCompiler: CCompilerConfig(
+        cc: fakeCl,
+        envScript: fakeVcVars,
+        envScriptArgs: ['x64'],
+      ),
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.dynamic,
+    );
+
+    final configFile = buildConfig1.toYaml();
+    final config = Config(fileParsed: configFile);
+    final fromConfig = BuildConfig.fromConfig(config);
+    expect(fromConfig, equals(buildConfig1));
+  });
+
+  for (final version in ['9001.0.0', '0.0.1']) {
+    test('BuildConfig version $version', () {
+      final outDir = outDirUri;
+      final config = Config(fileParsed: {
+        'link_mode_preference': 'prefer-static',
+        'out_dir': outDir.toFilePath(),
+        'package_root': tempUri.toFilePath(),
+        'target_os': 'linux',
+        'target_architecture': 'x64',
+        'version': version,
+      });
+      expect(
+        () => BuildConfig.fromConfig(config),
+        throwsA(predicate(
+          (e) =>
+              e is FormatException &&
+              e.message.contains(version) &&
+              e.message.contains(BuildConfig.version.toString()),
+        )),
+      );
+    });
+  }
+
+  test('checksum', () async {
+    await inTempDir((tempUri) async {
+      final nativeAddUri = tempUri.resolve('native_add/');
+      final fakeClangUri = tempUri.resolve('fake_clang');
+      await File.fromUri(fakeClangUri).create();
+
+      final name1 = BuildConfig.checksum(
+        packageName: packageName,
+        packageRoot: nativeAddUri,
+        targetArchitecture: Architecture.x64,
+        targetOs: OS.linux,
+        buildMode: BuildMode.release,
+        linkModePreference: LinkModePreference.dynamic,
+      );
+
+      // Using the checksum for a build folder should be stable.
+      expect(name1, '037109b9824b2559502fa7bd42e1b6f8');
+
+      // Build folder different due to metadata.
+      final name2 = BuildConfig.checksum(
+        packageName: packageName,
+        packageRoot: nativeAddUri,
+        targetArchitecture: Architecture.x64,
+        targetOs: OS.linux,
+        buildMode: BuildMode.release,
+        linkModePreference: LinkModePreference.dynamic,
+        dependencyMetadata: {
+          'foo': const Metadata({'key': 'value'})
+        },
+      );
+      printOnFailure([name1, name2].toString());
+      expect(name1 != name2, true);
+
+      // Build folder different due to cc.
+      final name3 = BuildConfig.checksum(
+          packageName: packageName,
+          packageRoot: nativeAddUri,
+          targetArchitecture: Architecture.x64,
+          targetOs: OS.linux,
+          buildMode: BuildMode.release,
+          linkModePreference: LinkModePreference.dynamic,
+          cCompiler: CCompilerConfig(
+            cc: fakeClangUri,
+          ));
+      printOnFailure([name1, name3].toString());
+      expect(name1 != name3, true);
+    });
+  });
+
+  test('BuildConfig invalid target os architecture combination', () {
+    final outDir = outDirUri;
+    final config = Config(fileParsed: {
+      'link_mode_preference': 'prefer-static',
+      'out_dir': outDir.toFilePath(),
+      'package_name': packageName,
+      'package_root': tempUri.toFilePath(),
+      'target_os': 'windows',
+      'target_architecture': 'arm',
+      'build_mode': 'debug',
+      'version': BuildConfig.version.toString(),
+    });
+    expect(
+      () => BuildConfig.fromConfig(config),
+      throwsA(predicate(
+        (e) => e is FormatException && e.message.contains('arm'),
+      )),
+    );
+  });
+
+  test('BuildConfig dry_run access invalid args', () {
+    final outDir = outDirUri;
+    final config = Config(fileParsed: {
+      'link_mode_preference': 'prefer-static',
+      'out_dir': outDir.toFilePath(),
+      'package_name': packageName,
+      'package_root': tempUri.toFilePath(),
+      'target_os': 'windows',
+      'target_architecture': 'arm64',
+      'build_mode': 'debug',
+      'dry_run': true,
+      'version': BuildConfig.version.toString(),
+    });
+    expect(
+      () => BuildConfig.fromConfig(config),
+      throwsA(predicate(
+        (e) =>
+            e is FormatException && e.message.contains('In Flutter projects'),
+      )),
+    );
+  });
+
+  test('BuildConfig dry_run access invalid args', () {
+    final outDir = outDirUri;
+    final config = Config(fileParsed: {
+      'link_mode_preference': 'prefer-static',
+      'out_dir': outDir.toFilePath(),
+      'package_name': packageName,
+      'package_root': tempUri.toFilePath(),
+      'target_os': 'windows',
+      'dry_run': true,
+      'version': BuildConfig.version.toString(),
+    });
+    final buildConfig = BuildConfig.fromConfig(config);
+    expect(
+      () => buildConfig.targetArchitecture,
+      throwsA(predicate(
+        (e) => e is StateError && e.message.contains('In Flutter projects'),
+      )),
+    );
+  });
+
+  test('BuildConfig dry_run access invalid args', () {
+    final buildConfig = BuildConfig.dryRun(
+      packageName: packageName,
+      outDir: outDirUri,
+      packageRoot: tempUri,
+      targetOs: OS.windows,
+      linkModePreference: LinkModePreference.dynamic,
+    );
+    buildConfig.toYamlString();
+    // No crash.
+  });
+}
diff --git a/pkgs/native_assets_cli/test/model/build_output_test.dart b/pkgs/native_assets_cli/test/model/build_output_test.dart
new file mode 100644
index 0000000..0dc0bad
--- /dev/null
+++ b/pkgs/native_assets_cli/test/model/build_output_test.dart
@@ -0,0 +1,173 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+void main() {
+  late Uri tempUri;
+
+  setUp(() async {
+    tempUri = (await Directory.systemTemp.createTemp()).uri;
+  });
+
+  tearDown(() async {
+    await Directory.fromUri(tempUri).delete(recursive: true);
+  });
+
+  final buildOutput = BuildOutput(
+    timestamp: DateTime.parse('2022-11-10 13:25:01.000'),
+    assets: [
+      Asset(
+        id: 'foo',
+        path: AssetAbsolutePath(Uri(path: 'path/to/libfoo.so')),
+        target: Target.androidX64,
+        linkMode: LinkMode.dynamic,
+      ),
+      Asset(
+        id: 'foo2',
+        path: AssetRelativePath(Uri(path: 'path/to/libfoo2.so')),
+        target: Target.androidX64,
+        linkMode: LinkMode.dynamic,
+      ),
+    ],
+    dependencies: Dependencies([
+      Uri.file('path/to/file.ext'),
+    ]),
+    metadata: const Metadata({
+      'key': 'value',
+    }),
+  );
+
+  final yamlEncoding = '''timestamp: 2022-11-10 13:25:01.000
+assets:
+  - id: foo
+    link_mode: dynamic
+    path:
+      path_type: absolute
+      uri: path/to/libfoo.so
+    target: android_x64
+  - id: foo2
+    link_mode: dynamic
+    path:
+      path_type: relative
+      uri: path/to/libfoo2.so
+    target: android_x64
+dependencies:
+  - path/to/file.ext
+metadata:
+  key: value
+version: ${BuildOutput.version}''';
+
+  test('built info yaml', () {
+    final yaml = buildOutput.toYamlString().replaceAll('\\', '/');
+    expect(yaml, yamlEncoding);
+    final buildOutput2 = BuildOutput.fromYamlString(yaml);
+    expect(buildOutput.hashCode, buildOutput2.hashCode);
+    expect(buildOutput, buildOutput2);
+  });
+
+  test('BuildOutput.toString', buildOutput.toString);
+
+  test('BuildOutput.hashCode', () {
+    final buildOutput2 = BuildOutput.fromYamlString(yamlEncoding);
+    expect(buildOutput.hashCode, buildOutput2.hashCode);
+
+    final buildOutput3 = BuildOutput(
+      timestamp: DateTime.parse('2022-11-10 13:25:01.000'),
+    );
+    expect(buildOutput.hashCode != buildOutput3.hashCode, true);
+  });
+
+  test('BuildOutput.readFromFile BuildOutput.writeToFile', () async {
+    final outDir = tempUri.resolve('out_dir/');
+    await buildOutput.writeToFile(outDir: outDir);
+    final buildOutput2 = await BuildOutput.readFromFile(outDir: outDir);
+    expect(buildOutput2, buildOutput);
+  });
+
+  test('Round timestamp', () {
+    final buildOutput3 = BuildOutput(
+      timestamp: DateTime.parse('2022-11-10 13:25:01.372257'),
+    );
+    expect(buildOutput3.timestamp, DateTime.parse('2022-11-10 13:25:01.000'));
+  });
+
+  for (final version in ['9001.0.0', '0.0.1']) {
+    test('BuildOutput version $version', () {
+      expect(
+        () => BuildOutput.fromYamlString('version: $version'),
+        throwsA(predicate(
+          (e) =>
+              e is FormatException &&
+              e.message.contains(version) &&
+              e.message.contains(BuildConfig.version.toString()),
+        )),
+      );
+    });
+  }
+
+  test('format exception', () {
+    expect(
+      () => BuildOutput.fromYamlString('''timestamp: 2022-11-10 13:25:01.000
+assets:
+  - name: foo
+    link_mode: dynamic
+    path:
+      path_type:
+        some: map
+      uri: path/to/libfoo.so
+    target: android_x64
+dependencies: []
+metadata:
+  key: value
+version: ${BuildOutput.version}'''),
+      throwsFormatException,
+    );
+    expect(
+      () => BuildOutput.fromYamlString('''timestamp: 2022-11-10 13:25:01.000
+assets:
+  - name: foo
+    link_mode: dynamic
+    path:
+      path_type: absolute
+      uri: path/to/libfoo.so
+    target: android_x64
+dependencies:
+  1: foo
+metadata:
+  key: value
+version: ${BuildOutput.version}'''),
+      throwsFormatException,
+    );
+    expect(
+      () => BuildOutput.fromYamlString('''timestamp: 2022-11-10 13:25:01.000
+assets:
+  - name: foo
+    link_mode: dynamic
+    path:
+      path_type: absolute
+      uri: path/to/libfoo.so
+    target: android_x64
+dependencies: []
+metadata:
+  123: value
+version: ${BuildOutput.version}'''),
+      throwsFormatException,
+    );
+  });
+
+  test('BuildOutput dependencies can be modified', () {
+    // TODO(https://github.com/dart-lang/native/issues/25):
+    // Remove once dependencies are made immutable.
+    final buildOutput = BuildOutput();
+    expect(
+      () => buildOutput.dependencies.dependencies
+          .add(Uri.file('path/to/file.ext')),
+      returnsNormally,
+    );
+  });
+}
diff --git a/pkgs/native_assets_cli/test/model/dependencies_test.dart b/pkgs/native_assets_cli/test/model/dependencies_test.dart
new file mode 100644
index 0000000..a4f05c5
--- /dev/null
+++ b/pkgs/native_assets_cli/test/model/dependencies_test.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+void main() {
+  late Uri tempUri;
+
+  setUp(() async => tempUri = Directory(
+          await (await Directory.systemTemp.createTemp())
+              .resolveSymbolicLinks())
+      .uri);
+
+  tearDown(
+      () async => await Directory.fromUri(tempUri).delete(recursive: true));
+
+  final dependencies = Dependencies([
+    Uri.file('src/bar.c'),
+    Uri.file('src/baz.c'),
+    Uri.directory('src/bla/'),
+    Uri.file('build.dart'),
+  ]);
+
+  const yamlEncoding = '''- src/bar.c
+- src/baz.c
+- src/bla/
+- build.dart''';
+
+  test('dependencies yaml', () {
+    final yaml = dependencies.toYamlString().replaceAll('\\', '/');
+    expect(yaml, yamlEncoding);
+    final dependencies2 = Dependencies.fromYamlString(yaml);
+    expect(dependencies.hashCode, dependencies2.hashCode);
+    expect(dependencies, dependencies2);
+  });
+
+  test('dependencies toString', dependencies.toString);
+
+  test('dependencies fromYamlString', () {
+    final dependencies = Dependencies.fromYamlString('');
+    expect(dependencies, const Dependencies([]));
+  });
+
+  test('dependencies lastModified', () async {
+    final dirUri = tempUri.resolve('foo/');
+    final dir = Directory.fromUri(dirUri);
+    await dir.create();
+    final fileUri = tempUri.resolve('bla.c');
+    final file = File.fromUri(fileUri);
+    await file.writeAsString('dummy contents');
+    final dependencies = Dependencies([dirUri, fileUri]);
+    expect(await dependencies.lastModified(), await file.lastModified());
+  });
+
+  test('dependencies lastModified symlinks', () async {
+    if (Platform.isWindows) {
+      // Requires extra privilege, skip.
+      // "A required privilege is not held by the client"
+      return;
+    }
+    final symlink = Link.fromUri(tempUri.resolve('my_link'));
+    await symlink.create(tempUri.toFilePath());
+
+    final someFileUri = tempUri.resolve('foo.txt');
+    final someFile = File.fromUri(someFileUri);
+    await someFile.writeAsString('yay!');
+
+    final dependencies = Dependencies([tempUri]);
+    expect(await dependencies.lastModified(), await someFile.lastModified());
+  });
+
+  test('dependencies lastModified does not exist', () async {
+    final someFileUri = tempUri.resolve('foo.txt');
+    final someFile = File.fromUri(someFileUri);
+    await someFile.writeAsString('yay!');
+
+    final deletedFileUri = tempUri.resolve('bar.txt');
+
+    final now = DateTime.now();
+
+    final dependencies = Dependencies([
+      someFileUri,
+      deletedFileUri,
+    ]);
+    final depsLastModified = await dependencies.lastModified();
+    expect(depsLastModified == now || depsLastModified.isAfter(now), true);
+  });
+}
diff --git a/pkgs/native_assets_cli/test/model/link_mode_test.dart b/pkgs/native_assets_cli/test/model/link_mode_test.dart
new file mode 100644
index 0000000..ba86d44
--- /dev/null
+++ b/pkgs/native_assets_cli/test/model/link_mode_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+void main() {
+  test('LinkMode toString', () async {
+    LinkMode.static.toString();
+  });
+}
diff --git a/pkgs/native_assets_cli/test/model/metadata_test.dart b/pkgs/native_assets_cli/test/model/metadata_test.dart
new file mode 100644
index 0000000..fd80b68
--- /dev/null
+++ b/pkgs/native_assets_cli/test/model/metadata_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+void main() {
+  const metadata = Metadata({
+    'key': 'value',
+    'my_list': [1, 2, 3],
+    'my_map': {
+      3: 4,
+      'foo': 'bar',
+    },
+  });
+
+  test('Metadata toString', metadata.toString);
+
+  test('Metadata toYamlString fromYamlString', () {
+    final yamlString = metadata.toYamlString();
+    final metadata2 = Metadata.fromYamlString(yamlString);
+    expect(metadata2, metadata);
+  });
+}
diff --git a/pkgs/native_assets_cli/test/model/target_test.dart b/pkgs/native_assets_cli/test/model/target_test.dart
new file mode 100644
index 0000000..3b1ce7b
--- /dev/null
+++ b/pkgs/native_assets_cli/test/model/target_test.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:test/test.dart';
+
+void main() {
+  test('OS naming conventions', () async {
+    expect(OS.android.dylibFileName('foo'), 'libfoo.so');
+    expect(OS.android.staticlibFileName('foo'), 'libfoo.a');
+    expect(OS.windows.dylibFileName('foo'), 'foo.dll');
+    expect(OS.windows.libraryFileName('foo', LinkMode.dynamic), 'foo.dll');
+    expect(OS.windows.staticlibFileName('foo'), 'foo.lib');
+    expect(OS.windows.libraryFileName('foo', LinkMode.static), 'foo.lib');
+    expect(OS.windows.executableFileName('foo'), 'foo.exe');
+  });
+
+  test('Target current', () async {
+    final current = Target.current;
+    expect(current.toString(), Abi.current().toString());
+  });
+
+  test('Target fromDartPlatform', () async {
+    final current = Target.fromDartPlatform(Platform.version);
+    expect(current.toString(), Abi.current().toString());
+    expect(
+      () => Target.fromDartPlatform('bogus'),
+      throwsA(predicate(
+        (e) =>
+            e is FormatException &&
+            e.message.contains('bogus') &&
+            e.message.contains('Unknown version'),
+      )),
+    );
+    expect(
+      () => Target.fromDartPlatform(
+        '3.0.0 (be) (Wed Apr 5 14:19:42 2023 +0000) on "myfancyos_ia32"',
+      ),
+      throwsA(predicate(
+        (e) =>
+            e is FormatException &&
+            e.message.contains('myfancyos_ia32') &&
+            e.message.contains('Unknown ABI'),
+      )),
+    );
+  });
+
+  test('Target cross compilation', () async {
+    // All hosts can cross compile to Android.
+    expect(
+        Target.current.supportedTargetTargets(), contains(Target.androidArm64));
+    expect(
+        Target.macOSArm64.supportedTargetTargets(), contains(Target.iOSArm64));
+  });
+
+  test('Target fromArchitectureAndOs', () async {
+    final current =
+        Target.fromArchitectureAndOs(Architecture.current, OS.current);
+    expect(current.toString(), Abi.current().toString());
+
+    expect(
+      () => Target.fromArchitectureAndOs(Architecture.arm, OS.windows),
+      throwsA(predicate(
+        (e) =>
+            e is ArgumentError &&
+            (e.message as String).contains('arm') &&
+            (e.message as String).contains('windows'),
+      )),
+    );
+  });
+}
diff --git a/pkgs/native_toolchain_c/.gitignore b/pkgs/native_toolchain_c/.gitignore
new file mode 100644
index 0000000..58e48f3
--- /dev/null
+++ b/pkgs/native_toolchain_c/.gitignore
@@ -0,0 +1,9 @@
+# https://dart.dev/guides/libraries/private-files
+# Created by `dart pub`
+.dart_tool/
+
+# Avoid committing pubspec.lock for library packages; see
+# https://dart.dev/guides/libraries/private-files#pubspeclock.
+pubspec.lock
+
+coverage/
diff --git a/pkgs/native_toolchain_c/CHANGELOG.md b/pkgs/native_toolchain_c/CHANGELOG.md
new file mode 100644
index 0000000..c347917
--- /dev/null
+++ b/pkgs/native_toolchain_c/CHANGELOG.md
@@ -0,0 +1,52 @@
+## 0.3.2
+
+- Added workaround minSdkVersion 19 and 20 for Android.
+- Start using sysroot for Android.
+- Added tests for up to Android API version 34.
+
+## 0.3.1
+
+- Added MSVC arm64 toolchain.
+
+## 0.3.0
+
+- Bump `package:native_assets_cli` to 0.3.0.
+
+## 0.2.5
+
+- Explicitly tell linker to create position dependent or position independent executable
+  ([#113](https://github.com/dart-lang/native/issues/133)).
+
+## 0.2.4
+
+- Added `includes` for specifying include directories.
+- Added `flags` for specifying arbitrary compiler flags.
+- Added `std` for specifying a language standard.
+- Added `language` for selecting the language (`c` and `cpp`) to compile source files as.
+- Added `cppLinkStdLib` for specifying the C++ standard library to link against.
+
+## 0.2.3
+
+- Fix MSVC tool resolution inside (x86) folder
+  ([#123](https://github.com/dart-lang/native/issues/123)).
+
+## 0.2.2
+
+- Generate position independent code for libraries by default and add
+  `pic` option to control this behavior.
+
+## 0.2.1
+
+- Added `defines` for specifying custom defines.
+- Added `buildModeDefine` to toggle define for current build mode.
+- Added `ndebugDefine` to toggle define of `NDEBUG` for non-debug builds.
+
+## 0.2.0
+
+- **Breaking change** Rename `assetName` to `assetId`
+  ([#100](https://github.com/dart-lang/native/issues/100)).
+- Added topics.
+
+## 0.1.0
+
+- Initial version.
diff --git a/pkgs/native_toolchain_c/LICENSE b/pkgs/native_toolchain_c/LICENSE
new file mode 100644
index 0000000..4fd5739
--- /dev/null
+++ b/pkgs/native_toolchain_c/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2023, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google LLC nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkgs/native_toolchain_c/README.md b/pkgs/native_toolchain_c/README.md
new file mode 100644
index 0000000..01b1448
--- /dev/null
+++ b/pkgs/native_toolchain_c/README.md
@@ -0,0 +1,26 @@
+[![dart](https://github.com/dart-lang/native/actions/workflows/native.yaml/badge.svg)](https://github.com/dart-lang/native/actions/workflows/native.yaml)
+[![Coverage Status](https://coveralls.io/repos/github/dart-lang/native/badge.svg?branch=main)](https://coveralls.io/github/dart-lang/native?branch=main)
+[![pub package](https://img.shields.io/pub/v/native_toolchain_c.svg)](https://pub.dev/packages/native_toolchain_c)
+[![package publisher](https://img.shields.io/pub/publisher/native_toolchain_c.svg)](https://pub.dev/packages/native_toolchain_c/publisher)
+
+A library to invoke the native C compiler installed on the host machine.
+
+## Status: Experimental
+
+**NOTE**: This package is currently experimental and published under the
+[labs.dart.dev](https://dart.dev/dart-team-packages) pub publisher in order to
+solicit feedback. 
+
+For packages in the labs.dart.dev publisher we generally plan to either graduate
+the package into a supported publisher (dart.dev, tools.dart.dev) after a period
+of feedback and iteration, or discontinue the package. These packages have a
+much higher expected rate of API and breaking changes.
+
+Your feedback is valuable and will help us evolve this package. 
+For bugs, please file an issue in the 
+[bug tracker](https://github.com/dart-lang/native/issues).
+
+
+## Example
+
+An example can be found in [../native_assets_cli/example/](../native_assets_cli/example/).
diff --git a/pkgs/native_toolchain_c/analysis_options.yaml b/pkgs/native_toolchain_c/analysis_options.yaml
new file mode 100644
index 0000000..dd3dcda
--- /dev/null
+++ b/pkgs/native_toolchain_c/analysis_options.yaml
@@ -0,0 +1,12 @@
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+analyzer:
+  language:
+    strict-raw-types: true
+
+linter:
+  rules:
+    - prefer_const_declarations
+    - prefer_expression_function_bodies
+    - prefer_final_in_for_each
+    - prefer_final_locals
diff --git a/pkgs/native_toolchain_c/lib/native_toolchain_c.dart b/pkgs/native_toolchain_c/lib/native_toolchain_c.dart
new file mode 100644
index 0000000..f6f90d1
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/native_toolchain_c.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A library to invoke the native C compiler installed on the host machine.
+library;
+
+export 'src/cbuilder/cbuilder.dart';
diff --git a/pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart b/pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart
new file mode 100644
index 0000000..a0a199b
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/cbuilder/cbuilder.dart
@@ -0,0 +1,289 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:logging/logging.dart';
+import 'package:meta/meta.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+import 'run_cbuilder.dart';
+
+abstract class Builder {
+  Future<void> run({
+    required BuildConfig buildConfig,
+    required BuildOutput buildOutput,
+    required Logger? logger,
+  });
+}
+
+/// A programming language that can be selected for compilation of source files.
+///
+/// See [CBuilder.language] for more information.
+class Language {
+  /// The name of the language.
+  final String name;
+
+  const Language._(this.name);
+
+  static const Language c = Language._('c');
+  static const Language cpp = Language._('c++');
+
+  /// Known values for [Language].
+  static const List<Language> values = [c, cpp];
+
+  @override
+  String toString() => name;
+}
+
+/// Specification for building an artifact with a C compiler.
+class CBuilder implements Builder {
+  /// What kind of artifact to build.
+  final _CBuilderType _type;
+
+  /// Name of the library or executable to build.
+  ///
+  /// The filename will be decided by [BuildConfig.target] and
+  /// [OS.libraryFileName] or [OS.executableFileName].
+  ///
+  /// File will be placed in [BuildConfig.outDir].
+  final String name;
+
+  /// Asset identifier.
+  ///
+  /// Used to output the [BuildOutput.assets].
+  ///
+  /// If omitted, no asset will be added to the build output.
+  final String? assetId;
+
+  /// Sources to build the library or executable.
+  ///
+  /// Resolved against [BuildConfig.packageRoot].
+  ///
+  /// Used to output the [BuildOutput.dependencies].
+  final List<String> sources;
+
+  /// Include directories to pass to the compiler.
+  ///
+  /// Resolved against [BuildConfig.packageRoot].
+  ///
+  /// Used to output the [BuildOutput.dependencies].
+  final List<String> includes;
+
+  /// The dart files involved in building this artifact.
+  ///
+  /// Resolved against [BuildConfig.packageRoot].
+  ///
+  /// Used to output the [BuildOutput.dependencies].
+  final List<String> dartBuildFiles;
+
+  /// TODO(https://github.com/dart-lang/native/issues/54): Move to [BuildConfig]
+  /// or hide in public API.
+  @visibleForTesting
+  final Uri? installName;
+
+  /// Flags to pass to the compiler.
+  final List<String> flags;
+
+  /// Definitions of preprocessor macros.
+  ///
+  /// When the value is `null`, the macro is defined without a value.
+  final Map<String, String?> defines;
+
+  /// Whether to define a macro for the current [BuildMode].
+  ///
+  /// The macro name is the uppercase name of the build mode and does not have a
+  /// value.
+  ///
+  /// Defaults to `true`.
+  final bool buildModeDefine;
+
+  /// Whether to define the standard `NDEBUG` macro when _not_ building with
+  /// [BuildMode.debug].
+  ///
+  /// When `NDEBUG` is defined, the C/C++ standard library
+  /// [`assert` macro in `assert.h`](https://en.wikipedia.org/wiki/Assert.h)
+  /// becomes a no-op. Other C/C++ code commonly use `NDEBUG` to disable debug
+  /// features, as well.
+  ///
+  /// Defaults to `true`.
+  final bool ndebugDefine;
+
+  /// Whether the compiler will emit position independent code.
+  ///
+  /// When set to `true`, libraries will be compiled with `-fPIC` and
+  /// executables with `-fPIE`. Accordingly the corresponding parameter of the
+  /// [CBuilder.executable] constructor is named `pie`.
+  ///
+  /// When set to `null`, the default behavior of the compiler will be used.
+  ///
+  /// This option has no effect when building for Windows, where generation of
+  /// position independent code is not configurable.
+  ///
+  /// Defaults to `true` for libraries and `false` for executables.
+  final bool? pic;
+
+  /// The language standard to use.
+  ///
+  /// When set to `null`, the default behavior of the compiler will be used.
+  final String? std;
+
+  /// The language to compile [sources] as.
+  ///
+  /// [cppLinkStdLib] only has an effect when this option is set to
+  /// [Language.cpp].
+  final Language language;
+
+  /// The C++ standard library to link against.
+  ///
+  /// This option has no effect when [language] is not set to [Language.cpp] or
+  /// when compiling for Windows.
+  ///
+  /// When set to `null`, the following defaults will be used, based on the
+  /// target OS:
+  ///
+  /// | OS      | Library      |
+  /// | :------ | :----------- |
+  /// | Android | `c++_shared` |
+  /// | iOS     | `c++`        |
+  /// | Linux   | `stdc++`     |
+  /// | macOS   | `c++`        |
+  /// | Fuchsia | `c++`        |
+  final String? cppLinkStdLib;
+
+  CBuilder.library({
+    required this.name,
+    required this.assetId,
+    this.sources = const [],
+    this.includes = const [],
+    this.dartBuildFiles = const ['build.dart'],
+    @visibleForTesting this.installName,
+    this.flags = const [],
+    this.defines = const {},
+    this.buildModeDefine = true,
+    this.ndebugDefine = true,
+    this.pic = true,
+    this.std,
+    this.language = Language.c,
+    this.cppLinkStdLib,
+  }) : _type = _CBuilderType.library;
+
+  CBuilder.executable({
+    required this.name,
+    this.sources = const [],
+    this.includes = const [],
+    this.dartBuildFiles = const ['build.dart'],
+    this.flags = const [],
+    this.defines = const {},
+    this.buildModeDefine = true,
+    this.ndebugDefine = true,
+    bool? pie = false,
+    this.std,
+    this.language = Language.c,
+    this.cppLinkStdLib,
+  })  : _type = _CBuilderType.executable,
+        assetId = null,
+        installName = null,
+        pic = pie;
+
+  /// Runs the C Compiler with on this C build spec.
+  ///
+  /// Completes with an error if the build fails.
+  @override
+  Future<void> run({
+    required BuildConfig buildConfig,
+    required BuildOutput buildOutput,
+    required Logger? logger,
+  }) async {
+    final outDir = buildConfig.outDir;
+    final packageRoot = buildConfig.packageRoot;
+    await Directory.fromUri(outDir).create(recursive: true);
+    final linkMode = buildConfig.linkModePreference.preferredLinkMode;
+    final libUri =
+        outDir.resolve(buildConfig.targetOs.libraryFileName(name, linkMode));
+    final exeUri =
+        outDir.resolve(buildConfig.targetOs.executableFileName(name));
+    final sources = [
+      for (final source in this.sources)
+        packageRoot.resolveUri(Uri.file(source)),
+    ];
+    final includes = [
+      for (final directory in this.includes)
+        packageRoot.resolveUri(Uri.file(directory)),
+    ];
+    final dartBuildFiles = [
+      for (final source in this.dartBuildFiles) packageRoot.resolve(source),
+    ];
+    if (!buildConfig.dryRun) {
+      final task = RunCBuilder(
+        buildConfig: buildConfig,
+        logger: logger,
+        sources: sources,
+        includes: includes,
+        dynamicLibrary:
+            _type == _CBuilderType.library && linkMode == LinkMode.dynamic
+                ? libUri
+                : null,
+        staticLibrary:
+            _type == _CBuilderType.library && linkMode == LinkMode.static
+                ? libUri
+                : null,
+        executable: _type == _CBuilderType.executable ? exeUri : null,
+        installName: installName,
+        flags: flags,
+        defines: {
+          ...defines,
+          if (buildModeDefine) buildConfig.buildMode.name.toUpperCase(): null,
+          if (ndebugDefine && buildConfig.buildMode != BuildMode.debug)
+            'NDEBUG': null,
+        },
+        pic: pic,
+        std: std,
+        language: language,
+        cppLinkStdLib: cppLinkStdLib,
+      );
+      await task.run();
+    }
+
+    if (assetId != null) {
+      final targets = [
+        if (!buildConfig.dryRun)
+          buildConfig.target
+        else
+          for (final target in Target.values)
+            if (target.os == buildConfig.targetOs) target
+      ];
+      for (final target in targets) {
+        buildOutput.assets.add(Asset(
+          id: assetId!,
+          linkMode: linkMode,
+          target: target,
+          path: AssetAbsolutePath(libUri),
+        ));
+      }
+    }
+    if (!buildConfig.dryRun) {
+      final includeFiles = await Stream.fromIterable(includes)
+          .asyncExpand(
+            (include) => Directory(include.toFilePath())
+                .list(recursive: true)
+                .where((entry) => entry is File)
+                .map((file) => file.uri),
+          )
+          .toList();
+
+      buildOutput.dependencies.dependencies.addAll({
+        // Note: We use a Set here to deduplicate the dependencies.
+        ...sources,
+        ...includeFiles,
+        ...dartBuildFiles,
+      });
+    }
+  }
+}
+
+enum _CBuilderType {
+  executable,
+  library,
+}
diff --git a/pkgs/native_toolchain_c/lib/src/cbuilder/compiler_resolver.dart b/pkgs/native_toolchain_c/lib/src/cbuilder/compiler_resolver.dart
new file mode 100644
index 0000000..17ec90a
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/cbuilder/compiler_resolver.dart
@@ -0,0 +1,226 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+import '../native_toolchain/android_ndk.dart';
+import '../native_toolchain/apple_clang.dart';
+import '../native_toolchain/clang.dart';
+import '../native_toolchain/gcc.dart';
+import '../native_toolchain/msvc.dart';
+import '../native_toolchain/recognizer.dart';
+import '../tool/tool.dart';
+import '../tool/tool_error.dart';
+import '../tool/tool_instance.dart';
+
+// TODO(dacoharkes): This should support alternatives.
+// For example use Clang or MSVC on Windows.
+class CompilerResolver {
+  final BuildConfig buildConfig;
+  final Logger? logger;
+  final Target host;
+
+  CompilerResolver({
+    required this.buildConfig,
+    required this.logger,
+    Target? host, // Only visible for testing.
+  }) : host = host ?? Target.current;
+
+  Future<ToolInstance> resolveCompiler() async {
+    // First, check if the launcher provided a direct path to the compiler.
+    var result = await _tryLoadCompilerFromConfig(
+      CCompilerConfig.ccConfigKeyFull,
+      (buildConfig) => buildConfig.cCompiler.cc,
+    );
+
+    // Then, try to detect on the host machine.
+    final tool = _selectCompiler();
+    if (tool != null) {
+      result ??= await _tryLoadToolFromNativeToolchain(tool);
+    }
+
+    if (result != null) {
+      return result;
+    }
+
+    final targetOs = buildConfig.targetOs;
+    final targetArchitecture = buildConfig.targetArchitecture;
+    final errorMessage = "No tools configured on host '$host' with target "
+        "'${targetOs}_$targetArchitecture'.";
+    logger?.severe(errorMessage);
+    throw ToolError(errorMessage);
+  }
+
+  /// Select the right compiler for cross compiling to the specified target.
+  Tool? _selectCompiler() {
+    final targetOs = buildConfig.targetOs;
+    final targetArch = buildConfig.targetArchitecture;
+
+    // TODO(dacoharkes): Support falling back on other tools.
+    if (targetArch == host.architecture &&
+        targetOs == host.os &&
+        host.os == OS.linux) return clang;
+    if (targetOs == OS.macOS || targetOs == OS.iOS) return appleClang;
+    if (targetOs == OS.android) return androidNdkClang;
+    if (host.os == OS.linux) {
+      switch (targetArch) {
+        case Architecture.arm:
+          return armLinuxGnueabihfGcc;
+        case Architecture.arm64:
+          return aarch64LinuxGnuGcc;
+        case Architecture.ia32:
+          return i686LinuxGnuGcc;
+        case Architecture.x64:
+          return x86_64LinuxGnuGcc;
+        case Architecture.riscv64:
+          return riscv64LinuxGnuGcc;
+      }
+    }
+
+    if (host.os == OS.windows) {
+      switch (targetArch) {
+        case Architecture.ia32:
+          return clIA32;
+        case Architecture.arm64:
+          return clArm64;
+        case Architecture.x64:
+          return cl;
+      }
+    }
+
+    return null;
+  }
+
+  Future<ToolInstance?> _tryLoadCompilerFromConfig(
+      String configKey, Uri? Function(BuildConfig) getter) async {
+    final configCcUri = getter(buildConfig);
+    if (configCcUri != null) {
+      assert(await File.fromUri(configCcUri).exists());
+      logger?.finer('Using compiler ${configCcUri.toFilePath()} '
+          'from config[${CCompilerConfig.ccConfigKeyFull}].');
+      return (await CompilerRecognizer(configCcUri).resolve(logger: logger))
+          .first;
+    }
+    logger?.finer(
+        'No compiler set in config[${CCompilerConfig.ccConfigKeyFull}].');
+    return null;
+  }
+
+  Future<ToolInstance?> _tryLoadToolFromNativeToolchain(Tool tool) async {
+    final resolved = (await tool.defaultResolver!.resolve(logger: logger))
+        .where((i) => i.tool == tool)
+        .toList()
+      ..sort();
+    return resolved.isEmpty ? null : resolved.first;
+  }
+
+  Future<ToolInstance> resolveArchiver() async {
+    // First, check if the launcher provided a direct path to the compiler.
+    var result = await _tryLoadArchiverFromConfig(
+      CCompilerConfig.arConfigKeyFull,
+      (buildConfig) => buildConfig.cCompiler.ar,
+    );
+
+    // Then, try to detect on the host machine.
+    final tool = _selectArchiver();
+    if (tool != null) {
+      result ??= await _tryLoadToolFromNativeToolchain(tool);
+    }
+
+    if (result != null) {
+      return result;
+    }
+
+    final targetOs = buildConfig.targetOs;
+    final targetArchitecture = buildConfig.targetArchitecture;
+    final errorMessage = "No tools configured on host '$host' with target "
+        "'${targetOs}_$targetArchitecture'.";
+    logger?.severe(errorMessage);
+    throw ToolError(errorMessage);
+  }
+
+  /// Select the right archiver for cross compiling to the specified target.
+  Tool? _selectArchiver() {
+    final targetOs = buildConfig.targetOs;
+    final targetArchitecture = buildConfig.targetArchitecture;
+
+    // TODO(dacoharkes): Support falling back on other tools.
+    if (targetArchitecture == host.architecture &&
+        targetOs == host.os &&
+        host.os == OS.linux) {
+      return llvmAr;
+    }
+    if (targetOs == OS.macOS || targetOs == OS.iOS) return appleAr;
+    if (targetOs == OS.android) return androidNdkLlvmAr;
+    if (host.os == OS.linux) {
+      switch (targetArchitecture) {
+        case Architecture.arm:
+          return armLinuxGnueabihfGccAr;
+        case Architecture.arm64:
+          return aarch64LinuxGnuGccAr;
+        case Architecture.ia32:
+          return i686LinuxGnuGccAr;
+        case Architecture.x64:
+          return x86_64LinuxGnuGccAr;
+        case Architecture.riscv64:
+          return riscv64LinuxGnuGccAr;
+      }
+    }
+    if (host.os == OS.windows) {
+      switch (targetArchitecture) {
+        case Architecture.ia32:
+          return libIA32;
+        case Architecture.arm64:
+          return libArm64;
+        case Architecture.x64:
+          return lib;
+      }
+    }
+
+    return null;
+  }
+
+  Future<ToolInstance?> _tryLoadArchiverFromConfig(
+      String configKey, Uri? Function(BuildConfig) getter) async {
+    final configArUri = getter(buildConfig);
+    if (configArUri != null) {
+      assert(await File.fromUri(configArUri).exists());
+      logger?.finer('Using archiver ${configArUri.toFilePath()} '
+          'from config[${CCompilerConfig.arConfigKeyFull}].');
+      return (await ArchiverRecognizer(configArUri).resolve(logger: logger))
+          .first;
+    }
+    logger?.finer(
+        'No archiver set in config[${CCompilerConfig.arConfigKeyFull}].');
+    return null;
+  }
+
+  Future<Uri?> toolchainEnvironmentScript(ToolInstance compiler) async {
+    final fromConfig = buildConfig.cCompiler.envScript;
+    if (fromConfig != null) {
+      logger?.fine('Using envScript from config: $fromConfig');
+      return fromConfig;
+    }
+
+    final compilerTool = compiler.tool;
+    assert(compilerTool == cl);
+    final vcvarsScript =
+        (await vcvars(compiler).defaultResolver!.resolve(logger: logger)).first;
+    return vcvarsScript.uri;
+  }
+
+  List<String>? toolchainEnvironmentScriptArguments() {
+    final fromConfig = buildConfig.cCompiler.envScriptArgs;
+    if (fromConfig != null) {
+      logger?.fine('Using envScriptArgs from config: $fromConfig');
+      return fromConfig;
+    }
+
+    // vcvars above already has x64 or x86 in the script name.
+    return null;
+  }
+}
diff --git a/pkgs/native_toolchain_c/lib/src/cbuilder/run_cbuilder.dart b/pkgs/native_toolchain_c/lib/src/cbuilder/run_cbuilder.dart
new file mode 100644
index 0000000..0db3dda
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/cbuilder/run_cbuilder.dart
@@ -0,0 +1,321 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:math';
+
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+import '../native_toolchain/apple_clang.dart';
+import '../native_toolchain/clang.dart';
+import '../native_toolchain/gcc.dart';
+import '../native_toolchain/msvc.dart';
+import '../native_toolchain/xcode.dart';
+import '../tool/tool_instance.dart';
+import '../utils/env_from_bat.dart';
+import '../utils/run_process.dart';
+import 'cbuilder.dart';
+import 'compiler_resolver.dart';
+
+class RunCBuilder {
+  final BuildConfig buildConfig;
+  final Logger? logger;
+  final List<Uri> sources;
+  final List<Uri> includes;
+  final Uri? executable;
+  final Uri? dynamicLibrary;
+  final Uri? staticLibrary;
+  final Uri outDir;
+  final Target target;
+
+  /// The install name of the [dynamicLibrary].
+  ///
+  /// Can be inspected with `otool -D <path-to-dylib>`.
+  ///
+  /// Can be modified with `install_name_tool`.
+  final Uri? installName;
+
+  final List<String> flags;
+  final Map<String, String?> defines;
+  final bool? pic;
+  final String? std;
+  final Language language;
+  final String? cppLinkStdLib;
+
+  RunCBuilder({
+    required this.buildConfig,
+    this.logger,
+    this.sources = const [],
+    this.includes = const [],
+    this.executable,
+    this.dynamicLibrary,
+    this.staticLibrary,
+    this.installName,
+    this.flags = const [],
+    this.defines = const {},
+    this.pic,
+    this.std,
+    this.language = Language.c,
+    this.cppLinkStdLib,
+  })  : outDir = buildConfig.outDir,
+        target = buildConfig.target,
+        assert([executable, dynamicLibrary, staticLibrary]
+                .whereType<Uri>()
+                .length ==
+            1) {
+    if (target.os == OS.windows && cppLinkStdLib != null) {
+      throw ArgumentError.value(
+        cppLinkStdLib,
+        'cppLinkStdLib',
+        'is not supported when targeting Windows',
+      );
+    }
+  }
+
+  late final _resolver =
+      CompilerResolver(buildConfig: buildConfig, logger: logger);
+
+  Future<ToolInstance> compiler() async => await _resolver.resolveCompiler();
+
+  Future<Uri> archiver() async => (await _resolver.resolveArchiver()).uri;
+
+  Future<Uri> iosSdk(IOSSdk iosSdk, {required Logger? logger}) async {
+    if (iosSdk == IOSSdk.iPhoneOs) {
+      return (await iPhoneOSSdk.defaultResolver!.resolve(logger: logger))
+          .where((i) => i.tool == iPhoneOSSdk)
+          .first
+          .uri;
+    }
+    assert(iosSdk == IOSSdk.iPhoneSimulator);
+    return (await iPhoneSimulatorSdk.defaultResolver!.resolve(logger: logger))
+        .where((i) => i.tool == iPhoneSimulatorSdk)
+        .first
+        .uri;
+  }
+
+  Future<Uri> macosSdk({required Logger? logger}) async =>
+      (await macosxSdk.defaultResolver!.resolve(logger: logger))
+          .where((i) => i.tool == macosxSdk)
+          .first
+          .uri;
+
+  Uri androidSysroot(ToolInstance compiler) =>
+      compiler.uri.resolve('../sysroot/');
+
+  Future<void> run() async {
+    final compiler_ = await compiler();
+    final compilerTool = compiler_.tool;
+    if (compilerTool == appleClang ||
+        compilerTool == clang ||
+        compilerTool == gcc) {
+      await runClangLike(compiler: compiler_);
+      return;
+    }
+    assert(compilerTool == cl);
+    await runCl(compiler: compiler_);
+  }
+
+  Future<void> runClangLike({required ToolInstance compiler}) async {
+    final isStaticLib = staticLibrary != null;
+    Uri? archiver_;
+    if (isStaticLib) {
+      archiver_ = await archiver();
+    }
+
+    late final IOSSdk targetIosSdk;
+    if (target.os == OS.iOS) {
+      targetIosSdk = buildConfig.targetIOSSdk!;
+    }
+
+    // The Android Gradle plugin does not honor API level 19 and 20 when
+    // invoking clang. Mimic that behavior here.
+    // See https://github.com/dart-lang/native/issues/171.
+    late final int targetAndroidNdkApi;
+    if (target.os == OS.android) {
+      targetAndroidNdkApi = max(buildConfig.targetAndroidNdkApi!, 21);
+    }
+
+    await runProcess(
+      executable: compiler.uri,
+      arguments: [
+        if (target.os == OS.android) ...[
+          '--target='
+              '${androidNdkClangTargetFlags[target]!}'
+              '$targetAndroidNdkApi',
+          '--sysroot=${androidSysroot(compiler).toFilePath()}',
+        ],
+        if (target.os == OS.macOS)
+          '--target=${appleClangMacosTargetFlags[target]!}',
+        if (target.os == OS.iOS)
+          '--target=${appleClangIosTargetFlags[target]![targetIosSdk]!}',
+        if (target.os == OS.iOS) ...[
+          '-isysroot',
+          (await iosSdk(targetIosSdk, logger: logger)).toFilePath(),
+        ],
+        if (target.os == OS.macOS) ...[
+          '-isysroot',
+          (await macosSdk(logger: logger)).toFilePath(),
+        ],
+        if (installName != null) ...[
+          '-install_name',
+          installName!.toFilePath(),
+        ],
+        if (pic != null)
+          if (pic!) ...[
+            if (dynamicLibrary != null) '-fPIC',
+            // Using PIC for static libraries allows them to be linked into
+            // any executable, but it is not necessarily the best option in
+            // terms of overhead. We would have to know wether the target into
+            // which the static library is linked is PIC, PIE or neither. Then
+            // we could use the same option for the static library.
+            if (staticLibrary != null) '-fPIC',
+            if (executable != null) ...[
+              // Generate position-independent code for executables.
+              '-fPIE',
+              // Tell the linker to generate a position-independent executable.
+              '-pie',
+            ],
+          ] else ...[
+            // Disable generation of any kind of position-independent code.
+            '-fno-PIC',
+            '-fno-PIE',
+            // Tell the linker to generate a position-dependent executable.
+            if (executable != null) '-no-pie',
+          ],
+        if (std != null) '-std=$std',
+        if (language == Language.cpp) ...[
+          '-x',
+          'c++',
+          '-l',
+          cppLinkStdLib ?? defaultCppLinkStdLib[target.os]!
+        ],
+        ...flags,
+        for (final MapEntry(key: name, :value) in defines.entries)
+          if (value == null) '-D$name' else '-D$name=$value',
+        for (final include in includes) '-I${include.toFilePath()}',
+        ...sources.map((e) => e.toFilePath()),
+        if (executable != null) ...[
+          '-o',
+          outDir.resolveUri(executable!).toFilePath(),
+        ],
+        if (dynamicLibrary != null) ...[
+          '--shared',
+          '-o',
+          outDir.resolveUri(dynamicLibrary!).toFilePath(),
+        ] else if (staticLibrary != null) ...[
+          '-c',
+          '-o',
+          outDir.resolve('out.o').toFilePath(),
+        ],
+      ],
+      logger: logger,
+      captureOutput: false,
+      throwOnUnexpectedExitCode: true,
+    );
+    if (staticLibrary != null) {
+      await runProcess(
+        executable: archiver_!,
+        arguments: [
+          'rc',
+          outDir.resolveUri(staticLibrary!).toFilePath(),
+          outDir.resolve('out.o').toFilePath(),
+        ],
+        logger: logger,
+        captureOutput: false,
+        throwOnUnexpectedExitCode: true,
+      );
+    }
+  }
+
+  Future<void> runCl({required ToolInstance compiler}) async {
+    final vcvars = (await _resolver.toolchainEnvironmentScript(compiler))!;
+    final vcvarsArgs = _resolver.toolchainEnvironmentScriptArguments();
+    final environment = await envFromBat(vcvars, arguments: vcvarsArgs ?? []);
+
+    final isStaticLib = staticLibrary != null;
+    Uri? archiver_;
+    if (isStaticLib) {
+      archiver_ = await archiver();
+    }
+
+    final result = await runProcess(
+      executable: compiler.uri,
+      arguments: [
+        if (std != null) '/std:$std',
+        if (language == Language.cpp) '/TP',
+        ...flags,
+        for (final MapEntry(key: name, :value) in defines.entries)
+          if (value == null) '/D$name' else '/D$name=$value',
+        for (final directory in includes) '/I${directory.toFilePath()}',
+        if (executable != null) ...[
+          ...sources.map((e) => e.toFilePath()),
+          '/link',
+          '/out:${outDir.resolveUri(executable!).toFilePath()}',
+        ],
+        if (dynamicLibrary != null) ...[
+          ...sources.map((e) => e.toFilePath()),
+          '/link',
+          '/DLL',
+          '/out:${outDir.resolveUri(dynamicLibrary!).toFilePath()}',
+        ],
+        if (staticLibrary != null) ...[
+          '/c',
+          ...sources.map((e) => e.toFilePath()),
+        ],
+      ],
+      workingDirectory: outDir,
+      environment: environment,
+      logger: logger,
+      captureOutput: false,
+      throwOnUnexpectedExitCode: true,
+    );
+
+    if (staticLibrary != null) {
+      await runProcess(
+        executable: archiver_!,
+        arguments: [
+          '/out:${staticLibrary!.toFilePath()}',
+          '*.obj',
+        ],
+        workingDirectory: outDir,
+        environment: environment,
+        logger: logger,
+        captureOutput: false,
+        throwOnUnexpectedExitCode: true,
+      );
+    }
+
+    assert(result.exitCode == 0);
+  }
+
+  static const androidNdkClangTargetFlags = {
+    Target.androidArm: 'armv7a-linux-androideabi',
+    Target.androidArm64: 'aarch64-linux-android',
+    Target.androidIA32: 'i686-linux-android',
+    Target.androidX64: 'x86_64-linux-android',
+  };
+
+  static const appleClangMacosTargetFlags = {
+    Target.macOSArm64: 'arm64-apple-darwin',
+    Target.macOSX64: 'x86_64-apple-darwin',
+  };
+
+  static const appleClangIosTargetFlags = {
+    Target.iOSArm64: {
+      IOSSdk.iPhoneOs: 'arm64-apple-ios',
+      IOSSdk.iPhoneSimulator: 'arm64-apple-ios-simulator',
+    },
+    Target.iOSX64: {
+      IOSSdk.iPhoneSimulator: 'x86_64-apple-ios-simulator',
+    },
+  };
+
+  static const defaultCppLinkStdLib = {
+    OS.android: 'c++_shared',
+    OS.fuchsia: 'c++',
+    OS.iOS: 'c++',
+    OS.linux: 'stdc++',
+    OS.macOS: 'c++',
+  };
+}
diff --git a/pkgs/native_toolchain_c/lib/src/native_toolchain/android_ndk.dart b/pkgs/native_toolchain_c/lib/src/native_toolchain/android_ndk.dart
new file mode 100644
index 0000000..31edfc5
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/native_toolchain/android_ndk.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+import '../tool/tool.dart';
+import '../tool/tool_instance.dart';
+import '../tool/tool_resolver.dart';
+import 'clang.dart';
+
+final androidNdk = Tool(
+  name: 'Android NDK',
+  defaultResolver: _AndroidNdkResolver(),
+);
+
+/// [clang] with [Tool.defaultResolver] for the [OS.android] NDK.
+final androidNdkClang = Tool(
+  name: clang.name,
+  defaultResolver: _AndroidNdkResolver(),
+);
+
+/// [llvmAr] with [Tool.defaultResolver] for the [OS.android] NDK.
+final androidNdkLlvmAr = Tool(
+  name: llvmAr.name,
+  defaultResolver: _AndroidNdkResolver(),
+);
+
+/// [lld] with [Tool.defaultResolver] for the [OS.android] NDK.
+final androidNdkLld = Tool(
+  name: lld.name,
+  defaultResolver: _AndroidNdkResolver(),
+);
+
+class _AndroidNdkResolver implements ToolResolver {
+  final installLocationResolver = PathVersionResolver(
+    wrappedResolver: ToolResolvers([
+      RelativeToolResolver(
+        toolName: 'Android NDK',
+        wrappedResolver: PathToolResolver(
+          toolName: 'ndk-build',
+          executableName: Platform.isWindows ? 'ndk-build.cmd' : 'ndk-build',
+        ),
+        relativePath: Uri(path: ''),
+      ),
+      InstallLocationResolver(
+        toolName: 'Android NDK',
+        paths: [
+          if (Platform.isLinux) ...[
+            '\$HOME/Android/Sdk/ndk/*/',
+            '\$HOME/Android/Sdk/ndk-bundle/',
+          ],
+          if (Platform.isMacOS) ...[
+            '\$HOME/Library/Android/sdk/ndk/*/',
+          ],
+          if (Platform.isWindows) ...[
+            '\$HOME/AppData/Local/Android/Sdk/ndk/*/',
+          ],
+        ],
+      ),
+    ]),
+  );
+
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    final ndkInstances = await installLocationResolver.resolve(logger: logger);
+
+    return [
+      for (final ndkInstance in ndkInstances) ...[
+        ndkInstance,
+        ...await tryResolveClang(
+          ndkInstance,
+          logger: logger,
+        )
+      ]
+    ];
+  }
+
+  Future<List<ToolInstance>> tryResolveClang(
+    ToolInstance androidNdkInstance, {
+    required Logger? logger,
+  }) async {
+    final result = <ToolInstance>[];
+    final prebuiltUri =
+        androidNdkInstance.uri.resolve('toolchains/llvm/prebuilt/');
+    final prebuiltDir = Directory.fromUri(prebuiltUri);
+    final hostArchDirs =
+        (await prebuiltDir.list().toList()).whereType<Directory>().toList();
+    for (final hostArchDir in hostArchDirs) {
+      final clangUri = hostArchDir.uri
+          .resolve('bin/')
+          .resolve(Target.current.os.executableFileName('clang'));
+      if (await File.fromUri(clangUri).exists()) {
+        result.add(await CliVersionResolver.lookupVersion(
+          ToolInstance(
+            tool: androidNdkClang,
+            uri: clangUri,
+          ),
+          logger: logger,
+        ));
+      }
+      final arUri = hostArchDir.uri
+          .resolve('bin/')
+          .resolve(Target.current.os.executableFileName('llvm-ar'));
+      if (await File.fromUri(arUri).exists()) {
+        result.add(await CliVersionResolver.lookupVersion(
+          ToolInstance(
+            tool: androidNdkLlvmAr,
+            uri: arUri,
+          ),
+          logger: logger,
+        ));
+      }
+      final ldUri = hostArchDir.uri
+          .resolve('bin/')
+          .resolve(Target.current.os.executableFileName('ld.lld'));
+      if (await File.fromUri(arUri).exists()) {
+        result.add(await CliVersionResolver.lookupVersion(
+          ToolInstance(
+            tool: androidNdkLld,
+            uri: ldUri,
+          ),
+          logger: logger,
+        ));
+      }
+    }
+    return result;
+  }
+}
diff --git a/pkgs/native_toolchain_c/lib/src/native_toolchain/apple_clang.dart b/pkgs/native_toolchain_c/lib/src/native_toolchain/apple_clang.dart
new file mode 100644
index 0000000..9c7eb4c
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/native_toolchain/apple_clang.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../tool/tool.dart';
+import '../tool/tool_resolver.dart';
+
+/// The Clang variant inside XCode.
+///
+/// https://developer.apple.com/xcode/
+final Tool appleClang = Tool(
+  name: 'Apple Clang',
+  defaultResolver: CliVersionResolver(
+    wrappedResolver: CliFilter(
+      cliArguments: ['--version'],
+      keepIf: ({required String stdout}) => stdout.contains('Apple clang'),
+      wrappedResolver: PathToolResolver(
+        toolName: 'Apple Clang',
+        executableName: 'clang',
+      ),
+    ),
+  ),
+);
+
+/// The archiver belonging to [appleClang].
+final Tool appleAr = Tool(
+  name: 'Apple archiver',
+  defaultResolver: ToolResolvers([
+    RelativeToolResolver(
+      toolName: 'Apple archiver',
+      wrappedResolver: appleClang.defaultResolver!,
+      relativePath: Uri.file('ar'),
+    ),
+  ]),
+);
+
+/// The linker belonging to [appleClang].
+final Tool appleLd = Tool(
+  name: 'Apple linker',
+  defaultResolver: ToolResolvers([
+    RelativeToolResolver(
+      toolName: 'Apple linker',
+      wrappedResolver: appleClang.defaultResolver!,
+      relativePath: Uri.file('ld'),
+    ),
+  ]),
+);
+
+/// The Mach-O dumping tool.
+///
+/// https://llvm.org/docs/CommandGuide/llvm-otool.html
+final Tool otool = Tool(
+  name: 'otool',
+  defaultResolver: CliVersionResolver(
+    wrappedResolver: PathToolResolver(
+      toolName: 'otool',
+      executableName: 'otool',
+    ),
+  ),
+);
diff --git a/pkgs/native_toolchain_c/lib/src/native_toolchain/clang.dart b/pkgs/native_toolchain_c/lib/src/native_toolchain/clang.dart
new file mode 100644
index 0000000..910e3b3
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/native_toolchain/clang.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../tool/tool.dart';
+import '../tool/tool_resolver.dart';
+
+/// The Clang compiler.
+///
+/// https://clang.llvm.org/
+final Tool clang = Tool(
+  name: 'Clang',
+  defaultResolver: CliVersionResolver(
+    wrappedResolver: CliFilter(
+      cliArguments: ['--version'],
+      keepIf: ({required String stdout}) => !stdout.contains('Apple clang'),
+      wrappedResolver: PathToolResolver(
+        toolName: 'Clang',
+        executableName: 'clang',
+      ),
+    ),
+  ),
+);
+
+/// The LLVM archiver.
+///
+/// https://llvm.org/docs/CommandGuide/llvm-ar.html
+final Tool llvmAr = Tool(
+  name: 'LLVM archiver',
+  defaultResolver: CliVersionResolver(
+    wrappedResolver: ToolResolvers([
+      RelativeToolResolver(
+        toolName: 'LLVM archiver',
+        wrappedResolver: clang.defaultResolver!,
+        relativePath: Uri.file('llvm-ar'),
+      ),
+    ]),
+  ),
+);
+
+/// The LLVM Linker.
+///
+/// https://lld.llvm.org/
+final Tool lld = Tool(
+  name: 'LLD',
+  defaultResolver: CliVersionResolver(
+    wrappedResolver: ToolResolvers([
+      RelativeToolResolver(
+        toolName: 'LLD',
+        wrappedResolver: clang.defaultResolver!,
+        relativePath: Uri.file('ld.lld'),
+      ),
+    ]),
+  ),
+);
diff --git a/pkgs/native_toolchain_c/lib/src/native_toolchain/gcc.dart b/pkgs/native_toolchain_c/lib/src/native_toolchain/gcc.dart
new file mode 100644
index 0000000..c3ea294
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/native_toolchain/gcc.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+import '../tool/tool.dart';
+import '../tool/tool_resolver.dart';
+
+/// The GNU Compiler Collection for [Architecture.current].
+///
+/// https://gcc.gnu.org/
+final gcc = Tool(name: 'GCC');
+
+/// The GNU GCC archiver for [Architecture.current].
+final gnuArchiver = Tool(name: 'GNU archiver');
+
+/// The GNU linker for [Architecture.current].
+///
+/// https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/ld.html
+final gnuLinker = Tool(name: 'GNU linker');
+
+/// [gcc] with [Tool.defaultResolver] for [Architecture.ia32].
+final i686LinuxGnuGcc = _gcc('i686-linux-gnu');
+
+/// [gnuArchiver] with [Tool.defaultResolver] for [Architecture.ia32].
+final i686LinuxGnuGccAr = _gnuArchiver('i686-linux-gnu');
+
+/// [gnuLinker] with [Tool.defaultResolver] for [Architecture.ia32].
+final i686LinuxGnuLd = _gnuLinker('i686-linux-gnu');
+
+/// [gcc] with [Tool.defaultResolver] for [Architecture.x64].
+final x86_64LinuxGnuGcc = _gcc('x86_64-linux-gnu');
+
+/// [gnuArchiver] with [Tool.defaultResolver] for [Architecture.x64].
+final x86_64LinuxGnuGccAr = _gnuArchiver('x86_64-linux-gnu');
+
+/// [gnuLinker] with [Tool.defaultResolver] for [Architecture.x64].
+final x86_64LinuxGnuLd = _gnuLinker('x86_64-linux-gnu');
+
+/// [gcc] with [Tool.defaultResolver] for [Architecture.arm].
+final armLinuxGnueabihfGcc = _gcc('arm-linux-gnueabihf');
+
+/// [gnuArchiver] with [Tool.defaultResolver] for [Architecture.arm].
+final armLinuxGnueabihfGccAr = _gnuArchiver('arm-linux-gnueabihf');
+
+/// [gnuLinker] with [Tool.defaultResolver] for [Architecture.arm].
+final armLinuxGnueabihfLd = _gnuLinker('arm-linux-gnueabihf');
+
+/// [gcc] with [Tool.defaultResolver] for [Architecture.arm64].
+final aarch64LinuxGnuGcc = _gcc('aarch64-linux-gnu');
+
+/// [gnuArchiver] with [Tool.defaultResolver] for [Architecture.arm64].
+final aarch64LinuxGnuGccAr = _gnuArchiver('aarch64-linux-gnu');
+
+/// [gnuLinker] with [Tool.defaultResolver] for [Architecture.arm64].
+final aarch64LinuxGnuLd = _gnuLinker('aarch64-linux-gnu');
+
+/// [gcc] with [Tool.defaultResolver] for [Architecture.riscv64].
+final riscv64LinuxGnuGcc = _gcc('riscv64-linux-gnu');
+
+/// [gnuArchiver] with [Tool.defaultResolver] for [Architecture.riscv64].
+final riscv64LinuxGnuGccAr = _gnuArchiver('riscv64-linux-gnu');
+
+/// [gnuLinker] with [Tool.defaultResolver] for [Architecture.riscv64].
+final riscv64LinuxGnuLd = _gnuLinker('riscv64-linux-gnu');
+
+Tool _gcc(String prefix) => Tool(
+      name: gcc.name,
+      defaultResolver: CliVersionResolver(
+        wrappedResolver: PathToolResolver(
+          toolName: gcc.name,
+          executableName: '$prefix-gcc',
+        ),
+      ),
+    );
+
+Tool _gnuArchiver(String prefix) {
+  final gcc = _gcc(prefix);
+  return Tool(
+    name: gnuArchiver.name,
+    defaultResolver: RelativeToolResolver(
+      toolName: gnuArchiver.name,
+      wrappedResolver: gcc.defaultResolver!,
+      relativePath: Uri.file('$prefix-gcc-ar'),
+    ),
+  );
+}
+
+Tool _gnuLinker(String prefix) {
+  final gcc = _gcc(prefix);
+  return Tool(
+    name: gnuLinker.name,
+    defaultResolver: RelativeToolResolver(
+      toolName: gnuLinker.name,
+      wrappedResolver: gcc.defaultResolver!,
+      relativePath: Uri.file('$prefix-ld'),
+    ),
+  );
+}
diff --git a/pkgs/native_toolchain_c/lib/src/native_toolchain/msvc.dart b/pkgs/native_toolchain_c/lib/src/native_toolchain/msvc.dart
new file mode 100644
index 0000000..a95356e
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/native_toolchain/msvc.dart
@@ -0,0 +1,310 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:glob/glob.dart';
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+import '../tool/tool.dart';
+import '../tool/tool_instance.dart';
+import '../tool/tool_resolver.dart';
+import '../utils/run_process.dart';
+import '../utils/sem_version.dart';
+
+/// The Visual Studio Locator.
+///
+/// https://github.com/microsoft/vswhere
+final Tool vswhere = Tool(
+  name: 'Visual Studio Locator',
+  defaultResolver: CliVersionResolver(
+    arguments: [],
+    wrappedResolver: ToolResolvers(
+      [
+        PathToolResolver(
+          toolName: 'Visual Studio Locator',
+          executableName: 'vswhere.exe',
+        ),
+        InstallLocationResolver(
+          toolName: 'Visual Studio Locator',
+          paths: [
+            'C:/Program Files \\(x86\\)/Microsoft Visual Studio/Installer/vswhere.exe',
+            'C:/Program Files/Microsoft Visual Studio/Installer/vswhere.exe',
+          ],
+        ),
+      ],
+    ),
+  ),
+);
+
+/// Visual Studio.
+///
+/// https://visualstudio.microsoft.com/
+final Tool visualStudio = Tool(
+  name: 'Visual Studio',
+  defaultResolver: VisualStudioResolver(),
+);
+
+/// The C/C++ Optimizing Compiler.
+final Tool msvc = Tool(
+  name: 'MSVC',
+  defaultResolver: PathVersionResolver(
+    wrappedResolver: RelativeToolResolver(
+      toolName: 'MSVC',
+      wrappedResolver: visualStudio.defaultResolver!,
+      relativePath: Uri(path: './VC/Tools/MSVC/*/'),
+    ),
+  ),
+);
+
+Tool vcvars(ToolInstance toolInstance) {
+  final tool = toolInstance.tool;
+  assert(tool == cl || tool == link || tool == lib);
+  final vcDir = toolInstance.uri.resolve('../../../../../../');
+  final String fileName;
+  if (toolInstance.uri.toFilePath().contains('\\x86\\')) {
+    fileName = 'vcvars32.bat';
+  } else if (toolInstance.uri.toFilePath().contains('\\arm64\\')) {
+    // TODO(https://github.com/dart-lang/native/issues/170): Support native
+    // windows-arm64 MSVC toolchain.
+    // vcvarsarm64 only works on native windows-arm64. In case of cross
+    // compilation, it's better to stick to cross toolchain, which works under
+    // emulation on windows-arm64.
+    fileName = 'vcvarsamd64_arm64.bat';
+  } else {
+    fileName = 'vcvars64.bat';
+  }
+  final batchScript = vcDir.resolve('Auxiliary/Build/$fileName');
+  return Tool(
+    name: fileName,
+    defaultResolver: InstallLocationResolver(
+      toolName: fileName,
+      paths: [
+        Glob.quote(batchScript.toFilePath().replaceAll('\\', '/')),
+      ],
+    ),
+  );
+}
+
+final Tool vcvars64 = Tool(
+  name: 'vcvars64.bat',
+  defaultResolver: RelativeToolResolver(
+    toolName: 'vcvars64.bat',
+    wrappedResolver: visualStudio.defaultResolver!,
+    relativePath: Uri(path: './VC/Auxiliary/Build/vcvars64.bat'),
+  ),
+);
+
+final Tool vcvars32 = Tool(
+  name: 'vcvars32.bat',
+  defaultResolver: RelativeToolResolver(
+    toolName: 'vcvars32.bat',
+    wrappedResolver: visualStudio.defaultResolver!,
+    relativePath: Uri(path: './VC/Auxiliary/Build/vcvars32.bat'),
+  ),
+);
+
+final Tool vcvarsarm64 = Tool(
+  // TODO(https://github.com/dart-lang/native/issues/170): Support native
+  // windows-arm64 MSVC toolchain.
+  // vcvarsarm64 only works on native windows-arm64. In case of cross
+  // compilation, it's better to stick to cross toolchain, which works under
+  // emulation on windows-arm64.
+  name: 'vcvarsamd64_arm64.bat',
+  defaultResolver: RelativeToolResolver(
+    toolName: 'vcvarsamd64_arm64.bat',
+    wrappedResolver: visualStudio.defaultResolver!,
+    relativePath: Uri(path: './VC/Auxiliary/Build/vcvarsamd64_arm64.bat'),
+  ),
+);
+
+final Tool vcvarsall = Tool(
+  name: 'vcvarsall.bat',
+  defaultResolver: RelativeToolResolver(
+    toolName: 'vcvars32.bat',
+    wrappedResolver: visualStudio.defaultResolver!,
+    relativePath: Uri(path: './VC/Auxiliary/Build/vcvarsall.bat'),
+  ),
+);
+
+final Tool vsDevCmd = Tool(
+  name: 'VsDevCmd.bat',
+  defaultResolver: RelativeToolResolver(
+    toolName: 'VsDevCmd.bat',
+    wrappedResolver: visualStudio.defaultResolver!,
+    relativePath: Uri(path: './Common7/Tools/VsDevCmd.bat'),
+  ),
+);
+
+/// The C/C++ Optimizing Compiler main executable.
+///
+/// For targeting [Architecture.x64].
+final Tool cl = _msvcTool(
+  name: 'cl',
+  versionArguments: [],
+  targetArchitecture: Architecture.x64,
+  hostArchitecture: Target.current.architecture,
+);
+
+/// The C/C++ Optimizing Compiler main executable.
+///
+/// For targeting [Architecture.ia32].
+final Tool clIA32 = _msvcTool(
+  name: 'cl',
+  versionArguments: [],
+  targetArchitecture: Architecture.ia32,
+  hostArchitecture: Target.current.architecture,
+);
+
+/// The C/C++ Optimizing Compiler main executable.
+///
+/// For targeting [Architecture.arm64].
+final Tool clArm64 = _msvcTool(
+  name: 'cl',
+  versionArguments: [],
+  targetArchitecture: Architecture.arm64,
+  hostArchitecture: Target.current.architecture,
+);
+
+final Tool lib = _msvcTool(
+  name: 'lib',
+  targetArchitecture: Architecture.x64,
+  hostArchitecture: Target.current.architecture,
+  // https://github.com/dart-lang/native/issues/18
+  resolveVersion: false,
+);
+
+final Tool libIA32 = _msvcTool(
+  name: 'lib',
+  targetArchitecture: Architecture.ia32,
+  hostArchitecture: Target.current.architecture,
+  // https://github.com/dart-lang/native/issues/18
+  resolveVersion: false,
+);
+
+final Tool libArm64 = _msvcTool(
+  name: 'lib',
+  targetArchitecture: Architecture.arm64,
+  hostArchitecture: Target.current.architecture,
+  // https://github.com/dart-lang/native/issues/18
+  resolveVersion: false,
+);
+
+final Tool link = _msvcTool(
+  name: 'link',
+  versionArguments: ['/help'],
+  versionExitCode: 1100,
+  targetArchitecture: Architecture.x64,
+  hostArchitecture: Target.current.architecture,
+);
+
+final Tool linkIA32 = _msvcTool(
+  name: 'link',
+  versionArguments: ['/help'],
+  versionExitCode: 1100,
+  targetArchitecture: Architecture.ia32,
+  hostArchitecture: Target.current.architecture,
+);
+
+final Tool linkArm64 = _msvcTool(
+  name: 'link',
+  versionArguments: ['/help'],
+  versionExitCode: 1100,
+  targetArchitecture: Architecture.arm64,
+  hostArchitecture: Target.current.architecture,
+);
+
+final Tool dumpbin = _msvcTool(
+  name: 'dumpbin',
+  targetArchitecture: Architecture.x64,
+  hostArchitecture: Target.current.architecture,
+);
+
+const _msvcArchNames = {
+  Architecture.ia32: 'x86',
+  Architecture.x64: 'x64',
+  Architecture.arm64: 'arm64',
+};
+
+Tool _msvcTool({
+  required String name,
+  required Architecture targetArchitecture,
+  required Architecture hostArchitecture,
+  List<String> versionArguments = const ['--version'],
+  int versionExitCode = 0,
+  bool resolveVersion = true,
+}) {
+  final executableName = OS.windows.executableFileName(name);
+  if (Target.current.os != OS.windows) {
+    return Tool(
+      name: executableName,
+      defaultResolver: ToolResolvers([]),
+    );
+  }
+  final hostArchName = _msvcArchNames[hostArchitecture]!;
+  final targetArchName = _msvcArchNames[targetArchitecture]!;
+  ToolResolver resolver = RelativeToolResolver(
+    toolName: executableName,
+    wrappedResolver: msvc.defaultResolver!,
+    relativePath: Uri(
+      path: 'bin/Host$hostArchName/$targetArchName/$executableName',
+    ),
+  );
+  if (resolveVersion) {
+    resolver = CliVersionResolver(
+      expectedExitCode: versionExitCode,
+      arguments: versionArguments,
+      wrappedResolver: resolver,
+    );
+  }
+  return Tool(
+    name: executableName,
+    defaultResolver: resolver,
+  );
+}
+
+class VisualStudioResolver implements ToolResolver {
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    final vswhereInstances =
+        await vswhere.defaultResolver!.resolve(logger: logger);
+
+    final result = <ToolInstance>[];
+    for (final vswhereInstance in vswhereInstances.take(1)) {
+      final vswhereResult = await runProcess(
+        executable: vswhereInstance.uri,
+        logger: logger,
+      );
+      final toolInfos = vswhereResult.stdout.split(_newLine * 2).skip(1);
+      for (final toolInfo in toolInfos) {
+        final toolInfoParsed = parseToolInfo(toolInfo);
+        final dir = Directory(toolInfoParsed['installationPath']!);
+        assert(await dir.exists());
+        final uri = dir.uri;
+        final version = versionFromString(toolInfoParsed['installationName']!);
+        final instance =
+            ToolInstance(tool: visualStudio, uri: uri, version: version);
+        logger?.fine('Found $instance.');
+        result.add(instance);
+      }
+    }
+    return result;
+  }
+
+  static Map<String, String> parseToolInfo(String toolInfo) {
+    final result = <String, String>{};
+    final lines = toolInfo.split(_newLine);
+    for (final line in lines) {
+      final splitLine = line.split(': ');
+      final key = splitLine.first;
+      final value = splitLine.skip(1).join(': ');
+      result[key] = value;
+    }
+    return result;
+  }
+}
+
+// runProcess uses writeln which uses '\n'.
+const _newLine = '\n';
diff --git a/pkgs/native_toolchain_c/lib/src/native_toolchain/recognizer.dart b/pkgs/native_toolchain_c/lib/src/native_toolchain/recognizer.dart
new file mode 100644
index 0000000..0de8418
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/native_toolchain/recognizer.dart
@@ -0,0 +1,148 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+
+import '../tool/tool.dart';
+import '../tool/tool_instance.dart';
+import '../tool/tool_resolver.dart';
+import 'apple_clang.dart';
+import 'clang.dart';
+import 'gcc.dart';
+import 'msvc.dart';
+
+class CompilerRecognizer implements ToolResolver {
+  final Uri uri;
+
+  CompilerRecognizer(this.uri);
+
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    final os = Target.current.os;
+    logger?.finer('Trying to recognize $uri.');
+    final filePath = uri.toFilePath();
+    Tool? tool;
+    if (filePath.contains('-gcc')) {
+      tool = gcc;
+    } else if (filePath.endsWith(os.executableFileName('clang'))) {
+      final stdout = await CliFilter.executeCli(uri,
+          arguments: ['--version'], logger: logger);
+      if (stdout.contains('Apple clang')) {
+        tool = appleClang;
+      } else {
+        tool = clang;
+      }
+    } else if (filePath.endsWith('cl.exe')) {
+      tool = cl;
+    }
+
+    if (tool != null) {
+      logger?.fine('Tool instance $uri is likely $tool.');
+      final toolInstance = ToolInstance(tool: tool, uri: uri);
+      return [
+        await CliVersionResolver.lookupVersion(
+          toolInstance,
+          logger: logger,
+          arguments: [
+            if (tool != cl) '--version',
+          ],
+        ),
+      ];
+    }
+
+    logger?.severe('Tool instance $uri not recognized.');
+    return [];
+  }
+}
+
+class LinkerRecognizer implements ToolResolver {
+  final Uri uri;
+
+  LinkerRecognizer(this.uri);
+
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    final os = Target.current.os;
+    logger?.finer('Trying to recognize $uri.');
+    final filePath = uri.toFilePath();
+    Tool? tool;
+    if (filePath.contains('-ld')) {
+      tool = gnuLinker;
+    } else if (filePath.endsWith(os.executableFileName('ld.lld'))) {
+      tool = lld;
+    } else if (filePath.endsWith(os.executableFileName('ld'))) {
+      tool = appleLd;
+    } else if (filePath.endsWith('link.exe')) {
+      tool = link;
+    }
+
+    if (tool != null) {
+      logger?.fine('Tool instance $uri is likely $tool.');
+      final toolInstance = ToolInstance(tool: tool, uri: uri);
+      if (tool == lld) {
+        return [
+          await CliVersionResolver.lookupVersion(
+            toolInstance,
+            logger: logger,
+          ),
+        ];
+      }
+      if (tool == link) {
+        return [
+          await CliVersionResolver.lookupVersion(
+            toolInstance,
+            logger: logger,
+            arguments: ['/help'],
+            expectedExitCode: 1100,
+          ),
+        ];
+      }
+      return [toolInstance];
+    }
+
+    logger?.severe('Tool instance $uri not recognized.');
+    return [];
+  }
+}
+
+class ArchiverRecognizer implements ToolResolver {
+  final Uri uri;
+
+  ArchiverRecognizer(this.uri);
+
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    logger?.finer('Trying to recognize $uri.');
+    final os = Target.current.os;
+    final filePath = uri.toFilePath();
+    Tool? tool;
+    if (filePath.contains('-gcc-ar')) {
+      tool = gnuArchiver;
+    } else if (filePath.endsWith(os.executableFileName('llvm-ar'))) {
+      tool = llvmAr;
+    } else if (filePath.endsWith(os.executableFileName('ar'))) {
+      tool = appleAr;
+    } else if (filePath.endsWith('lib.exe')) {
+      tool = lib;
+    }
+
+    if (tool != null) {
+      logger?.fine('Tool instance $uri is likely $tool.');
+      final toolInstance = ToolInstance(tool: tool, uri: uri);
+      if (tool == llvmAr) {
+        return [
+          await CliVersionResolver.lookupVersion(
+            toolInstance,
+            logger: logger,
+          ),
+        ];
+      }
+      return [toolInstance];
+    }
+
+    logger?.severe('Tool instance $uri not recognized.');
+    return [];
+  }
+}
diff --git a/pkgs/native_toolchain_c/lib/src/native_toolchain/xcode.dart b/pkgs/native_toolchain_c/lib/src/native_toolchain/xcode.dart
new file mode 100644
index 0000000..48c25c3
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/native_toolchain/xcode.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:logging/logging.dart';
+
+import '../tool/tool.dart';
+import '../tool/tool_instance.dart';
+import '../tool/tool_resolver.dart';
+import '../utils/run_process.dart';
+
+/// The xcrun from XCode.
+///
+/// https://developer.apple.com/xcode/
+final Tool xcrun = Tool(
+  name: 'xcrun',
+  defaultResolver: CliVersionResolver(
+    wrappedResolver: PathToolResolver(
+      toolName: 'xcrun',
+      executableName: 'xcrun',
+    ),
+  ),
+);
+
+/// The MacOSX SDK.
+final Tool macosxSdk = Tool(
+  name: 'MacOSX SDK',
+  defaultResolver: XCodeSdkResolver(),
+);
+
+/// The iPhoneOS SDK.
+final Tool iPhoneOSSdk = Tool(
+  name: 'iPhoneOS SDK',
+  defaultResolver: XCodeSdkResolver(),
+);
+
+/// The iPhoneSimulator SDK.
+final Tool iPhoneSimulatorSdk = Tool(
+  name: 'iPhoneSimulator SDK',
+  defaultResolver: XCodeSdkResolver(),
+);
+
+class XCodeSdkResolver implements ToolResolver {
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    final xcrunInstances = await xcrun.defaultResolver!.resolve(logger: logger);
+
+    return [
+      for (final xcrunInstance in xcrunInstances) ...[
+        ...await tryResolveSdk(
+          xcrunInstance: xcrunInstance,
+          sdk: 'macosx',
+          tool: macosxSdk,
+          logger: logger,
+        ),
+        ...await tryResolveSdk(
+          xcrunInstance: xcrunInstance,
+          sdk: 'iphoneos',
+          tool: iPhoneOSSdk,
+          logger: logger,
+        ),
+        ...await tryResolveSdk(
+          xcrunInstance: xcrunInstance,
+          sdk: 'iphonesimulator',
+          tool: iPhoneSimulatorSdk,
+          logger: logger,
+        ),
+      ],
+      // xcrun --sdk macosx --show-sdk-path)
+    ];
+  }
+
+  static Future<List<ToolInstance>> tryResolveSdk({
+    required ToolInstance xcrunInstance,
+    required String sdk,
+    required Tool tool,
+    required Logger? logger,
+  }) async {
+    final result = await runProcess(
+      executable: xcrunInstance.uri,
+      arguments: ['--sdk', sdk, '--show-sdk-path'],
+      logger: logger,
+    );
+    if (result.exitCode == 1) {
+      assert(result.stderr.contains('cannot be located'));
+      logger?.warning('SDK $sdk not installed.');
+      return [];
+    }
+    assert(result.exitCode == 0);
+    final uriSymbolic = Uri.directory(result.stdout.trim());
+    logger?.fine('Found $sdk at ${uriSymbolic.toFilePath()}');
+    final uri = Uri.directory(
+        await Directory.fromUri(uriSymbolic).resolveSymbolicLinks());
+    if (uriSymbolic != uri) {
+      logger?.fine('Found $sdk at ${uri.toFilePath()}');
+    }
+    assert(await Directory.fromUri(uri).exists());
+    return [ToolInstance(tool: tool, uri: uri)];
+  }
+}
diff --git a/pkgs/native_toolchain_c/lib/src/tool/tool.dart b/pkgs/native_toolchain_c/lib/src/tool/tool.dart
new file mode 100644
index 0000000..ff42f28
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/tool/tool.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'tool_resolver.dart';
+
+class Tool {
+  final String name;
+
+  ToolResolver? defaultResolver;
+
+  Tool({
+    required this.name,
+    this.defaultResolver,
+  });
+
+  @override
+  bool operator ==(Object other) => other is Tool && name == other.name;
+
+  @override
+  int get hashCode => Object.hash(name, 133709);
+
+  @override
+  String toString() => 'Tool($name)';
+}
diff --git a/pkgs/native_toolchain_c/lib/src/tool/tool_error.dart b/pkgs/native_toolchain_c/lib/src/tool/tool_error.dart
new file mode 100644
index 0000000..def9ce4
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/tool/tool_error.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// The operation could not be performed due to a configuration error on the
+/// host system.
+class ToolError extends Error {
+  final String message;
+
+  ToolError(this.message);
+
+  @override
+  String toString() => 'System not configured correctly: $message';
+}
diff --git a/pkgs/native_toolchain_c/lib/src/tool/tool_instance.dart b/pkgs/native_toolchain_c/lib/src/tool/tool_instance.dart
new file mode 100644
index 0000000..c1a373b
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/tool/tool_instance.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:pub_semver/pub_semver.dart';
+
+import 'tool.dart';
+
+class ToolInstance implements Comparable<ToolInstance> {
+  /// The name of the tool.
+  final Tool tool;
+
+  /// The path of the native tool on the system.
+  final Uri uri;
+
+  /// The version of the native tool.
+  ///
+  /// Can be null if version is hard to determine.
+  final Version? version;
+
+  ToolInstance({
+    required this.tool,
+    required this.uri,
+    this.version,
+  });
+
+  ToolInstance copyWith({
+    Uri? uri,
+    Version? version,
+  }) =>
+      ToolInstance(
+        tool: tool,
+        uri: uri ?? this.uri,
+        version: version ?? this.version,
+      );
+
+  @override
+  String toString() => 'ToolInstance(${tool.name}, $version, $uri)';
+
+  /// Compares this tool instance to [other].
+  ///
+  /// When used in sorting, orders [ToolInstance]s according to:
+  /// 1. [tool] name, alphabetically; then
+  /// 2. [version], newest first and preferring having a version; then
+  /// 3. [uri], alphabetically.
+  @override
+  int compareTo(ToolInstance other) {
+    final nameCompare = tool.name.compareTo(other.tool.name);
+    if (nameCompare != 0) {
+      return nameCompare;
+    }
+    final version = this.version;
+    final otherVersion = other.version;
+    if (version != null || otherVersion != null) {
+      if (version == null) {
+        return 1;
+      }
+      if (otherVersion == null) {
+        return -1;
+      }
+      final versionCompare = version.compareTo(otherVersion);
+      if (versionCompare != 0) {
+        return -versionCompare;
+      }
+    }
+    return uri.toFilePath().compareTo(other.uri.toFilePath());
+  }
+
+  @override
+  bool operator ==(Object other) =>
+      other is ToolInstance &&
+      tool == other.tool &&
+      uri == other.uri &&
+      version == other.version;
+
+  @override
+  int get hashCode => Object.hash(tool, uri, version);
+}
diff --git a/pkgs/native_toolchain_c/lib/src/tool/tool_requirement.dart b/pkgs/native_toolchain_c/lib/src/tool/tool_requirement.dart
new file mode 100644
index 0000000..33dba8b
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/tool/tool_requirement.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:pub_semver/pub_semver.dart';
+
+import 'tool.dart';
+import 'tool_instance.dart';
+
+abstract class Requirement {
+  /// Tries to satisfy this requirement.
+  ///
+  /// If the requirement can be satisfied, returns the set of tools that
+  /// satisfy the requirement.
+  ///
+  /// Currently does not check that we only use a single version of a tool.
+  List<ToolInstance>? satisfy(List<ToolInstance> allAvailableTools);
+}
+
+class ToolRequirement implements Requirement {
+  final Tool tool;
+
+  final Version? minimumVersion;
+
+  ToolRequirement(
+    this.tool, {
+    this.minimumVersion,
+  });
+
+  @override
+  String toString() =>
+      'ToolRequirement(${tool.name}, minimumVersion: $minimumVersion)';
+
+  @override
+  List<ToolInstance>? satisfy(List<ToolInstance> availableToolInstances) {
+    final candidates = <ToolInstance>[];
+    for (final instance in availableToolInstances) {
+      if (instance.tool == tool) {
+        final minimumVersion_ = minimumVersion;
+        if (minimumVersion_ == null) {
+          candidates.add(instance);
+        } else {
+          final version = instance.version;
+          if (version != null && version >= minimumVersion_) {
+            candidates.add(instance);
+          }
+        }
+      }
+    }
+    if (candidates.isEmpty) {
+      return null;
+    }
+    candidates.sort();
+    return [candidates.first];
+  }
+}
+
+class RequireOne implements Requirement {
+  final List<Requirement> alternatives;
+
+  RequireOne(this.alternatives);
+
+  @override
+  List<ToolInstance>? satisfy(List<ToolInstance> allAvailableTools) {
+    for (final alternative in alternatives) {
+      final result = alternative.satisfy(allAvailableTools);
+      if (result != null) {
+        return result;
+      }
+    }
+    return null;
+  }
+}
+
+class RequireAll implements Requirement {
+  final List<Requirement> requirements;
+
+  RequireAll(this.requirements);
+
+  @override
+  List<ToolInstance>? satisfy(List<ToolInstance> allAvailableTools) {
+    final result = <ToolInstance>[];
+    for (final requirement in requirements) {
+      final requirementResult = requirement.satisfy(allAvailableTools);
+      if (requirementResult == null) {
+        return null;
+      }
+      result.addAll(requirementResult);
+    }
+    return result;
+  }
+}
diff --git a/pkgs/native_toolchain_c/lib/src/tool/tool_resolver.dart b/pkgs/native_toolchain_c/lib/src/tool/tool_resolver.dart
new file mode 100644
index 0000000..257ef8e
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/tool/tool_resolver.dart
@@ -0,0 +1,349 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:glob/glob.dart';
+import 'package:glob/list_local_fs.dart';
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:pub_semver/pub_semver.dart';
+
+import '../utils/run_process.dart';
+import '../utils/sem_version.dart';
+import 'tool.dart';
+import 'tool_error.dart';
+import 'tool_instance.dart';
+
+abstract class ToolResolver {
+  /// Resolves tools on the host system.
+  Future<List<ToolInstance>> resolve({required Logger? logger});
+}
+
+/// Tries to resolve a tool on the `PATH`.
+///
+/// Uses `which` (`where` on Windows) to resolve a tool.
+class PathToolResolver extends ToolResolver {
+  /// The [Tool.name] of the [Tool] to find on the `PATH`.
+  final String toolName;
+
+  final String executableName;
+
+  PathToolResolver({
+    required this.toolName,
+    String? executableName,
+  }) : executableName = executableName ??
+            Target.current.os.executableFileName(toolName.toLowerCase());
+
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    logger?.finer('Looking for $toolName on PATH.');
+    final uri = await runWhich(logger: logger);
+    if (uri == null) {
+      logger?.fine('Did not find  $toolName on PATH.');
+      return [];
+    }
+    final toolInstances = [
+      ToolInstance(tool: Tool(name: toolName), uri: uri),
+    ];
+    logger?.fine('Found ${toolInstances.single}.');
+    return toolInstances;
+  }
+
+  static Uri get which => Uri.file(Platform.isWindows ? 'where' : 'which');
+
+  Future<Uri?> runWhich({required Logger? logger}) async {
+    final process = await runProcess(
+      executable: which,
+      arguments: [executableName],
+      logger: logger,
+    );
+    if (process.exitCode == 0) {
+      final file = File(LineSplitter.split(process.stdout).first);
+      final uri = File(await file.resolveSymbolicLinks()).uri;
+      if (uri.pathSegments.last == 'llvm') {
+        // https://github.com/dart-lang/native/issues/136
+        return file.uri;
+      }
+      return uri;
+    }
+    // The exit code for executable not being on the `PATH`.
+    assert(process.exitCode == 1);
+    return null;
+  }
+}
+
+class CliVersionResolver implements ToolResolver {
+  final ToolResolver wrappedResolver;
+  final List<String> arguments;
+  final int expectedExitCode;
+
+  CliVersionResolver({
+    required this.wrappedResolver,
+    this.arguments = const ['--version'],
+    this.expectedExitCode = 0,
+  });
+
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    final toolInstances = await wrappedResolver.resolve(logger: logger);
+    return [
+      for (final toolInstance in toolInstances)
+        await lookupVersion(
+          toolInstance,
+          arguments: arguments,
+          expectedExitCode: expectedExitCode,
+          logger: logger,
+        )
+    ];
+  }
+
+  static Future<ToolInstance> lookupVersion(
+    ToolInstance toolInstance, {
+    List<String> arguments = const ['--version'],
+    int expectedExitCode = 0,
+    required Logger? logger,
+  }) async {
+    if (toolInstance.version != null) return toolInstance;
+    logger?.finer('Looking up version with --version for $toolInstance.');
+    final version = await executableVersion(
+      toolInstance.uri,
+      arguments: arguments,
+      expectedExitCode: expectedExitCode,
+      logger: logger,
+    );
+    final result = toolInstance.copyWith(version: version);
+    logger?.fine('Found version for $result.');
+    return result;
+  }
+
+  static Future<Version> executableVersion(
+    Uri executable, {
+    List<String> arguments = const ['--version'],
+    int expectedExitCode = 0,
+    required Logger? logger,
+  }) async {
+    final process = await runProcess(
+      executable: executable,
+      arguments: arguments,
+      logger: logger,
+    );
+    if (process.exitCode != expectedExitCode) {
+      final executablePath = executable.toFilePath();
+      throw ToolError(
+          '`$executablePath ${arguments.join(' ')}` returned unexpected exit'
+          ' code: ${process.exitCode}.');
+    }
+    return versionFromString(process.stderr) ??
+        versionFromString(process.stdout)!;
+  }
+}
+
+class PathVersionResolver implements ToolResolver {
+  ToolResolver wrappedResolver;
+
+  PathVersionResolver({required this.wrappedResolver});
+
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    final toolInstances = await wrappedResolver.resolve(logger: logger);
+
+    return [
+      for (final toolInstance in toolInstances) lookupVersion(toolInstance)
+    ];
+  }
+
+  static ToolInstance lookupVersion(ToolInstance toolInstance) {
+    if (toolInstance.version != null) {
+      return toolInstance;
+    }
+    return toolInstance.copyWith(
+      version: version(toolInstance.uri),
+    );
+  }
+
+  static Version? version(Uri uri) {
+    final versionString = uri.pathSegments.where((e) => e != '').last;
+    final version = versionFromString(versionString);
+    return version;
+  }
+}
+
+/// A resolver which invokes all [resolvers] tools.
+class ToolResolvers implements ToolResolver {
+  final List<ToolResolver> resolvers;
+
+  ToolResolvers(this.resolvers);
+
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async => [
+        for (final resolver in resolvers)
+          ...await resolver.resolve(logger: logger)
+      ];
+}
+
+class InstallLocationResolver implements ToolResolver {
+  final String toolName;
+  final List<String> paths;
+
+  InstallLocationResolver({
+    required this.toolName,
+    required this.paths,
+  });
+
+  static const home = '\$HOME';
+
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    logger?.finer('Looking for $toolName in $paths.');
+    final resolvedPaths = [
+      for (final path in paths) ...await tryResolvePath(path)
+    ];
+    final toolInstances = [
+      for (final uri in resolvedPaths)
+        ToolInstance(tool: Tool(name: toolName), uri: uri),
+    ];
+    if (toolInstances.isNotEmpty) {
+      logger?.fine('Found $toolInstances.');
+    } else {
+      logger?.finer('Found no $toolName in $paths.');
+    }
+    return toolInstances;
+  }
+
+  Future<List<Uri>> tryResolvePath(String path) async {
+    if (path.startsWith(home)) {
+      final homeDir_ = homeDir;
+      assert(homeDir_ != null);
+      path = path.replaceAll(
+          '$home/', homeDir!.toFilePath().replaceAll('\\', '/'));
+    }
+
+    final result = <Uri>[];
+    final fileSystemEntities = await Glob(path).list().toList();
+    for (final fileSystemEntity in fileSystemEntities) {
+      if (!await fileSystemEntity.exists()) {
+        continue;
+      }
+      if (fileSystemEntity is! Directory && path.endsWith('/')) {
+        continue;
+      }
+      result.add(fileSystemEntity.uri);
+    }
+    return result;
+  }
+
+  static final Uri? homeDir = () {
+    final path =
+        Platform.environment['HOME'] ?? Platform.environment['USERPROFILE'];
+    if (path == null) return null;
+    return Directory(path).uri;
+  }();
+}
+
+class RelativeToolResolver implements ToolResolver {
+  final String toolName;
+  final ToolResolver wrappedResolver;
+  final Uri relativePath;
+
+  RelativeToolResolver({
+    required this.toolName,
+    required this.wrappedResolver,
+    required this.relativePath,
+  });
+
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    final otherToolInstances = await wrappedResolver.resolve(logger: logger);
+
+    logger?.finer('Looking for $toolName relative to $otherToolInstances '
+        'with $relativePath.');
+    final globs = [
+      for (final toolInstance in otherToolInstances)
+        Glob([
+          Glob.quote(
+              toolInstance.uri.resolve('.').toFilePath().replaceAll('\\', '/')),
+          relativePath.path
+        ].join())
+    ];
+    // print(globs);
+    // exit(0);
+    final fileSystemEntities = [
+      for (final glob in globs) ...await glob.list().toList(),
+    ];
+
+    final result = [
+      for (final fileSystemEntity in fileSystemEntities)
+        ToolInstance(
+          tool: Tool(name: toolName),
+          uri: fileSystemEntity.uri,
+        ),
+    ];
+
+    if (result.isNotEmpty) {
+      logger?.fine('Found $result.');
+    } else {
+      logger?.finer('Found no $toolName relative to $otherToolInstances.');
+    }
+    return result;
+  }
+}
+
+class CliFilter implements ToolResolver {
+  final ToolResolver wrappedResolver;
+  final List<String> cliArguments;
+  final bool Function({required String stdout}) keepIf;
+
+  CliFilter({
+    required this.wrappedResolver,
+    required this.cliArguments,
+    required this.keepIf,
+  });
+
+  @override
+  Future<List<ToolInstance>> resolve({required Logger? logger}) async {
+    final toolInstances = await wrappedResolver.resolve(logger: logger);
+    return [
+      for (final toolInstance in toolInstances)
+        await filter(toolInstance, logger: logger)
+    ].whereType<ToolInstance>().toList();
+  }
+
+  Future<ToolInstance?> filter(
+    ToolInstance toolInstance, {
+    required Logger? logger,
+  }) async {
+    if (toolInstance.version != null) return toolInstance;
+    logger?.finer('Checking if $toolInstance satisfies CLI filter.');
+    final stdout = await executeCli(
+      toolInstance.uri,
+      arguments: cliArguments,
+      logger: logger,
+    );
+    final doKeep = keepIf(stdout: stdout);
+    if (doKeep) {
+      logger?.fine('$toolInstance satisfies CLI filter.');
+      return toolInstance;
+    }
+    logger?.fine('$toolInstance does not satisfy CLI filter.');
+    return null;
+  }
+
+  static Future<String> executeCli(
+    Uri executable, {
+    required List<String> arguments,
+    int expectedExitCode = 0,
+    required Logger? logger,
+  }) async {
+    final process = await runProcess(
+      executable: executable,
+      arguments: arguments,
+      logger: logger,
+    );
+    final exitCode = process.exitCode;
+    assert(exitCode == expectedExitCode);
+    return process.stdout;
+  }
+}
diff --git a/pkgs/native_toolchain_c/lib/src/utils/env_from_bat.dart b/pkgs/native_toolchain_c/lib/src/utils/env_from_bat.dart
new file mode 100644
index 0000000..31958bb
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/utils/env_from_bat.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+Future<Map<String, String>> envFromBat(
+  Uri batchFile, {
+  List<String> arguments = const [],
+}) async {
+  final fileName = batchFile.pathSegments.last;
+  final dir = batchFile.resolve('.');
+  const separator = '=======';
+  final processResult = await Process.run(
+    'set && echo $separator && $fileName ${arguments.join(' ')} > nul && set',
+    [],
+    runInShell: true,
+    workingDirectory: dir.toFilePath(),
+  );
+  assert(processResult.exitCode == 0);
+  final resultSplit = (processResult.stdout as String).split(separator);
+  assert(resultSplit.length == 2);
+  final unmodifiedParsed = parseDefines(resultSplit.first.trim());
+  final modifiedParsed = parseDefines(resultSplit[1].trim());
+  final result = <String, String>{};
+  for (final entry in modifiedParsed.entries) {
+    final key = entry.key;
+    final value = entry.value;
+    if (!unmodifiedParsed.containsKey(key) || value != unmodifiedParsed[key]) {
+      result[key] = value;
+    }
+  }
+  return result;
+}
+
+// Ensures it doesn't return empty keys.
+Map<String, String> parseDefines(String defines) {
+  final result = <String, String>{};
+  final lines = defines.trim().split('\r\n');
+  for (final line in lines) {
+    if (line.isEmpty) continue;
+    final lineSplit = line.split('=');
+    final key = lineSplit.first;
+    final value = lineSplit.skip(1).join('=');
+    result[key] = value;
+  }
+  return result;
+}
diff --git a/pkgs/native_toolchain_c/lib/src/utils/run_process.dart b/pkgs/native_toolchain_c/lib/src/utils/run_process.dart
new file mode 100644
index 0000000..f9204e5
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/utils/run_process.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:logging/logging.dart';
+
+/// Runs a [Process].
+///
+/// If [logger] is provided, stream stdout and stderr to it.
+///
+/// If [captureOutput], captures stdout and stderr.
+Future<RunProcessResult> runProcess({
+  required Uri executable,
+  List<String> arguments = const [],
+  Uri? workingDirectory,
+  Map<String, String>? environment,
+  bool includeParentEnvironment = true,
+  required Logger? logger,
+  bool captureOutput = true,
+  int expectedExitCode = 0,
+  bool throwOnUnexpectedExitCode = false,
+}) async {
+  if (Platform.isWindows && !includeParentEnvironment) {
+    const winEnvKeys = [
+      'SYSTEMROOT',
+      'TEMP',
+      'TMP',
+    ];
+    environment = {
+      for (final winEnvKey in winEnvKeys)
+        winEnvKey: Platform.environment[winEnvKey]!,
+      ...?environment,
+    };
+  }
+
+  final printWorkingDir =
+      workingDirectory != null && workingDirectory != Directory.current.uri;
+  final commandString = [
+    if (printWorkingDir) '(cd ${workingDirectory.toFilePath()};',
+    ...?environment?.entries.map((entry) => '${entry.key}=${entry.value}'),
+    executable.toFilePath(),
+    ...arguments.map((a) => a.contains(' ') ? "'$a'" : a),
+    if (printWorkingDir) ')',
+  ].join(' ');
+  logger?.info('Running `$commandString`.');
+
+  final stdoutBuffer = StringBuffer();
+  final stderrBuffer = StringBuffer();
+  final process = await Process.start(
+    executable.toFilePath(),
+    arguments,
+    workingDirectory: workingDirectory?.toFilePath(),
+    environment: environment,
+    includeParentEnvironment: includeParentEnvironment,
+    runInShell: Platform.isWindows && !includeParentEnvironment,
+  );
+
+  final stdoutSub = process.stdout
+      .transform(utf8.decoder)
+      .transform(const LineSplitter())
+      .listen(captureOutput
+          ? (s) {
+              logger?.fine(s);
+              stdoutBuffer.writeln(s);
+            }
+          : logger?.fine);
+  final stderrSub = process.stderr
+      .transform(utf8.decoder)
+      .transform(const LineSplitter())
+      .listen(captureOutput
+          ? (s) {
+              logger?.severe(s);
+              stderrBuffer.writeln(s);
+            }
+          : logger?.severe);
+
+  final (exitCode, _, _) = await (
+    process.exitCode,
+    stdoutSub.asFuture<void>(),
+    stderrSub.asFuture<void>()
+  ).wait;
+  final result = RunProcessResult(
+    pid: process.pid,
+    command: commandString,
+    exitCode: exitCode,
+    stdout: stdoutBuffer.toString(),
+    stderr: stderrBuffer.toString(),
+  );
+  if (throwOnUnexpectedExitCode && expectedExitCode != exitCode) {
+    throw ProcessException(
+      executable.toFilePath(),
+      arguments,
+      "Full command string: '$commandString'.\n"
+      "Exit code: '$exitCode'.\n"
+      'For the output of the process check the logger output.',
+    );
+  }
+  return result;
+}
+
+/// Drop in replacement of [ProcessResult].
+class RunProcessResult {
+  final int pid;
+
+  final String command;
+
+  final int exitCode;
+
+  final String stderr;
+
+  final String stdout;
+
+  RunProcessResult({
+    required this.pid,
+    required this.command,
+    required this.exitCode,
+    required this.stderr,
+    required this.stdout,
+  });
+
+  @override
+  String toString() => '''command: $command
+exitCode: $exitCode
+stdout: $stdout
+stderr: $stderr''';
+}
diff --git a/pkgs/native_toolchain_c/lib/src/utils/sem_version.dart b/pkgs/native_toolchain_c/lib/src/utils/sem_version.dart
new file mode 100644
index 0000000..39f8342
--- /dev/null
+++ b/pkgs/native_toolchain_c/lib/src/utils/sem_version.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:pub_semver/pub_semver.dart';
+
+/// Reads a version out of a string.
+///
+/// If no semantic version is found, tries to read find a version number
+/// that doesn't follow semantic versioning. It will default [Version.minor]
+/// and [Version.patch] to `0` if the relaxed version doesn't contain them.
+Version? versionFromString(String containsVersion) {
+  final match = _semverRegex.firstMatch(containsVersion);
+  if (match != null) {
+    return Version(
+      int.parse(match.group(1)!),
+      int.parse(match.group(2)!),
+      int.parse(match.group(3)!),
+      pre: match.group(4),
+      build: match.group(5),
+    );
+  }
+
+  final relaxedMatch = _semverRegexReleaxed.firstMatch(containsVersion);
+  if (relaxedMatch != null) {
+    return Version(
+      int.parse(relaxedMatch.group(1)!),
+      int.parse(relaxedMatch.group(2) ?? '0'),
+      int.parse(relaxedMatch.group(3) ?? '0'),
+      pre: relaxedMatch.group(4),
+      build: relaxedMatch.group(5),
+    );
+  }
+
+  return null;
+}
+
+final _semverRegex = RegExp(
+    r'(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?');
+
+final _semverRegexReleaxed = RegExp(
+    r'(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:\.(0|[1-9]\d*))?(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?');
diff --git a/pkgs/native_toolchain_c/pubspec.yaml b/pkgs/native_toolchain_c/pubspec.yaml
new file mode 100644
index 0000000..886e745
--- /dev/null
+++ b/pkgs/native_toolchain_c/pubspec.yaml
@@ -0,0 +1,28 @@
+name: native_toolchain_c
+description: >-
+  A library to invoke the native C compiler installed on the host machine.
+version: 0.3.2
+repository: https://github.com/dart-lang/native/tree/main/pkgs/native_toolchain_c
+
+topics:
+  - compiler
+  - ffi
+  - interop
+  - native-assets
+  - native-toolchain
+
+environment:
+  sdk: '>=3.1.0 <4.0.0'
+
+dependencies:
+  cli_config: ^0.1.1
+  glob: ^2.1.1
+  logging: ^1.1.1
+  meta: ^1.9.1
+  native_assets_cli: ^0.3.0
+  pub_semver: ^2.1.3
+
+dev_dependencies:
+  collection: ^1.17.1
+  dart_flutter_team_lints: ^2.1.1
+  test: ^1.21.0
diff --git a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_build_failure_test.dart b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_build_failure_test.dart
new file mode 100644
index 0000000..f2a73c4
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_build_failure_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@OnPlatform({
+  'mac-os': Timeout.factor(2),
+  'windows': Timeout.factor(10),
+})
+library;
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  test('build failure', () async {
+    final tempUri = await tempDirForTest();
+    final addCOriginalUri =
+        packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
+    final addCUri = tempUri.resolve('add.c');
+    final addCOriginalContents =
+        await File.fromUri(addCOriginalUri).readAsString();
+    final addCBrokenContents = addCOriginalContents.replaceAll(
+        'int32_t a, int32_t b', 'int64_t blabla');
+    await File.fromUri(addCUri).writeAsString(addCBrokenContents);
+    const name = 'add';
+
+    final buildConfig = BuildConfig(
+      outDir: tempUri,
+      packageName: name,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.current,
+      targetOs: OS.current,
+      linkModePreference: LinkModePreference.dynamic,
+      buildMode: BuildMode.release,
+      cCompiler: CCompilerConfig(
+        cc: cc,
+        envScript: envScript,
+        envScriptArgs: envScriptArgs,
+      ),
+    );
+    final buildOutput = BuildOutput();
+
+    final cbuilder = CBuilder.library(
+      sources: [addCUri.toFilePath()],
+      name: name,
+      assetId: name,
+    );
+    expect(
+      () => cbuilder.run(
+        buildConfig: buildConfig,
+        buildOutput: buildOutput,
+        logger: logger,
+      ),
+      throwsException,
+    );
+  });
+}
diff --git a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_android_test.dart b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_android_test.dart
new file mode 100644
index 0000000..0f5081a
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_android_test.dart
@@ -0,0 +1,150 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+import 'package:native_toolchain_c/src/utils/run_process.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  const targets = [
+    Target.androidArm,
+    Target.androidArm64,
+    Target.androidIA32,
+    Target.androidX64,
+  ];
+
+  const readElfMachine = {
+    Target.androidArm: 'ARM',
+    Target.androidArm64: 'AArch64',
+    Target.androidIA32: 'Intel 80386',
+    Target.androidX64: 'Advanced Micro Devices X86-64',
+  };
+
+  const objdumpFileFormat = {
+    Target.androidArm: 'elf32-littlearm',
+    Target.androidArm64: 'elf64-littleaarch64',
+    Target.androidIA32: 'elf32-i386',
+    Target.androidX64: 'elf64-x86-64',
+  };
+
+  /// From https://docs.flutter.dev/reference/supported-platforms.
+  const flutterAndroidNdkVersionLowestBestEffort = 19;
+
+  /// From https://docs.flutter.dev/reference/supported-platforms.
+  const flutterAndroidNdkVersionLowestSupported = 21;
+
+  /// From https://docs.flutter.dev/reference/supported-platforms.
+  const flutterAndroidNdkVersionHighestSupported = 34;
+
+  for (final linkMode in LinkMode.values) {
+    for (final target in targets) {
+      for (final apiLevel in [
+        flutterAndroidNdkVersionLowestBestEffort,
+        flutterAndroidNdkVersionLowestSupported,
+        flutterAndroidNdkVersionHighestSupported,
+      ]) {
+        test('CBuilder $linkMode library $target minSdkVersion $apiLevel',
+            () async {
+          final tempUri = await tempDirForTest();
+          final libUri = await buildLib(
+            tempUri,
+            target,
+            apiLevel,
+            linkMode,
+          );
+          if (Platform.isLinux) {
+            final result = await runProcess(
+              executable: Uri.file('readelf'),
+              arguments: ['-h', libUri.path],
+              logger: logger,
+            );
+            expect(result.exitCode, 0);
+            final machine = result.stdout
+                .split('\n')
+                .firstWhere((e) => e.contains('Machine:'));
+            expect(machine, contains(readElfMachine[target]));
+          } else if (Platform.isMacOS) {
+            final result = await runProcess(
+              executable: Uri.file('objdump'),
+              arguments: ['-T', libUri.path],
+              logger: logger,
+            );
+            expect(result.exitCode, 0);
+            final machine = result.stdout
+                .split('\n')
+                .firstWhere((e) => e.contains('file format'));
+            expect(machine, contains(objdumpFileFormat[target]));
+          }
+        });
+      }
+    }
+  }
+
+  test('CBuilder API levels binary difference', () async {
+    const target = Target.androidArm64;
+    const linkMode = LinkMode.dynamic;
+    const apiLevel1 = flutterAndroidNdkVersionLowestSupported;
+    const apiLevel2 = flutterAndroidNdkVersionHighestSupported;
+    final tempUri = await tempDirForTest();
+    final out1Uri = tempUri.resolve('out1/');
+    final out2Uri = tempUri.resolve('out2/');
+    final out3Uri = tempUri.resolve('out3/');
+    await Directory.fromUri(out1Uri).create();
+    await Directory.fromUri(out2Uri).create();
+    await Directory.fromUri(out3Uri).create();
+    final lib1Uri = await buildLib(out1Uri, target, apiLevel1, linkMode);
+    final lib2Uri = await buildLib(out2Uri, target, apiLevel2, linkMode);
+    final lib3Uri = await buildLib(out3Uri, target, apiLevel2, linkMode);
+    final bytes1 = await File.fromUri(lib1Uri).readAsBytes();
+    final bytes2 = await File.fromUri(lib2Uri).readAsBytes();
+    final bytes3 = await File.fromUri(lib3Uri).readAsBytes();
+    // Different API levels should lead to a different binary.
+    expect(bytes1, isNot(bytes2));
+    // Identical API levels should lead to an identical binary.
+    expect(bytes2, bytes3);
+  });
+}
+
+Future<Uri> buildLib(
+  Uri tempUri,
+  Target target,
+  int androidNdkApi,
+  LinkMode linkMode,
+) async {
+  final addCUri = packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
+  const name = 'add';
+
+  final buildConfig = BuildConfig(
+    outDir: tempUri,
+    packageName: name,
+    packageRoot: tempUri,
+    targetArchitecture: target.architecture,
+    targetOs: target.os,
+    targetAndroidNdkApi: androidNdkApi,
+    buildMode: BuildMode.release,
+    linkModePreference: linkMode == LinkMode.dynamic
+        ? LinkModePreference.dynamic
+        : LinkModePreference.static,
+  );
+  final buildOutput = BuildOutput();
+
+  final cbuilder = CBuilder.library(
+    name: name,
+    assetId: name,
+    sources: [addCUri.toFilePath()],
+  );
+  await cbuilder.run(
+    buildConfig: buildConfig,
+    buildOutput: buildOutput,
+    logger: logger,
+  );
+
+  final libUri = tempUri.resolve(target.os.libraryFileName(name, linkMode));
+  return libUri;
+}
diff --git a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_ios_test.dart b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_ios_test.dart
new file mode 100644
index 0000000..586f7ff
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_ios_test.dart
@@ -0,0 +1,151 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('mac-os')
+@OnPlatform({
+  'mac-os': Timeout.factor(2),
+})
+library;
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+import 'package:native_toolchain_c/src/utils/run_process.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  if (!Platform.isMacOS) {
+    // Avoid needing status files on Dart SDK CI.
+    return;
+  }
+
+  const targets = [
+    Target.iOSArm64,
+    Target.iOSX64,
+  ];
+
+  // Dont include 'mach-o' or 'Mach-O', different spelling is used.
+  const objdumpFileFormat = {
+    Target.iOSArm64: 'arm64',
+    Target.iOSX64: '64-bit x86-64',
+  };
+
+  const name = 'add';
+
+  for (final linkMode in LinkMode.values) {
+    for (final targetIOSSdk in IOSSdk.values) {
+      for (final target in targets) {
+        if (target == Target.iOSX64 && targetIOSSdk == IOSSdk.iPhoneOs) {
+          continue;
+        }
+
+        final libName = target.os.libraryFileName(name, linkMode);
+        for (final installName in [
+          null,
+          if (linkMode == LinkMode.dynamic)
+            Uri.file('@executable_path/Frameworks/$libName'),
+        ]) {
+          test(
+              'CBuilder $linkMode library $targetIOSSdk $target'
+                      ' ${installName ?? ''}'
+                  .trim(), () async {
+            final tempUri = await tempDirForTest();
+            final addCUri =
+                packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
+            final buildConfig = BuildConfig(
+              outDir: tempUri,
+              packageName: name,
+              packageRoot: tempUri,
+              targetArchitecture: target.architecture,
+              targetOs: target.os,
+              buildMode: BuildMode.release,
+              linkModePreference: linkMode == LinkMode.dynamic
+                  ? LinkModePreference.dynamic
+                  : LinkModePreference.static,
+              targetIOSSdk: targetIOSSdk,
+            );
+            final buildOutput = BuildOutput();
+
+            final cbuilder = CBuilder.library(
+              name: name,
+              assetId: name,
+              sources: [addCUri.toFilePath()],
+              installName: installName,
+            );
+            await cbuilder.run(
+              buildConfig: buildConfig,
+              buildOutput: buildOutput,
+              logger: logger,
+            );
+
+            final libUri = tempUri.resolve(libName);
+            final objdumpResult = await runProcess(
+              executable: Uri.file('objdump'),
+              arguments: ['-t', libUri.path],
+              logger: logger,
+            );
+            expect(objdumpResult.exitCode, 0);
+            final machine = objdumpResult.stdout
+                .split('\n')
+                .firstWhere((e) => e.contains('file format'));
+            expect(machine, contains(objdumpFileFormat[target]));
+
+            final otoolResult = await runProcess(
+              executable: Uri.file('otool'),
+              arguments: ['-l', libUri.path],
+              logger: logger,
+            );
+            expect(otoolResult.exitCode, 0);
+            if (targetIOSSdk == IOSSdk.iPhoneOs || target == Target.iOSX64) {
+              // The x64 simulator behaves as device, presumably because the
+              // devices are never x64.
+              expect(otoolResult.stdout, contains('LC_VERSION_MIN_IPHONEOS'));
+              expect(otoolResult.stdout, isNot(contains('LC_BUILD_VERSION')));
+            } else {
+              expect(otoolResult.stdout,
+                  isNot(contains('LC_VERSION_MIN_IPHONEOS')));
+              expect(otoolResult.stdout, contains('LC_BUILD_VERSION'));
+              final platform = otoolResult.stdout
+                  .split('\n')
+                  .firstWhere((e) => e.contains('platform'));
+              const platformIosSimulator = 7;
+              expect(platform, contains(platformIosSimulator.toString()));
+            }
+
+            if (linkMode == LinkMode.dynamic) {
+              final libInstallName = await runOtoolInstallName(libUri, libName);
+              if (installName == null) {
+                // If no install path is passed, we have an absolute path.
+                final tempName = tempUri.pathSegments.lastWhere((e) => e != '');
+                final pathEnding =
+                    Uri.directory(tempName).resolve(libName).toFilePath();
+                expect(Uri.file(libInstallName).isAbsolute, true);
+                expect(libInstallName, contains(pathEnding));
+                final targetInstallName =
+                    '@executable_path/Frameworks/$libName';
+                await runProcess(
+                  executable: Uri.file('install_name_tool'),
+                  arguments: [
+                    '-id',
+                    targetInstallName,
+                    libUri.toFilePath(),
+                  ],
+                  logger: logger,
+                );
+                final libInstallName2 =
+                    await runOtoolInstallName(libUri, libName);
+                expect(libInstallName2, targetInstallName);
+              } else {
+                expect(libInstallName, installName.toFilePath());
+              }
+            }
+          });
+        }
+      }
+    }
+  }
+}
diff --git a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_linux_host_test.dart b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_linux_host_test.dart
new file mode 100644
index 0000000..8abe7a4
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_linux_host_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('linux')
+library;
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+import 'package:native_toolchain_c/src/utils/run_process.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  if (!Platform.isLinux) {
+    // Avoid needing status files on Dart SDK CI.
+    return;
+  }
+
+  const targets = [
+    Target.linuxArm,
+    Target.linuxArm64,
+    Target.linuxIA32,
+    Target.linuxX64,
+    Target.linuxRiscv64,
+  ];
+
+  const readElfMachine = {
+    Target.linuxArm: 'ARM',
+    Target.linuxArm64: 'AArch64',
+    Target.linuxIA32: 'Intel 80386',
+    Target.linuxX64: 'Advanced Micro Devices X86-64',
+    Target.linuxRiscv64: 'RISC-V',
+  };
+
+  for (final linkMode in LinkMode.values) {
+    for (final target in targets) {
+      test('CBuilder $linkMode library $target', () async {
+        final tempUri = await tempDirForTest();
+        final addCUri =
+            packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
+        const name = 'add';
+
+        final buildConfig = BuildConfig(
+          outDir: tempUri,
+          packageName: name,
+          packageRoot: tempUri,
+          targetArchitecture: target.architecture,
+          targetOs: target.os,
+          buildMode: BuildMode.release,
+          linkModePreference: linkMode == LinkMode.dynamic
+              ? LinkModePreference.dynamic
+              : LinkModePreference.static,
+        );
+        final buildOutput = BuildOutput();
+
+        final cbuilder = CBuilder.library(
+          name: name,
+          assetId: name,
+          sources: [addCUri.toFilePath()],
+        );
+        await cbuilder.run(
+          buildConfig: buildConfig,
+          buildOutput: buildOutput,
+          logger: logger,
+        );
+
+        final libUri =
+            tempUri.resolve(target.os.libraryFileName(name, linkMode));
+        final result = await runProcess(
+          executable: Uri.file('readelf'),
+          arguments: ['-h', libUri.path],
+          logger: logger,
+        );
+        expect(result.exitCode, 0);
+        final machine =
+            result.stdout.split('\n').firstWhere((e) => e.contains('Machine:'));
+        expect(machine, contains(readElfMachine[target]));
+        expect(result.exitCode, 0);
+      });
+    }
+  }
+}
diff --git a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_macos_host_test.dart b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_macos_host_test.dart
new file mode 100644
index 0000000..655ea25
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_macos_host_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('mac-os')
+@OnPlatform({
+  'mac-os': Timeout.factor(2),
+})
+library;
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+import 'package:native_toolchain_c/src/utils/run_process.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  if (!Platform.isMacOS) {
+    // Avoid needing status files on Dart SDK CI.
+    return;
+  }
+
+  const targets = [
+    Target.macOSArm64,
+    Target.macOSX64,
+  ];
+
+  // Dont include 'mach-o' or 'Mach-O', different spelling is used.
+  const objdumpFileFormat = {
+    Target.macOSArm64: 'arm64',
+    Target.macOSX64: '64-bit x86-64',
+  };
+
+  for (final linkMode in LinkMode.values) {
+    for (final target in targets) {
+      test('CBuilder $linkMode library $target', () async {
+        final tempUri = await tempDirForTest();
+        final addCUri =
+            packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
+        const name = 'add';
+
+        final buildConfig = BuildConfig(
+          outDir: tempUri,
+          packageName: name,
+          packageRoot: tempUri,
+          targetArchitecture: target.architecture,
+          targetOs: target.os,
+          buildMode: BuildMode.release,
+          linkModePreference: linkMode == LinkMode.dynamic
+              ? LinkModePreference.dynamic
+              : LinkModePreference.static,
+        );
+        final buildOutput = BuildOutput();
+
+        final cbuilder = CBuilder.library(
+          name: name,
+          assetId: name,
+          sources: [addCUri.toFilePath()],
+        );
+        await cbuilder.run(
+          buildConfig: buildConfig,
+          buildOutput: buildOutput,
+          logger: logger,
+        );
+
+        final libUri =
+            tempUri.resolve(target.os.libraryFileName(name, linkMode));
+        final result = await runProcess(
+          executable: Uri.file('objdump'),
+          arguments: ['-t', libUri.path],
+          logger: logger,
+        );
+        expect(result.exitCode, 0);
+        final machine = result.stdout
+            .split('\n')
+            .firstWhere((e) => e.contains('file format'));
+        expect(machine, contains(objdumpFileFormat[target]));
+      });
+    }
+  }
+}
diff --git a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_windows_host_test.dart b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_windows_host_test.dart
new file mode 100644
index 0000000..bf0e836
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_cross_windows_host_test.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('windows')
+@OnPlatform({
+  'windows': Timeout.factor(10),
+})
+library;
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+import 'package:native_toolchain_c/src/native_toolchain/msvc.dart';
+import 'package:native_toolchain_c/src/utils/run_process.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  if (!Platform.isWindows) {
+    // Avoid needing status files on Dart SDK CI.
+    return;
+  }
+
+  const targets = [
+    Target.windowsIA32,
+    Target.windowsX64,
+  ];
+
+  late Uri dumpbinUri;
+
+  setUp(() async {
+    dumpbinUri =
+        (await dumpbin.defaultResolver!.resolve(logger: logger)).first.uri;
+  });
+
+  const dumpbinMachine = {
+    Target.windowsIA32: 'x86',
+    Target.windowsX64: 'x64',
+  };
+
+  const dumpbinFileType = {
+    LinkMode.dynamic: 'DLL',
+    LinkMode.static: 'LIBRARY',
+  };
+
+  for (final linkMode in LinkMode.values) {
+    for (final target in targets) {
+      test('CBuilder $linkMode library $target', () async {
+        final tempUri = await tempDirForTest();
+        final addCUri =
+            packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
+        const name = 'add';
+
+        final buildConfig = BuildConfig(
+          outDir: tempUri,
+          packageName: name,
+          packageRoot: tempUri,
+          targetOs: target.os,
+          targetArchitecture: target.architecture,
+          buildMode: BuildMode.release,
+          linkModePreference: linkMode == LinkMode.dynamic
+              ? LinkModePreference.dynamic
+              : LinkModePreference.static,
+        );
+        final buildOutput = BuildOutput();
+
+        final cbuilder = CBuilder.library(
+          name: name,
+          assetId: name,
+          sources: [addCUri.toFilePath()],
+        );
+        await cbuilder.run(
+          buildConfig: buildConfig,
+          buildOutput: buildOutput,
+          logger: logger,
+        );
+
+        final libUri =
+            tempUri.resolve(target.os.libraryFileName(name, linkMode));
+        expect(await File.fromUri(libUri).exists(), true);
+        final result = await runProcess(
+          executable: dumpbinUri,
+          arguments: ['/HEADERS', libUri.toFilePath()],
+          logger: logger,
+        );
+        expect(result.exitCode, 0);
+        final machine =
+            result.stdout.split('\n').firstWhere((e) => e.contains('machine'));
+        expect(machine, contains(dumpbinMachine[target]));
+        final fileType = result.stdout
+            .split('\n')
+            .firstWhere((e) => e.contains('File Type'));
+        expect(fileType, contains(dumpbinFileType[linkMode]));
+      });
+    }
+  }
+}
diff --git a/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart
new file mode 100644
index 0000000..53b5a96
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/cbuilder_test.dart
@@ -0,0 +1,593 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@OnPlatform({
+  'mac-os': Timeout.factor(2),
+  'windows': Timeout.factor(10),
+})
+library;
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+import 'package:native_toolchain_c/src/utils/run_process.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  test('Langauge.toString', () {
+    expect(Language.c.toString(), 'c');
+    expect(Language.cpp.toString(), 'c++');
+  });
+
+  for (final pic in [null, true, false]) {
+    final picTag =
+        switch (pic) { null => 'auto_pic', true => 'pic', false => 'no_pic' };
+
+    for (final buildMode in BuildMode.values) {
+      final suffix = testSuffix([buildMode, picTag]);
+
+      test('CBuilder executable$suffix', () async {
+        final tempUri = await tempDirForTest();
+        final helloWorldCUri = packageUri
+            .resolve('test/cbuilder/testfiles/hello_world/src/hello_world.c');
+        if (!await File.fromUri(helloWorldCUri).exists()) {
+          throw Exception('Run the test from the root directory.');
+        }
+        const name = 'hello_world';
+
+        final logMessages = <String>[];
+        final logger = createCapturingLogger(logMessages);
+
+        final buildConfig = BuildConfig(
+          outDir: tempUri,
+          packageName: name,
+          packageRoot: tempUri,
+          targetArchitecture: Architecture.current,
+          targetOs: OS.current,
+          buildMode: buildMode,
+          // Ignored by executables.
+          linkModePreference: LinkModePreference.dynamic,
+          cCompiler: CCompilerConfig(
+            cc: cc,
+            envScript: envScript,
+            envScriptArgs: envScriptArgs,
+          ),
+        );
+        final buildOutput = BuildOutput();
+        final cbuilder = CBuilder.executable(
+          name: name,
+          sources: [helloWorldCUri.toFilePath()],
+          pie: pic,
+        );
+        await cbuilder.run(
+          buildConfig: buildConfig,
+          buildOutput: buildOutput,
+          logger: logger,
+        );
+
+        final executableUri =
+            tempUri.resolve(Target.current.os.executableFileName(name));
+        expect(await File.fromUri(executableUri).exists(), true);
+        final result = await runProcess(
+          executable: executableUri,
+          logger: logger,
+        );
+        expect(result.exitCode, 0);
+        if (buildMode == BuildMode.debug) {
+          expect(result.stdout.trim(), startsWith('Running in debug mode.'));
+        }
+        expect(result.stdout.trim(), endsWith('Hello world.'));
+
+        final compilerInvocation = logMessages.singleWhere(
+          (message) => message.contains(helloWorldCUri.toFilePath()),
+        );
+
+        switch ((buildConfig.targetOs, pic)) {
+          case (OS.windows, _) || (_, null):
+            expect(compilerInvocation, isNot(contains('-fPIC')));
+            expect(compilerInvocation, isNot(contains('-fPIE')));
+            expect(compilerInvocation, isNot(contains('-fno-PIC')));
+            expect(compilerInvocation, isNot(contains('-fno-PIE')));
+          case (_, true):
+            expect(compilerInvocation, contains('-fPIE'));
+          case (_, false):
+            expect(compilerInvocation, contains('-fno-PIC'));
+            expect(compilerInvocation, contains('-fno-PIE'));
+        }
+      });
+    }
+
+    for (final dryRun in [true, false]) {
+      final suffix = testSuffix([if (dryRun) 'dry_run', picTag]);
+
+      test('CBuilder dylib$suffix', () async {
+        final tempUri = await tempDirForTest();
+        final addCUri =
+            packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
+        const name = 'add';
+
+        final logMessages = <String>[];
+        final logger = createCapturingLogger(logMessages);
+
+        final buildConfig = dryRun
+            ? BuildConfig.dryRun(
+                outDir: tempUri,
+                packageName: name,
+                packageRoot: tempUri,
+                targetOs: OS.current,
+                linkModePreference: LinkModePreference.dynamic,
+              )
+            : BuildConfig(
+                outDir: tempUri,
+                packageName: name,
+                packageRoot: tempUri,
+                targetArchitecture: Architecture.current,
+                targetOs: OS.current,
+                buildMode: BuildMode.release,
+                linkModePreference: LinkModePreference.dynamic,
+                cCompiler: CCompilerConfig(
+                  cc: cc,
+                  envScript: envScript,
+                  envScriptArgs: envScriptArgs,
+                ),
+              );
+        final buildOutput = BuildOutput();
+
+        final cbuilder = CBuilder.library(
+          sources: [addCUri.toFilePath()],
+          name: name,
+          assetId: name,
+          pic: pic,
+        );
+        await cbuilder.run(
+          buildConfig: buildConfig,
+          buildOutput: buildOutput,
+          logger: logger,
+        );
+
+        final dylibUri = tempUri.resolve(Target.current.os.dylibFileName(name));
+        expect(await File.fromUri(dylibUri).exists(), !dryRun);
+        if (!dryRun) {
+          final dylib = openDynamicLibraryForTest(dylibUri.toFilePath());
+          final add = dylib.lookupFunction<Int32 Function(Int32, Int32),
+              int Function(int, int)>('add');
+          expect(add(1, 2), 3);
+
+          final compilerInvocation = logMessages.singleWhere(
+            (message) => message.contains(addCUri.toFilePath()),
+          );
+          switch ((buildConfig.targetOs, pic)) {
+            case (OS.windows, _) || (_, null):
+              expect(compilerInvocation, isNot(contains('-fPIC')));
+              expect(compilerInvocation, isNot(contains('-fPIE')));
+              expect(compilerInvocation, isNot(contains('-fno-PIC')));
+              expect(compilerInvocation, isNot(contains('-fno-PIE')));
+            case (_, true):
+              expect(compilerInvocation, contains('-fPIC'));
+            case (_, false):
+              expect(compilerInvocation, contains('-fno-PIC'));
+              expect(compilerInvocation, contains('-fno-PIE'));
+          }
+        }
+      });
+    }
+  }
+
+  for (final buildMode in BuildMode.values) {
+    for (final enabled in [true, false]) {
+      final suffix = testSuffix([buildMode, enabled ? 'enabled' : 'disabled']);
+
+      test(
+        'CBuilder build mode defines$suffix',
+        () => testDefines(
+          buildMode: buildMode,
+          buildModeDefine: enabled,
+          ndebugDefine: enabled,
+        ),
+      );
+    }
+  }
+
+  for (final value in [true, false]) {
+    final suffix = testSuffix([value ? 'with_value' : 'without_value']);
+
+    test(
+      'CBuilder define$suffix',
+      () => testDefines(customDefineWithValue: value),
+    );
+  }
+
+  test('CBuilder flags', () async {
+    final tempUri = await tempDirForTest();
+    final definesCUri =
+        packageUri.resolve('test/cbuilder/testfiles/defines/src/defines.c');
+    if (!await File.fromUri(definesCUri).exists()) {
+      throw Exception('Run the test from the root directory.');
+    }
+    const name = 'defines';
+
+    final logMessages = <String>[];
+    final logger = createCapturingLogger(logMessages);
+
+    final buildConfig = BuildConfig(
+      outDir: tempUri,
+      packageName: name,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.current,
+      targetOs: OS.current,
+      buildMode: BuildMode.release,
+      // Ignored by executables.
+      linkModePreference: LinkModePreference.dynamic,
+      cCompiler: CCompilerConfig(
+        cc: cc,
+        envScript: envScript,
+        envScriptArgs: envScriptArgs,
+      ),
+    );
+    final buildOutput = BuildOutput();
+
+    final flag = switch (buildConfig.targetOs) {
+      OS.windows => '/DFOO=USER_FLAG',
+      _ => '-DFOO=USER_FLAG',
+    };
+
+    final cbuilder = CBuilder.executable(
+      name: name,
+      sources: [definesCUri.toFilePath()],
+      flags: [flag],
+    );
+    await cbuilder.run(
+      buildConfig: buildConfig,
+      buildOutput: buildOutput,
+      logger: logger,
+    );
+
+    final executableUri =
+        tempUri.resolve(Target.current.os.executableFileName(name));
+    expect(await File.fromUri(executableUri).exists(), true);
+    final result = await runProcess(
+      executable: executableUri,
+      logger: logger,
+    );
+    expect(result.exitCode, 0);
+    expect(result.stdout, contains('Macro FOO is defined: USER_FLAG'));
+
+    final compilerInvocation = logMessages.singleWhere(
+      (message) => message.contains(definesCUri.toFilePath()),
+    );
+    expect(compilerInvocation, contains(flag));
+  });
+
+  test('CBuilder includes', () async {
+    final tempUri = await tempDirForTest();
+    final includeDirectoryUri =
+        packageUri.resolve('test/cbuilder/testfiles/includes/include');
+    final includesHUri = packageUri
+        .resolve('test/cbuilder/testfiles/includes/include/includes.h');
+    final includesCUri =
+        packageUri.resolve('test/cbuilder/testfiles/includes/src/includes.c');
+    const name = 'includes';
+
+    final buildConfig = BuildConfig(
+      outDir: tempUri,
+      packageName: name,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.current,
+      targetOs: OS.current,
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.dynamic,
+      cCompiler: CCompilerConfig(
+        cc: cc,
+        envScript: envScript,
+        envScriptArgs: envScriptArgs,
+      ),
+    );
+    final buildOutput = BuildOutput();
+
+    final cbuilder = CBuilder.library(
+      name: name,
+      assetId: name,
+      includes: [includeDirectoryUri.toFilePath()],
+      sources: [includesCUri.toFilePath()],
+    );
+    await cbuilder.run(
+      buildConfig: buildConfig,
+      buildOutput: buildOutput,
+      logger: logger,
+    );
+
+    expect(buildOutput.dependencies.dependencies, contains(includesHUri));
+
+    final dylibUri = tempUri.resolve(Target.current.os.dylibFileName(name));
+    final dylib = openDynamicLibraryForTest(dylibUri.toFilePath());
+    final x = dylib.lookup<Int>('x');
+    expect(x.value, 42);
+  });
+
+  test('CBuilder std', () async {
+    final tempUri = await tempDirForTest();
+    final addCUri = packageUri.resolve('test/cbuilder/testfiles/add/src/add.c');
+    const name = 'add';
+    const std = 'c99';
+
+    final logMessages = <String>[];
+    final logger = createCapturingLogger(logMessages);
+
+    final buildConfig = BuildConfig(
+      outDir: tempUri,
+      packageName: name,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.current,
+      targetOs: OS.current,
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.dynamic,
+      cCompiler: CCompilerConfig(
+        cc: cc,
+        envScript: envScript,
+        envScriptArgs: envScriptArgs,
+      ),
+    );
+    final buildOutput = BuildOutput();
+
+    final stdFlag = switch (buildConfig.targetOs) {
+      OS.windows => '/std:$std',
+      _ => '-std=$std',
+    };
+
+    final cbuilder = CBuilder.library(
+      sources: [addCUri.toFilePath()],
+      name: name,
+      assetId: name,
+      std: std,
+    );
+    await cbuilder.run(
+      buildConfig: buildConfig,
+      buildOutput: buildOutput,
+      logger: logger,
+    );
+
+    final dylibUri = tempUri.resolve(Target.current.os.dylibFileName(name));
+
+    final dylib = openDynamicLibraryForTest(dylibUri.toFilePath());
+    final add = dylib.lookupFunction<Int32 Function(Int32, Int32),
+        int Function(int, int)>('add');
+    expect(add(1, 2), 3);
+
+    final compilerInvocation = logMessages.singleWhere(
+      (message) => message.contains(addCUri.toFilePath()),
+    );
+    expect(compilerInvocation, contains(stdFlag));
+  });
+
+  test('CBuilder compile c++', () async {
+    final tempUri = await tempDirForTest();
+    final helloWorldCppUri = packageUri.resolve(
+        'test/cbuilder/testfiles/hello_world_cpp/src/hello_world_cpp.cc');
+    if (!await File.fromUri(helloWorldCppUri).exists()) {
+      throw Exception('Run the test from the root directory.');
+    }
+    const name = 'hello_world_cpp';
+
+    final logMessages = <String>[];
+    final logger = createCapturingLogger(logMessages);
+
+    final buildConfig = BuildConfig(
+      buildMode: BuildMode.release,
+      outDir: tempUri,
+      packageName: name,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.current,
+      targetOs: OS.current,
+      // Ignored by executables.
+      linkModePreference: LinkModePreference.dynamic,
+      cCompiler: CCompilerConfig(
+        cc: cc,
+        envScript: envScript,
+        envScriptArgs: envScriptArgs,
+      ),
+    );
+    final buildOutput = BuildOutput();
+
+    final defaultStdLibLinkFlag = switch (buildConfig.targetOs) {
+      OS.windows => null,
+      OS.linux => '-l stdc++',
+      OS.macOS => '-l c++',
+      _ => throw UnimplementedError(),
+    };
+
+    final cbuilder = CBuilder.executable(
+      name: name,
+      sources: [helloWorldCppUri.toFilePath()],
+      language: Language.cpp,
+    );
+    await cbuilder.run(
+      buildConfig: buildConfig,
+      buildOutput: buildOutput,
+      logger: logger,
+    );
+
+    final executableUri =
+        tempUri.resolve(Target.current.os.executableFileName(name));
+    expect(await File.fromUri(executableUri).exists(), true);
+    final result = await runProcess(
+      executable: executableUri,
+      logger: logger,
+    );
+    expect(result.exitCode, 0);
+    expect(result.stdout.trim(), endsWith('Hello world.'));
+
+    if (defaultStdLibLinkFlag != null) {
+      final compilerInvocation = logMessages.singleWhere(
+        (message) => message.contains(helloWorldCppUri.toFilePath()),
+      );
+      expect(compilerInvocation, contains(defaultStdLibLinkFlag));
+    }
+  });
+
+  test('CBuilder cppLinkStdLib', () async {
+    final tempUri = await tempDirForTest();
+    final helloWorldCppUri = packageUri.resolve(
+        'test/cbuilder/testfiles/hello_world_cpp/src/hello_world_cpp.cc');
+    if (!await File.fromUri(helloWorldCppUri).exists()) {
+      throw Exception('Run the test from the root directory.');
+    }
+    const name = 'hello_world_cpp';
+
+    final logMessages = <String>[];
+    final logger = createCapturingLogger(logMessages);
+
+    final buildConfig = BuildConfig(
+      buildMode: BuildMode.release,
+      outDir: tempUri,
+      packageName: name,
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.current,
+      targetOs: OS.current,
+      // Ignored by executables.
+      linkModePreference: LinkModePreference.dynamic,
+      cCompiler: CCompilerConfig(
+        cc: cc,
+        envScript: envScript,
+        envScriptArgs: envScriptArgs,
+      ),
+    );
+    final buildOutput = BuildOutput();
+    final cbuilder = CBuilder.executable(
+      name: name,
+      sources: [helloWorldCppUri.toFilePath()],
+      language: Language.cpp,
+      cppLinkStdLib: 'stdc++',
+    );
+
+    if (buildConfig.targetOs == OS.windows) {
+      await expectLater(
+        () => cbuilder.run(
+          buildConfig: buildConfig,
+          buildOutput: buildOutput,
+          logger: logger,
+        ),
+        throwsArgumentError,
+      );
+    } else {
+      await cbuilder.run(
+        buildConfig: buildConfig,
+        buildOutput: buildOutput,
+        logger: logger,
+      );
+
+      final executableUri =
+          tempUri.resolve(Target.current.os.executableFileName(name));
+      expect(await File.fromUri(executableUri).exists(), true);
+      final result = await runProcess(
+        executable: executableUri,
+        logger: logger,
+      );
+      expect(result.exitCode, 0);
+      expect(result.stdout.trim(), endsWith('Hello world.'));
+
+      final compilerInvocation = logMessages.singleWhere(
+        (message) => message.contains(helloWorldCppUri.toFilePath()),
+      );
+      expect(compilerInvocation, contains('-l stdc++'));
+    }
+  });
+}
+
+Future<void> testDefines({
+  BuildMode buildMode = BuildMode.debug,
+  bool buildModeDefine = false,
+  bool ndebugDefine = false,
+  bool? customDefineWithValue,
+}) async {
+  final tempUri = await tempDirForTest();
+  final definesCUri =
+      packageUri.resolve('test/cbuilder/testfiles/defines/src/defines.c');
+  if (!await File.fromUri(definesCUri).exists()) {
+    throw Exception('Run the test from the root directory.');
+  }
+  const name = 'defines';
+
+  final buildConfig = BuildConfig(
+    outDir: tempUri,
+    packageName: name,
+    packageRoot: tempUri,
+    targetArchitecture: Architecture.current,
+    targetOs: OS.current,
+    buildMode: buildMode,
+    // Ignored by executables.
+    linkModePreference: LinkModePreference.dynamic,
+    cCompiler: CCompilerConfig(
+      cc: cc,
+      envScript: envScript,
+      envScriptArgs: envScriptArgs,
+    ),
+  );
+  final buildOutput = BuildOutput();
+  final cbuilder = CBuilder.executable(
+    name: name,
+    sources: [definesCUri.toFilePath()],
+    defines: {
+      if (customDefineWithValue != null)
+        'FOO': customDefineWithValue ? 'BAR' : null,
+    },
+    buildModeDefine: buildModeDefine,
+    ndebugDefine: ndebugDefine,
+  );
+  await cbuilder.run(
+    buildConfig: buildConfig,
+    buildOutput: buildOutput,
+    logger: logger,
+  );
+
+  final executableUri =
+      tempUri.resolve(Target.current.os.executableFileName(name));
+  expect(await File.fromUri(executableUri).exists(), true);
+  final result = await runProcess(
+    executable: executableUri,
+    logger: logger,
+  );
+  expect(result.exitCode, 0);
+
+  if (buildModeDefine) {
+    expect(
+      result.stdout,
+      contains('Macro ${buildMode.name.toUpperCase()} is defined: 1'),
+    );
+  } else {
+    expect(
+      result.stdout,
+      contains('Macro ${buildMode.name.toUpperCase()} is undefined.'),
+    );
+  }
+
+  if (ndebugDefine && buildMode != BuildMode.debug) {
+    expect(
+      result.stdout,
+      contains('Macro NDEBUG is defined: 1'),
+    );
+  } else {
+    expect(
+      result.stdout,
+      contains('Macro NDEBUG is undefined.'),
+    );
+  }
+
+  if (customDefineWithValue != null) {
+    expect(
+      result.stdout,
+      contains(
+        'Macro FOO is defined: ${customDefineWithValue ? 'BAR' : '1'}',
+      ),
+    );
+  } else {
+    expect(
+      result.stdout,
+      contains('Macro FOO is undefined.'),
+    );
+  }
+}
diff --git a/pkgs/native_toolchain_c/test/cbuilder/compiler_resolver_test.dart b/pkgs/native_toolchain_c/test/cbuilder/compiler_resolver_test.dart
new file mode 100644
index 0000000..b77c231
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/compiler_resolver_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@OnPlatform({
+  'mac-os': Timeout.factor(2),
+  'windows': Timeout.factor(10),
+})
+library;
+
+import 'package:collection/collection.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/src/cbuilder/compiler_resolver.dart';
+import 'package:native_toolchain_c/src/native_toolchain/apple_clang.dart';
+import 'package:native_toolchain_c/src/native_toolchain/clang.dart';
+import 'package:native_toolchain_c/src/native_toolchain/msvc.dart';
+import 'package:native_toolchain_c/src/tool/tool_error.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  test('Config provided compiler', () async {
+    final tempUri = await tempDirForTest();
+    final ar = [
+      ...await appleAr.defaultResolver!.resolve(logger: logger),
+      ...await lib.defaultResolver!.resolve(logger: logger),
+      ...await llvmAr.defaultResolver!.resolve(logger: logger),
+    ].first.uri;
+    final cc = [
+      ...await appleClang.defaultResolver!.resolve(logger: logger),
+      ...await cl.defaultResolver!.resolve(logger: logger),
+      ...await clang.defaultResolver!.resolve(logger: logger),
+    ].first.uri;
+    final ld = [
+      ...await appleLd.defaultResolver!.resolve(logger: logger),
+      ...await link.defaultResolver!.resolve(logger: logger),
+      ...await lld.defaultResolver!.resolve(logger: logger),
+    ].first.uri;
+    final envScript = [
+      ...await vcvars64.defaultResolver!.resolve(logger: logger)
+    ].firstOrNull?.uri;
+    final buildConfig = BuildConfig(
+      outDir: tempUri,
+      packageName: 'dummy',
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.current,
+      targetOs: OS.current,
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.dynamic,
+      cCompiler: CCompilerConfig(
+        ar: ar,
+        cc: cc,
+        ld: ld,
+        envScript: envScript,
+      ),
+    );
+    final resolver = CompilerResolver(buildConfig: buildConfig, logger: logger);
+    final compiler = await resolver.resolveCompiler();
+    final archiver = await resolver.resolveArchiver();
+    expect(compiler.uri, buildConfig.cCompiler.cc);
+    expect(archiver.uri, buildConfig.cCompiler.ar);
+  });
+
+  test('No compiler found', () async {
+    final tempUri = await tempDirForTest();
+    final buildConfig = BuildConfig(
+      outDir: tempUri,
+      packageName: 'dummy',
+      packageRoot: tempUri,
+      targetArchitecture: Architecture.arm64,
+      targetOs: OS.windows,
+      buildMode: BuildMode.release,
+      linkModePreference: LinkModePreference.dynamic,
+    );
+    final resolver = CompilerResolver(
+      buildConfig: buildConfig,
+      logger: logger,
+      host: Target.androidArm64, // This is never a host.
+    );
+    expect(resolver.resolveCompiler, throwsA(isA<ToolError>()));
+    expect(resolver.resolveArchiver, throwsA(isA<ToolError>()));
+  });
+}
diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.c
new file mode 100644
index 0000000..6a16cca
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/add/src/add.c
@@ -0,0 +1,22 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdint.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#if _WIN32
+#define FFI_EXPORT __declspec(dllexport)
+#else
+#define FFI_EXPORT
+#endif
+
+FFI_EXPORT int32_t add(int32_t a, int32_t b) {
+#ifdef DEBUG
+  printf("Adding %i and %i.\n", a, b);
+#endif
+  return a + b;
+}
diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/defines/src/defines.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/defines/src/defines.c
new file mode 100644
index 0000000..7bb554b
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/defines/src/defines.c
@@ -0,0 +1,38 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdio.h>
+
+#define STRINGIFY(X) #X
+#define MACRO_IS_UNDEFINED(name) printf("Macro " #name " is undefined.\n");
+#define MACRO_IS_DEFINED(name)                                                 \
+  printf("Macro " #name " is defined: " STRINGIFY(name) "\n");
+
+int main() {
+#ifdef DEBUG
+  MACRO_IS_DEFINED(DEBUG);
+#else
+  MACRO_IS_UNDEFINED(DEBUG);
+#endif
+
+#ifdef RELEASE
+  MACRO_IS_DEFINED(RELEASE);
+#else
+  MACRO_IS_UNDEFINED(RELEASE);
+#endif
+
+#ifdef NDEBUG
+  MACRO_IS_DEFINED(NDEBUG);
+#else
+  MACRO_IS_UNDEFINED(NDEBUG);
+#endif
+
+#ifdef FOO
+  MACRO_IS_DEFINED(FOO);
+#else
+  MACRO_IS_UNDEFINED(FOO);
+#endif
+
+  return 0;
+}
diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/hello_world/src/hello_world.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/hello_world/src/hello_world.c
new file mode 100644
index 0000000..2d42059
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/hello_world/src/hello_world.c
@@ -0,0 +1,13 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdio.h>
+
+int main() {
+#ifdef DEBUG
+  printf("Running in debug mode.\n");
+#endif
+  printf("Hello world.\n");
+  return 0;
+}
diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/hello_world_cpp/src/hello_world_cpp.cc b/pkgs/native_toolchain_c/test/cbuilder/testfiles/hello_world_cpp/src/hello_world_cpp.cc
new file mode 100644
index 0000000..d883a32
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/hello_world_cpp/src/hello_world_cpp.cc
@@ -0,0 +1,14 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <iostream>
+
+int main() {
+#ifdef DEBUG
+  std::cout << "Running in debug mode." << std::endl;
+#endif
+  std::cout << "Hello world." << std::endl;
+  return 0;
+}
+
diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/includes/include/includes.h b/pkgs/native_toolchain_c/test/cbuilder/testfiles/includes/include/includes.h
new file mode 100644
index 0000000..c2f78a8
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/includes/include/includes.h
@@ -0,0 +1,12 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#if _WIN32
+#define FFI_EXPORT __declspec(dllexport)
+#else
+#define FFI_EXPORT
+#endif
+
+FFI_EXPORT int x = 42;
+
diff --git a/pkgs/native_toolchain_c/test/cbuilder/testfiles/includes/src/includes.c b/pkgs/native_toolchain_c/test/cbuilder/testfiles/includes/src/includes.c
new file mode 100644
index 0000000..851907f
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/cbuilder/testfiles/includes/src/includes.c
@@ -0,0 +1,6 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "includes.h"
+
diff --git a/pkgs/native_toolchain_c/test/helpers.dart b/pkgs/native_toolchain_c/test/helpers.dart
new file mode 100644
index 0000000..abb157b
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/helpers.dart
@@ -0,0 +1,182 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:logging/logging.dart';
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/src/native_toolchain/apple_clang.dart';
+import 'package:native_toolchain_c/src/utils/run_process.dart';
+import 'package:test/test.dart';
+
+/// Returns a suffix for a test that is parameterized.
+///
+/// [tags] represent the current configuration of the test. Each element
+/// is converted to a string by calling [Object.toString].
+///
+/// ## Example
+///
+/// The instances of the test below will have the following descriptions:
+///
+/// - `My test`
+/// - `My test (dry_run)`
+///
+/// ```dart
+/// void main() {
+///   for (final dryRun in [true, false]) {
+///     final suffix = testSuffix([if (dryRun) 'dry_run']);
+///
+///     test('My test$suffix', () {});
+///   }
+/// }
+/// ```
+String testSuffix(List<Object> tags) => switch (tags) {
+      [] => '',
+      _ => ' (${tags.join(', ')})',
+    };
+
+const keepTempKey = 'KEEP_TEMPORARY_DIRECTORIES';
+
+Future<Uri> tempDirForTest({String? prefix, bool keepTemp = false}) async {
+  final tempDir = await Directory.systemTemp.createTemp(prefix);
+  // Deal with Windows temp folder aliases.
+  final tempUri =
+      Directory(await tempDir.resolveSymbolicLinks()).uri.normalizePath();
+  if ((!Platform.environment.containsKey(keepTempKey) ||
+          Platform.environment[keepTempKey]!.isEmpty) &&
+      !keepTemp) {
+    addTearDown(() => tempDir.delete(recursive: true));
+  }
+  return tempUri;
+}
+
+/// Logger that outputs the full trace when a test fails.
+Logger get logger => _logger ??= () {
+      // A new logger is lazily created for each test so that the messages
+      // captured by printOnFailure are scoped to the correct test.
+      addTearDown(() => _logger = null);
+      return _createTestLogger();
+    }();
+
+Logger? _logger;
+
+Logger createCapturingLogger(List<String> capturedMessages) =>
+    _createTestLogger(capturedMessages: capturedMessages);
+
+Logger _createTestLogger({List<String>? capturedMessages}) =>
+    Logger.detached('')
+      ..level = Level.ALL
+      ..onRecord.listen((record) {
+        printOnFailure(
+            '${record.level.name}: ${record.time}: ${record.message}');
+        capturedMessages?.add(record.message);
+      });
+
+/// Test files are run in a variety of ways, find this package root in all.
+///
+/// Test files can be run from source from any working directory. The Dart SDK
+/// `tools/test.py` runs them from the root of the SDK for example.
+///
+/// Test files can be run from dill from the root of package. `package:test`
+/// does this.
+///
+/// https://github.com/dart-lang/test/issues/110
+Uri findPackageRoot(String packageName) {
+  final script = Platform.script;
+  final fileName = script.name;
+  if (fileName.endsWith('_test.dart')) {
+    // We're likely running from source.
+    var directory = script.resolve('.');
+    while (true) {
+      final dirName = directory.name;
+      if (dirName == packageName) {
+        return directory;
+      }
+      final parent = directory.resolve('..');
+      if (parent == directory) break;
+      directory = parent;
+    }
+  } else if (fileName.endsWith('.dill')) {
+    final cwd = Directory.current.uri;
+    final dirName = cwd.name;
+    if (dirName == packageName) {
+      return cwd;
+    }
+  }
+  throw StateError("Could not find package root for package '$packageName'. "
+      'Tried finding the package root via Platform.script '
+      "'${Platform.script.toFilePath()}' and Directory.current "
+      "'${Directory.current.uri.toFilePath()}'.");
+}
+
+Uri packageUri = findPackageRoot('native_toolchain_c');
+
+extension on Uri {
+  String get name => pathSegments.where((e) => e != '').last;
+}
+
+String unparseKey(String key) => key.replaceAll('.', '__').toUpperCase();
+
+/// Archiver provided by the environment.
+final Uri? ar = Platform
+    .environment[unparseKey(CCompilerConfig.arConfigKeyFull)]
+    ?.asFileUri();
+
+/// Compiler provided by the environment.
+final Uri? cc = Platform
+    .environment[unparseKey(CCompilerConfig.ccConfigKeyFull)]
+    ?.asFileUri();
+
+/// Linker provided by the environment.
+final Uri? ld = Platform
+    .environment[unparseKey(CCompilerConfig.ldConfigKeyFull)]
+    ?.asFileUri();
+
+/// Path to script that sets environment variables for [cc], [ld], and [ar].
+///
+/// Provided by environment.
+final Uri? envScript = Platform
+    .environment[unparseKey(CCompilerConfig.envScriptConfigKeyFull)]
+    ?.asFileUri();
+
+/// Arguments for [envScript] provided by environment.
+final List<String>? envScriptArgs = Platform
+    .environment[unparseKey(CCompilerConfig.envScriptArgsConfigKeyFull)]
+    ?.split(' ');
+
+extension on String {
+  Uri asFileUri() => Uri.file(this);
+}
+
+/// Looks up the install name of a dynamic library at [libraryUri].
+///
+/// Because `otool` output multiple names, [libraryName] as search parameter.
+Future<String> runOtoolInstallName(Uri libraryUri, String libraryName) async {
+  final otoolUri =
+      (await otool.defaultResolver!.resolve(logger: logger)).first.uri;
+  final otoolResult = await runProcess(
+    executable: otoolUri,
+    arguments: ['-l', libraryUri.path],
+    logger: logger,
+  );
+  expect(otoolResult.exitCode, 0);
+  // Leading space on purpose to differentiate from other types of names.
+  const installNameName = ' name ';
+  final installName = otoolResult.stdout
+      .split('\n')
+      .firstWhere((e) => e.contains(installNameName) && e.contains(libraryName))
+      .trim()
+      .split(' ')[1];
+  return installName;
+}
+
+/// Opens the [DynamicLibrary] at [path] and register a tear down hook to close
+/// it when the current test is done.
+DynamicLibrary openDynamicLibraryForTest(String path) {
+  final library = DynamicLibrary.open(path);
+  addTearDown(library.close);
+  return library;
+}
diff --git a/pkgs/native_toolchain_c/test/native_toolchain/apple_clang_test.dart b/pkgs/native_toolchain_c/test/native_toolchain/apple_clang_test.dart
new file mode 100644
index 0000000..14829cb
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/native_toolchain/apple_clang_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('mac-os')
+@OnPlatform({
+  'mac-os': Timeout.factor(2),
+})
+library;
+
+import 'dart:io';
+
+import 'package:native_toolchain_c/src/native_toolchain/apple_clang.dart';
+import 'package:native_toolchain_c/src/tool/tool_requirement.dart';
+import 'package:pub_semver/pub_semver.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  if (!Platform.isMacOS) {
+    // Avoid needing status files on Dart SDK CI.
+    return;
+  }
+
+  test('smoke test', () async {
+    final requirement = ToolRequirement(appleClang,
+        minimumVersion: Version(12, 0, 0, pre: '0'));
+    final resolved = await appleClang.defaultResolver!.resolve(logger: logger);
+    expect(resolved.isNotEmpty, true);
+    final satisfied = requirement.satisfy(resolved);
+    expect(satisfied?.length, 1);
+  });
+
+  test('ar test', () async {
+    final requirement = ToolRequirement(appleAr);
+    final resolved = await appleAr.defaultResolver!.resolve(logger: logger);
+    expect(resolved.isNotEmpty, true);
+    final satisfied = requirement.satisfy(resolved);
+    expect(satisfied?.length, 1);
+  });
+
+  test('ld test', () async {
+    final requirement = ToolRequirement(appleLd);
+    final resolved = await appleLd.defaultResolver!.resolve(logger: logger);
+    expect(resolved.isNotEmpty, true);
+    final satisfied = requirement.satisfy(resolved);
+    expect(satisfied?.length, 1);
+  });
+
+  test('otool test', () async {
+    final requirement = ToolRequirement(otool);
+    final resolved = await otool.defaultResolver!.resolve(logger: logger);
+    expect(resolved.isNotEmpty, true);
+    final satisfied = requirement.satisfy(resolved);
+    expect(satisfied?.length, 1);
+  });
+}
diff --git a/pkgs/native_toolchain_c/test/native_toolchain/clang_test.dart b/pkgs/native_toolchain_c/test/native_toolchain/clang_test.dart
new file mode 100644
index 0000000..88be30c
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/native_toolchain/clang_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('linux')
+library;
+
+import 'dart:io';
+
+import 'package:native_toolchain_c/src/native_toolchain/clang.dart';
+import 'package:native_toolchain_c/src/tool/tool_instance.dart';
+import 'package:native_toolchain_c/src/tool/tool_requirement.dart';
+import 'package:pub_semver/pub_semver.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  if (!Platform.isLinux) {
+    // Avoid needing status files on Dart SDK CI.
+    return;
+  }
+
+  test('clang smoke test', () async {
+    final requirement =
+        ToolRequirement(clang, minimumVersion: Version(14, 0, 0, pre: '0'));
+    final resolved = await clang.defaultResolver!.resolve(logger: logger);
+    expect(resolved.isNotEmpty, true);
+    final satisfied = requirement.satisfy(resolved);
+    expect(satisfied?.length, 1);
+  });
+
+  test('clang versions', () {
+    final clangInstance = ToolInstance(
+      tool: clang,
+      uri: Uri.file('some/path'),
+      version: Version.parse('14.0.0-1'),
+    );
+    final requirement =
+        ToolRequirement(clang, minimumVersion: Version(14, 0, 0, pre: '0'));
+    final satisfied = requirement.satisfy([clangInstance]);
+    expect(satisfied?.length, 1);
+  });
+
+  test('llvm-ar smoke test', () async {
+    final requirement = ToolRequirement(llvmAr);
+    final resolved = await llvmAr.defaultResolver!.resolve(logger: logger);
+    expect(resolved.isNotEmpty, true);
+    final satisfied = requirement.satisfy(resolved);
+    expect(satisfied?.length, 1);
+  });
+
+  test('ld test', () async {
+    final requirement = ToolRequirement(lld);
+    final resolved = await lld.defaultResolver!.resolve(logger: logger);
+    expect(resolved.isNotEmpty, true);
+    final satisfied = requirement.satisfy(resolved);
+    expect(satisfied?.length, 1);
+  });
+}
diff --git a/pkgs/native_toolchain_c/test/native_toolchain/gcc_test.dart b/pkgs/native_toolchain_c/test/native_toolchain/gcc_test.dart
new file mode 100644
index 0000000..c87f53e
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/native_toolchain/gcc_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('linux')
+library;
+
+import 'dart:io';
+
+import 'package:native_toolchain_c/src/native_toolchain/gcc.dart';
+import 'package:native_toolchain_c/src/tool/tool.dart';
+import 'package:native_toolchain_c/src/tool/tool_requirement.dart';
+import 'package:native_toolchain_c/src/tool/tool_resolver.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  if (!Platform.isLinux) {
+    // Avoid needing status files on Dart SDK CI.
+    return;
+  }
+
+  void testToolSet(String name, List<Tool> tools) {
+    test('gcc cross compilation $name smoke test', () async {
+      final resolver = ToolResolvers([
+        for (final tool in tools) tool.defaultResolver!,
+      ]);
+
+      final resolved = await resolver.resolve(logger: logger);
+      printOnFailure(resolved.toString());
+      expect(resolved.isNotEmpty, true);
+
+      final requirement = RequireAll([
+        for (final tool in tools) ToolRequirement(tool),
+      ]);
+
+      final satisfied = requirement.satisfy(resolved);
+      printOnFailure(tools.toString());
+      printOnFailure(satisfied.toString());
+      expect(satisfied?.length, tools.length);
+    });
+  }
+
+  testToolSet('aarch64LinuxGnuGcc', [
+    aarch64LinuxGnuGcc,
+    aarch64LinuxGnuGccAr,
+    aarch64LinuxGnuLd,
+  ]);
+
+  testToolSet('armLinuxGnueabihfGcc', [
+    armLinuxGnueabihfGcc,
+    armLinuxGnueabihfGccAr,
+    armLinuxGnueabihfLd,
+  ]);
+
+  testToolSet('i686LinuxGnuGcc', [
+    i686LinuxGnuGcc,
+    i686LinuxGnuGccAr,
+    i686LinuxGnuLd,
+  ]);
+
+  testToolSet('x86_64LinuxGnuGcc', [
+    x86_64LinuxGnuGcc,
+    x86_64LinuxGnuGccAr,
+    x86_64LinuxGnuLd,
+  ]);
+
+  testToolSet('riscv64LinuxGnuGcc', [
+    riscv64LinuxGnuGcc,
+    riscv64LinuxGnuGccAr,
+    riscv64LinuxGnuLd,
+  ]);
+}
diff --git a/pkgs/native_toolchain_c/test/native_toolchain/msvc_test.dart b/pkgs/native_toolchain_c/test/native_toolchain/msvc_test.dart
new file mode 100644
index 0000000..7e9e348
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/native_toolchain/msvc_test.dart
@@ -0,0 +1,188 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('windows')
+@OnPlatform({
+  'windows': Timeout.factor(10),
+})
+library;
+
+import 'dart:io';
+
+import 'package:native_toolchain_c/src/native_toolchain/msvc.dart';
+import 'package:native_toolchain_c/src/utils/env_from_bat.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  if (!Platform.isWindows) {
+    // Avoid needing status files on Dart SDK CI.
+    return;
+  }
+
+  test('vswhere', () async {
+    final instances = await vswhere.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('visualStudio', () async {
+    final instances =
+        await visualStudio.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('msvc', () async {
+    final instances = await msvc.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('cl', () async {
+    final instances = await cl.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('clIA32', () async {
+    final instances = await clIA32.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('clArm64', () async {
+    final instances = await clArm64.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('lib', () async {
+    final instances = await lib.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('libIA32', () async {
+    final instances = await libIA32.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('libArm64', () async {
+    final instances = await libArm64.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('link', () async {
+    final instances = await link.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('linkIA32', () async {
+    final instances = await linkIA32.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('linkArm64', () async {
+    final instances = await linkArm64.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('dumpbin', () async {
+    final instances = await dumpbin.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+  });
+
+  test('vcvars32 from cl.exe', () async {
+    final clInstances = await clIA32.defaultResolver!.resolve(logger: logger);
+    expect(clInstances.isNotEmpty, true);
+
+    final instances = await vcvars(clInstances.first)
+        .defaultResolver!
+        .resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+    final instance = instances.first;
+    expect(instance.tool, vcvars32);
+    final env = await envFromBat(instance.uri);
+    expect(env['INCLUDE'] != null, true);
+    expect(env['WindowsSdkDir'] != null, true); // stdio.h
+  });
+
+  test('vcvars64 from cl.exe', () async {
+    final clInstances = await cl.defaultResolver!.resolve(logger: logger);
+    expect(clInstances.isNotEmpty, true);
+
+    final instances = await vcvars(clInstances.first)
+        .defaultResolver!
+        .resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+    final instance = instances.first;
+    expect(instance.tool, vcvars64);
+    final env = await envFromBat(instance.uri);
+    expect(env['INCLUDE'] != null, true);
+    expect(env['WindowsSdkDir'] != null, true); // stdio.h
+  });
+
+  test('vcvarsarm64 from cl.exe', () async {
+    final clInstances = await clArm64.defaultResolver!.resolve(logger: logger);
+    expect(clInstances.isNotEmpty, true);
+
+    final instances = await vcvars(clInstances.first)
+        .defaultResolver!
+        .resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+    final instance = instances.first;
+    expect(instance.tool, vcvarsarm64);
+    final env = await envFromBat(instance.uri);
+    expect(env['INCLUDE'] != null, true);
+    expect(env['WindowsSdkDir'] != null, true); // stdio.h
+  });
+
+  test('vcvars32', () async {
+    final instances = await vcvars32.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+    final instance = instances.first;
+    final env = await envFromBat(instance.uri);
+    expect(env['INCLUDE'] != null, true);
+    expect(env['WindowsSdkDir'] != null, true); // stdio.h
+  });
+
+  test('vcvars64', () async {
+    final instances = await vcvars64.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+    final instance = instances.first;
+    final env = await envFromBat(instance.uri);
+    expect(env['INCLUDE'] != null, true);
+    expect(env['WindowsSdkDir'] != null, true); // stdio.h
+  });
+
+  test('vcvarsarm64', () async {
+    final instances =
+        await vcvarsarm64.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+    final instance = instances.first;
+    final env = await envFromBat(instance.uri);
+    expect(env['INCLUDE'] != null, true);
+    expect(env['WindowsSdkDir'] != null, true); // stdio.h
+  });
+
+  test('vcvarsall', () async {
+    final instances = await vcvarsall.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+    final instance = instances.first;
+    final env = await envFromBat(
+      instance.uri,
+      arguments: [
+        'x64',
+        'uwp',
+        '10.0',
+      ],
+    );
+    expect(env['INCLUDE'] != null, true);
+    expect(env['WindowsSdkDir'] != null, true); // stdio.h
+  });
+
+  test('vsDevCmd', () async {
+    final instances = await vsDevCmd.defaultResolver!.resolve(logger: logger);
+    expect(instances.isNotEmpty, true);
+    final instance = instances.first;
+    final env = await envFromBat(instance.uri);
+    expect(env['INCLUDE'] != null, true);
+    expect(env['WindowsSdkDir'] != null, true); // stdio.h
+  });
+}
diff --git a/pkgs/native_toolchain_c/test/native_toolchain/ndk_test.dart b/pkgs/native_toolchain_c/test/native_toolchain/ndk_test.dart
new file mode 100644
index 0000000..f6cde28
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/native_toolchain/ndk_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_toolchain_c/src/native_toolchain/android_ndk.dart';
+import 'package:native_toolchain_c/src/tool/tool_requirement.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  test('NDK smoke test', () async {
+    final requirement = RequireAll([
+      ToolRequirement(androidNdk),
+      ToolRequirement(androidNdkClang),
+      ToolRequirement(androidNdkLlvmAr),
+      ToolRequirement(androidNdkLld),
+    ]);
+    final resolved = await androidNdk.defaultResolver!.resolve(logger: logger);
+    final satisfied = requirement.satisfy(resolved);
+    expect(satisfied?.length, 4);
+  });
+}
diff --git a/pkgs/native_toolchain_c/test/native_toolchain/recognizer_test.dart b/pkgs/native_toolchain_c/test/native_toolchain/recognizer_test.dart
new file mode 100644
index 0000000..0f18d39
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/native_toolchain/recognizer_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:collection/collection.dart';
+import 'package:native_toolchain_c/src/native_toolchain/android_ndk.dart';
+import 'package:native_toolchain_c/src/native_toolchain/apple_clang.dart';
+import 'package:native_toolchain_c/src/native_toolchain/clang.dart';
+import 'package:native_toolchain_c/src/native_toolchain/gcc.dart';
+import 'package:native_toolchain_c/src/native_toolchain/msvc.dart';
+import 'package:native_toolchain_c/src/native_toolchain/recognizer.dart';
+import 'package:native_toolchain_c/src/tool/tool.dart';
+import 'package:native_toolchain_c/src/tool/tool_instance.dart';
+import 'package:native_toolchain_c/src/tool/tool_resolver.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() async {
+  final tests = [
+    RecognizerTest(appleAr, ArchiverRecognizer.new),
+    RecognizerTest(appleClang, CompilerRecognizer.new),
+    RecognizerTest(appleLd, LinkerRecognizer.new),
+    RecognizerTest(aarch64LinuxGnuGcc, CompilerRecognizer.new),
+    RecognizerTest(aarch64LinuxGnuGccAr, ArchiverRecognizer.new),
+    RecognizerTest(aarch64LinuxGnuLd, LinkerRecognizer.new),
+    RecognizerTest(androidNdkClang, CompilerRecognizer.new),
+    RecognizerTest(androidNdkLld, LinkerRecognizer.new),
+    RecognizerTest(androidNdkLlvmAr, ArchiverRecognizer.new),
+    RecognizerTest(armLinuxGnueabihfGcc, CompilerRecognizer.new),
+    RecognizerTest(armLinuxGnueabihfGccAr, ArchiverRecognizer.new),
+    RecognizerTest(armLinuxGnueabihfLd, LinkerRecognizer.new),
+    RecognizerTest(cl, CompilerRecognizer.new),
+    RecognizerTest(clang, CompilerRecognizer.new),
+    RecognizerTest(i686LinuxGnuGcc, CompilerRecognizer.new),
+    RecognizerTest(i686LinuxGnuGccAr, ArchiverRecognizer.new),
+    RecognizerTest(i686LinuxGnuLd, LinkerRecognizer.new),
+    RecognizerTest(lib, ArchiverRecognizer.new),
+    RecognizerTest(link, LinkerRecognizer.new),
+    RecognizerTest(lld, LinkerRecognizer.new),
+    RecognizerTest(llvmAr, ArchiverRecognizer.new),
+    RecognizerTest(riscv64LinuxGnuGcc, CompilerRecognizer.new),
+    RecognizerTest(riscv64LinuxGnuGccAr, ArchiverRecognizer.new),
+    RecognizerTest(riscv64LinuxGnuLd, LinkerRecognizer.new),
+    RecognizerTest(x86_64LinuxGnuGcc, CompilerRecognizer.new),
+    RecognizerTest(x86_64LinuxGnuGccAr, ArchiverRecognizer.new),
+    RecognizerTest(x86_64LinuxGnuLd, LinkerRecognizer.new),
+  ];
+
+  for (final test in tests) {
+    await test.setUp();
+  }
+
+  for (final test in tests) {
+    test.addTest();
+  }
+
+  test('compiler does not exist', () async {
+    final tempUri = await tempDirForTest();
+    final recognizer = CompilerRecognizer(tempUri.resolve('asdf'));
+    final result = await recognizer.resolve(logger: logger);
+    expect(result, <ToolInstance>[]);
+  });
+
+  test('linker does not exist', () async {
+    final tempUri = await tempDirForTest();
+    final recognizer = LinkerRecognizer(tempUri.resolve('asdf'));
+    final result = await recognizer.resolve(logger: logger);
+    expect(result, <ToolInstance>[]);
+  });
+
+  test('archiver does not exist', () async {
+    final tempUri = await tempDirForTest();
+    final recognizer = ArchiverRecognizer(tempUri.resolve('asdf'));
+    final result = await recognizer.resolve(logger: logger);
+    expect(result, <ToolInstance>[]);
+  });
+}
+
+class RecognizerTest {
+  final Tool tool;
+  final ToolResolver Function(Uri) recognizer;
+  late final ToolInstance? toolInstance;
+
+  RecognizerTest(this.tool, this.recognizer);
+
+  Future<void> setUp() async {
+    toolInstance = (await tool.defaultResolver!.resolve(
+      logger: null /* no printOnFailure support in setup. */,
+    ))
+        .where((element) => element.tool == tool)
+        .firstOrNull;
+  }
+
+  void addTest() {
+    if (toolInstance == null) {
+      // We only want to test if we would recognize the tool again if it exists
+      // on the host. Skipping pollutes the stdout, so just don't run the test
+      // at all.
+      return;
+    }
+
+    test(
+      'recognize ${tool.name}',
+      () async {
+        final recognizer_ = recognizer(toolInstance!.uri);
+        final toolInstanceAgain =
+            (await recognizer_.resolve(logger: logger)).first;
+        expect(toolInstanceAgain, toolInstance);
+      },
+    );
+  }
+}
diff --git a/pkgs/native_toolchain_c/test/native_toolchain/xcode_test.dart b/pkgs/native_toolchain_c/test/native_toolchain/xcode_test.dart
new file mode 100644
index 0000000..208851b
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/native_toolchain/xcode_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('mac-os')
+@OnPlatform({
+  'mac-os': Timeout.factor(2),
+})
+library;
+
+import 'dart:io';
+
+import 'package:native_toolchain_c/src/native_toolchain/xcode.dart';
+import 'package:native_toolchain_c/src/tool/tool.dart';
+import 'package:native_toolchain_c/src/tool/tool_instance.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  if (!Platform.isMacOS) {
+    // Avoid needing status files on Dart SDK CI.
+    return;
+  }
+
+  test('xcrun', () async {
+    final resolved = (await xcrun.defaultResolver!.resolve(logger: logger))
+        .where((i) => i.tool == xcrun);
+    expect(resolved.isNotEmpty, true);
+  });
+
+  test('macosxSdk', () async {
+    final resolved = (await macosxSdk.defaultResolver!.resolve(logger: logger))
+        .where((i) => i.tool == macosxSdk);
+    expect(resolved.isNotEmpty, true);
+  });
+
+  test('iPhoneOSSdk', () async {
+    final resolved =
+        (await iPhoneOSSdk.defaultResolver!.resolve(logger: logger))
+            .where((i) => i.tool == iPhoneOSSdk);
+    expect(resolved.isNotEmpty, true);
+  });
+
+  test('iPhoneSimulatorSdk', () async {
+    final resolved =
+        (await iPhoneSimulatorSdk.defaultResolver!.resolve(logger: logger))
+            .where((i) => i.tool == iPhoneSimulatorSdk);
+    expect(resolved.isNotEmpty, true);
+  });
+
+  test('non-existing SDK', () async {
+    final xcrunInstance =
+        (await xcrun.defaultResolver!.resolve(logger: logger)).first;
+    final tool = Tool(name: 'non-tool');
+    final result = await XCodeSdkResolver.tryResolveSdk(
+      xcrunInstance: xcrunInstance,
+      sdk: 'doesnotexist',
+      tool: tool,
+      logger: logger,
+    );
+    expect(result, <ToolInstance>[]);
+  });
+}
diff --git a/pkgs/native_toolchain_c/test/tool/tool_instance_test.dart b/pkgs/native_toolchain_c/test/tool/tool_instance_test.dart
new file mode 100644
index 0000000..b4a873b
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/tool/tool_instance_test.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:collection/collection.dart';
+import 'package:native_toolchain_c/src/tool/tool.dart';
+import 'package:native_toolchain_c/src/tool/tool_instance.dart';
+import 'package:pub_semver/pub_semver.dart';
+import 'package:test/test.dart';
+
+void main() {
+  test('equals and hashCode', () {
+    final barToolInstance =
+        ToolInstance(tool: Tool(name: 'bar'), uri: Uri.file('path/to/bar'));
+    final fooToolInstance =
+        ToolInstance(tool: Tool(name: 'foo'), uri: Uri.file('path/to/foo'));
+
+    expect(barToolInstance, barToolInstance);
+    expect(barToolInstance != fooToolInstance, true);
+
+    expect(barToolInstance.hashCode, barToolInstance.hashCode);
+    expect(barToolInstance.hashCode != fooToolInstance.hashCode, true);
+
+    expect(
+        ToolInstance(
+                tool: Tool(name: 'bar'),
+                version: Version(1, 0, 0),
+                uri: Uri.file('path/to/bar')) !=
+            ToolInstance(
+                tool: Tool(name: 'bar'),
+                version: Version(1, 0, 1),
+                uri: Uri.file('path/to/bar')),
+        true);
+  });
+
+  test('compareTo', () {
+    final toolInstances = [
+      ToolInstance(
+        tool: Tool(name: 'bar'),
+        version: Version(2, 0, 0),
+        uri: Uri.file('path/to/bar'),
+      ),
+      ToolInstance(
+          tool: Tool(name: 'bar'),
+          version: Version(1, 0, 0),
+          uri: Uri.file('path/to/bar')),
+      ToolInstance(
+        tool: Tool(name: 'bar'),
+        uri: Uri.file('path/to/bar'),
+      ),
+      ToolInstance(
+        tool: Tool(name: 'bar'),
+        uri: Uri.file('path/to/some/other/bar'),
+      ),
+      ToolInstance(
+        tool: Tool(name: 'baz'),
+        uri: Uri.file('path/to/baz'),
+      ),
+    ];
+
+    final toolInstancesSorted = [...toolInstances]..sort();
+    expect(
+      const DeepCollectionEquality().equals(toolInstancesSorted, toolInstances),
+      true,
+    );
+  });
+
+  test('toString', () {
+    final instance = ToolInstance(
+      tool: Tool(name: 'bar'),
+      version: Version(1, 0, 0),
+      uri: Uri.file('path/to/bar'),
+    );
+
+    expect(instance.toString(), contains('bar'));
+    expect(instance.toString(), contains('1.0.0'));
+    expect(instance.toString(), contains('path/to/bar'));
+  });
+
+  test('copyWith', () {
+    final instance = ToolInstance(
+      tool: Tool(name: 'bar'),
+      version: Version(1, 0, 0),
+      uri: Uri.file('path/to/bar'),
+    );
+
+    expect(instance.copyWith(), instance);
+    expect(instance.copyWith(uri: Uri.file('foo/bar')) != instance, true);
+  });
+}
diff --git a/pkgs/native_toolchain_c/test/tool/tool_requirement_test.dart b/pkgs/native_toolchain_c/test/tool/tool_requirement_test.dart
new file mode 100644
index 0000000..9f802db
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/tool/tool_requirement_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_toolchain_c/src/tool/tool.dart';
+import 'package:native_toolchain_c/src/tool/tool_instance.dart';
+import 'package:native_toolchain_c/src/tool/tool_requirement.dart';
+import 'package:pub_semver/pub_semver.dart';
+import 'package:test/test.dart';
+
+void main() {
+  test('toString', () {
+    final requirement =
+        ToolRequirement(Tool(name: 'clang'), minimumVersion: Version(10, 0, 0));
+    expect(requirement.toString(), contains('clang'));
+    expect(requirement.toString(), contains('10.0.0'));
+  });
+
+  test('RequireOne', () {
+    final requirement = RequireOne([
+      ToolRequirement(Tool(name: 'bar'), minimumVersion: Version(10, 0, 0)),
+      ToolRequirement(Tool(name: 'foo'), minimumVersion: Version(10, 0, 0)),
+    ]);
+    final toolInstances = [
+      ToolInstance(
+        tool: Tool(name: 'bar'),
+        version: Version(10, 0, 0),
+        uri: Uri.file('path/to/bar'),
+      ),
+      ToolInstance(
+        tool: Tool(name: 'foo'),
+        version: Version(9, 0, 0),
+        uri: Uri.file('path/to/foo'),
+      ),
+    ];
+    final result = requirement.satisfy(toolInstances);
+    expect(
+      result,
+      [
+        ToolInstance(
+          tool: Tool(name: 'bar'),
+          version: Version(10, 0, 0),
+          uri: Uri.file('path/to/bar'),
+        )
+      ],
+    );
+  });
+}
diff --git a/pkgs/native_toolchain_c/test/tool/tool_resolver_test.dart b/pkgs/native_toolchain_c/test/tool/tool_resolver_test.dart
new file mode 100644
index 0000000..9f30ce0
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/tool/tool_resolver_test.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_assets_cli/native_assets_cli.dart';
+import 'package:native_toolchain_c/src/native_toolchain/apple_clang.dart';
+import 'package:native_toolchain_c/src/native_toolchain/clang.dart';
+import 'package:native_toolchain_c/src/native_toolchain/msvc.dart';
+import 'package:native_toolchain_c/src/tool/tool.dart';
+import 'package:native_toolchain_c/src/tool/tool_error.dart';
+import 'package:native_toolchain_c/src/tool/tool_instance.dart';
+import 'package:native_toolchain_c/src/tool/tool_resolver.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  test('CliVersionResolver.executableVersion', () async {
+    final toolInstances = [
+      ...await appleClang.defaultResolver!.resolve(logger: logger),
+      ...await clang.defaultResolver!.resolve(logger: logger),
+      ...await cl.defaultResolver!.resolve(logger: logger),
+    ];
+    expect(toolInstances.isNotEmpty, true);
+    final toolInstance = toolInstances.first;
+    final versionArguments = [
+      if (toolInstance.tool != cl) '--version',
+    ];
+    final version = await CliVersionResolver.executableVersion(
+      toolInstance.uri,
+      arguments: versionArguments,
+      logger: logger,
+    );
+    expect(version.major > 5, true);
+    expect(
+      () => CliVersionResolver.executableVersion(
+        toolInstances.first.uri,
+        arguments: versionArguments,
+        expectedExitCode: 9999,
+        logger: logger,
+      ),
+      throwsA(isA<ToolError>()),
+    );
+
+    try {
+      await CliVersionResolver.executableVersion(
+        toolInstances.first.uri,
+        arguments: versionArguments,
+        expectedExitCode: 9999,
+        logger: logger,
+      );
+      // ignore: avoid_catching_errors
+    } on ToolError catch (e) {
+      expect(e.toString(), contains('returned unexpected exit code'));
+    }
+  });
+
+  test('RelativeToolResolver', () async {
+    final tempUri = await tempDirForTest();
+    final barExeUri =
+        tempUri.resolve(Target.current.os.executableFileName('bar'));
+    final bazExeName = Target.current.os.executableFileName('baz');
+    final bazExeUri = tempUri.resolve(bazExeName);
+    await File.fromUri(barExeUri).writeAsString('dummy');
+    await File.fromUri(bazExeUri).writeAsString('dummy');
+    expect(await File.fromUri(barExeUri).exists(), true);
+    expect(await File.fromUri(bazExeUri).exists(), true);
+    final barResolver = InstallLocationResolver(
+      toolName: 'bar',
+      paths: [barExeUri.toFilePath().replaceAll('\\', '/')],
+    );
+    final bazResolver = RelativeToolResolver(
+      toolName: 'baz',
+      wrappedResolver: barResolver,
+      relativePath: Uri.file(bazExeName),
+    );
+    final resolvedBarInstances = await barResolver.resolve(logger: logger);
+    expect(
+      resolvedBarInstances,
+      [ToolInstance(tool: Tool(name: 'bar'), uri: barExeUri)],
+    );
+    final resolvedBazInstances = await bazResolver.resolve(logger: logger);
+    expect(
+      resolvedBazInstances,
+      [ToolInstance(tool: Tool(name: 'baz'), uri: bazExeUri)],
+    );
+  });
+
+  test('logger', () async {
+    final tempUri = await tempDirForTest();
+    final barExeUri =
+        tempUri.resolve(Target.current.os.executableFileName('bar'));
+    final bazExeName = Target.current.os.executableFileName('baz');
+    final bazExeUri = tempUri.resolve(bazExeName);
+    await File.fromUri(barExeUri).writeAsString('dummy');
+    final barResolver = InstallLocationResolver(
+        toolName: 'bar', paths: [barExeUri.toFilePath().replaceAll('\\', '/')]);
+    final bazResolver = InstallLocationResolver(
+        toolName: 'baz', paths: [bazExeUri.toFilePath().replaceAll('\\', '/')]);
+    final barLogs = <String>[];
+    final bazLogs = <String>[];
+    await barResolver.resolve(logger: createCapturingLogger(barLogs));
+    await bazResolver.resolve(logger: createCapturingLogger(bazLogs));
+    expect(barLogs.join('\n'), contains('Found [ToolInstance(bar'));
+    expect(bazLogs.join('\n'), contains('Found no baz'));
+  });
+}
diff --git a/pkgs/native_toolchain_c/test/tool/tool_test.dart b/pkgs/native_toolchain_c/test/tool/tool_test.dart
new file mode 100644
index 0000000..c14aff9
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/tool/tool_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:native_toolchain_c/src/native_toolchain/android_ndk.dart';
+import 'package:native_toolchain_c/src/native_toolchain/clang.dart';
+import 'package:native_toolchain_c/src/tool/tool.dart';
+import 'package:native_toolchain_c/src/tool/tool_resolver.dart';
+import 'package:test/test.dart';
+
+void main() {
+  test('equals and hashCode', () async {
+    expect(clang, clang);
+    expect(clang != androidNdk, true);
+    expect(
+      Tool(name: 'foo'),
+      Tool(name: 'foo', defaultResolver: PathToolResolver(toolName: 'foo')),
+    );
+    expect(Tool(name: 'foo') != Tool(name: 'bar'), true);
+    expect(
+      Tool(name: 'foo').hashCode,
+      Tool(name: 'foo', defaultResolver: PathToolResolver(toolName: 'foo'))
+          .hashCode,
+    );
+    expect(Tool(name: 'foo').hashCode != Tool(name: 'bar').hashCode, true);
+  });
+}
diff --git a/pkgs/native_toolchain_c/test/utils/run_process_test.dart b/pkgs/native_toolchain_c/test/utils/run_process_test.dart
new file mode 100644
index 0000000..21d7c9d
--- /dev/null
+++ b/pkgs/native_toolchain_c/test/utils/run_process_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:native_toolchain_c/src/utils/run_process.dart';
+import 'package:test/test.dart';
+
+import '../helpers.dart';
+
+void main() {
+  final whichUri = Uri.file(Platform.isWindows ? 'where' : 'which');
+
+  test('log contains working dir', () async {
+    final tempUri = await tempDirForTest();
+    final messages = <String>[];
+    await runProcess(
+      executable: whichUri,
+      workingDirectory: tempUri,
+      logger: createCapturingLogger(messages),
+    );
+    expect(messages.join('\n'), contains('cd'));
+  });
+
+  test('log contains env', () async {
+    final messages = <String>[];
+    await runProcess(
+      executable: whichUri,
+      environment: {'FOO': 'BAR'},
+      logger: createCapturingLogger(messages),
+    );
+    expect(messages.join('\n'), contains('FOO=BAR'));
+  });
+
+  test('stderr', () async {
+    final messages = <String>[];
+    const filePath = 'a/dart/file/which/does/not/exist.dart';
+    final result = await runProcess(
+      executable: Uri.file(Platform.resolvedExecutable),
+      arguments: [filePath],
+      logger: createCapturingLogger(messages),
+    );
+    expect(result.stderr, contains(filePath));
+    expect(result.toString(), contains(filePath));
+  });
+}
