Version 2.10.0-14.0.dev

Merge commit '552a8b1a0cc0acb8b924230533ff81d4b08987c9' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index f7c4d16..760e76a 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,5 +1,5 @@
 name: _fe_analyzer_shared
-version: 6.0.0
+version: 7.0.0
 description: Logic that is shared between the front_end and analyzer packages.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/_fe_analyzer_shared
 
diff --git a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
index f0a7bba..d85e724 100644
--- a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
+++ b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
@@ -7,13 +7,8 @@
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/ast_factory.dart';
-import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/ast/ast_factory.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -243,24 +238,12 @@
   /// name as in the original source.
   List<ImportedElements> _filterImportedElements(
       List<ImportedElements> originalList) {
-    var libraryElement = libraryResult.libraryElement;
-    var libraryScope = libraryElement.scope;
-    AstFactory factory = AstFactoryImpl();
     var filteredList = <ImportedElements>[];
     for (var elements in originalList) {
       var originalElements = elements.elements;
       var filteredElements = originalElements.toList();
       for (var name in originalElements) {
-        Identifier identifier = factory
-            .simpleIdentifier(StringToken(TokenType.IDENTIFIER, name, -1));
-        if (elements.prefix.isNotEmpty) {
-          var prefix = factory.simpleIdentifier(
-              StringToken(TokenType.IDENTIFIER, elements.prefix, -1));
-          Token period = SimpleToken(TokenType.PERIOD, -1);
-          identifier = factory.prefixedIdentifier(prefix, period, identifier);
-        }
-        var element = libraryScope.lookupIdentifier(identifier);
-        if (element != null) {
+        if (_hasElement(elements.prefix, name)) {
           filteredElements.remove(name);
         }
       }
@@ -340,6 +323,22 @@
     return context.split(relativeFile).join('/');
   }
 
+  bool _hasElement(String prefix, String name) {
+    var scope = libraryResult.libraryElement.scope;
+
+    if (prefix.isNotEmpty) {
+      var prefixElement = scope.lookup2(prefix).getter;
+      if (prefixElement is PrefixElement) {
+        scope = prefixElement.scope;
+      } else {
+        return false;
+      }
+    }
+
+    var lookupResult = scope.lookup2(name);
+    return lookupResult.getter != null || lookupResult.setter != null;
+  }
+
   /// Return `true` if the given [import] matches the given specification of
   /// [importedElements]. They will match if they import the same library using
   /// the same prefix.
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_relevance_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_relevance_test.dart
index 8a51410..1e39e30 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_relevance_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_relevance_test.dart
@@ -2,7 +2,6 @@
 // for 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:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -16,22 +15,23 @@
 }
 
 @reflectiveTest
-class NamedArgumentRelevanceTest extends CompletionRelevanceTest
-    with PackageMixin {
-  @override
-  Map<String, List<Folder>> packageMap = {};
-
+class NamedArgumentRelevanceTest extends CompletionRelevanceTest {
   @override
   void setUp() {
     super.setUp();
+
+    var metaPath = '/.pub-cache/meta';
+    PackagesContent.addMetaPackageFiles(
+      getFolder(metaPath),
+    );
+
     newFile('$projectPath/.packages', content: '''
-meta:${toUri('/.pub-cache/meta/lib')}
+meta:${toUri('$metaPath/lib')}
 project:${toUri('$projectPath/lib')}
 ''');
   }
 
   Future<void> test_requiredAnnotation() async {
-    addMetaPackage();
     await addTestFile('''
 import 'package:meta/meta.dart';
 
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 50ac6e8..7d6d0e3 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 0.39.17
+* Depend on cli_util 0.2.0.
+
 ## 0.39.16
 * Added `TypeVisitorWithArgument` and `DartType.acceptWithArgument`.
 * Bumped the analyzer's SDK requirement to `>=2.7.0`, so that extension methods
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index c8b7f64..40f9dcf 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer/dart/element/scope.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 
 /// Helper for [MethodInvocation]s into [InstanceCreationExpression] to support
@@ -33,7 +32,7 @@
         // This isn't a constructor invocation because it's in a cascade.
         return node;
       }
-      Element element = nameScope.lookupIdentifier(methodName);
+      Element element = nameScope.lookup2(methodName.name).getter;
       if (element is ClassElement) {
         TypeName typeName = astFactory.typeName(methodName, node.typeArguments);
         ConstructorName constructorName =
@@ -57,7 +56,7 @@
         // This isn't a constructor invocation because a null aware operator is
         // being used.
       }
-      Element element = nameScope.lookupIdentifier(target);
+      Element element = nameScope.lookup2(target.name).getter;
       if (element is ClassElement) {
         // Possible case: C.n()
         var constructorElement = element.getNamedConstructor(methodName.name);
@@ -82,11 +81,7 @@
         }
       } else if (element is PrefixElement) {
         // Possible cases: p.C() or p.C<>()
-        Identifier identifier = astFactory.prefixedIdentifier(
-            astFactory.simpleIdentifier(target.token),
-            null,
-            astFactory.simpleIdentifier(methodName.token));
-        Element prefixedElement = nameScope.lookupIdentifier(identifier);
+        Element prefixedElement = element.scope.lookup2(methodName.name).getter;
         if (prefixedElement is ClassElement) {
           TypeName typeName = astFactory.typeName(
               astFactory.prefixedIdentifier(target, node.operator, methodName),
@@ -111,10 +106,11 @@
       }
     } else if (target is PrefixedIdentifier) {
       // Possible case: p.C.n()
-      Element prefixElement = nameScope.lookupIdentifier(target.prefix);
+      Element prefixElement = nameScope.lookup2(target.prefix.name).getter;
       target.prefix.staticElement = prefixElement;
       if (prefixElement is PrefixElement) {
-        Element element = nameScope.lookupIdentifier(target);
+        Element element =
+            prefixElement.scope.lookup2(target.identifier.name).getter;
         if (element is ClassElement) {
           var constructorElement = element.getNamedConstructor(methodName.name);
           if (constructorElement != null) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index 2787d4b..0eebe01 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -449,26 +449,4 @@
     }
     throw StateError('Can only be used in a LibraryScope.');
   }
-
-  // TODO(scheglov) check if it might be inlined
-  Element lookupIdentifier(Identifier identifier) {
-    if (identifier is SimpleIdentifier) {
-      var result = lookup2(identifier.name);
-      return result.getter ?? result.setter;
-    } else {
-      var prefixedIdentifier = identifier as PrefixedIdentifier;
-
-      var prefixIdentifier = prefixedIdentifier.prefix;
-      var prefixName = prefixIdentifier.name;
-      var prefixElement = lookup2(prefixName).getter;
-      prefixIdentifier.staticElement = prefixElement;
-
-      if (prefixElement is PrefixElement) {
-        var name = prefixedIdentifier.identifier.name;
-        var result = prefixElement.scope.lookup2(name);
-        return result.getter ?? result.setter;
-      }
-    }
-    return null;
-  }
 }
diff --git a/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart b/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart
index f28b925..efefa53 100644
--- a/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart
+++ b/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart
@@ -80,7 +80,7 @@
     _fieldMap.forEach((FieldElement field, _InitState state) {
       if (state != _InitState.notInit) return;
       if (field.isLate) return;
-      if (field.isAbstract) return;
+      if (field.isAbstract || field.isExternal) return;
 
       if (field.isFinal) {
         notInitFinalFields.add(field);
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 4eb6d7d..056efeb 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -3566,7 +3566,7 @@
 
     for (var field in fields.variables) {
       var fieldElement = field.declaredElement as FieldElement;
-      if (fieldElement.isAbstract) continue;
+      if (fieldElement.isAbstract || fieldElement.isExternal) continue;
       if (field.initializer != null) continue;
 
       var type = fieldElement.type;
@@ -3603,6 +3603,11 @@
       return;
     }
 
+    var parent = node.parent;
+    if (parent is FieldDeclaration && parent.externalKeyword != null) {
+      return;
+    }
+
     if (node.type == null) {
       return;
     }
diff --git a/pkg/analyzer/lib/src/test_utilities/package_mixin.dart b/pkg/analyzer/lib/src/test_utilities/package_mixin.dart
index 7889ece..9294d4e 100644
--- a/pkg/analyzer/lib/src/test_utilities/package_mixin.dart
+++ b/pkg/analyzer/lib/src/test_utilities/package_mixin.dart
@@ -3,41 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-
-/// A mixin for test classes that provides support for creating packages.
-mixin PackageMixin implements ResourceProviderMixin {
-  /// Return the map from package names to lists of folders that is used to
-  /// resolve 'package:' URIs.
-  Map<String, List<Folder>> get packageMap;
-
-  /// Create a fake 'js' package that can be used by tests.
-  void addJsPackage() {
-    var rootFolder = getFolder('/.pub-cache/js');
-    PackagesContent.addJsPackageFiles(rootFolder);
-    addPubPackage('js');
-  }
-
-  /// Create a fake 'meta' package that can be used by tests.
-  void addMetaPackage() {
-    var rootFolder = getFolder('/.pub-cache/meta');
-    PackagesContent.addMetaPackageFiles(rootFolder);
-    addPubPackage('meta');
-  }
-
-  /// Return a newly created directory in which the contents of a pub package
-  /// with the given [packageName] can be written. The package will be added to
-  /// the package map so that the package can be referenced from the code being
-  /// analyzed.
-  Folder addPubPackage(String packageName) {
-    // TODO(brianwilkerson) Consider renaming this to `addPackage` and passing
-    //  in a `PackageStyle` (pub, bazel, gn, build, plain) in order to support
-    //  creating other styles of packages.
-    Folder lib = getFolder('/.pub-cache/$packageName/lib');
-    packageMap[packageName] = [lib];
-    return lib;
-  }
-}
 
 /// Helper for creating mock packages.
 class PackagesContent {
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index becd0e8..be78fcc 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.39.16
+version: 0.39.17
 description: This package provides a library that performs static analysis of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
 
@@ -7,7 +7,7 @@
   sdk: '>=2.7.0 <3.0.0'
 
 dependencies:
-  _fe_analyzer_shared: ^6.0.0
+  _fe_analyzer_shared: ^7.0.0
   args: ^1.0.0
   charcode: ^1.1.0
   cli_util: '>=0.1.4 <0.3.0'
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
index 779b01d..9fca7de 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
@@ -55,8 +55,9 @@
     _assertNoLinkedCycles();
   }
 
-  void _assertContainsLinkedCycle(Set<String> expected,
+  void _assertContainsLinkedCycle(Set<String> expectedPosix,
       {bool andClear = false}) {
+    var expected = expectedPosix.map(convertPath).toSet();
     expect(_linkedCycles, contains(unorderedEquals(expected)));
     if (andClear) {
       _linkedCycles.clear();
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart
index fc35f34..7f20112 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart
@@ -577,6 +577,21 @@
 ''');
   }
 
+  test_external_field_covariant_inheritance() async {
+    await assertNoErrorsInCode('''
+abstract class A {
+  external covariant num x;
+}
+abstract class B implements A {
+  void set x(Object value); // Implicitly covariant
+}
+abstract class C implements B {
+  int get x;
+  void set x(int value); // Ok because covariant
+}
+''');
+  }
+
   test_getter_overrides_abstract_field_covariant_invalid() async {
     await assertErrorsInCode('''
 abstract class A {
@@ -652,6 +667,56 @@
 ''');
   }
 
+  test_getter_overrides_external_field_covariant_invalid() async {
+    await assertErrorsInCode('''
+class A {
+  external covariant int x;
+}
+abstract class B implements A {
+  num get x;
+  void set x(num value);
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_OVERRIDE, 82, 1),
+    ]);
+  }
+
+  test_getter_overrides_external_field_covariant_valid() async {
+    await assertNoErrorsInCode('''
+class A {
+  external covariant num x;
+}
+abstract class B implements A {
+  int get x;
+}
+''');
+  }
+
+  test_getter_overrides_external_field_invalid() async {
+    await assertErrorsInCode('''
+class A {
+  external int x;
+}
+abstract class B implements A {
+  num get x;
+  void set x(num value);
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_OVERRIDE, 72, 1),
+    ]);
+  }
+
+  test_getter_overrides_external_field_valid() async {
+    await assertNoErrorsInCode('''
+class A {
+  external num x;
+}
+abstract class B implements A {
+  int get x;
+}
+''');
+  }
+
   test_method_parameter_functionTyped_optOut_extends_optIn() async {
     newFile('$testPackageLibPath/a.dart', content: r'''
 abstract class A {
@@ -798,6 +863,43 @@
 ''');
   }
 
+  test_setter_overrides_external_field_covariant_valid() async {
+    await assertNoErrorsInCode('''
+class A {
+  external covariant num x;
+}
+abstract class B implements A {
+  int get x;
+  void set x(int value);
+}
+''');
+  }
+
+  test_setter_overrides_external_field_invalid() async {
+    await assertErrorsInCode('''
+class A {
+  external num x;
+}
+abstract class B implements A {
+  int get x;
+  void set x(int value);
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_OVERRIDE, 86, 1),
+    ]);
+  }
+
+  test_setter_overrides_external_field_valid() async {
+    await assertNoErrorsInCode('''
+class A {
+  external int x;
+}
+abstract class B implements A {
+  void set x(num value);
+}
+''');
+  }
+
   test_viaLegacy_class() async {
     newFile('$testPackageLibPath/a.dart', content: r'''
 class A1 {
diff --git a/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_instance_field_test.dart b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_instance_field_test.dart
index 08e6965..7ade83f 100644
--- a/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_instance_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_instance_field_test.dart
@@ -87,6 +87,23 @@
 ''');
   }
 
+  test_external_field_non_nullable() async {
+    await assertNoErrorsInCode('''
+class A {
+  external int x;
+}
+''');
+  }
+
+  test_external_field_non_nullable_with_constructor() async {
+    await assertNoErrorsInCode('''
+class A {
+  external int x;
+  A();
+}
+''');
+  }
+
   test_fieldFormal() async {
     await assertNoErrorsInCode('''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_variable_test.dart
index d7d101e..bb1f2d1 100644
--- a/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_variable_test.dart
@@ -16,6 +16,14 @@
 @reflectiveTest
 class NotInitializedNonNullableVariableTest extends PubPackageResolutionTest
     with WithNullSafetyMixin {
+  test_external_static_field_non_nullable() async {
+    await assertNoErrorsInCode('''
+class A {
+  external static int x;
+}
+''');
+  }
+
   test_staticField_futureOr_questionArgument_none() async {
     await assertNoErrorsInCode('''
 import 'dart:async';
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
index 65b9468..eaa394f 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
@@ -374,6 +374,24 @@
 ''');
   }
 
+  test_get_from_external_field_valid() async {
+    await assertNoErrorsInCode('''
+class A {
+  external int x;
+}
+int f(A a) => a.x;
+''');
+  }
+
+  test_get_from_external_static_field_valid() async {
+    await assertNoErrorsInCode('''
+class A {
+  external static int x;
+}
+int f() => A.x;
+''');
+  }
+
   @override
   @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/42957')
   test_typeLiteral_conditionalAccess() {
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
index d5c09b8..3fbb7c1 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
@@ -153,4 +153,26 @@
 }
 ''');
   }
+
+  test_set_external_field_valid() async {
+    await assertNoErrorsInCode('''
+class A {
+  external int x;
+}
+void f(A a, int x) {
+  a.x = x;
+}
+''');
+  }
+
+  test_set_external_static_field_valid() async {
+    await assertNoErrorsInCode('''
+class A {
+  external static int x;
+}
+void f(int x) {
+  A.x = x;
+}
+''');
+  }
 }
diff --git a/pkg/dartfix/README.md b/pkg/dartfix/README.md
index 245ac92..a3f0493 100644
--- a/pkg/dartfix/README.md
+++ b/pkg/dartfix/README.md
@@ -73,10 +73,10 @@
 If no issue exists for the fix, [create a GitHub issue.][new issue]
 
 [dartfix]: https://pub.dev/packages/dartfix
-[dartfmt]: https://www.dartlang.org/tools/dartfmt
+[dartfmt]: https://dart.dev/tools/dartfmt
 [added in Dart in 2.1]: https://github.com/dart-lang/sdk/blob/master/CHANGELOG.md#210---2018-11-15
 [features added to Dart in 2.1]: https://github.com/dart-lang/sdk/blob/master/CHANGELOG.md#210---2018-11-15
-[globally install]: https://www.dartlang.org/tools/pub/cmd/pub-global
+[globally install]: https://dart.dev/tools/pub/cmd/pub-global
 [new issue]: https://github.com/dart-lang/sdk/issues/new?title=dartfix%20request%3A%20%3CSUMMARIZE%20REQUEST%20HERE%3E
 [dartfix issues]: https://github.com/dart-lang/sdk/issues?q=is%3Aissue+is%3Aopen+label%3Aanalyzer-dartfix
-[PATH]: https://www.dartlang.org/tools/pub/cmd/pub-global#running-a-script-from-your-path
+[PATH]: https://dart.dev/tools/pub/cmd/pub-global#running-a-script-from-your-path
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 14ddeb8..f1c0e20 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -705,6 +705,12 @@
                   isSetter: m.isSetter);
           addUsedMember(m.forwardingStubInterfaceTarget);
         }
+        if (m.memberSignatureOrigin != null) {
+          m.memberSignatureOrigin = fieldMorpher.adjustInstanceCallTarget(
+              m.memberSignatureOrigin,
+              isSetter: m.isSetter);
+          addUsedMember(m.memberSignatureOrigin);
+        }
       } else if (m is Constructor) {
         func = m.function;
       } else {
diff --git a/pkg/vm_service/java/src/org/dartlang/vm/service/VmServiceBase.java b/pkg/vm_service/java/src/org/dartlang/vm/service/VmServiceBase.java
index f335d5c..c44b31d 100644
--- a/pkg/vm_service/java/src/org/dartlang/vm/service/VmServiceBase.java
+++ b/pkg/vm_service/java/src/org/dartlang/vm/service/VmServiceBase.java
@@ -313,7 +313,7 @@
   /**
    * Invoke a specific service protocol extension method.
    * <p>
-   * See https://api.dartlang.org/stable/dart-developer/dart-developer-library.html.
+   * See https://api.dart.dev/stable/dart-developer/dart-developer-library.html.
    */
   public void callServiceExtension(String isolateId, String method, ServiceExtensionConsumer consumer) {
     JsonObject params = new JsonObject();
@@ -324,7 +324,7 @@
   /**
    * Invoke a specific service protocol extension method.
    * <p>
-   * See https://api.dartlang.org/stable/dart-developer/dart-developer-library.html.
+   * See https://api.dart.dev/stable/dart-developer/dart-developer-library.html.
    */
   public void callServiceExtension(String isolateId, String method, JsonObject params, ServiceExtensionConsumer consumer) {
     params.addProperty("isolateId", isolateId);
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index c317c46..9fd8aba 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -2005,7 +2005,7 @@
 
   /// Invoke a specific service protocol extension method.
   ///
-  /// See https://api.dartlang.org/stable/dart-developer/dart-developer-library.html.
+  /// See https://api.dart.dev/stable/dart-developer/dart-developer-library.html.
   @override
   Future<Response> callServiceExtension(String method,
       {String isolateId, Map args}) {
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index 02ae7e1..1553861 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -77,7 +77,7 @@
 
   /// Invoke a specific service protocol extension method.
   ///
-  /// See https://api.dartlang.org/stable/dart-developer/dart-developer-library.html.
+  /// See https://api.dart.dev/stable/dart-developer/dart-developer-library.html.
   @override
   Future<Response> callServiceExtension(String method, {
     String isolateId,
diff --git a/pkg/vm_service/tool/java/generate_java.dart b/pkg/vm_service/tool/java/generate_java.dart
index 6254446..675ce5b 100644
--- a/pkg/vm_service/tool/java/generate_java.dart
+++ b/pkg/vm_service/tool/java/generate_java.dart
@@ -36,7 +36,7 @@
 </pre>
 where <strong>some-port</strong> is a port number of your choice
 which this client will use to communicate with the Dart VM.
-See https://www.dartlang.org/tools/dart-vm/ for more details.
+See https://dart.dev/tools/dart-vm for more details.
 Once the VM is running, instantiate a new {@link VmService}
 to connect to that VM via {@link VmService#connect(String)}
 or {@link VmService#localConnect(int)}.
diff --git a/samples/ffi/sqlite/.gitignore b/samples/ffi/sqlite/.gitignore
index 61f2cb6..7a6bc2e 100644
--- a/samples/ffi/sqlite/.gitignore
+++ b/samples/ffi/sqlite/.gitignore
@@ -4,4 +4,4 @@
 .vscode
 pubspec.lock
 test.db
-test.db-journal
+test.db-journal
\ No newline at end of file
diff --git a/samples/ffi/sqlite/lib/src/bindings/bindings.dart b/samples/ffi/sqlite/lib/src/bindings/bindings.dart
new file mode 100644
index 0000000..0271506
--- /dev/null
+++ b/samples/ffi/sqlite/lib/src/bindings/bindings.dart
@@ -0,0 +1,394 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 "../ffi/dylib_utils.dart";
+
+import "signatures.dart";
+import "types.dart";
+
+class _SQLiteBindings {
+  DynamicLibrary sqlite;
+
+  /// Opening A New Database Connection
+  ///
+  /// ^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.
+  int Function(Pointer<Utf8> filename, Pointer<Pointer<Database>> databaseOut,
+      int flags, Pointer<Utf8> vfs) sqlite3_open_v2;
+
+  int Function(Pointer<Database> database) sqlite3_close_v2;
+
+  /// Compiling An SQL Statement
+  ///
+  /// To execute an SQL query, it must first be compiled into a byte-code
+  /// program using one of these routines.
+  ///
+  /// 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() and sqlite3_prepare_v2()
+  /// interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
+  /// use UTF-16.
+  ///
+  /// ^If the nByte argument is less than zero, then zSql is read up to the
+  /// first zero terminator. ^If nByte is non-negative, then it is the maximum
+  /// number of  bytes read from zSql.  ^When nByte is non-negative, the
+  /// zSql string ends at either the first '\000' or '\u0000' character or
+  /// the nByte-th byte, whichever comes first. If the caller knows
+  /// that the supplied string is nul-terminated, then there is a small
+  /// performance advantage to be gained by passing an nByte parameter that
+  /// is equal to the number of bytes in the input string <i>including</i>
+  /// the nul-terminator bytes.
+  ///
+  /// ^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() and sqlite3_prepare16_v2() interfaces are
+  /// recommended for all new programs. The two older interfaces are retained
+  /// for backwards compatibility, but their use is discouraged.
+  /// ^In the "v2" 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:
+  int Function(
+      Pointer<Database> database,
+      Pointer<Utf8> query,
+      int nbytes,
+      Pointer<Pointer<Statement>> statementOut,
+      Pointer<Pointer<Utf8>> tail) sqlite3_prepare_v2;
+
+  /// Evaluate An SQL Statement
+  ///
+  /// After a prepared statement has been prepared using either
+  /// [sqlite3_prepare_v2] or sqlite3_prepare16_v2() 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 "v2" interface
+  /// [sqlite3_prepare_v2] and sqlite3_prepare16_v2() or the older legacy
+  /// interface sqlite3_prepare() and sqlite3_prepare16().  The use of the
+  /// new "v2" 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 [Errors.SQLITE_ROW] before any subsequent invocation of
+  /// sqlite3_step().  Failure to reset the prepared statement using
+  /// [sqlite3_reset()] would result in an [Errors.SQLITE_MISUSE] return from
+  /// sqlite3_step().  But after version 3.6.23.1, sqlite3_step() began
+  /// calling [sqlite3_reset] automatically in this circumstance rather
+  /// than returning [Errors.SQLITE_MISUSE]. This is not considered a
+  /// compatibility break because any application that ever receives an
+  /// [Errors.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 either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] 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 "v2" interface is recommended.
+  int Function(Pointer<Statement> statement) sqlite3_step;
+
+  /// CAPI3REF: Reset A Prepared Statement Object
+  ///
+  /// 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] interface resets the prepared statement S
+  /// back to the beginning of its program.
+  ///
+  /// ^If the most recent call to [sqlite3_step] for the
+  /// prepared statement S returned [Errors.SQLITE_ROW] or [Errors.SQLITE_DONE],
+  /// or if [sqlite3_step] has never before been called on S,
+  /// then [sqlite3_reset] returns [Errors.SQLITE_OK].
+  ///
+  /// ^If the most recent call to [sqlite3_step(S)] for the
+  /// prepared statement S indicated an error, then
+  /// [sqlite3_reset] returns an appropriate [Errors].
+  ///
+  /// ^The [sqlite3_reset] interface does not change the values
+  int Function(Pointer<Statement> statement) sqlite3_reset;
+
+  /// Destroy A Prepared Statement Object
+  ///
+  /// ^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 Function(Pointer<Statement> statement) sqlite3_finalize;
+
+  /// Number Of Columns In A Result Set
+  ///
+  /// ^Return the number of columns in the result set returned by the
+  /// prepared statement. ^This routine returns 0 if pStmt is an SQL
+  /// statement that does not return data (for example an [UPDATE]).
+  int Function(Pointer<Statement> statement) sqlite3_column_count;
+
+  /// Column Names In A Result Set
+  ///
+  /// ^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
+  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_name;
+
+  /// CAPI3REF: Declared Datatype Of A Query Result
+  ///
+  /// ^(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.
+  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_decltype;
+
+  int Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_type;
+
+  Pointer<Value> Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_value;
+
+  double Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_double;
+
+  int Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_int;
+
+  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_text;
+
+  /// 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.
+  Pointer<Utf8> Function(int code) sqlite3_errstr;
+
+  /// Error Codes And Messages
+  ///
+  /// ^The sqlite3_errcode() interface returns the numeric [result code] or
+  /// [extended result code] for the most recent failed sqlite3_* API call
+  /// associated with a [database connection]. If a prior API call failed
+  /// but the most recent API call succeeded, the return value from
+  /// sqlite3_errcode() is undefined.  ^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 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.)^
+  ///
+  /// 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.
+  Pointer<Utf8> Function(Pointer<Database> database) sqlite3_errmsg;
+
+  _SQLiteBindings() {
+    sqlite = dlopenPlatformSpecific("sqlite3");
+    sqlite3_open_v2 = sqlite
+        .lookup<NativeFunction<sqlite3_open_v2_native_t>>("sqlite3_open_v2")
+        .asFunction();
+    sqlite3_close_v2 = sqlite
+        .lookup<NativeFunction<sqlite3_close_v2_native_t>>("sqlite3_close_v2")
+        .asFunction();
+    sqlite3_prepare_v2 = sqlite
+        .lookup<NativeFunction<sqlite3_prepare_v2_native_t>>(
+            "sqlite3_prepare_v2")
+        .asFunction();
+    sqlite3_step = sqlite
+        .lookup<NativeFunction<sqlite3_step_native_t>>("sqlite3_step")
+        .asFunction();
+    sqlite3_reset = sqlite
+        .lookup<NativeFunction<sqlite3_reset_native_t>>("sqlite3_reset")
+        .asFunction();
+    sqlite3_finalize = sqlite
+        .lookup<NativeFunction<sqlite3_finalize_native_t>>("sqlite3_finalize")
+        .asFunction();
+    sqlite3_errstr = sqlite
+        .lookup<NativeFunction<sqlite3_errstr_native_t>>("sqlite3_errstr")
+        .asFunction();
+    sqlite3_errmsg = sqlite
+        .lookup<NativeFunction<sqlite3_errmsg_native_t>>("sqlite3_errmsg")
+        .asFunction();
+    sqlite3_column_count = sqlite
+        .lookup<NativeFunction<sqlite3_column_count_native_t>>(
+            "sqlite3_column_count")
+        .asFunction();
+    sqlite3_column_name = sqlite
+        .lookup<NativeFunction<sqlite3_column_name_native_t>>(
+            "sqlite3_column_name")
+        .asFunction();
+    sqlite3_column_decltype = sqlite
+        .lookup<NativeFunction<sqlite3_column_decltype_native_t>>(
+            "sqlite3_column_decltype")
+        .asFunction();
+    sqlite3_column_type = sqlite
+        .lookup<NativeFunction<sqlite3_column_type_native_t>>(
+            "sqlite3_column_type")
+        .asFunction();
+    sqlite3_column_value = sqlite
+        .lookup<NativeFunction<sqlite3_column_value_native_t>>(
+            "sqlite3_column_value")
+        .asFunction();
+    sqlite3_column_double = sqlite
+        .lookup<NativeFunction<sqlite3_column_double_native_t>>(
+            "sqlite3_column_double")
+        .asFunction();
+    sqlite3_column_int = sqlite
+        .lookup<NativeFunction<sqlite3_column_int_native_t>>(
+            "sqlite3_column_int")
+        .asFunction();
+    sqlite3_column_text = sqlite
+        .lookup<NativeFunction<sqlite3_column_text_native_t>>(
+            "sqlite3_column_text")
+        .asFunction();
+  }
+}
+
+_SQLiteBindings _cachedBindings;
+_SQLiteBindings get bindings => _cachedBindings ??= _SQLiteBindings();
diff --git a/samples/ffi/sqlite/lib/src/bindings/constants.dart b/samples/ffi/sqlite/lib/src/bindings/constants.dart
new file mode 100644
index 0000000..71aa82e
--- /dev/null
+++ b/samples/ffi/sqlite/lib/src/bindings/constants.dart
@@ -0,0 +1,182 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Result Codes
+///
+/// Many SQLite functions return an integer result code from the set shown
+/// here in order to indicates success or failure.
+///
+/// New error codes may be added in future versions of SQLite.
+///
+/// See also: SQLITE_IOERR_READ | extended result codes,
+/// sqlite3_vtab_on_conflict() SQLITE_ROLLBACK | result codes.
+class Errors {
+  /// Successful result
+  static const int SQLITE_OK = 0;
+
+  /// Generic error
+  static const int SQLITE_ERROR = 1;
+
+  /// Internal logic error in SQLite
+  static const int SQLITE_INTERNAL = 2;
+
+  /// Access permission denied
+  static const int SQLITE_PERM = 3;
+
+  /// Callback routine requested an abort
+  static const int SQLITE_ABORT = 4;
+
+  /// The database file is locked
+  static const int SQLITE_BUSY = 5;
+
+  /// A table in the database is locked
+  static const int SQLITE_LOCKED = 6;
+
+  /// A malloc() failed
+  static const int SQLITE_NOMEM = 7;
+
+  /// Attempt to write a readonly database
+  static const int SQLITE_READONLY = 8;
+
+  /// Operation terminated by sqlite3_interrupt()
+  static const int SQLITE_INTERRUPT = 9;
+
+  /// Some kind of disk I/O error occurred
+  static const int SQLITE_IOERR = 10;
+
+  /// The database disk image is malformed
+  static const int SQLITE_CORRUPT = 11;
+
+  /// Unknown opcode in sqlite3_file_control()
+  static const int SQLITE_NOTFOUND = 12;
+
+  /// Insertion failed because database is full
+  static const int SQLITE_FULL = 13;
+
+  /// Unable to open the database file
+  static const int SQLITE_CANTOPEN = 14;
+
+  /// Database lock protocol error
+  static const int SQLITE_PROTOCOL = 15;
+
+  /// Internal use only
+  static const int SQLITE_EMPTY = 16;
+
+  /// The database schema changed
+  static const int SQLITE_SCHEMA = 17;
+
+  /// String or BLOB exceeds size limit
+  static const int SQLITE_TOOBIG = 18;
+
+  /// Abort due to constraint violation
+  static const int SQLITE_CONSTRAINT = 19;
+
+  /// Data type mismatch
+  static const int SQLITE_MISMATCH = 20;
+
+  /// Library used incorrectly
+  static const int SQLITE_MISUSE = 21;
+
+  /// Uses OS features not supported on host
+  static const int SQLITE_NOLFS = 22;
+
+  /// Authorization denied
+  static const int SQLITE_AUTH = 23;
+
+  /// Not used
+  static const int SQLITE_FORMAT = 24;
+
+  /// 2nd parameter to sqlite3_bind out of range
+  static const int SQLITE_RANGE = 25;
+
+  /// File opened that is not a database file
+  static const int SQLITE_NOTADB = 26;
+
+  /// Notifications from sqlite3_log()
+  static const int SQLITE_NOTICE = 27;
+
+  /// Warnings from sqlite3_log()
+  static const int SQLITE_WARNING = 28;
+
+  /// sqlite3_step() has another row ready
+  static const int SQLITE_ROW = 100;
+
+  /// sqlite3_step() has finished executing
+  static const int SQLITE_DONE = 101;
+}
+
+/// 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.
+class Flags {
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_READONLY = 0x00000001;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_READWRITE = 0x00000002;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_CREATE = 0x00000004;
+
+  /// VFS only
+  static const int SQLITE_OPEN_DELETEONCLOSE = 0x00000008;
+
+  /// VFS only
+  static const int SQLITE_OPEN_EXCLUSIVE = 0x00000010;
+
+  /// VFS only
+  static const int SQLITE_OPEN_AUTOPROXY = 0x00000020;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_URI = 0x00000040;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_MEMORY = 0x00000080;
+
+  /// VFS only
+  static const int SQLITE_OPEN_MAIN_DB = 0x00000100;
+
+  /// VFS only
+  static const int SQLITE_OPEN_TEMP_DB = 0x00000200;
+
+  /// VFS only
+  static const int SQLITE_OPEN_TRANSIENT_DB = 0x00000400;
+
+  /// VFS only
+  static const int SQLITE_OPEN_MAIN_JOURNAL = 0x00000800;
+
+  /// VFS only
+  static const int SQLITE_OPEN_TEMP_JOURNAL = 0x00001000;
+
+  /// VFS only
+  static const int SQLITE_OPEN_SUBJOURNAL = 0x00002000;
+
+  /// VFS only
+  static const int SQLITE_OPEN_MASTER_JOURNAL = 0x00004000;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_NOMUTEX = 0x00008000;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_FULLMUTEX = 0x00010000;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_SHAREDCACHE = 0x00020000;
+
+  /// Ok for sqlite3_open_v2()
+  static const int SQLITE_OPEN_PRIVATECACHE = 0x00040000;
+
+  /// VFS only
+  static const int SQLITE_OPEN_WAL = 0x00080000;
+}
+
+class Types {
+  static const int SQLITE_INTEGER = 1;
+  static const int SQLITE_FLOAT = 2;
+  static const int SQLITE_TEXT = 3;
+  static const int SQLITE_BLOB = 4;
+  static const int SQLITE_NULL = 5;
+}
diff --git a/samples/ffi/sqlite/lib/src/bindings/signatures.dart b/samples/ffi/sqlite/lib/src/bindings/signatures.dart
new file mode 100644
index 0000000..2f38dad
--- /dev/null
+++ b/samples/ffi/sqlite/lib/src/bindings/signatures.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 "types.dart";
+
+typedef sqlite3_open_v2_native_t = Int32 Function(Pointer<Utf8> filename,
+    Pointer<Pointer<Database>> ppDb, Int32 flags, Pointer<Utf8> vfs);
+
+typedef sqlite3_close_v2_native_t = Int32 Function(Pointer<Database> database);
+
+typedef sqlite3_prepare_v2_native_t = Int32 Function(
+    Pointer<Database> database,
+    Pointer<Utf8> query,
+    Int32 nbytes,
+    Pointer<Pointer<Statement>> statementOut,
+    Pointer<Pointer<Utf8>> tail);
+
+typedef sqlite3_step_native_t = Int32 Function(Pointer<Statement> statement);
+
+typedef sqlite3_reset_native_t = Int32 Function(Pointer<Statement> statement);
+
+typedef sqlite3_finalize_native_t = Int32 Function(
+    Pointer<Statement> statement);
+
+typedef sqlite3_errstr_native_t = Pointer<Utf8> Function(Int32 error);
+
+typedef sqlite3_errmsg_native_t = Pointer<Utf8> Function(
+    Pointer<Database> database);
+
+typedef sqlite3_column_count_native_t = Int32 Function(
+    Pointer<Statement> statement);
+
+typedef sqlite3_column_name_native_t = Pointer<Utf8> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_decltype_native_t = Pointer<Utf8> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_type_native_t = Int32 Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_value_native_t = Pointer<Value> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_double_native_t = Double Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_int_native_t = Int32 Function(
+    Pointer<Statement> statement, Int32 columnIndex);
+
+typedef sqlite3_column_text_native_t = Pointer<Utf8> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
diff --git a/samples/ffi/sqlite/lib/src/bindings/types.dart b/samples/ffi/sqlite/lib/src/bindings/types.dart
new file mode 100644
index 0000000..494cdef
--- /dev/null
+++ b/samples/ffi/sqlite/lib/src/bindings/types.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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";
+
+/// Database Connection Handle
+///
+/// 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()]
+/// is its destructor.  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
+class Database extends Struct {}
+
+/// SQL Statement Object
+///
+/// An instance of this object represents a single SQL statement.
+/// This object is variously known as a "prepared statement" or a
+/// "compiled SQL statement" or simply as a "statement".
+///
+/// The life of a statement object goes something like this:
+///
+/// <ol>
+/// <li> Create the object using [sqlite3_prepare_v2()] or a related
+///      function.
+/// <li> Bind values to [host parameters] using the sqlite3_bind_*()
+///      interfaces.
+/// <li> Run the SQL by calling [sqlite3_step()] one or more times.
+/// <li> Reset the statement using [sqlite3_reset()] then go back
+///      to step 2.  Do this zero or more times.
+/// <li> Destroy the object using [sqlite3_finalize()].
+/// </ol>
+///
+/// Refer to documentation on individual methods above for additional
+/// information.
+class Statement extends Struct {}
+
+/// Dynamically Typed Value Object
+///
+/// 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 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 with
+/// [sqlite3_result_value()] and [sqlite3_bind_value()].
+/// The [sqlite3_value_blob | sqlite3_value_type()] family of
+/// interfaces require protected sqlite3_value objects.
+class Value extends Struct {}
diff --git a/samples/ffi/sqlite/lib/src/database.dart b/samples/ffi/sqlite/lib/src/database.dart
index ffbe710..be2b7ef 100644
--- a/samples/ffi/sqlite/lib/src/database.dart
+++ b/samples/ffi/sqlite/lib/src/database.dart
@@ -7,11 +7,13 @@
 
 import "package:ffi/ffi.dart";
 
-import "third_party/sqlite/sqlite3_bindings_generated.dart" as bindings;
-import "collections/closable_iterator.dart";
-import "ffi/dylib_utils.dart";
+import "bindings/bindings.dart";
 
-final sqlite = bindings.SQLite(dlopenPlatformSpecific("sqlite3"));
+import "bindings/types.dart" as types;
+import "bindings/types.dart" hide Database;
+
+import "bindings/constants.dart";
+import "collections/closable_iterator.dart";
 
 /// [Database] represents an open connection to a SQLite database.
 ///
@@ -19,27 +21,26 @@
 ///
 /// This database interacts with SQLite synchonously.
 class Database {
-  Pointer<bindings.sqlite3> _database;
+  Pointer<types.Database> _database;
   bool _open = false;
 
   /// Open a database located at the file [path].
   Database(String path,
-      [int flags =
-          bindings.SQLITE_OPEN_READWRITE | bindings.SQLITE_OPEN_CREATE]) {
-    Pointer<Pointer<bindings.sqlite3>> dbOut = allocate();
-    final pathC = Utf8.toUtf8(path).cast<Int8>();
-    final int resultCode = sqlite.sqlite3_open_v2(pathC, dbOut, flags, nullptr);
+      [int flags = Flags.SQLITE_OPEN_READWRITE | Flags.SQLITE_OPEN_CREATE]) {
+    Pointer<Pointer<types.Database>> dbOut = allocate();
+    final pathC = Utf8.toUtf8(path);
+    final int resultCode =
+        bindings.sqlite3_open_v2(pathC, dbOut, flags, nullptr);
     _database = dbOut.value;
     free(dbOut);
     free(pathC);
 
-    if (resultCode == bindings.SQLITE_OK) {
+    if (resultCode == Errors.SQLITE_OK) {
       _open = true;
     } else {
       // Even if "open" fails, sqlite3 will still create a database object. We
       // can just destroy it.
       SQLiteException exception = _loadError(resultCode);
-      _open = true;
       close();
       throw exception;
     }
@@ -52,8 +53,8 @@
   /// avoid resource leaks.
   void close() {
     assert(_open);
-    final int resultCode = sqlite.sqlite3_close_v2(_database);
-    if (resultCode == bindings.SQLITE_OK) {
+    final int resultCode = bindings.sqlite3_close_v2(_database);
+    if (resultCode == Errors.SQLITE_OK) {
       _open = false;
     } else {
       throw _loadError(resultCode);
@@ -62,44 +63,43 @@
 
   /// Execute a query, discarding any returned rows.
   void execute(String query) {
-    Pointer<Pointer<bindings.sqlite3_stmt>> statementOut = allocate();
-    final queryC = Utf8.toUtf8(query).cast<Int8>();
-    int resultCode =
-        sqlite.sqlite3_prepare_v2(_database, queryC, -1, statementOut, nullptr);
-    Pointer<bindings.sqlite3_stmt> statement = statementOut.value;
+    Pointer<Pointer<Statement>> statementOut = allocate();
+    Pointer<Utf8> queryC = Utf8.toUtf8(query);
+    int resultCode = bindings.sqlite3_prepare_v2(
+        _database, queryC, -1, statementOut, nullptr);
+    Pointer<Statement> statement = statementOut.value;
     free(statementOut);
     free(queryC);
 
-    while (
-        resultCode == bindings.SQLITE_ROW || resultCode == bindings.SQLITE_OK) {
-      resultCode = sqlite.sqlite3_step(statement);
+    while (resultCode == Errors.SQLITE_ROW || resultCode == Errors.SQLITE_OK) {
+      resultCode = bindings.sqlite3_step(statement);
     }
-    sqlite.sqlite3_finalize(statement);
-    if (resultCode != bindings.SQLITE_DONE) {
+    bindings.sqlite3_finalize(statement);
+    if (resultCode != Errors.SQLITE_DONE) {
       throw _loadError(resultCode);
     }
   }
 
   /// Evaluate a query and return the resulting rows as an iterable.
   Result query(String query) {
-    Pointer<Pointer<bindings.sqlite3_stmt>> statementOut = allocate();
-    final queryC = Utf8.toUtf8(query).cast<Int8>();
-    int resultCode =
-        sqlite.sqlite3_prepare_v2(_database, queryC, -1, statementOut, nullptr);
-    Pointer<bindings.sqlite3_stmt> statement = statementOut.value;
+    Pointer<Pointer<Statement>> statementOut = allocate();
+    Pointer<Utf8> queryC = Utf8.toUtf8(query);
+    int resultCode = bindings.sqlite3_prepare_v2(
+        _database, queryC, -1, statementOut, nullptr);
+    Pointer<Statement> statement = statementOut.value;
     free(statementOut);
     free(queryC);
 
-    if (resultCode != bindings.SQLITE_OK) {
-      sqlite.sqlite3_finalize(statement);
+    if (resultCode != Errors.SQLITE_OK) {
+      bindings.sqlite3_finalize(statement);
       throw _loadError(resultCode);
     }
 
     Map<String, int> columnIndices = {};
-    int columnCount = sqlite.sqlite3_column_count(statement);
+    int columnCount = bindings.sqlite3_column_count(statement);
     for (int i = 0; i < columnCount; i++) {
       String columnName =
-          sqlite.sqlite3_column_name(statement, i).cast<Utf8>().ref.toString();
+          bindings.sqlite3_column_name(statement, i).ref.toString();
       columnIndices[columnName] = i;
     }
 
@@ -107,13 +107,12 @@
   }
 
   SQLiteException _loadError([int errorCode]) {
-    String errorMessage =
-        sqlite.sqlite3_errmsg(_database).cast<Utf8>().ref.toString();
+    String errorMessage = bindings.sqlite3_errmsg(_database).ref.toString();
     if (errorCode == null) {
       return SQLiteException(errorMessage);
     }
     String errorCodeExplanation =
-        sqlite.sqlite3_errstr(errorCode).cast<Utf8>().ref.toString();
+        bindings.sqlite3_errstr(errorCode).ref.toString();
     return SQLiteException(
         "$errorMessage (Code $errorCode: $errorCodeExplanation)");
   }
@@ -127,7 +126,7 @@
 class Result extends IterableBase<Row> implements ClosableIterable<Row> {
   final Database _database;
   final ClosableIterator<Row> _iterator;
-  final Pointer<bindings.sqlite3_stmt> _statement;
+  final Pointer<Statement> _statement;
   final Map<String, int> _columnIndices;
 
   Row _currentRow = null;
@@ -144,7 +143,7 @@
 }
 
 class _ResultIterator implements ClosableIterator<Row> {
-  final Pointer<bindings.sqlite3_stmt> _statement;
+  final Pointer<Statement> _statement;
   final Map<String, int> _columnIndices;
 
   Row _currentRow = null;
@@ -157,8 +156,8 @@
       throw SQLiteException("The result has already been closed.");
     }
     _currentRow?._setNotCurrent();
-    int stepResult = sqlite.sqlite3_step(_statement);
-    if (stepResult == bindings.SQLITE_ROW) {
+    int stepResult = bindings.sqlite3_step(_statement);
+    if (stepResult == Errors.SQLITE_ROW) {
       _currentRow = Row._(_statement, _columnIndices);
       return true;
     } else {
@@ -177,12 +176,12 @@
   void close() {
     _currentRow?._setNotCurrent();
     _closed = true;
-    sqlite.sqlite3_finalize(_statement);
+    bindings.sqlite3_finalize(_statement);
   }
 }
 
 class Row {
-  final Pointer<bindings.sqlite3_stmt> _statement;
+  final Pointer<Statement> _statement;
   final Map<String, int> _columnIndices;
 
   bool _isCurrentRow = true;
@@ -211,11 +210,10 @@
     Type dynamicType;
     if (convert == Convert.DynamicType) {
       dynamicType =
-          _typeFromCode(sqlite.sqlite3_column_type(_statement, columnIndex));
+          _typeFromCode(bindings.sqlite3_column_type(_statement, columnIndex));
     } else {
-      dynamicType = _typeFromText(sqlite
+      dynamicType = _typeFromText(bindings
           .sqlite3_column_decltype(_statement, columnIndex)
-          .cast<Utf8>()
           .ref
           .toString());
     }
@@ -242,7 +240,7 @@
   /// integer.
   int readColumnByIndexAsInt(int columnIndex) {
     _checkIsCurrentRow();
-    return sqlite.sqlite3_column_int(_statement, columnIndex);
+    return bindings.sqlite3_column_int(_statement, columnIndex);
   }
 
   /// Reads column [columnName] and converts to [Type.Text] if not text.
@@ -253,11 +251,7 @@
   /// Reads column [columnIndex] and converts to [Type.Text] if not text.
   String readColumnByIndexAsText(int columnIndex) {
     _checkIsCurrentRow();
-    return sqlite
-        .sqlite3_column_text(_statement, columnIndex)
-        .cast<Utf8>()
-        .ref
-        .toString();
+    return bindings.sqlite3_column_text(_statement, columnIndex).ref.toString();
   }
 
   void _checkIsCurrentRow() {
@@ -275,15 +269,15 @@
 
 Type _typeFromCode(int code) {
   switch (code) {
-    case bindings.SQLITE_INTEGER:
+    case Types.SQLITE_INTEGER:
       return Type.Integer;
-    case bindings.SQLITE_FLOAT:
+    case Types.SQLITE_FLOAT:
       return Type.Float;
-    case bindings.SQLITE_TEXT:
+    case Types.SQLITE_TEXT:
       return Type.Text;
-    case bindings.SQLITE_BLOB:
+    case Types.SQLITE_BLOB:
       return Type.Blob;
-    case bindings.SQLITE_NULL:
+    case Types.SQLITE_NULL:
       return Type.Null;
   }
   throw Exception("Unknown type [$code]");
diff --git a/samples/ffi/sqlite/lib/src/third_party/sqlite/sqlite3_bindings_generated.dart b/samples/ffi/sqlite/lib/src/third_party/sqlite/sqlite3_bindings_generated.dart
deleted file mode 100644
index bfbd4c8..0000000
--- a/samples/ffi/sqlite/lib/src/third_party/sqlite/sqlite3_bindings_generated.dart
+++ /dev/null
@@ -1,1968 +0,0 @@
-// 2001 September 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.
-
-import 'dart:ffi' as ffi;
-
-/// SQLite bindings.
-class SQLite {
-  /// Holds the Dynamic library.
-  final ffi.DynamicLibrary _dylib;
-
-  /// The symbols are looked up in [dynamicLibrary].
-  SQLite(ffi.DynamicLibrary dynamicLibrary) : _dylib = dynamicLibrary;
-
-  int sqlite3_close_v2(
-    ffi.Pointer<sqlite3> arg0,
-  ) {
-    _sqlite3_close_v2 ??=
-        _dylib.lookupFunction<_c_sqlite3_close_v2, _dart_sqlite3_close_v2>(
-            'sqlite3_close_v2');
-    return _sqlite3_close_v2(
-      arg0,
-    );
-  }
-
-  _dart_sqlite3_close_v2 _sqlite3_close_v2;
-
-  int sqlite3_open_v2(
-    ffi.Pointer<ffi.Int8> filename,
-    ffi.Pointer<ffi.Pointer<sqlite3>> ppDb,
-    int flags,
-    ffi.Pointer<ffi.Int8> zVfs,
-  ) {
-    _sqlite3_open_v2 ??=
-        _dylib.lookupFunction<_c_sqlite3_open_v2, _dart_sqlite3_open_v2>(
-            'sqlite3_open_v2');
-    return _sqlite3_open_v2(
-      filename,
-      ppDb,
-      flags,
-      zVfs,
-    );
-  }
-
-  _dart_sqlite3_open_v2 _sqlite3_open_v2;
-
-  ffi.Pointer<ffi.Int8> sqlite3_errmsg(
-    ffi.Pointer<sqlite3> arg0,
-  ) {
-    _sqlite3_errmsg ??=
-        _dylib.lookupFunction<_c_sqlite3_errmsg, _dart_sqlite3_errmsg>(
-            'sqlite3_errmsg');
-    return _sqlite3_errmsg(
-      arg0,
-    );
-  }
-
-  _dart_sqlite3_errmsg _sqlite3_errmsg;
-
-  ffi.Pointer<ffi.Int8> sqlite3_errstr(
-    int arg0,
-  ) {
-    _sqlite3_errstr ??=
-        _dylib.lookupFunction<_c_sqlite3_errstr, _dart_sqlite3_errstr>(
-            'sqlite3_errstr');
-    return _sqlite3_errstr(
-      arg0,
-    );
-  }
-
-  _dart_sqlite3_errstr _sqlite3_errstr;
-
-  int sqlite3_prepare_v2(
-    ffi.Pointer<sqlite3> db,
-    ffi.Pointer<ffi.Int8> zSql,
-    int nByte,
-    ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
-    ffi.Pointer<ffi.Pointer<ffi.Int8>> pzTail,
-  ) {
-    _sqlite3_prepare_v2 ??=
-        _dylib.lookupFunction<_c_sqlite3_prepare_v2, _dart_sqlite3_prepare_v2>(
-            'sqlite3_prepare_v2');
-    return _sqlite3_prepare_v2(
-      db,
-      zSql,
-      nByte,
-      ppStmt,
-      pzTail,
-    );
-  }
-
-  _dart_sqlite3_prepare_v2 _sqlite3_prepare_v2;
-
-  /// 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,
-  ) {
-    _sqlite3_column_count ??= _dylib.lookupFunction<_c_sqlite3_column_count,
-        _dart_sqlite3_column_count>('sqlite3_column_count');
-    return _sqlite3_column_count(
-      pStmt,
-    );
-  }
-
-  _dart_sqlite3_column_count _sqlite3_column_count;
-
-  /// 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.Int8> sqlite3_column_name(
-    ffi.Pointer<sqlite3_stmt> arg0,
-    int N,
-  ) {
-    _sqlite3_column_name ??= _dylib.lookupFunction<_c_sqlite3_column_name,
-        _dart_sqlite3_column_name>('sqlite3_column_name');
-    return _sqlite3_column_name(
-      arg0,
-      N,
-    );
-  }
-
-  _dart_sqlite3_column_name _sqlite3_column_name;
-
-  /// 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.Int8> sqlite3_column_decltype(
-    ffi.Pointer<sqlite3_stmt> arg0,
-    int arg1,
-  ) {
-    _sqlite3_column_decltype ??= _dylib.lookupFunction<
-        _c_sqlite3_column_decltype,
-        _dart_sqlite3_column_decltype>('sqlite3_column_decltype');
-    return _sqlite3_column_decltype(
-      arg0,
-      arg1,
-    );
-  }
-
-  _dart_sqlite3_column_decltype _sqlite3_column_decltype;
-
-  /// 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,
-  ) {
-    _sqlite3_step ??= _dylib
-        .lookupFunction<_c_sqlite3_step, _dart_sqlite3_step>('sqlite3_step');
-    return _sqlite3_step(
-      arg0,
-    );
-  }
-
-  _dart_sqlite3_step _sqlite3_step;
-
-  int sqlite3_column_int(
-    ffi.Pointer<sqlite3_stmt> arg0,
-    int iCol,
-  ) {
-    _sqlite3_column_int ??=
-        _dylib.lookupFunction<_c_sqlite3_column_int, _dart_sqlite3_column_int>(
-            'sqlite3_column_int');
-    return _sqlite3_column_int(
-      arg0,
-      iCol,
-    );
-  }
-
-  _dart_sqlite3_column_int _sqlite3_column_int;
-
-  ffi.Pointer<ffi.Uint8> sqlite3_column_text(
-    ffi.Pointer<sqlite3_stmt> arg0,
-    int iCol,
-  ) {
-    _sqlite3_column_text ??= _dylib.lookupFunction<_c_sqlite3_column_text,
-        _dart_sqlite3_column_text>('sqlite3_column_text');
-    return _sqlite3_column_text(
-      arg0,
-      iCol,
-    );
-  }
-
-  _dart_sqlite3_column_text _sqlite3_column_text;
-
-  int sqlite3_column_type(
-    ffi.Pointer<sqlite3_stmt> arg0,
-    int iCol,
-  ) {
-    _sqlite3_column_type ??= _dylib.lookupFunction<_c_sqlite3_column_type,
-        _dart_sqlite3_column_type>('sqlite3_column_type');
-    return _sqlite3_column_type(
-      arg0,
-      iCol,
-    );
-  }
-
-  _dart_sqlite3_column_type _sqlite3_column_type;
-
-  /// 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,
-  ) {
-    _sqlite3_finalize ??=
-        _dylib.lookupFunction<_c_sqlite3_finalize, _dart_sqlite3_finalize>(
-            'sqlite3_finalize');
-    return _sqlite3_finalize(
-      pStmt,
-    );
-  }
-
-  _dart_sqlite3_finalize _sqlite3_finalize;
-}
-
-class sqlite3 extends ffi.Struct {}
-
-class sqlite3_file extends ffi.Struct {}
-
-class sqlite3_io_methods extends ffi.Struct {
-  @ffi.Int32()
-  int iVersion;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_1>> xClose;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_2>> xRead;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_3>> xWrite;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_4>> xTruncate;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_5>> xSync;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_6>> xFileSize;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_7>> xLock;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_8>> xUnlock;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_9>> xCheckReservedLock;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_10>> xFileControl;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_11>> xSectorSize;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_12>> xDeviceCharacteristics;
-
-  /// Methods above are valid for version 1
-  ffi.Pointer<ffi.NativeFunction<_typedefC_13>> xShmMap;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_14>> xShmLock;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_15>> xShmBarrier;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_16>> xShmUnmap;
-
-  /// Methods above are valid for version 2
-  ffi.Pointer<ffi.NativeFunction<_typedefC_17>> xFetch;
-
-  ffi.Pointer<ffi.NativeFunction<_typedefC_18>> xUnfetch;
-}
-
-class sqlite3_mutex extends ffi.Struct {}
-
-class sqlite3_api_routines extends ffi.Struct {}
-
-class sqlite3_vfs extends ffi.Struct {}
-
-class sqlite3_mem_methods extends ffi.Struct {}
-
-class sqlite3_stmt extends ffi.Struct {}
-
-class sqlite3_value extends ffi.Struct {}
-
-class sqlite3_context extends ffi.Struct {}
-
-/// 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.
-class sqlite3_vtab extends ffi.Struct {}
-
-/// 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.
-class sqlite3_index_info extends ffi.Struct {}
-
-/// 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.
-class sqlite3_vtab_cursor extends ffi.Struct {}
-
-/// 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.
-class sqlite3_module extends ffi.Struct {}
-
-class sqlite3_blob extends ffi.Struct {}
-
-class sqlite3_mutex_methods extends ffi.Struct {}
-
-class sqlite3_str extends ffi.Struct {}
-
-class sqlite3_pcache extends ffi.Struct {}
-
-class sqlite3_pcache_page extends ffi.Struct {}
-
-class sqlite3_pcache_methods2 extends ffi.Struct {}
-
-class sqlite3_pcache_methods extends ffi.Struct {}
-
-class sqlite3_backup extends ffi.Struct {}
-
-/// 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.
-class sqlite3_snapshot extends ffi.Struct {}
-
-/// A pointer to a structure of the following type is passed as the first
-/// argument to callbacks registered using rtree_geometry_callback().
-class sqlite3_rtree_geometry extends ffi.Struct {}
-
-/// 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.
-class sqlite3_rtree_query_info extends ffi.Struct {}
-
-/// 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.
-class Fts5ExtensionApi extends ffi.Struct {}
-
-class Fts5Context extends ffi.Struct {}
-
-class Fts5PhraseIter extends ffi.Struct {}
-
-class Fts5Tokenizer extends ffi.Struct {}
-
-class fts5_tokenizer extends ffi.Struct {}
-
-class fts5_api extends ffi.Struct {}
-
-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;
-
-typedef _c_sqlite3_close_v2 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3> arg0,
-);
-
-typedef _dart_sqlite3_close_v2 = int Function(
-  ffi.Pointer<sqlite3> arg0,
-);
-
-typedef _c_sqlite3_open_v2 = ffi.Int32 Function(
-  ffi.Pointer<ffi.Int8> filename,
-  ffi.Pointer<ffi.Pointer<sqlite3>> ppDb,
-  ffi.Int32 flags,
-  ffi.Pointer<ffi.Int8> zVfs,
-);
-
-typedef _dart_sqlite3_open_v2 = int Function(
-  ffi.Pointer<ffi.Int8> filename,
-  ffi.Pointer<ffi.Pointer<sqlite3>> ppDb,
-  int flags,
-  ffi.Pointer<ffi.Int8> zVfs,
-);
-
-typedef _c_sqlite3_errmsg = ffi.Pointer<ffi.Int8> Function(
-  ffi.Pointer<sqlite3> arg0,
-);
-
-typedef _dart_sqlite3_errmsg = ffi.Pointer<ffi.Int8> Function(
-  ffi.Pointer<sqlite3> arg0,
-);
-
-typedef _c_sqlite3_errstr = ffi.Pointer<ffi.Int8> Function(
-  ffi.Int32 arg0,
-);
-
-typedef _dart_sqlite3_errstr = ffi.Pointer<ffi.Int8> Function(
-  int arg0,
-);
-
-typedef _c_sqlite3_prepare_v2 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3> db,
-  ffi.Pointer<ffi.Int8> zSql,
-  ffi.Int32 nByte,
-  ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
-  ffi.Pointer<ffi.Pointer<ffi.Int8>> pzTail,
-);
-
-typedef _dart_sqlite3_prepare_v2 = int Function(
-  ffi.Pointer<sqlite3> db,
-  ffi.Pointer<ffi.Int8> zSql,
-  int nByte,
-  ffi.Pointer<ffi.Pointer<sqlite3_stmt>> ppStmt,
-  ffi.Pointer<ffi.Pointer<ffi.Int8>> pzTail,
-);
-
-typedef _c_sqlite3_column_count = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_stmt> pStmt,
-);
-
-typedef _dart_sqlite3_column_count = int Function(
-  ffi.Pointer<sqlite3_stmt> pStmt,
-);
-
-typedef _c_sqlite3_column_name = ffi.Pointer<ffi.Int8> Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-  ffi.Int32 N,
-);
-
-typedef _dart_sqlite3_column_name = ffi.Pointer<ffi.Int8> Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-  int N,
-);
-
-typedef _c_sqlite3_column_decltype = ffi.Pointer<ffi.Int8> Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-  ffi.Int32 arg1,
-);
-
-typedef _dart_sqlite3_column_decltype = ffi.Pointer<ffi.Int8> Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-  int arg1,
-);
-
-typedef _c_sqlite3_step = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-);
-
-typedef _dart_sqlite3_step = int Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-);
-
-typedef _c_sqlite3_column_int = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-  ffi.Int32 iCol,
-);
-
-typedef _dart_sqlite3_column_int = int Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-  int iCol,
-);
-
-typedef _c_sqlite3_column_text = ffi.Pointer<ffi.Uint8> Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-  ffi.Int32 iCol,
-);
-
-typedef _dart_sqlite3_column_text = ffi.Pointer<ffi.Uint8> Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-  int iCol,
-);
-
-typedef _c_sqlite3_column_type = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-  ffi.Int32 iCol,
-);
-
-typedef _dart_sqlite3_column_type = int Function(
-  ffi.Pointer<sqlite3_stmt> arg0,
-  int iCol,
-);
-
-typedef _c_sqlite3_finalize = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_stmt> pStmt,
-);
-
-typedef _dart_sqlite3_finalize = int Function(
-  ffi.Pointer<sqlite3_stmt> pStmt,
-);
-
-typedef _typedefC_1 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-);
-
-typedef _typedefC_2 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Pointer<ffi.Void>,
-  ffi.Int32,
-  ffi.Int64,
-);
-
-typedef _typedefC_3 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Pointer<ffi.Void>,
-  ffi.Int32,
-  ffi.Int64,
-);
-
-typedef _typedefC_4 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Int64,
-);
-
-typedef _typedefC_5 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Int32,
-);
-
-typedef _typedefC_6 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Pointer<ffi.Int64>,
-);
-
-typedef _typedefC_7 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Int32,
-);
-
-typedef _typedefC_8 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Int32,
-);
-
-typedef _typedefC_9 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Pointer<ffi.Int32>,
-);
-
-typedef _typedefC_10 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Int32,
-  ffi.Pointer<ffi.Void>,
-);
-
-typedef _typedefC_11 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-);
-
-typedef _typedefC_12 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-);
-
-typedef _typedefC_13 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Int32,
-  ffi.Int32,
-  ffi.Int32,
-  ffi.Pointer<ffi.Pointer<ffi.Void>>,
-);
-
-typedef _typedefC_14 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Int32,
-  ffi.Int32,
-  ffi.Int32,
-);
-
-typedef _typedefC_15 = ffi.Void Function(
-  ffi.Pointer<sqlite3_file>,
-);
-
-typedef _typedefC_16 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Int32,
-);
-
-typedef _typedefC_17 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Int64,
-  ffi.Int32,
-  ffi.Pointer<ffi.Pointer<ffi.Void>>,
-);
-
-typedef _typedefC_18 = ffi.Int32 Function(
-  ffi.Pointer<sqlite3_file>,
-  ffi.Int64,
-  ffi.Pointer<ffi.Void>,
-);
diff --git a/samples/ffi/sqlite/pubspec.yaml b/samples/ffi/sqlite/pubspec.yaml
index b70a25a..dcc5d40 100644
--- a/samples/ffi/sqlite/pubspec.yaml
+++ b/samples/ffi/sqlite/pubspec.yaml
@@ -1,55 +1,11 @@
 name: sqlite3
-
 version: 0.0.1
-
 description: >-
   Sqlite3 wrapper. Demo for dart:ffi.
-
 author: Daco Harkes <dacoharkes@google.com>, Samir Jindel <sjindel@google.com>
-
 environment:
   sdk: '>=2.1.0 <3.0.0'
-
 dependencies:
   ffi: ^0.1.3
-
 dev_dependencies:
   test: ^1.5.3
-  ffigen: ^0.2.0
-
-ffigen:
-  name: SQLite
-  description: SQLite bindings.
-  output: 'lib/src/third_party/sqlite/sqlite3_bindings_generated.dart'
-  headers:
-    entry-points:
-      - '/usr/include/sqlite3.h'
-    include-directives:
-      - '**sqlite3.h'
-  functions:
-    include:
-      - sqlite3_close_v2
-      - sqlite3_column_count
-      - sqlite3_column_decltype
-      - sqlite3_column_int
-      - sqlite3_column_name
-      - sqlite3_column_text
-      - sqlite3_column_type
-      - sqlite3_errmsg
-      - sqlite3_errstr
-      - sqlite3_finalize
-      - sqlite3_open_v2
-      - sqlite3_prepare_v2
-      - sqlite3_step
-  comments:
-    style: any
-    length: full
-  preamble: |
-    // 2001 September 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.
diff --git a/samples/ffi/sqlite/test/sqlite_test.dart b/samples/ffi/sqlite/test/sqlite_test.dart
index 7b36917..7bef552 100644
--- a/samples/ffi/sqlite/test/sqlite_test.dart
+++ b/samples/ffi/sqlite/test/sqlite_test.dart
@@ -13,7 +13,6 @@
 import '../lib/sqlite.dart';
 
 void main() {
-  assert(Platform.script.hasAbsolutePath); // `pub run test` is broken.
   final dbPath = Platform.script.resolve("test.db").path;
   test("sqlite integration test", () {
     Database d = Database(dbPath);
@@ -167,7 +166,6 @@
     r.close();
     d.close();
   });
-
   test("Utf8 unit test", () {
     final String test = 'Hasta Mañana';
     final medium = Utf8.toUtf8(test);
diff --git a/tests/language/unsorted/external_test.dart b/tests/language/unsorted/external_test.dart
index 8418280..12d6306c 100644
--- a/tests/language/unsorted/external_test.dart
+++ b/tests/language/unsorted/external_test.dart
@@ -15,8 +15,6 @@
   Foo() : x = 0;
 //^^^
 // [analyzer] COMPILE_TIME_ERROR.NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD
-//^^^
-// [analyzer] COMPILE_TIME_ERROR.NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD
 
   external var x01;
   external int x02;
@@ -69,13 +67,13 @@
 }
 
 external int t06(int i) { return 1; }
-// [error line 71, column 1, length 8]
+// [error line 69, column 1, length 8]
 // [analyzer] SYNTACTIC_ERROR.EXTERNAL_METHOD_WITH_BODY
 // [cfe] An external or native method can't have a body.
 //                      ^
 // [cfe] An external or native method can't have a body.
 external int t07(int i) => i + 1;
-// [error line 77, column 1, length 8]
+// [error line 75, column 1, length 8]
 // [analyzer] SYNTACTIC_ERROR.EXTERNAL_METHOD_WITH_BODY
 // [cfe] An external or native method can't have a body.
 //                         ^
diff --git a/third_party/.gitignore b/third_party/.gitignore
index ced573a..0bd8a83 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -13,6 +13,5 @@
 !unittest.tar.gz.sha1
 !update.sh
 !/wasmer
-!/sqlite
 # but ignore a subfolder of tcmalloc (some client ignores /tcmalloc/.gitignore)
 /tcmalloc/gperftools
diff --git a/third_party/sqlite/LICENSE.md b/third_party/sqlite/LICENSE.md
deleted file mode 100644
index f677190..0000000
--- a/third_party/sqlite/LICENSE.md
+++ /dev/null
@@ -1,9 +0,0 @@
-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 files are in
-samples/ffi/sqlite/lib/src/third_party/sqlite.
diff --git a/third_party/wasmer/Cargo.toml b/third_party/wasmer/Cargo.toml
index 9f08f16..bfe6172 100644
--- a/third_party/wasmer/Cargo.toml
+++ b/third_party/wasmer/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "wasmer"
-version = "0.7.0"
+version = "0.17.1"
 
 [lib]
 name = "wasmer"
@@ -8,4 +8,4 @@
 path = "wasmer.rs"
 
 [dependencies]
-wasmer-runtime-c-api = "0.7.0"
+wasmer-runtime-c-api = "0.17.1"
diff --git a/third_party/wasmer/LICENSE b/third_party/wasmer/LICENSE
index 079740d..62bb543 100644
--- a/third_party/wasmer/LICENSE
+++ b/third_party/wasmer/LICENSE
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2019 Wasmer, Inc. and its affiliates.
+Copyright (c) 2019-present Wasmer, Inc. and its affiliates.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/third_party/wasmer/README.md b/third_party/wasmer/README.md
index 1e741cf..d1475b7 100644
--- a/third_party/wasmer/README.md
+++ b/third_party/wasmer/README.md
@@ -1,31 +1,31 @@
 <p align="center">
   <a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
-    <img width="400" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
+    <img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
   </a>
 </p>
 
 <p align="center">
-  <a href="https://circleci.com/gh/wasmerio/wasmer/">
-    <img src="https://img.shields.io/circleci/project/github/wasmerio/wasmer/master.svg" alt="Build Status">
+  <a href="https://dev.azure.com/wasmerio/wasmer/_build/latest?definitionId=3&branchName=master">
+    <img src="https://img.shields.io/azure-devops/build/wasmerio/wasmer/3.svg?style=flat-square" alt="Build Status">
   </a>
   <a href="https://github.com/wasmerio/wasmer/blob/master/LICENSE">
-    <img src="https://img.shields.io/github/license/wasmerio/wasmer.svg" alt="License">
+    <img src="https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square" alt="License">
   </a>
   <a href="https://spectrum.chat/wasmer">
     <img src="https://withspectrum.github.io/badge/badge.svg" alt="Join the Wasmer Community">
   </a>
   <a href="https://crates.io/crates/wasmer-runtime-c-api">
-    <img src="https://img.shields.io/crates/d/wasmer-runtime-c-api.svg" alt="Number of downloads from crates.io">
+    <img src="https://img.shields.io/crates/d/wasmer-runtime-c-api.svg?style=flat-square" alt="Number of downloads from crates.io">
   </a>
-  <a href="https://docs.rs/wasmer-runtime-c-api">
-    <img src="https://docs.rs/wasmer-runtime-c-api/badge.svg" alt="Read our API documentation">
+  <a href="https://wasmerio.github.io/wasmer/c/runtime-c-api/">
+    <img src="https://img.shields.io/badge/Docs-Wasmer%20C%20API-blue?style=flat-square" alt="Wasmer C API Documentation">
   </a>
 </p>
 
 # Wasmer Runtime C API
 
 Wasmer is a standalone JIT WebAssembly runtime, aiming to be fully
-compatible with Emscripten, Rust and Go. [Learn
+compatible with WASI, Emscripten, Rust and Go. [Learn
 more](https://github.com/wasmerio/wasmer).
 
 This crate exposes a C and a C++ API for the Wasmer runtime.
@@ -36,6 +36,10 @@
 crate, respectively [`wasmer.h`][wasmer_h] and
 [`wasmer.hh`][wasmer_hh]. They are automatically generated, and always
 up-to-date in this repository.
+The runtime shared library (so, dll, dylib) can also be downloaded in Wasmer [release page](https://github.com/wasmerio/wasmer/releases).
+
+You can find the full C API documentation here:
+https://wasmerio.github.io/wasmer/c/runtime-c-api/
 
 Here is a simple example to use the C API:
 
@@ -104,10 +108,14 @@
 
 # Testing
 
+Tests are run using the release build of the library.  If you make
+changes or compile with non-default features, please ensure you
+rebuild in release mode for the tests to see the changes.
+
 The tests can be run via `cargo test`, such as:
 
 ```sh
-$ cargo test -- --nocapture
+$ cargo test --release -- --nocapture
 ```
 
 To run tests manually, enter the `lib/runtime-c-api/tests` directory
diff --git a/third_party/wasmer/wasmer.hh b/third_party/wasmer/wasmer.hh
index cf7a1c7..647e637 100644
--- a/third_party/wasmer/wasmer.hh
+++ b/third_party/wasmer/wasmer.hh
@@ -1,3 +1,36 @@
+
+#if !defined(WASMER_H_MACROS)
+
+#define WASMER_H_MACROS
+
+// Define the `ARCH_X86_X64` constant.
+#if defined(MSVC) && defined(_M_AMD64)
+#  define ARCH_X86_64
+#elif (defined(GCC) || defined(__GNUC__) || defined(__clang__)) && defined(__x86_64__)
+#  define ARCH_X86_64
+#endif
+
+// Compatibility with non-Clang compilers.
+#if !defined(__has_attribute)
+#  define __has_attribute(x) 0
+#endif
+
+// Compatibility with non-Clang compilers.
+#if !defined(__has_declspec_attribute)
+#  define __has_declspec_attribute(x) 0
+#endif
+
+// Define the `DEPRECATED` macro.
+#if defined(GCC) || defined(__GNUC__) || __has_attribute(deprecated)
+#  define DEPRECATED(message) __attribute__((deprecated(message)))
+#elif defined(MSVC) || __has_declspec_attribute(deprecated)
+#  define DEPRECATED(message) __declspec(deprecated(message))
+#endif
+
+#define WASMER_WASI_ENABLED
+#endif // WASMER_H_MACROS
+
+
 #ifndef WASMER_H
 #define WASMER_H
 
@@ -6,22 +39,52 @@
 #include <cstdlib>
 #include <new>
 
+#if defined(WASMER_WASI_ENABLED)
+enum class Version : uint8_t {
+  /// Version cannot be detected or is unknown.
+  Unknown = 0,
+  /// Latest version. See `wasmer_wasi::WasiVersion::Latest` to
+  /// learn more.
+  Latest = 1,
+  /// `wasi_unstable`.
+  Snapshot0 = 2,
+  /// `wasi_snapshot_preview1`.
+  Snapshot1 = 3,
+};
+#endif
+
+/// List of export/import kinds.
 enum class wasmer_import_export_kind : uint32_t {
-  WASM_FUNCTION,
-  WASM_GLOBAL,
-  WASM_MEMORY,
-  WASM_TABLE,
+  /// The export/import is a function.
+  WASM_FUNCTION = 0,
+  /// The export/import is a global.
+  WASM_GLOBAL = 1,
+  /// The export/import is a memory.
+  WASM_MEMORY = 2,
+  /// The export/import is a table.
+  WASM_TABLE = 3,
 };
 
+/// The `wasmer_result_t` enum is a type that represents either a
+/// success, or a failure.
 enum class wasmer_result_t {
+  /// Represents a success.
   WASMER_OK = 1,
+  /// Represents a failure.
   WASMER_ERROR = 2,
 };
 
+/// Represents all possibles WebAssembly value types.
+///
+/// See `wasmer_value_t` to get a complete example.
 enum class wasmer_value_tag : uint32_t {
+  /// Represents the `i32` WebAssembly type.
   WASM_I32,
+  /// Represents the `i64` WebAssembly type.
   WASM_I64,
+  /// Represents the `f32` WebAssembly type.
   WASM_F32,
+  /// Represents the `f64` WebAssembly type.
   WASM_F64,
 };
 
@@ -29,7 +92,12 @@
 
 };
 
-struct wasmer_export_descriptor_t {
+/// Opaque pointer to a `wasmer_runtime::Instance` value in Rust.
+///
+/// A `wasmer_runtime::Instance` represents a WebAssembly instance. It
+/// is generally generated by the `wasmer_instantiate()` function, or by
+/// the `wasmer_module_instantiate()` function for the most common paths.
+struct wasmer_instance_t {
 
 };
 
@@ -38,14 +106,38 @@
   uint32_t bytes_len;
 };
 
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Type used to construct an import_object_t with Emscripten imports.
+struct wasmer_emscripten_globals_t {
+
+};
+#endif
+
+struct wasmer_import_object_t {
+
+};
+
+/// Opaque pointer to `NamedExportDescriptor`.
+struct wasmer_export_descriptor_t {
+
+};
+
+/// Opaque pointer to `NamedExportDescriptors`.
 struct wasmer_export_descriptors_t {
 
 };
 
+/// Opaque pointer to `wasmer_export_t`.
 struct wasmer_export_func_t {
 
 };
 
+/// Represents a WebAssembly value.
+///
+/// This is a [Rust union][rust-union], which is equivalent to the C
+/// union. See `wasmer_value_t` to get a complete example.
+///
+/// [rust-union]: https://doc.rust-lang.org/reference/items/unions.html
 union wasmer_value {
   int32_t I32;
   int64_t I64;
@@ -53,19 +145,53 @@
   double F64;
 };
 
+/// Represents a WebAssembly type and value pair,
+/// i.e. `wasmer_value_tag` and `wasmer_value`. Since the latter is an
+/// union, it's the safe way to read or write a WebAssembly value in
+/// C.
+///
+/// Example:
+///
+/// ```c
+/// // Create a WebAssembly value.
+/// wasmer_value_t wasm_value = {
+///     .tag = WASM_I32,
+///     .value.I32 = 42,
+/// };
+///
+/// // Read a WebAssembly value.
+/// if (wasm_value.tag == WASM_I32) {
+///     int32_t x = wasm_value.value.I32;
+///     // …
+/// }
+/// ```
 struct wasmer_value_t {
+  /// The value type.
   wasmer_value_tag tag;
+  /// The value.
   wasmer_value value;
 };
 
+/// Opaque pointer to `NamedExport`.
 struct wasmer_export_t {
 
 };
 
+/// Opaque pointer to a `wasmer_runtime::Memory` value in Rust.
+///
+/// A `wasmer_runtime::Memory` represents a WebAssembly memory. It is
+/// possible to create one with `wasmer_memory_new()` and pass it as
+/// imports of an instance, or to read it from exports of an instance
+/// with `wasmer_export_to_memory()`.
 struct wasmer_memory_t {
 
 };
 
+/// Opaque pointer to the opaque structure `crate::NamedExports`,
+/// which is a wrapper around a vector of the opaque structure
+/// `crate::NamedExport`.
+///
+/// Check the `wasmer_instance_exports()` function to learn more.
 struct wasmer_exports_t {
 
 };
@@ -91,14 +217,11 @@
 
 };
 
-struct wasmer_import_object_t {
-
-};
-
 struct wasmer_table_t {
 
 };
 
+/// Union of import/export value.
 union wasmer_import_export_value {
   const wasmer_import_func_t *func;
   const wasmer_table_t *table;
@@ -113,21 +236,55 @@
   wasmer_import_export_value value;
 };
 
-struct wasmer_instance_t {
+struct wasmer_import_object_iter_t {
 
 };
 
+/// Opaque pointer to a `wasmer_runtime::Ctx` value in Rust.
+///
+/// An instance context is passed to any host function (aka imported
+/// function) as the first argument. It is necessary to read the
+/// instance data or the memory, respectively with the
+/// `wasmer_instance_context_data_get()` function, and the
+/// `wasmer_instance_context_memory()` function.
+///
+/// It is also possible to get the instance context outside a host
+/// function by using the `wasmer_instance_context_get()`
+/// function. See also `wasmer_instance_context_data_set()` to set the
+/// instance context data.
+///
+/// Example:
+///
+/// ```c
+/// // A host function that prints data from the WebAssembly memory to
+/// // the standard output.
+/// void print(wasmer_instance_context_t *context, int32_t pointer, int32_t length) {
+///     // Use `wasmer_instance_context` to get back the first instance memory.
+///     const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0);
+///
+///     // Continue…
+/// }
+/// ```
 struct wasmer_instance_context_t {
 
 };
 
+/// The `wasmer_limit_option_t` struct represents an optional limit
+/// for `wasmer_limits_t`.
 struct wasmer_limit_option_t {
+  /// Whether the limit is set.
   bool has_some;
+  /// The limit value.
   uint32_t some;
 };
 
+/// The `wasmer_limits_t` struct is a type that describes a memory
+/// options. See the `wasmer_memory_t` struct or the
+/// `wasmer_memory_new()` function to get more information.
 struct wasmer_limits_t {
+  /// The minimum number of allowed pages.
   uint32_t min;
+  /// The maximum number of allowed pages.
   wasmer_limit_option_t max;
 };
 
@@ -135,28 +292,95 @@
 
 };
 
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
 struct wasmer_trampoline_buffer_builder_t {
 
 };
+#endif
 
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
 struct wasmer_trampoline_callable_t {
 
 };
+#endif
 
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
 struct wasmer_trampoline_buffer_t {
 
 };
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Opens a directory that's visible to the WASI module as `alias` but
+/// is backed by the host file at `host_file_path`
+struct wasmer_wasi_map_dir_entry_t {
+  /// What the WASI module will see in its virtual root
+  wasmer_byte_array alias;
+  /// The backing file that the WASI module will interact with via the alias
+  wasmer_byte_array host_file_path;
+};
+#endif
 
 extern "C" {
 
 /// Creates a new Module from the given wasm bytes.
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_compile(wasmer_module_t **module,
                                uint8_t *wasm_bytes,
                                uint32_t wasm_bytes_len);
 
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Convenience function for setting up arguments and calling the Emscripten
+/// main function.
+///
+/// WARNING:
+///
+/// Do not call this function on untrusted code when operating without
+/// additional sandboxing in place.
+/// Emscripten has access to many host system calls and therefore may do very
+/// bad things.
+wasmer_result_t wasmer_emscripten_call_main(wasmer_instance_t *instance,
+                                            const wasmer_byte_array *args,
+                                            unsigned int args_len);
+#endif
+
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Destroy `wasmer_emscrpten_globals_t` created by
+/// `wasmer_emscripten_get_emscripten_globals`.
+void wasmer_emscripten_destroy_globals(wasmer_emscripten_globals_t *globals);
+#endif
+
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Create a `wasmer_import_object_t` with Emscripten imports, use
+/// `wasmer_emscripten_get_emscripten_globals` to get a
+/// `wasmer_emscripten_globals_t` from a `wasmer_module_t`.
+///
+/// WARNING:
+///
+/// This `import_object_t` contains thin-wrappers around host system calls.
+/// Do not use this to execute untrusted code without additional sandboxing.
+wasmer_import_object_t *wasmer_emscripten_generate_import_object(wasmer_emscripten_globals_t *globals);
+#endif
+
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Create a `wasmer_emscripten_globals_t` from a Wasm module.
+wasmer_emscripten_globals_t *wasmer_emscripten_get_globals(const wasmer_module_t *module);
+#endif
+
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Execute global constructors (required if the module is compiled from C++)
+/// and sets up the internal environment.
+///
+/// This function sets the data pointer in the same way that
+/// [`wasmer_instance_context_data_set`] does.
+wasmer_result_t wasmer_emscripten_set_up(wasmer_instance_t *instance,
+                                         wasmer_emscripten_globals_t *globals);
+#endif
+
 /// Gets export descriptor kind
 wasmer_import_export_kind wasmer_export_descriptor_kind(wasmer_export_descriptor_t *export_);
 
@@ -164,6 +388,7 @@
 wasmer_byte_array wasmer_export_descriptor_name(wasmer_export_descriptor_t *export_descriptor);
 
 /// Gets export descriptors for the given module
+///
 /// The caller owns the object and should call `wasmer_export_descriptors_destroy` to free it.
 void wasmer_export_descriptors(const wasmer_module_t *module,
                                wasmer_export_descriptors_t **export_descriptors);
@@ -180,17 +405,21 @@
 
 /// Calls a `func` with the provided parameters.
 /// Results are set using the provided `results` pointer.
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_export_func_call(const wasmer_export_func_t *func,
                                         const wasmer_value_t *params,
-                                        int params_len,
+                                        unsigned int params_len,
                                         wasmer_value_t *results,
-                                        int results_len);
+                                        unsigned int results_len);
 
 /// Sets the params buffer to the parameter types of the given wasmer_export_func_t
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_export_func_params(const wasmer_export_func_t *func,
@@ -198,13 +427,17 @@
                                           uint32_t params_len);
 
 /// Sets the result parameter to the arity of the params of the wasmer_export_func_t
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_export_func_params_arity(const wasmer_export_func_t *func, uint32_t *result);
 
 /// Sets the returns buffer to the parameter types of the given wasmer_export_func_t
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_export_func_returns(const wasmer_export_func_t *func,
@@ -212,7 +445,9 @@
                                            uint32_t returns_len);
 
 /// Sets the result parameter to the arity of the returns of the wasmer_export_func_t
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_export_func_returns_arity(const wasmer_export_func_t *func,
@@ -228,12 +463,30 @@
 const wasmer_export_func_t *wasmer_export_to_func(const wasmer_export_t *export_);
 
 /// Gets a memory pointer from an export pointer.
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_export_to_memory(const wasmer_export_t *export_, wasmer_memory_t **memory);
 
-/// Frees the memory for the given exports
+/// Frees the memory for the given exports.
+///
+/// Check the `wasmer_instance_exports()` function to get a complete
+/// example.
+///
+/// If `exports` is a null pointer, this function does nothing.
+///
+/// Example:
+///
+/// ```c
+/// // Get some exports.
+/// wasmer_exports_t *exports = NULL;
+/// wasmer_instance_exports(instance, &exports);
+///
+/// // Destroy the exports.
+/// wasmer_exports_destroy(exports);
+/// ```
 void wasmer_exports_destroy(wasmer_exports_t *exports);
 
 /// Gets wasmer_export by index
@@ -268,6 +521,7 @@
 wasmer_byte_array wasmer_import_descriptor_name(wasmer_import_descriptor_t *import_descriptor);
 
 /// Gets import descriptors for the given module
+///
 /// The caller owns the object and should call `wasmer_import_descriptors_destroy` to free it.
 void wasmer_import_descriptors(const wasmer_module_t *module,
                                wasmer_import_descriptors_t **import_descriptors);
@@ -285,8 +539,23 @@
 /// Frees memory for the given Func
 void wasmer_import_func_destroy(wasmer_import_func_t *func);
 
-/// Creates new func
-/// The caller owns the object and should call `wasmer_import_func_destroy` to free it.
+/// Creates new host function, aka imported function. `func` is a
+/// function pointer, where the first argument is the famous `vm::Ctx`
+/// (in Rust), or `wasmer_instance_context_t` (in C). All arguments
+/// must be typed with compatible WebAssembly native types:
+///
+/// | WebAssembly type | C/C++ type |
+/// | ---------------- | ---------- |
+/// | `i32`            | `int32_t`  |
+/// | `i64`            | `int64_t`  |
+/// | `f32`            | `float`    |
+/// | `f64`            | `double`   |
+///
+/// The function pointer must have a lifetime greater than the
+/// WebAssembly instance lifetime.
+///
+/// The caller owns the object and should call
+/// `wasmer_import_func_destroy` to free it.
 wasmer_import_func_t *wasmer_import_func_new(void (*func)(void *data),
                                              const wasmer_value_tag *params,
                                              unsigned int params_len,
@@ -294,7 +563,9 @@
                                              unsigned int returns_len);
 
 /// Sets the params buffer to the parameter types of the given wasmer_import_func_t
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_import_func_params(const wasmer_import_func_t *func,
@@ -302,13 +573,17 @@
                                           unsigned int params_len);
 
 /// Sets the result parameter to the arity of the params of the wasmer_import_func_t
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_import_func_params_arity(const wasmer_import_func_t *func, uint32_t *result);
 
 /// Sets the returns buffer to the parameter types of the given wasmer_import_func_t
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_import_func_returns(const wasmer_import_func_t *func,
@@ -316,7 +591,9 @@
                                            unsigned int returns_len);
 
 /// Sets the result parameter to the arity of the returns of the wasmer_import_func_t
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_import_func_returns_arity(const wasmer_import_func_t *func,
@@ -327,18 +604,101 @@
 
 /// Extends an existing import object with new imports
 wasmer_result_t wasmer_import_object_extend(wasmer_import_object_t *import_object,
-                                            wasmer_import_t *imports,
+                                            const wasmer_import_t *imports,
                                             unsigned int imports_len);
 
+/// Gets an entry from an ImportObject at the name and namespace.
+/// Stores `name`, `namespace`, and `import_export_value` in `import`.
+/// Thus these must remain valid for the lifetime of `import`.
+///
+/// The caller owns all data involved.
+/// `import_export_value` will be written to based on `tag`.
+wasmer_result_t wasmer_import_object_get_import(const wasmer_import_object_t *import_object,
+                                                wasmer_byte_array namespace_,
+                                                wasmer_byte_array name,
+                                                wasmer_import_t *import,
+                                                wasmer_import_export_value *import_export_value,
+                                                uint32_t tag);
+
+/// Frees the memory allocated in `wasmer_import_object_iter_next`
+///
+/// This function does not free the memory in `wasmer_import_object_t`;
+/// it only frees memory allocated while querying a `wasmer_import_object_t`.
+void wasmer_import_object_imports_destroy(wasmer_import_t *imports, uint32_t imports_len);
+
+/// Returns true if further calls to `wasmer_import_object_iter_next` will
+/// not return any new data
+bool wasmer_import_object_iter_at_end(wasmer_import_object_iter_t *import_object_iter);
+
+/// Frees the memory allocated by `wasmer_import_object_iterate_functions`
+void wasmer_import_object_iter_destroy(wasmer_import_object_iter_t *import_object_iter);
+
+/// Writes the next value to `import`.  `WASMER_ERROR` is returned if there
+/// was an error or there's nothing left to return.
+///
+/// To free the memory allocated here, pass the import to `wasmer_import_object_imports_destroy`.
+/// To check if the iterator is done, use `wasmer_import_object_iter_at_end`.
+wasmer_result_t wasmer_import_object_iter_next(wasmer_import_object_iter_t *import_object_iter,
+                                               wasmer_import_t *import);
+
+/// Create an iterator over the functions in the import object.
+/// Get the next import with `wasmer_import_object_iter_next`
+/// Free the iterator with `wasmer_import_object_iter_destroy`
+wasmer_import_object_iter_t *wasmer_import_object_iterate_functions(const wasmer_import_object_t *import_object);
+
 /// Creates a new empty import object.
 /// See also `wasmer_import_object_append`
 wasmer_import_object_t *wasmer_import_object_new();
 
-/// Calls an instances exported function by `name` with the provided parameters.
-/// Results are set using the provided `results` pointer.
-/// Returns `wasmer_result_t::WASMER_OK` upon success.
-/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
-/// and `wasmer_last_error_message` to get an error message.
+/// Calls an exported function of a WebAssembly instance by `name`
+/// with the provided parameters. The exported function results are
+/// stored on the provided `results` pointer.
+///
+/// This function returns `wasmer_result_t::WASMER_OK` upon success,
+/// `wasmer_result_t::WASMER_ERROR` otherwise. You can use
+/// `wasmer_last_error_message()` to get the generated error message.
+///
+/// Potential errors are the following:
+///
+///   * `instance` is a null pointer,
+///   * `name` is a null pointer,
+///   * `params` is a null pointer.
+///
+/// Example of calling an exported function that needs two parameters, and returns one value:
+///
+/// ```c
+/// // First argument.
+/// wasmer_value_t argument_one = {
+///     .tag = WASM_I32,
+///     .value.I32 = 3,
+/// };
+///
+/// // Second argument.
+/// wasmer_value_t argument_two = {
+///     .tag = WASM_I32,
+///     .value.I32 = 4,
+/// };
+///
+/// // First result.
+/// wasmer_value_t result_one;
+///
+/// // All arguments and results.
+/// wasmer_value_t arguments[] = {argument_one, argument_two};
+/// wasmer_value_t results[]   = {result_one};
+///
+/// wasmer_result_t call_result = wasmer_instance_call(
+///     instance,  // instance pointer
+///     "sum",     // the exported function name
+///     arguments, // the arguments
+///     2,         // the number of arguments
+///     results,   // the results
+///     1          // the number of results
+/// );
+///
+/// if (call_result == WASMER_OK) {
+///     printf("Result is: %d\n", results[0].value.I32);
+/// }
+/// ```
 wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
                                      const char *name,
                                      const wasmer_value_t *params,
@@ -346,89 +706,362 @@
                                      wasmer_value_t *results,
                                      uint32_t results_len);
 
-/// Gets the `data` field within the context.
+/// Gets the data that can be hold by an instance.
+///
+/// This function is complementary of
+/// `wasmer_instance_context_data_set()`. Please read its
+/// documentation. You can also read the documentation of
+/// `wasmer_instance_context_t` to get other examples.
+///
+/// This function returns nothing if `ctx` is a null pointer.
 void *wasmer_instance_context_data_get(const wasmer_instance_context_t *ctx);
 
-/// Sets the `data` field of the instance context. This context will be
-/// passed to all imported function for instance.
-void wasmer_instance_context_data_set(wasmer_instance_t *instance, void *data_ptr);
+/// Sets the data that can be hold by an instance context.
+///
+/// An instance context (represented by the opaque
+/// `wasmer_instance_context_t` structure) can hold user-defined
+/// data. This function sets the data. This function is complementary
+/// of `wasmer_instance_context_data_get()`.
+///
+/// This function does nothing if `instance` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// // Define your own data.
+/// typedef struct {
+///     // …
+/// } my_data;
+///
+/// // Allocate them and set them on the given instance.
+/// my_data *data = malloc(sizeof(my_data));
+/// data->… = …;
+/// wasmer_instance_context_data_set(instance, (void*) data);
+///
+/// // You can read your data.
+/// {
+///     my_data *data = (my_data*) wasmer_instance_context_data_get(wasmer_instance_context_get(instance));
+///     // …
+/// }
+/// ```
+void wasmer_instance_context_data_set(wasmer_instance_t *instance,
+                                      void *data_ptr);
 
-/// Extracts the instance's context and returns it.
+/// Returns the instance context. Learn more by looking at the
+/// `wasmer_instance_context_t` struct.
+///
+/// This function returns `null` if `instance` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// const wasmer_instance_context_get *context = wasmer_instance_context_get(instance);
+/// my_data *data = (my_data *) wasmer_instance_context_data_get(context);
+/// // Do something with `my_data`.
+/// ```
+///
+/// It is often useful with `wasmer_instance_context_data_set()`.
 const wasmer_instance_context_t *wasmer_instance_context_get(wasmer_instance_t *instance);
 
-/// Gets the memory within the context at the index `memory_idx`.
-/// The index is always 0 until multiple memories are supported.
+/// Gets the `memory_idx`th memory of the instance.
+///
+/// Note that the index is always `0` until multiple memories are supported.
+///
+/// This function is mostly used inside host functions (aka imported
+/// functions) to read the instance memory.
+///
+/// Example of a _host function_ that reads and prints a string based on a pointer and a length:
+///
+/// ```c
+/// void print_string(const wasmer_instance_context_t *context, int32_t pointer, int32_t length) {
+///     // Get the 0th memory.
+///     const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0);
+///
+///     // Get the memory data as a pointer.
+///     uint8_t *memory_bytes = wasmer_memory_data(memory);
+///
+///     // Print what we assumed to be a string!
+///     printf("%.*s", length, memory_bytes + pointer);
+/// }
+/// ```
 const wasmer_memory_t *wasmer_instance_context_memory(const wasmer_instance_context_t *ctx,
                                                       uint32_t _memory_idx);
 
-/// Frees memory for the given Instance
+/// Frees memory for the given `wasmer_instance_t`.
+///
+/// Check the `wasmer_instantiate()` function to get a complete
+/// example.
+///
+/// If `instance` is a null pointer, this function does nothing.
+///
+/// Example:
+///
+/// ```c
+/// // Get an instance.
+/// wasmer_instance_t *instance = NULL;
+/// wasmer_instantiate(&instance, bytes, bytes_length, imports, 0);
+///
+/// // Destroy the instance.
+/// wasmer_instance_destroy(instance);
+/// ```
 void wasmer_instance_destroy(wasmer_instance_t *instance);
 
-/// Gets Exports for the given instance
-/// The caller owns the object and should call `wasmer_exports_destroy` to free it.
+/// Gets all the exports of the given WebAssembly instance.
+///
+/// This function stores a Rust vector of exports into `exports` as an
+/// opaque pointer of kind `wasmer_exports_t`.
+///
+/// As is, you can do anything with `exports` except using the
+/// companion functions, like `wasmer_exports_len()`,
+/// `wasmer_exports_get()` or `wasmer_export_kind()`. See the example below.
+///
+/// **Warning**: The caller owns the object and should call
+/// `wasmer_exports_destroy()` to free it.
+///
+/// Example:
+///
+/// ```c
+/// // Get the exports.
+/// wasmer_exports_t *exports = NULL;
+/// wasmer_instance_exports(instance, &exports);
+///
+/// // Get the number of exports.
+/// int exports_length = wasmer_exports_len(exports);
+/// printf("Number of exports: %d\n", exports_length);
+///
+/// // Read the first export.
+/// wasmer_export_t *export = wasmer_exports_get(exports, 0);
+///
+/// // Get the kind of the export.
+/// wasmer_import_export_kind export_kind = wasmer_export_kind(export);
+///
+/// // Assert it is a function (why not).
+/// assert(export_kind == WASM_FUNCTION);
+///
+/// // Read the export name.
+/// wasmer_byte_array name_bytes = wasmer_export_name(export);
+///
+/// assert(name_bytes.bytes_len == sizeof("sum") - 1);
+/// assert(memcmp(name_bytes.bytes, "sum", sizeof("sum") - 1) == 0);
+///
+/// // Destroy the exports.
+/// wasmer_exports_destroy(exports);
+/// ```
 void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exports);
 
-/// Creates a new Instance from the given wasm bytes and imports.
-/// Returns `wasmer_result_t::WASMER_OK` upon success.
-/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
-/// and `wasmer_last_error_message` to get an error message.
+/// Creates a new WebAssembly instance from the given bytes and imports.
+///
+/// The result is stored in the first argument `instance` if
+/// successful, i.e. when the function returns
+/// `wasmer_result_t::WASMER_OK`. Otherwise
+/// `wasmer_result_t::WASMER_ERROR` is returned, and
+/// `wasmer_last_error_length()` with `wasmer_last_error_message()` must
+/// be used to read the error message.
+///
+/// The caller is responsible to free the instance with
+/// `wasmer_instance_destroy()`.
+///
+/// Example:
+///
+/// ```c
+/// // 1. Read a WebAssembly module from a file.
+/// FILE *file = fopen("sum.wasm", "r");
+/// fseek(file, 0, SEEK_END);
+/// long bytes_length = ftell(file);
+/// uint8_t *bytes = malloc(bytes_length);
+/// fseek(file, 0, SEEK_SET);
+/// fread(bytes, 1, bytes_length, file);
+/// fclose(file);
+///
+/// // 2. Declare the imports (here, none).
+/// wasmer_import_t imports[] = {};
+///
+/// // 3. Instantiate the WebAssembly module.
+/// wasmer_instance_t *instance = NULL;
+/// wasmer_result_t result = wasmer_instantiate(&instance, bytes, bytes_length, imports, 0);
+///
+/// // 4. Check for errors.
+/// if (result != WASMER_OK) {
+///     int error_length = wasmer_last_error_length();
+///     char *error = malloc(error_length);
+///     wasmer_last_error_message(error, error_length);
+///     // Do something with `error`…
+/// }
+///
+/// // 5. Free the memory!
+/// wasmer_instance_destroy(instance);
+/// ```
 wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance,
                                    uint8_t *wasm_bytes,
                                    uint32_t wasm_bytes_len,
                                    wasmer_import_t *imports,
                                    int imports_len);
 
-/// Gets the length in bytes of the last error.
+/// Gets the length in bytes of the last error if any.
+///
 /// This can be used to dynamically allocate a buffer with the correct number of
 /// bytes needed to store a message.
-/// # Example
-/// ```c
-/// int error_len = wasmer_last_error_length();
-/// char *error_str = malloc(error_len);
-/// ```
+///
+/// See `wasmer_last_error_message()` to get a full example.
 int wasmer_last_error_length();
 
-/// Stores the last error message into the provided buffer up to the given `length`.
-/// The `length` parameter must be large enough to store the last error message.
-/// Returns the length of the string in bytes.
-/// Returns `-1` if an error occurs.
-/// # Example
+/// Gets the last error message if any into the provided buffer
+/// `buffer` up to the given `length`.
+///
+/// The `length` parameter must be large enough to store the last
+/// error message. Ideally, the value should come from
+/// `wasmer_last_error_length()`.
+///
+/// The function returns the length of the string in bytes, `-1` if an
+/// error occurs. Potential errors are:
+///
+///  * The buffer is a null pointer,
+///  * The buffer is too smal to hold the error message.
+///
+/// Note: The error message always has a trailing null character.
+///
+/// Example:
+///
 /// ```c
-/// int error_len = wasmer_last_error_length();
-/// char *error_str = malloc(error_len);
-/// wasmer_last_error_message(error_str, error_len);
-/// printf("Error str: `%s`\n", error_str);
+/// int error_length = wasmer_last_error_length();
+///
+/// if (error_length > 0) {
+///     char *error_message = malloc(error_length);
+///     wasmer_last_error_message(error_message, error_length);
+///     printf("Error message: `%s`\n", error_message);
+/// } else {
+///     printf("No error message\n");
+/// }
 /// ```
 int wasmer_last_error_message(char *buffer, int length);
 
-/// Gets the start pointer to the bytes within a Memory
-uint8_t *wasmer_memory_data(const wasmer_memory_t *mem);
+/// Gets a pointer to the beginning of the contiguous memory data
+/// bytes.
+///
+/// The function returns `NULL` if `memory` is a null pointer.
+///
+/// Note that when the memory grows, it can be reallocated, and thus
+/// the returned pointer can be invalidated.
+///
+/// Example:
+///
+/// ```c
+/// uint8_t *memory_data = wasmer_memory_data(memory);
+/// char *str = (char*) malloc(sizeof(char) * 7);
+///
+/// for (uint32_t nth = 0; nth < 7; ++nth) {
+///     str[nth] = (char) memory_data[nth];
+/// }
+/// ```
+uint8_t *wasmer_memory_data(const wasmer_memory_t *memory);
 
-/// Gets the size in bytes of a Memory
-uint32_t wasmer_memory_data_length(wasmer_memory_t *mem);
+/// Gets the size in bytes of the memory data.
+///
+/// This function returns 0 if `memory` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// uint32_t memory_data_length = wasmer_memory_data_length(memory);
+/// ```
+uint32_t wasmer_memory_data_length(const wasmer_memory_t *memory);
 
-/// Frees memory for the given Memory
+/// Frees memory for the given `wasmer_memory_t`.
+///
+/// Check the `wasmer_memory_new()` function to get a complete
+/// example.
+///
+/// If `memory` is a null pointer, this function does nothing.
+///
+/// Example:
+///
+/// ```c
+/// // Get a memory.
+/// wasmer_memory_t *memory = NULL;
+/// wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
+///
+/// // Destroy the memory.
+/// wasmer_memory_destroy(memory);
+/// ```
 void wasmer_memory_destroy(wasmer_memory_t *memory);
 
-/// Grows a Memory by the given number of pages.
-/// Returns `wasmer_result_t::WASMER_OK` upon success.
-/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
-/// and `wasmer_last_error_message` to get an error message.
+/// Grows a memory by the given number of pages (of 65Kb each).
+///
+/// The functions return `wasmer_result_t::WASMER_OK` upon success,
+/// `wasmer_result_t::WASMER_ERROR` otherwise. Use
+/// `wasmer_last_error_length()` with `wasmer_last_error_message()` to
+/// read the error message.
+///
+/// Example:
+///
+/// ```c
+/// wasmer_result_t result = wasmer_memory_grow(memory, 10);
+///
+/// if (result != WASMER_OK) {
+///     // …
+/// }
+/// ```
 wasmer_result_t wasmer_memory_grow(wasmer_memory_t *memory, uint32_t delta);
 
-/// Returns the current length in pages of the given memory
+/// Reads the current length (in pages) of the given memory.
+///
+/// The function returns zero if `memory` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// uint32_t memory_length = wasmer_memory_length(memory);
+///
+/// printf("Memory pages length: %d\n", memory_length);
+/// ```
 uint32_t wasmer_memory_length(const wasmer_memory_t *memory);
 
-/// Creates a new Memory for the given descriptor and initializes the given
-/// pointer to pointer to a pointer to the new memory.
-/// The caller owns the object and should call `wasmer_memory_destroy` to free it.
-/// Returns `wasmer_result_t::WASMER_OK` upon success.
-/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
-/// and `wasmer_last_error_message` to get an error message.
+/// Creates a new empty WebAssembly memory for the given descriptor.
+///
+/// The result is stored in the first argument `memory` if successful,
+/// i.e. when the function returns
+/// `wasmer_result_t::WASMER_OK`. Otherwise,
+/// `wasmer_result_t::WASMER_ERROR` is returned, and
+/// `wasmer_last_error_length()` with `wasmer_last_error_message()`
+/// must be used to read the error message.
+///
+/// The caller owns the memory and is responsible to free it with
+/// `wasmer_memory_destroy()`.
+///
+/// Example:
+///
+/// ```c
+/// // 1. The memory object.
+/// wasmer_memory_t *memory = NULL;
+///
+/// // 2. The memory descriptor.
+/// wasmer_limits_t memory_descriptor = {
+///     .min = 10,
+///     .max = {
+///         .has_some = true,
+///         .some = 15,
+///     },
+/// };
+///
+/// // 3. Initialize the memory.
+/// wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
+///
+/// if (result != WASMER_OK) {
+///     int error_length = wasmer_last_error_length();
+///     char *error = malloc(error_length);
+///     wasmer_last_error_message(error, error_length);
+///     // Do something with `error`…
+/// }
+///
+/// // 4. Free the memory!
+/// wasmer_memory_destroy(memory);
+/// ```
 wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limits);
 
 /// Deserialize the given serialized module.
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_module_deserialize(wasmer_module_t **module,
@@ -438,15 +1071,18 @@
 void wasmer_module_destroy(wasmer_module_t *module);
 
 /// Given:
-///  A prepared `wasmer` import-object
-///  A compiled wasmer module
+/// * A prepared `wasmer` import-object
+/// * A compiled wasmer module
+///
 /// Instantiates a wasmer instance
 wasmer_result_t wasmer_module_import_instantiate(wasmer_instance_t **instance,
                                                  const wasmer_module_t *module,
                                                  const wasmer_import_object_t *import_object);
 
 /// Creates a new Instance from the given module and imports.
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_module_instantiate(const wasmer_module_t *module,
@@ -455,8 +1091,11 @@
                                           int imports_len);
 
 /// Serialize the given Module.
+///
 /// The caller owns the object and should call `wasmer_serialized_module_destroy` to free it.
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_module_serialize(wasmer_serialized_module_t **serialized_module,
@@ -469,8 +1108,11 @@
 void wasmer_serialized_module_destroy(wasmer_serialized_module_t *serialized_module);
 
 /// Transform a sequence of bytes into a serialized module.
+///
 /// The caller owns the object and should call `wasmer_serialized_module_destroy` to free it.
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_serialized_module_from_bytes(wasmer_serialized_module_t **serialized_module,
@@ -481,7 +1123,9 @@
 void wasmer_table_destroy(wasmer_table_t *table);
 
 /// Grows a Table by the given number of elements.
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_table_grow(wasmer_table_t *table, uint32_t delta);
@@ -491,42 +1135,139 @@
 
 /// Creates a new Table for the given descriptor and initializes the given
 /// pointer to pointer to a pointer to the new Table.
+///
 /// The caller owns the object and should call `wasmer_table_destroy` to free it.
+///
 /// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
 /// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
 /// and `wasmer_last_error_message` to get an error message.
 wasmer_result_t wasmer_table_new(wasmer_table_t **table, wasmer_limits_t limits);
 
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
 /// Adds a callinfo trampoline to the builder.
+///
+/// Deprecated. In a future version `DynamicFunc::new` will be exposed to the C API and should be used instead of this function.
 uintptr_t wasmer_trampoline_buffer_builder_add_callinfo_trampoline(wasmer_trampoline_buffer_builder_t *builder,
                                                                    const wasmer_trampoline_callable_t *func,
                                                                    const void *ctx,
                                                                    uint32_t num_params);
+#endif
 
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
 /// Adds a context trampoline to the builder.
 uintptr_t wasmer_trampoline_buffer_builder_add_context_trampoline(wasmer_trampoline_buffer_builder_t *builder,
                                                                   const wasmer_trampoline_callable_t *func,
                                                                   const void *ctx);
+#endif
 
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
 /// Finalizes the trampoline builder into an executable buffer.
 wasmer_trampoline_buffer_t *wasmer_trampoline_buffer_builder_build(wasmer_trampoline_buffer_builder_t *builder);
+#endif
 
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
 /// Creates a new trampoline builder.
 wasmer_trampoline_buffer_builder_t *wasmer_trampoline_buffer_builder_new();
+#endif
 
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
 /// Destroys the trampoline buffer if not null.
 void wasmer_trampoline_buffer_destroy(wasmer_trampoline_buffer_t *buffer);
+#endif
 
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
 /// Returns the callable pointer for the trampoline with index `idx`.
 const wasmer_trampoline_callable_t *wasmer_trampoline_buffer_get_trampoline(const wasmer_trampoline_buffer_t *buffer,
                                                                             uintptr_t idx);
+#endif
 
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
 /// Returns the context added by `add_context_trampoline`, from within the callee function.
 void *wasmer_trampoline_get_context();
+#endif
 
-/// Returns true for valid wasm bytes and false for invalid bytes
+/// Stop the execution of a host function, aka imported function. The
+/// function must be used _only_ inside a host function.
+///
+/// The pointer to `wasmer_instance_context_t` is received by the host
+/// function as its first argument. Just passing it to `ctx` is fine.
+///
+/// The error message must have a greater lifetime than the host
+/// function itself since the error is read outside the host function
+/// with `wasmer_last_error_message`.
+///
+/// This function returns `wasmer_result_t::WASMER_ERROR` if `ctx` or
+/// `error_message` are null.
+///
+/// This function never returns otherwise.
+wasmer_result_t wasmer_trap(const wasmer_instance_context_t *ctx, const char *error_message);
+
+/// Validates a sequence of bytes hoping it represents a valid WebAssembly module.
+///
+/// The function returns true if the bytes are valid, false otherwise.
+///
+/// Example:
+///
+/// ```c
+/// bool result = wasmer_validate(bytes, bytes_length);
+///
+/// if (false == result) {
+///     // Do something…
+/// }
+/// ```
 bool wasmer_validate(const uint8_t *wasm_bytes, uint32_t wasm_bytes_len);
 
+#if defined(WASMER_WASI_ENABLED)
+/// Convenience function that creates a WASI import object with no arguments,
+/// environment variables, preopened files, or mapped directories.
+///
+/// This function is the same as calling [`wasmer_wasi_generate_import_object`] with all
+/// empty values.
+wasmer_import_object_t *wasmer_wasi_generate_default_import_object();
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Creates a WASI import object.
+///
+/// This function treats null pointers as empty collections.
+/// For example, passing null for a string in `args`, will lead to a zero
+/// length argument in that position.
+wasmer_import_object_t *wasmer_wasi_generate_import_object(const wasmer_byte_array *args,
+                                                           unsigned int args_len,
+                                                           const wasmer_byte_array *envs,
+                                                           unsigned int envs_len,
+                                                           const wasmer_byte_array *preopened_files,
+                                                           unsigned int preopened_files_len,
+                                                           const wasmer_wasi_map_dir_entry_t *mapped_dirs,
+                                                           unsigned int mapped_dirs_len);
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Creates a WASI import object for a specific version.
+///
+/// This function is similar to `wasmer_wasi_generate_import_object`
+/// except that the first argument describes the WASI version.
+///
+/// The version is expected to be of kind `Version`.
+wasmer_import_object_t *wasmer_wasi_generate_import_object_for_version(unsigned char version,
+                                                                       const wasmer_byte_array *args,
+                                                                       unsigned int args_len,
+                                                                       const wasmer_byte_array *envs,
+                                                                       unsigned int envs_len,
+                                                                       const wasmer_byte_array *preopened_files,
+                                                                       unsigned int preopened_files_len,
+                                                                       const wasmer_wasi_map_dir_entry_t *mapped_dirs,
+                                                                       unsigned int mapped_dirs_len);
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Find the version of WASI used by the module.
+///
+/// In case of error, the returned version is `Version::Unknown`.
+Version wasmer_wasi_get_version(const wasmer_module_t *module);
+#endif
+
 } // extern "C"
 
 #endif // WASMER_H
diff --git a/tools/VERSION b/tools/VERSION
index 2753997..2fcf00b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 13
+PRERELEASE 14
 PRERELEASE_PATCH 0
\ No newline at end of file