[jnigen] Initial code generator support (https://github.com/dart-lang/jnigen/issues/19)

diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml
index 24e7d5e..f35e0bb 100644
--- a/.github/workflows/test-package.yml
+++ b/.github/workflows/test-package.yml
@@ -17,8 +17,14 @@
   PUB_ENVIRONMENT: bot.github
 
 jobs:
-  # Check code formatting and static analysis on a single OS (linux)
-  # against Dart stable.
+  check_java_format:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2 # v2 minimum required
+      - uses: axel-op/googlejavaformat-action@v3
+        with:
+          args: "--set-exit-if-changed"
+
   analyze_jni_gen:
     runs-on: ubuntu-latest
     defaults:
@@ -60,6 +66,11 @@
       - uses: dart-lang/setup-dart@v1.0
         with:
           sdk: stable
+      - uses: actions/setup-java@v2
+        with:
+          distribution: 'zulu'
+          java-version: '11'
+          cache: maven
       - name: Install dependencies
         run: dart pub get
       - name: Run VM tests
@@ -80,6 +91,20 @@
   ## i.e do not rerun analyze and format steps, and do not require flutter.
   ## IssueRef: https://github.com/dart-lang/jni_gen/issues/15
 
+  test_summarizer:
+    runs-on: ubuntu-latest
+    defaults:
+      run:
+        working-directory: ./pkgs/jni_gen/java
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-java@v2
+        with:
+          distribution: 'zulu'
+          java-version: '11'
+      - name: run tests using maven surefire
+        run: mvn surefire:test
+
   test_jni:
     runs-on: ubuntu-latest
     defaults:
@@ -139,12 +164,9 @@
       - run: |
           sudo apt-get update -y
           sudo apt-get install -y ninja-build libgtk-3-dev
-      - run: dart pub get
-        working-directory: ./pkgs/jni
-      - run: dart run bin/setup.dart
-        working-directory: ./pkgs/jni
       - run: flutter config --enable-linux-desktop
       - run: flutter pub get
+      - run: dart run jni:setup
       - run: flutter test
       - run: flutter build linux
 
diff --git a/pkgs/jni/android/build.gradle b/pkgs/jni/android/build.gradle
index 1fe097a..b91cb7b 100644
--- a/pkgs/jni/android/build.gradle
+++ b/pkgs/jni/android/build.gradle
@@ -31,12 +31,9 @@
 
     // Bumping the plugin ndkVersion requires all clients of this plugin to bump
     // the version in their app and to download a newer version of the NDK.
-
-    // Note(MaheshH): Seems 22 is lowest one can get through SDKManager now?
-    //
-    // It's more of a logistic issue, I can't download NDK 21, so keeping it
-    // 22. You might get a warning to bump some versions.
-    ndkVersion "22.1.7171670"
+    // Note(MaheshH) - Flutter seems to download minimum NDK of flutter when
+    // below line is commented out.
+    // How about leaving it?
     // ndkVersion "21.1.6352462"
 
     // Invoke the shared CMake build with the Android Gradle Plugin.
diff --git a/pkgs/jni/android/src/main/java/dev/dart/jni/JniPlugin.java b/pkgs/jni/android/src/main/java/dev/dart/jni/JniPlugin.java
index dbf8727..589ba85 100644
--- a/pkgs/jni/android/src/main/java/dev/dart/jni/JniPlugin.java
+++ b/pkgs/jni/android/src/main/java/dev/dart/jni/JniPlugin.java
@@ -1,32 +1,29 @@
 package dev.dart.jni;
 
+import android.app.Activity;
+import android.content.Context;
 import androidx.annotation.Keep;
 import androidx.annotation.NonNull;
-import android.util.Log;
-import android.app.Activity;
-import io.flutter.plugin.common.PluginRegistry.Registrar;
 import io.flutter.embedding.engine.plugins.FlutterPlugin;
 import io.flutter.embedding.engine.plugins.activity.ActivityAware;
 import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
-
-import android.content.Context;
+import io.flutter.plugin.common.PluginRegistry.Registrar;
 
 @Keep
 public class JniPlugin implements FlutterPlugin, ActivityAware {
-  
+
   @Override
-  public void
-  onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
-	  setup(binding.getApplicationContext());
+  public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
+    setup(binding.getApplicationContext());
   }
 
   public static void registerWith(Registrar registrar) {
     JniPlugin plugin = new JniPlugin();
-	plugin.setup(registrar.activeContext());
+    plugin.setup(registrar.activeContext());
   }
 
   private void setup(Context context) {
-	initializeJni(context, getClass().getClassLoader());
+    initializeJni(context, getClass().getClassLoader());
   }
 
   @Override
@@ -35,8 +32,8 @@
   // Activity handling methods
   @Override
   public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
-	Activity activity = binding.getActivity();
-	setJniActivity(activity, activity.getApplicationContext());
+    Activity activity = binding.getActivity();
+    setJniActivity(activity, activity.getApplicationContext());
   }
 
   @Override
@@ -44,18 +41,18 @@
 
   @Override
   public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
-	Activity activity = binding.getActivity();
-	setJniActivity(activity, activity.getApplicationContext());
+    Activity activity = binding.getActivity();
+    setJniActivity(activity, activity.getApplicationContext());
   }
 
   @Override
   public void onDetachedFromActivity() {}
 
   native void initializeJni(Context context, ClassLoader classLoader);
+
   native void setJniActivity(Activity activity, Context context);
 
   static {
-	System.loadLibrary("dartjni");
+    System.loadLibrary("dartjni");
   }
 }
-
diff --git a/pkgs/jni/bin/setup.dart b/pkgs/jni/bin/setup.dart
index 508f5e2..67d9f96 100644
--- a/pkgs/jni/bin/setup.dart
+++ b/pkgs/jni/bin/setup.dart
@@ -5,10 +5,27 @@
 
 const _buildDir = "build-dir";
 const _srcDir = "source-dir";
+const _packageName = 'package-name';
 const _verbose = "verbose";
 const _cmakeArgs = "cmake-args";
 const _clean = "clean";
 
+const _cmakeTemporaryFiles = [
+  'CMakeCache.txt',
+  'CMakeFiles/',
+  'cmake_install.cmake',
+  'Makefile'
+];
+
+void deleteCMakeTemps(Uri buildDir) async {
+  for (var filename in _cmakeTemporaryFiles) {
+    if (options.verbose) {
+      stderr.writeln('remove $filename');
+    }
+    await File(buildDir.resolve(filename).toFilePath()).delete(recursive: true);
+  }
+}
+
 // Sets up input output channels and maintains state.
 class CommandRunner {
   CommandRunner({this.printCmds = false});
@@ -25,7 +42,7 @@
     }
     final process = await Process.start(exec, args,
         workingDirectory: workingDir,
-        runInShell: Platform.isWindows,
+        runInShell: true,
         mode: ProcessStartMode.inheritStdio);
     final exitCode = await process.exitCode;
     if (exitCode != 0) {
@@ -39,11 +56,14 @@
   Options(ArgResults arg)
       : buildDir = arg[_buildDir],
         srcDir = arg[_srcDir],
+        packageName = arg[_packageName] ?? 'jni',
         cmakeArgs = arg[_cmakeArgs],
         verbose = arg[_verbose] ?? false,
         clean = arg[_clean] ?? false;
 
-  String? buildDir, srcDir, cmakeArgs;
+  String? buildDir, srcDir;
+  String packageName;
+  List<String> cmakeArgs;
   bool verbose, clean;
 }
 
@@ -63,7 +83,7 @@
   }
   final packages = packageConfig.packages;
   for (var package in packages) {
-    if (package.name == 'jni') {
+    if (package.name == options.packageName) {
       return package.root.resolve("src/").toFilePath();
     }
   }
@@ -76,14 +96,18 @@
         abbr: 'B', help: 'Directory to place built artifacts')
     ..addOption(_srcDir,
         abbr: 'S', help: 'alternative path to package:jni sources')
+    ..addOption(_packageName,
+        abbr: 'p',
+        help: 'package for which native'
+            'library should be built',
+        defaultsTo: 'jni')
     ..addFlag(_verbose, abbr: 'v', help: 'Enable verbose output')
     ..addFlag(_clean,
         negatable: false,
         abbr: 'C',
         help: 'Clear built artifacts instead of running a build')
-    ..addOption(_cmakeArgs,
-        abbr: 'm',
-        help: 'additional space separated arguments to pass to CMake');
+    ..addMultiOption(_cmakeArgs,
+        abbr: 'm', help: 'additional argument to pass to CMake');
   final cli = parser.parse(arguments);
   options = Options(cli);
   final rest = cli.rest;
@@ -114,7 +138,7 @@
 
   final currentDirUri = Uri.file(".");
   final buildPath =
-      options.buildDir ?? currentDirUri.resolve("src/build").toFilePath();
+      options.buildDir ?? currentDirUri.resolve("build/jni_libs").toFilePath();
   final buildDir = Directory(buildPath);
   await buildDir.create(recursive: true);
   log("buildPath: $buildPath");
@@ -136,15 +160,15 @@
 Future<void> build(Options options, String srcPath, String buildPath) async {
   final runner = CommandRunner(printCmds: true);
   final cmakeArgs = <String>[];
-  if (options.cmakeArgs != null) {
-    cmakeArgs.addAll(options.cmakeArgs!.split(" "));
-  }
+  cmakeArgs.addAll(options.cmakeArgs);
   cmakeArgs.add(srcPath);
   await runner.run("cmake", cmakeArgs, buildPath);
   await runner.run("cmake", ["--build", "."], buildPath);
   if (Platform.isWindows) {
     await runner.run("move", ["Debug\\dartjni.dll", "."], buildPath);
   }
+  // delete cmakeTemporaryArtifacts
+  deleteCMakeTemps(Uri.directory(buildPath));
 }
 
 Future<void> cleanup(Options options, String srcPath, String buildPath) async {
diff --git a/pkgs/jni/example/android/app/src/main/java/dev/dart/jni_example/AnyToast.java b/pkgs/jni/example/android/app/src/main/java/dev/dart/jni_example/AnyToast.java
index 59f07f7..7de08d3 100644
--- a/pkgs/jni/example/android/app/src/main/java/dev/dart/jni_example/AnyToast.java
+++ b/pkgs/jni/example/android/app/src/main/java/dev/dart/jni_example/AnyToast.java
@@ -1,28 +1,28 @@
 package dev.dart.jni_example;
 
 import android.app.Activity;
-import android.os.Handler;
 import android.content.Context;
 import android.widget.Toast;
 import androidx.annotation.Keep;
 
 @Keep
 class AnyToast {
-	static AnyToast makeText(Activity mainActivity, Context context, CharSequence text, int duration) {
-		AnyToast toast = new AnyToast();
-		toast.mainActivity = mainActivity;
-		toast.context = context;
-		toast.text = text;
-		toast.duration = duration;
-		return toast;
-	}
+  static AnyToast makeText(
+      Activity mainActivity, Context context, CharSequence text, int duration) {
+    AnyToast toast = new AnyToast();
+    toast.mainActivity = mainActivity;
+    toast.context = context;
+    toast.text = text;
+    toast.duration = duration;
+    return toast;
+  }
 
-	void show() {
-		mainActivity.runOnUiThread(() -> Toast.makeText(context, text, duration).show());
-	}
+  void show() {
+    mainActivity.runOnUiThread(() -> Toast.makeText(context, text, duration).show());
+  }
 
-	Activity mainActivity;
-	Context context;
-	CharSequence text;
-	int duration;
+  Activity mainActivity;
+  Context context;
+  CharSequence text;
+  int duration;
 }
diff --git a/pkgs/jni/example/test/widget_test.dart b/pkgs/jni/example/test/widget_test.dart
index c2336a0..2607462 100644
--- a/pkgs/jni/example/test/widget_test.dart
+++ b/pkgs/jni/example/test/widget_test.dart
@@ -14,7 +14,7 @@
 
 void main() {
   if (!Platform.isAndroid) {
-    Jni.spawn(helperDir: "../src/build");
+    Jni.spawn(helperDir: "build/jni_libs");
   }
   final jni = Jni.getInstance();
   testWidgets("simple toString example", (tester) async {
diff --git a/pkgs/jni/lib/jni.dart b/pkgs/jni/lib/jni.dart
index b604a5b..87049cb 100644
--- a/pkgs/jni/lib/jni.dart
+++ b/pkgs/jni/lib/jni.dart
@@ -64,3 +64,4 @@
 export 'src/extensions.dart'
     show StringMethodsForJni, CharPtrMethodsForJni, AdditionalJniEnvMethods;
 export 'src/jni_exceptions.dart';
+export 'src/jl_object.dart';
diff --git a/pkgs/jni/lib/src/jl_object.dart b/pkgs/jni/lib/src/jl_object.dart
new file mode 100644
index 0000000..36558f4
--- /dev/null
+++ b/pkgs/jni/lib/src/jl_object.dart
@@ -0,0 +1,61 @@
+import 'dart:ffi';
+
+import 'package:ffi/ffi.dart';
+
+import 'third_party/jni_bindings_generated.dart';
+import 'jni_exceptions.dart';
+import 'jni.dart';
+
+/// A container for a global [JObject] reference.
+class JlObject {
+  /// Constructs a `JlObject` from JNI reference.
+  JlObject.fromRef(this.reference);
+
+  /// Stored JNI global reference to the object.
+  JObject reference;
+
+  bool _deleted = false;
+
+  /// Deletes the underlying JNI reference.
+  ///
+  /// Must be called after this object is no longer needed.
+  void delete() {
+    if (_deleted) {
+      throw DoubleFreeException(this, reference);
+    }
+    _deleted = true;
+    // TODO(#12): this should be done in jni-thread-safe way
+    // will be solved when #12 is implemented.
+    Jni.getInstance().getEnv().DeleteGlobalRef(reference);
+  }
+}
+
+/// A container for JNI strings, with convertion to & from dart strings.
+class JlString extends JlObject {
+  JlString.fromRef(JString reference) : super.fromRef(reference);
+
+  static JString _toJavaString(String s) {
+    final chars = s.toNativeUtf8().cast<Char>();
+    final jstr = Jni.getInstance().toJavaString(chars);
+    malloc.free(chars);
+    return jstr;
+  }
+
+  JlString.fromString(String s) : super.fromRef(_toJavaString(s));
+
+  String toDartString() {
+    final jni = Jni.getInstance();
+    if (reference == nullptr) {
+      throw NullJlStringException();
+    }
+    final chars = jni.getJavaStringChars(reference);
+    final result = chars.cast<Utf8>().toDartString();
+    jni.releaseJavaStringChars(reference, chars);
+    return result;
+  }
+
+  late final _dartString = toDartString();
+
+  @override
+  String toString() => _dartString;
+}
diff --git a/pkgs/jni/lib/src/jni.dart b/pkgs/jni/lib/src/jni.dart
index beac5f7..b3ce6df 100644
--- a/pkgs/jni/lib/src/jni.dart
+++ b/pkgs/jni/lib/src/jni.dart
@@ -7,10 +7,10 @@
 import 'third_party/jni_bindings_generated.dart';
 import 'extensions.dart';
 import 'jvalues.dart';
-import 'jni_exceptions.dart';
 
 import 'jni_object.dart';
 import 'jni_class.dart';
+import 'jni_exceptions.dart';
 
 part 'direct_methods_generated.dart';
 
@@ -52,10 +52,16 @@
 class Jni {
   final JniBindings _bindings;
 
-  Jni._(this._bindings);
+  Jni._(DynamicLibrary library, [this._helperDir])
+      : _bindings = JniBindings(library),
+        _getJniEnvFn = library.lookup<Void>('GetJniEnv'),
+        _getJniContextFn = library.lookup<Void>('GetJniContext');
 
   static Jni? _instance;
 
+  /// Stores helperDir if any was used.
+  final String? _helperDir;
+
   /// Returns the existing Jni object.
   ///
   /// If not running on Android and no Jni is spawned
@@ -63,9 +69,12 @@
   ///
   /// On Dart standalone, when calling for the first time from
   /// a new isolate, make sure to pass the library path.
+  final Pointer<Void> _getJniEnvFn, _getJniContextFn;
+
   static Jni getInstance() {
     if (_instance == null) {
-      final inst = Jni._(JniBindings(_loadJniHelpersLibrary()));
+      final dylib = _loadJniHelpersLibrary();
+      final inst = Jni._(dylib);
       if (inst.getJavaVM() == nullptr) {
         throw StateError("Fatal: No JVM associated with this process!"
             " Did you call Jni.spawn?");
@@ -88,7 +97,7 @@
     if (_instance != null) {
       throw StateError('Fatal: a JNI instance already exists in this isolate');
     }
-    final inst = Jni._(JniBindings(_loadJniHelpersLibrary(dir: helperDir)));
+    final inst = Jni._(_loadJniHelpersLibrary(dir: helperDir), helperDir);
     if (inst.getJavaVM() == nullptr) {
       throw StateError("Fatal: No JVM associated with this process");
     }
@@ -117,7 +126,7 @@
       throw UnsupportedError("Currently only 1 VM is supported.");
     }
     final dylib = _loadJniHelpersLibrary(dir: helperDir);
-    final inst = Jni._(JniBindings(dylib));
+    final inst = Jni._(dylib, helperDir);
     _instance = inst;
     inst._bindings.SetJNILogging(logLevel);
     final jArgs = _createVMArgs(
@@ -256,6 +265,21 @@
     return JniClass.of(getEnv(), cls);
   }
 
+  Pointer<T> Function<T extends NativeType>(String) initGeneratedLibrary(
+      String name) {
+    var path = _getLibraryFileName(name);
+    if (_helperDir != null) {
+      path = join(_helperDir!, path);
+    }
+    final dl = DynamicLibrary.open(path);
+    final setJniGetters =
+        dl.lookupFunction<SetJniGettersNativeType, SetJniGettersDartType>(
+            'setJniGetters');
+    setJniGetters(_getJniContextFn, _getJniEnvFn);
+    final lookup = dl.lookup;
+    return lookup;
+  }
+
   /// Converts passed arguments to JValue array
   /// for use in methods that take arguments.
   ///
@@ -266,4 +290,14 @@
       {Allocator allocator = calloc}) {
     return toJValues(args, allocator: allocator);
   }
+
+  // Temporarily for JlString.
+  // A future idea is to unify JlObject and JniObject, and use global refs
+  // everywhere for simplicity.
+  late final toJavaString = _bindings.ToJavaString;
+  late final getJavaStringChars = _bindings.GetJavaStringChars;
+  late final releaseJavaStringChars = _bindings.ReleaseJavaStringChars;
 }
+
+typedef SetJniGettersNativeType = Void Function(Pointer<Void>, Pointer<Void>);
+typedef SetJniGettersDartType = void Function(Pointer<Void>, Pointer<Void>);
diff --git a/pkgs/jni/lib/src/jni_exceptions.dart b/pkgs/jni/lib/src/jni_exceptions.dart
index 1533437..c765ec4 100644
--- a/pkgs/jni/lib/src/jni_exceptions.dart
+++ b/pkgs/jni/lib/src/jni_exceptions.dart
@@ -13,6 +13,11 @@
   }
 }
 
+class NullJlStringException implements Exception {
+  @override
+  String toString() => 'toDartString called on null JlString reference';
+}
+
 class DoubleFreeException implements Exception {
   dynamic object;
   Pointer<Void> ptr;
diff --git a/pkgs/jni/lib/src/third_party/jni_bindings_generated.dart b/pkgs/jni/lib/src/third_party/jni_bindings_generated.dart
index 005029c..77a1700 100644
--- a/pkgs/jni/lib/src/third_party/jni_bindings_generated.dart
+++ b/pkgs/jni/lib/src/third_party/jni_bindings_generated.dart
@@ -207,6 +207,51 @@
       _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int)>>('SetJNILogging');
   late final _SetJNILogging =
       _SetJNILoggingPtr.asFunction<void Function(int)>();
+
+  JString ToJavaString(
+    ffi.Pointer<ffi.Char> str,
+  ) {
+    return _ToJavaString(
+      str,
+    );
+  }
+
+  late final _ToJavaStringPtr =
+      _lookup<ffi.NativeFunction<JString Function(ffi.Pointer<ffi.Char>)>>(
+          'ToJavaString');
+  late final _ToJavaString =
+      _ToJavaStringPtr.asFunction<JString Function(ffi.Pointer<ffi.Char>)>();
+
+  ffi.Pointer<ffi.Char> GetJavaStringChars(
+    JString jstr,
+  ) {
+    return _GetJavaStringChars(
+      jstr,
+    );
+  }
+
+  late final _GetJavaStringCharsPtr =
+      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(JString)>>(
+          'GetJavaStringChars');
+  late final _GetJavaStringChars = _GetJavaStringCharsPtr.asFunction<
+      ffi.Pointer<ffi.Char> Function(JString)>();
+
+  void ReleaseJavaStringChars(
+    JString jstr,
+    ffi.Pointer<ffi.Char> buf,
+  ) {
+    return _ReleaseJavaStringChars(
+      jstr,
+      buf,
+    );
+  }
+
+  late final _ReleaseJavaStringCharsPtr = _lookup<
+      ffi.NativeFunction<
+          ffi.Void Function(
+              JString, ffi.Pointer<ffi.Char>)>>('ReleaseJavaStringChars');
+  late final _ReleaseJavaStringChars = _ReleaseJavaStringCharsPtr.asFunction<
+      void Function(JString, ffi.Pointer<ffi.Char>)>();
 }
 
 class jfieldID_ extends ffi.Opaque {}
diff --git a/pkgs/jni/src/dartjni.c b/pkgs/jni/src/dartjni.c
index cf4e7d5..82f1597 100644
--- a/pkgs/jni/src/dartjni.c
+++ b/pkgs/jni/src/dartjni.c
@@ -15,8 +15,7 @@
 }
 
 void jni_log(int level, const char *format, ...) {
-	// TODO: Not working
-	// IssueRef: https://github.com/dart-lang/jni_gen/issues/16
+	// TODO(#16): This is not working.
 	if (level >= jni_log_level) {
 		va_list args;
         va_start(args, format);
@@ -30,6 +29,8 @@
 	}
 }
 
+FFI_PLUGIN_EXPORT struct jni_context GetJniContext() { return jni; }
+
 /// Get JVM associated with current process.
 /// Returns NULL if no JVM is running.
 FFI_PLUGIN_EXPORT
@@ -86,6 +87,26 @@
 	return (*jniEnv)->NewLocalRef(jniEnv, jni.currentActivity);
 }
 
+FFI_PLUGIN_EXPORT
+jstring ToJavaString(char *str) {
+	attach_thread();
+	jstring s = (*jniEnv)->NewStringUTF(jniEnv, str);
+	jstring g = (*jniEnv)->NewGlobalRef(jniEnv, s);
+	(*jniEnv)->DeleteLocalRef(jniEnv, s);
+	return g;
+}
+
+FFI_PLUGIN_EXPORT
+const char *GetJavaStringChars(jstring jstr) {
+	const char *buf = (*jniEnv)->GetStringUTFChars(jniEnv, jstr, NULL);
+	return buf;
+}
+
+FFI_PLUGIN_EXPORT
+void ReleaseJavaStringChars(jstring jstr, const char *buf) {
+	(*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, buf);
+}
+
 #ifdef __ANDROID__
 JNIEXPORT void JNICALL Java_dev_dart_jni_JniPlugin_initializeJni(
     JNIEnv *env, jobject obj, jobject appContext, jobject classLoader) {
diff --git a/pkgs/jni/src/dartjni.h b/pkgs/jni/src/dartjni.h
index 5b7fb5b..407312b 100644
--- a/pkgs/jni/src/dartjni.h
+++ b/pkgs/jni/src/dartjni.h
@@ -1,6 +1,6 @@
+#include <jni.h>
 #include <stdint.h>
 #include <stdio.h>
-#include <jni.h>
 #include <stdlib.h>
 
 #if _WIN32
@@ -23,7 +23,7 @@
 #endif
 
 #ifdef __ANDROID__
-#include<android/log.h>
+#include <android/log.h>
 #endif
 
 #define JNI_LOG_TAG "Dart-JNI"
@@ -43,12 +43,19 @@
 };
 
 extern thread_local JNIEnv *jniEnv;
+
 extern struct jni_context jni;
 
 enum DartJniLogLevel {
-	JNI_VERBOSE = 2, JNI_DEBUG, JNI_INFO, JNI_WARN, JNI_ERROR
+	JNI_VERBOSE = 2,
+	JNI_DEBUG,
+	JNI_INFO,
+	JNI_WARN,
+	JNI_ERROR
 };
 
+FFI_PLUGIN_EXPORT struct jni_context GetJniContext();
+
 FFI_PLUGIN_EXPORT JavaVM *GetJavaVM(void);
 
 FFI_PLUGIN_EXPORT JNIEnv *GetJniEnv(void);
@@ -65,23 +72,39 @@
 
 FFI_PLUGIN_EXPORT void SetJNILogging(int level);
 
-/// For use by jni_gen's generated code
-/// don't use these.
+FFI_PLUGIN_EXPORT jstring ToJavaString(char *str);
 
-// `static inline` because `inline` doesn't work, it may still not 
+FFI_PLUGIN_EXPORT const char *GetJavaStringChars(jstring jstr);
+
+FFI_PLUGIN_EXPORT void ReleaseJavaStringChars(jstring jstr, const char *buf);
+
+// These 2 are the function pointer variables defined and exported by
+// the generated C files.
+//
+// initGeneratedLibrary function in Jni class will set these to
+// corresponding functions to the implementations from `dartjni` base library
+// which initializes and manages the JNI.
+extern struct jni_context (*context_getter)(void);
+extern JNIEnv *(*env_getter)(void);
+
+// This function will be exported by generated code library and will set the
+// above 2 variables.
+FFI_PLUGIN_EXPORT void setJniGetters(struct jni_context (*cg)(void),
+		JNIEnv *(*eg)(void));
+
+// `static inline` because `inline` doesn't work, it may still not
 // inline the function in which case a linker error may be produced.
 //
 // There has to be a better way to do this. Either to force inlining on target
 // platforms, or just leave it as normal function.
-
 static inline void __load_class_into(jclass *cls, const char *name) {
 #ifdef __ANDROID__
-		jstring className = (*jniEnv)->NewStringUTF(jniEnv, name);
-		*cls = (*jniEnv)->CallObjectMethod(
-		    jniEnv, jni.classLoader, jni.loadClassMethod, className);
-		(*jniEnv)->DeleteLocalRef(jniEnv, className);
+	jstring className = (*jniEnv)->NewStringUTF(jniEnv, name);
+	*cls = (*jniEnv)->CallObjectMethod(jniEnv, jni.classLoader,
+	                                   jni.loadClassMethod, className);
+	(*jniEnv)->DeleteLocalRef(jniEnv, className);
 #else
-		*cls = (*jniEnv)->FindClass(jniEnv, name);
+	*cls = (*jniEnv)->FindClass(jniEnv, name);
 #endif
 }
 
@@ -102,11 +125,18 @@
 
 static inline void attach_thread() {
 	if (jniEnv == NULL) {
-		(*jni.jvm)->AttachCurrentThread(jni.jvm, __ENVP_CAST &jniEnv,
+		(*jni.jvm)->AttachCurrentThread(jni.jvm, __ENVP_CAST & jniEnv,
 		                                NULL);
 	}
 }
 
+static inline void load_env() {
+	if (jniEnv == NULL) {
+		jni = context_getter();
+		jniEnv = env_getter();
+	}
+}
+
 static inline void load_method(jclass cls, jmethodID *res, const char *name,
                                const char *sig) {
 	if (*res == NULL) {
@@ -121,3 +151,23 @@
 	}
 }
 
+static inline void load_field(jclass cls, jfieldID *res, const char *name,
+                              const char *sig) {
+	if (*res == NULL) {
+		*res = (*jniEnv)->GetFieldID(jniEnv, cls, name, sig);
+	}
+}
+
+static inline void load_static_field(jclass cls, jfieldID *res,
+                                     const char *name, const char *sig) {
+	if (*res == NULL) {
+		*res = (*jniEnv)->GetStaticFieldID(jniEnv, cls, name, sig);
+	}
+}
+
+static inline jobject to_global_ref(jobject ref) {
+	jobject g = (*jniEnv)->NewGlobalRef(jniEnv, ref);
+	(*jniEnv)->DeleteLocalRef(jniEnv, ref);
+	return g;
+}
+
diff --git a/pkgs/jni/test/exception_test.dart b/pkgs/jni/test/exception_test.dart
index 9a3194c..109a7e6 100644
--- a/pkgs/jni/test/exception_test.dart
+++ b/pkgs/jni/test/exception_test.dart
@@ -15,7 +15,7 @@
       Jni.spawn(helperDir: "wrong_dir");
     } on HelperNotFoundException catch (_) {
       // stderr.write("\n$_\n");
-      Jni.spawn(helperDir: "src/build");
+      Jni.spawn(helperDir: "build/jni_libs");
       caught = true;
     }
     if (!caught) {
diff --git a/pkgs/jni/test/jni_object_test.dart b/pkgs/jni/test/jni_object_test.dart
index c671323..6124d1f 100644
--- a/pkgs/jni/test/jni_object_test.dart
+++ b/pkgs/jni/test/jni_object_test.dart
@@ -10,7 +10,7 @@
 void main() {
   // Don't forget to initialize JNI.
   if (!Platform.isAndroid) {
-    Jni.spawn(helperDir: "src/build");
+    Jni.spawn(helperDir: "build/jni_libs");
   }
 
   final jni = Jni.getInstance();
@@ -210,7 +210,7 @@
   // when doing getInstance first time in a new isolate.
   //
   // otherwise getInstance will throw a "library not found" exception.
-  Jni.load(helperDir: "src/build");
+  Jni.load(helperDir: "build/jni_libs");
   final jni = Jni.getInstance();
   final random = jni.newInstance("java/util/Random", "()V", []);
   // final r = random.callIntMethodByName("nextInt", "(I)I", [256]);
diff --git a/pkgs/jni/test/jni_test.dart b/pkgs/jni/test/jni_test.dart
index 9982cf1..29f536b 100644
--- a/pkgs/jni/test/jni_test.dart
+++ b/pkgs/jni/test/jni_test.dart
@@ -18,7 +18,7 @@
   // You have to manually pass the path to the `dartjni` dynamic library.
 
   if (!Platform.isAndroid) {
-    Jni.spawn(helperDir: "src/build");
+    Jni.spawn(helperDir: "build/jni_libs");
   }
 
   final jni = Jni.getInstance();
diff --git a/pkgs/jni_gen/.gitignore b/pkgs/jni_gen/.gitignore
index 93533a5..2c67603 100644
--- a/pkgs/jni_gen/.gitignore
+++ b/pkgs/jni_gen/.gitignore
@@ -6,6 +6,9 @@
 build/
 pubspec.lock
 
+# created by maven
+/target/
+
 # Directory created by dartdoc.
 doc/api/
 
@@ -33,3 +36,7 @@
 
 # Mac
 .DS_Store
+
+# Vim
+.*.swp
+
diff --git a/pkgs/jni_gen/README.md b/pkgs/jni_gen/README.md
index d0f0474..373127b 100644
--- a/pkgs/jni_gen/README.md
+++ b/pkgs/jni_gen/README.md
@@ -4,3 +4,4 @@
 This enables calling Java code from Dart.
 
 This is a GSoC 2022 project.
+
diff --git a/pkgs/jni_gen/analysis_options.yaml b/pkgs/jni_gen/analysis_options.yaml
index 9c8e2c5..3fa121a 100644
--- a/pkgs/jni_gen/analysis_options.yaml
+++ b/pkgs/jni_gen/analysis_options.yaml
@@ -3,3 +3,15 @@
 # BSD-style license that can be found in the LICENSE file.
 
 include: package:lints/recommended.yaml
+
+analyzer:
+  exclude: [build/**]
+  language:
+    strict-raw-types: true
+    strict-inference: true
+
+linter:
+  rules:
+    - prefer_final_locals
+    - prefer_const_declarations
+
diff --git a/pkgs/jni_gen/bin/setup.dart b/pkgs/jni_gen/bin/setup.dart
new file mode 100644
index 0000000..656b5da
--- /dev/null
+++ b/pkgs/jni_gen/bin/setup.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This script gets the java sources using the copy of this package, and builds
+// ApiSummarizer jar using Maven.
+import 'dart:io';
+
+import 'package:path/path.dart';
+
+import 'package:jni_gen/src/util/find_package.dart';
+
+final toolPath = join('.', '.dart_tool', 'jni_gen');
+final mvnTargetDir = join(toolPath, 'target');
+final jarFile = join(toolPath, 'ApiSummarizer.jar');
+final targetJarFile = join(mvnTargetDir, 'ApiSummarizer.jar');
+
+Future<void> buildApiSummarizer() async {
+  final pkg = await findPackageRoot('jni_gen');
+  if (pkg == null) {
+    stderr.writeln('package jni_gen not found!');
+    exitCode = 2;
+    return;
+  }
+  final pom = pkg.resolve('java/pom.xml');
+  await Directory(toolPath).create(recursive: true);
+  final mvnProc = await Process.start(
+      'mvn',
+      [
+        '--batch-mode',
+        '--update-snapshots',
+        '-f',
+        pom.toFilePath(),
+        'assembly:assembly'
+      ],
+      workingDirectory: toolPath,
+      mode: ProcessStartMode.inheritStdio);
+  await mvnProc.exitCode;
+  // move ApiSummarizer.jar from target to current directory
+  File(targetJarFile).renameSync(jarFile);
+  Directory(mvnTargetDir).deleteSync(recursive: true);
+}
+
+void main(List<String> args) async {
+  bool force = false;
+  if (args.isNotEmpty) {
+    if (args.length != 1 || args[0] != '-f') {
+      stderr.writeln('usage: dart run jni_gen:setup [-f]');
+      stderr.writeln('use -f option to rebuild ApiSummarizer jar '
+          'even if it already exists.');
+    } else {
+      force = true;
+    }
+  }
+  final jarExists = await File(jarFile).exists();
+  final isJarStale = jarExists &&
+      await isPackageModifiedAfter(
+          'jni_gen', await File(jarFile).lastModified(), 'java/');
+  if (isJarStale) {
+    stderr.writeln('Rebuilding ApiSummarizer component since sources '
+        'have changed. This might take some time.');
+  }
+  if (!jarExists || isJarStale || force) {
+    await buildApiSummarizer();
+  } else {
+    stderr.writeln('ApiSummarizer.jar exists. Skipping build..');
+  }
+}
diff --git a/pkgs/jni_gen/cmake/CMakeLists.txt.tmpl b/pkgs/jni_gen/cmake/CMakeLists.txt.tmpl
new file mode 100644
index 0000000..21d0d80
--- /dev/null
+++ b/pkgs/jni_gen/cmake/CMakeLists.txt.tmpl
@@ -0,0 +1,30 @@
+# The Flutter tooling requires that developers have CMake 3.10 or later
+# installed. You should not increase this version, as doing so will cause
+# the plugin to fail to compile for some customers of the plugin.
+cmake_minimum_required(VERSION 3.10)
+
+project({{LIBRARY_NAME}} VERSION 0.0.1 LANGUAGES C)
+
+add_library({{LIBRARY_NAME}} SHARED
+  "{{LIBRARY_NAME}}.c"
+)
+
+set_target_properties({{LIBRARY_NAME}} PROPERTIES
+  OUTPUT_NAME "{{LIBRARY_NAME}}"
+)
+
+target_compile_definitions({{LIBRARY_NAME}} PUBLIC DART_SHARED_LIB)
+
+if(WIN32)
+	set_target_properties(${TARGET_NAME} PROPERTIES
+		LINK_FLAGS "/DELAYLOAD:jvm.dll")
+endif()
+
+if (ANDROID)
+	target_link_libraries({{LIBRARY_NAME}} log)
+else()
+	find_package(Java REQUIRED)
+	find_package(JNI REQUIRED)
+	include_directories(${JNI_INCLUDE_DIRS})
+	target_link_libraries({{LIBRARY_NAME}} ${JNI_LIBRARIES})
+endif()
diff --git a/pkgs/jni_gen/java/.gitignore b/pkgs/jni_gen/java/.gitignore
new file mode 100644
index 0000000..fe41dfd
--- /dev/null
+++ b/pkgs/jni_gen/java/.gitignore
@@ -0,0 +1,10 @@
+target/*
+*.class
+*.jar
+
+.idea/compiler.xml
+.idea/dictionaries
+.idea/inspectionProfiles/
+.idea/jarRepositories.xml
+.idea/misc.xml
+.idea/runConfigurations.xml
diff --git a/pkgs/jni_gen/java/README.md b/pkgs/jni_gen/java/README.md
new file mode 100644
index 0000000..25a04b3
--- /dev/null
+++ b/pkgs/jni_gen/java/README.md
@@ -0,0 +1,46 @@
+## ApiSummarizer
+An early version of ApiSummarizer.
+
+It analyzes java source code / jars and outputs a JSON representation of the public API.
+
+It's currently used in `jni_gen` to get the information of the Java API.
+
+## Build
+When using it via `jni_gen`, the `jni_gen:setup` script will take care of building the jar in appropriate location.
+
+To build the jar manually, run `mvn assembly:assembly` in project root. The jar will be created in `target/` directory.
+
+## Command line
+```
+usage: java -jar <JAR> [-s <SOURCE_DIR=.>] [-c <CLASSES_JAR>]
+<CLASS_OR_PACKAGE_NAMES>
+Class or package names should be fully qualified.
+
+-b,--backend <arg>        backend to use for summary generation ('doclet'
+or 'asm').
+-c,--classes <arg>        paths to search for compiled classes
+-D,--doctool-args <arg>   Arguments to pass to the documentation tool
+-M,--use-modules          use Java modules
+-m,--module-names <arg>   comma separated list of module names
+-r,--recursive            Include dependencies of classes
+-s,--sources <arg>        paths to search for source files
+-v,--verbose              Enable verbose output
+```
+
+Here class or package names are specified as fully qualified names, for example `org.apache.pdfbox.pdmodel.PDDocument` will load `org/apache/pdfbox/pdmodel/PDDocument.java`. It assumes the package naming reflects directory structure. If such mapping results in a directory, for example `android.os` is given and a directory `android/os` is found under the source path, it is considered as a package and all Java source files under that directory are loaded recursively. 
+
+Note that some options are directly forwarded to the underlying tool.
+
+ApiSummarizer's current use is in `jni_gen` for obtaining public API of java packages. Only the features strictly required for that purpose are focused upon.
+
+## Running tests
+Run `mvn surefire:test`
+
+There are not many tests at the moment. We plan to add some later.
+
+## ASM backend
+
+The main backend is based on javadoc API and generates summary based on java sources. A more experimental ASM backend also exists, and works somewhat okay-ish. It can summarize the compiled JARs. However, compiled jars without debug information do not include method parameter names. Some basic renaming is applied, i.e If type is `Object`, the parameter name will be output as `object` if an actual name is absent.
+
+## TODO
+See issue #23.
\ No newline at end of file
diff --git a/pkgs/jni_gen/java/pom.xml b/pkgs/jni_gen/java/pom.xml
new file mode 100644
index 0000000..a36c78f
--- /dev/null
+++ b/pkgs/jni_gen/java/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.github.dart_lang.jni_gen</groupId>
+    <artifactId>ApiSummarizer</artifactId>
+    <description>Summarize public APIs of java packages in JSON or protobuf.</description>
+    <version>0.0.1-SNAPSHOT</version>
+
+    <properties>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+        <jackson.version>2.13.3</jackson.version>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<buildDir>${user.dir}</buildDir>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-cli</groupId>
+            <artifactId>commons-cli</artifactId>
+            <version>1.5.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ow2.asm</groupId>
+            <artifactId>asm-tree</artifactId>
+            <version>9.3</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.13.2</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+		<directory>${buildDir}/target</directory>
+        <finalName>ApiSummarizer</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>3.0.0-M7</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <configuration>
+                    <descriptorId>jar-with-dependencies</descriptorId>
+                    <appendAssemblyId>false</appendAssemblyId>
+                    <archive>
+                        <manifest>
+                            <mainClass>com.github.dart_lang.jni_gen.apisummarizer.Main</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.10.1</version>
+                <configuration>
+                    <source>11</source>
+                    <target>11</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/Main.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/Main.java
new file mode 100644
index 0000000..f733c8e
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/Main.java
@@ -0,0 +1,205 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.github.dart_lang.jni_gen.apisummarizer.disasm.AsmSummarizer;
+import com.github.dart_lang.jni_gen.apisummarizer.doclet.SummarizerDoclet;
+import com.github.dart_lang.jni_gen.apisummarizer.elements.ClassDecl;
+import com.github.dart_lang.jni_gen.apisummarizer.util.Log;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.tools.DocumentationTool;
+import javax.tools.ToolProvider;
+import jdk.javadoc.doclet.Doclet;
+import org.apache.commons.cli.*;
+
+public class Main {
+  private static final CommandLineParser parser = new DefaultParser();
+  static SummarizerOptions config;
+
+  public static void writeAll(List<ClassDecl> decls) {
+    var mapper = new ObjectMapper();
+    Log.timed("Writing JSON");
+    mapper.enable(SerializationFeature.INDENT_OUTPUT);
+    mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+    try {
+      mapper.writeValue(System.out, decls);
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+    Log.timed("Finished");
+  }
+
+  public static void runDoclet(List<String> qualifiedNames, SummarizerOptions options) {
+    runDocletWithClass(SummarizerDoclet.class, qualifiedNames, options);
+  }
+
+  public static void runDocletWithClass(
+      Class<? extends Doclet> docletClass, List<String> qualifiedNames, SummarizerOptions options) {
+    List<File> javaFilePaths =
+        qualifiedNames.stream()
+            .map(s -> findSourceLocation(s, options.sourcePaths.split(File.pathSeparator)))
+            .collect(Collectors.toList());
+    Log.setVerbose(options.verbose);
+
+    var files =
+        javaFilePaths.stream()
+            .flatMap(
+                path -> recursiveListFiles(path, file -> file.getName().endsWith(".java")).stream())
+            .map(File::getPath)
+            .toArray(String[]::new);
+
+    DocumentationTool javadoc = ToolProvider.getSystemDocumentationTool();
+    var fileManager = javadoc.getStandardFileManager(null, null, null);
+    var fileObjects = fileManager.getJavaFileObjects(files);
+
+    var cli = new ArrayList<String>();
+    cli.add((options.useModules ? "--module-" : "--") + "source-path=" + options.sourcePaths);
+    if (options.classPaths != null) {
+      cli.add("--class-path=" + options.classPaths);
+    }
+    if (options.addDependencies) {
+      cli.add("--expand-requires=all");
+    }
+    if (options.toolOptions != null) {
+      cli.addAll(List.of(options.toolOptions.split(" ")));
+    }
+
+    javadoc.getTask(null, fileManager, System.err::println, docletClass, cli, fileObjects).call();
+  }
+
+  public static void main(String[] args) {
+    CommandLine cl = parseArgs(args);
+    config = SummarizerOptions.fromCommandLine(cl);
+    if (config.useAsm) {
+      System.err.println("use-asm: ignoring all flags other than --classes (-c)");
+      try {
+        writeAll(AsmSummarizer.run(config.classPaths.split(File.pathSeparator), cl.getArgs()));
+      } catch (IOException e) {
+        e.printStackTrace();
+      }
+      return;
+    }
+    runDoclet(List.of(cl.getArgs()), config);
+  }
+
+  public static File findSourceLocation(String qualifiedName, String[] paths) {
+    var s = qualifiedName.replace(".", "/");
+    for (var folder : paths) {
+      var f = new File(folder, s + ".java");
+      if (f.exists() && f.isFile()) {
+        return f;
+      }
+      var d = new File(folder, s);
+      if (d.exists() && d.isDirectory()) {
+        return d;
+      }
+    }
+    throw new RuntimeException("cannot find class: " + s);
+  }
+
+  public static List<File> recursiveListFiles(File file, FileFilter filter) {
+    if (!file.isDirectory()) {
+      return List.of(file);
+    }
+    var files = new ArrayList<File>();
+    var queue = new ArrayDeque<File>();
+    queue.add(file);
+    while (!queue.isEmpty()) {
+      var dir = queue.poll();
+      var list = dir.listFiles(entry -> entry.isDirectory() || filter.accept(entry));
+      if (list == null) {
+        throw new IllegalArgumentException();
+      }
+      for (var path : list) {
+        if (path.isDirectory()) {
+          queue.add(path);
+        } else {
+          files.add(path);
+        }
+      }
+    }
+    return files;
+  }
+
+  public static CommandLine parseArgs(String[] args) {
+    var options = new Options();
+    Option sources = new Option("s", "sources", true, "paths to search for source files");
+    Option classes = new Option("c", "classes", true, "paths to search for compiled classes");
+    Option backend =
+        new Option(
+            "b", "backend", true, "backend to use for summary generation ('doclet' or 'asm').");
+    Option useModules = new Option("M", "use-modules", false, "use Java modules");
+    Option recursive = new Option("r", "recursive", false, "Include dependencies of classes");
+    Option moduleNames =
+        new Option("m", "module-names", true, "comma separated list of module names");
+    Option doctoolArgs =
+        new Option("D", "doctool-args", true, "Arguments to pass to the documentation tool");
+    Option verbose = new Option("v", "verbose", false, "Enable verbose output");
+    for (Option opt :
+        new Option[] {
+          sources, classes, backend, useModules, recursive, moduleNames, doctoolArgs, verbose
+        }) {
+      options.addOption(opt);
+    }
+
+    HelpFormatter help = new HelpFormatter();
+
+    CommandLine cmd;
+
+    try {
+      cmd = parser.parse(options, args);
+      if (cmd.getArgs().length < 1) {
+        throw new ParseException("Need to specify paths to source files");
+      }
+    } catch (ParseException e) {
+      System.out.println(e.getMessage());
+      help.printHelp(
+          "java -jar <JAR> [-s <SOURCE_DIR=.>] "
+              + "[-c <CLASSES_JAR>] <CLASS_OR_PACKAGE_NAMES>\n"
+              + "Class or package names should be fully qualified.\n\n",
+          options);
+      System.exit(1);
+      return null;
+    }
+    return cmd;
+  }
+
+  public static class SummarizerOptions {
+    String sourcePaths, classPaths;
+    boolean useModules, useAsm;
+    String modulesList;
+    boolean addDependencies;
+    String toolOptions;
+    boolean verbose;
+
+    public static SummarizerOptions fromCommandLine(CommandLine cmd) {
+      var opts = new SummarizerOptions();
+      opts.sourcePaths = cmd.getOptionValue("sources", ".");
+      var backend = cmd.getOptionValue("backend", "doclet");
+      if (backend.equalsIgnoreCase("asm")) {
+        opts.useAsm = true;
+      } else if (!backend.equalsIgnoreCase("doclet")) {
+        System.err.println("supported backends: asm, doclet");
+        System.exit(1);
+      }
+      opts.classPaths = cmd.getOptionValue("classes", null);
+      opts.useModules = cmd.hasOption("use-modules");
+      opts.modulesList = cmd.getOptionValue("module-names", null);
+      opts.addDependencies = cmd.hasOption("recursive");
+      opts.toolOptions = cmd.getOptionValue("doctool-args", null);
+      opts.verbose = cmd.hasOption("verbose");
+      return opts;
+    }
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmAnnotatedElementVisitor.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmAnnotatedElementVisitor.java
new file mode 100644
index 0000000..8938ed7
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmAnnotatedElementVisitor.java
@@ -0,0 +1,24 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.disasm;
+
+import com.github.dart_lang.jni_gen.apisummarizer.elements.JavaAnnotation;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Type;
+
+// This interface removes some repetitive code using default methods
+
+public interface AsmAnnotatedElementVisitor {
+  void addAnnotation(JavaAnnotation annotation);
+
+  default AnnotationVisitor visitAnnotationDefault(String descriptor, boolean visible) {
+    var annotation = new JavaAnnotation();
+    var aType = Type.getType(descriptor);
+    annotation.binaryName = aType.getClassName();
+    annotation.simpleName = TypeUtils.simpleName(aType);
+    addAnnotation(annotation);
+    return new AsmAnnotationVisitor(annotation);
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmAnnotationVisitor.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmAnnotationVisitor.java
new file mode 100644
index 0000000..7496fc7
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmAnnotationVisitor.java
@@ -0,0 +1,86 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.disasm;
+
+import com.github.dart_lang.jni_gen.apisummarizer.elements.JavaAnnotation;
+import java.util.ArrayList;
+import java.util.List;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Type;
+
+public class AsmAnnotationVisitor extends AnnotationVisitor {
+
+  JavaAnnotation annotation;
+
+  protected AsmAnnotationVisitor(JavaAnnotation annotation) {
+    super(AsmConstants.API);
+    this.annotation = annotation;
+  }
+
+  @Override
+  public void visit(String name, Object value) {
+    annotation.properties.put(name, value);
+  }
+
+  @Override
+  public void visitEnum(String name, String descriptor, String value) {
+    annotation.properties.put(
+        name, new JavaAnnotation.EnumVal(Type.getType(descriptor).getClassName(), value));
+  }
+
+  @Override
+  public AnnotationVisitor visitAnnotation(String name, String descriptor) {
+    var type = Type.getType(descriptor);
+    var nested = new JavaAnnotation();
+    nested.binaryName = type.getClassName();
+    nested.simpleName = TypeUtils.simpleName(type);
+    annotation.properties.put(name, nested);
+    return new AsmAnnotationVisitor(nested);
+  }
+
+  @Override
+  public AnnotationVisitor visitArray(String name) {
+    List<Object> list = new ArrayList<>();
+    annotation.properties.put(name, list);
+    return new AnnotationArrayVisitor(list);
+  }
+
+  public static class AnnotationArrayVisitor extends AnnotationVisitor {
+    List<Object> list;
+
+    protected AnnotationArrayVisitor(List<Object> list) {
+      super(AsmConstants.API);
+      this.list = list;
+    }
+
+    @Override
+    public void visit(String unused, Object value) {
+      list.add(value);
+    }
+
+    @Override
+    public void visitEnum(String unused, String descriptor, String value) {
+      var type = Type.getType(descriptor);
+      list.add(new JavaAnnotation.EnumVal(type.getClassName(), value));
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(String unused, String descriptor) {
+      var type = Type.getType(descriptor);
+      var nested = new JavaAnnotation();
+      nested.binaryName = type.getClassName();
+      nested.simpleName = TypeUtils.simpleName(type);
+      list.add(nested);
+      return new AsmAnnotationVisitor(nested);
+    }
+
+    @Override
+    public AnnotationVisitor visitArray(String unused) {
+      List<Object> nested = new ArrayList<>();
+      list.add(nested);
+      return new AnnotationArrayVisitor(nested);
+    }
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmClassVisitor.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmClassVisitor.java
new file mode 100644
index 0000000..faed831
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmClassVisitor.java
@@ -0,0 +1,144 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.disasm;
+
+import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
+import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
+
+import com.github.dart_lang.jni_gen.apisummarizer.elements.*;
+import com.github.dart_lang.jni_gen.apisummarizer.util.SkipException;
+import com.github.dart_lang.jni_gen.apisummarizer.util.StreamUtil;
+import java.util.*;
+import org.objectweb.asm.*;
+
+public class AsmClassVisitor extends ClassVisitor implements AsmAnnotatedElementVisitor {
+  private static Param param(
+      Type type, String name, @SuppressWarnings("SameParameterValue") String signature) {
+    var param = new Param();
+    param.name = name;
+    param.type = TypeUtils.typeUsage(type, signature);
+    return param;
+  }
+
+  public List<ClassDecl> getVisited() {
+    return visited;
+  }
+
+  List<ClassDecl> visited = new ArrayList<>();
+  Stack<ClassDecl> visiting = new Stack<>();
+
+  public AsmClassVisitor() {
+    super(AsmConstants.API);
+  }
+
+  @Override
+  public void visit(
+      int version,
+      int access,
+      String name,
+      String signature,
+      String superName,
+      String[] interfaces) {
+    var current = new ClassDecl();
+    visiting.push(current);
+    var type = Type.getObjectType(name);
+    current.binaryName = type.getClassName();
+    current.modifiers = TypeUtils.access(access);
+    current.parentName = TypeUtils.parentName(type);
+    current.packageName = TypeUtils.packageName(type);
+    current.declKind = TypeUtils.declKind(access);
+    current.simpleName = TypeUtils.simpleName(type);
+    current.superclass = TypeUtils.typeUsage(Type.getObjectType(superName), null);
+    current.interfaces =
+        StreamUtil.map(interfaces, i -> TypeUtils.typeUsage(Type.getObjectType(i), null));
+    super.visit(version, access, name, signature, superName, interfaces);
+  }
+
+  private static boolean isPrivate(int access) {
+    return ((access & ACC_PUBLIC) == 0) && ((access & ACC_PROTECTED) == 0);
+  }
+
+  @Override
+  public FieldVisitor visitField(
+      int access, String name, String descriptor, String signature, Object value) {
+    if (name.contains("$") || isPrivate(access)) {
+      return null;
+    }
+    var field = new Field();
+    field.name = name;
+    field.type = TypeUtils.typeUsage(Type.getType(descriptor), signature);
+    field.defaultValue = value;
+    field.modifiers = TypeUtils.access(access);
+    peekVisiting().fields.add(field);
+    return new AsmFieldVisitor(field);
+  }
+
+  @Override
+  public MethodVisitor visitMethod(
+      int access, String name, String descriptor, String signature, String[] exceptions) {
+    var method = new Method();
+    if (name.contains("$") || isPrivate(access)) {
+      return null;
+    }
+    method.name = name;
+    var type = Type.getType(descriptor);
+    var params = new ArrayList<Param>();
+    var paramTypes = type.getArgumentTypes();
+    var paramNames = new HashMap<String, Integer>();
+    for (var pt : paramTypes) {
+      var paramName = TypeUtils.defaultParamName(pt);
+      if (paramNames.containsKey(paramName)) {
+        var nth = paramNames.get(paramName);
+        paramNames.put(paramName, nth + 1);
+        paramName = paramName + nth;
+      } else {
+        paramNames.put(paramName, 1);
+      }
+      params.add(param(pt, paramName, null));
+    }
+    method.returnType = TypeUtils.typeUsage(type.getReturnType(), signature);
+    method.modifiers = TypeUtils.access(access);
+    method.params = params;
+    peekVisiting().methods.add(method);
+    return new AsmMethodVisitor(method);
+  }
+
+  @Override
+  public void addAnnotation(JavaAnnotation annotation) {
+    peekVisiting().annotations.add(annotation);
+  }
+
+  @Override
+  public AnnotationVisitor visitAnnotationDefault(String descriptor, boolean visible) {
+    return super.visitAnnotation(descriptor, visible);
+  }
+
+  @Override
+  public AnnotationVisitor visitTypeAnnotation(
+      int typeRef, TypePath typePath, String descriptor, boolean visible) {
+    return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+  }
+
+  @Override
+  public void visitEnd() {
+    visited.add(popVisiting());
+  }
+
+  private ClassDecl peekVisiting() {
+    try {
+      return visiting.peek();
+    } catch (EmptyStackException e) {
+      throw new SkipException("Error: stack was empty when visitEnd was called.");
+    }
+  }
+
+  private ClassDecl popVisiting() {
+    try {
+      return visiting.pop();
+    } catch (EmptyStackException e) {
+      throw new SkipException("Error: stack was empty when visitEnd was called.");
+    }
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmConstants.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmConstants.java
new file mode 100644
index 0000000..668db64
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmConstants.java
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.disasm;
+
+import static org.objectweb.asm.Opcodes.ASM9;
+
+public class AsmConstants {
+  static final int API = ASM9;
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmFieldVisitor.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmFieldVisitor.java
new file mode 100644
index 0000000..5c91cb6
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmFieldVisitor.java
@@ -0,0 +1,29 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.disasm;
+
+import com.github.dart_lang.jni_gen.apisummarizer.elements.Field;
+import com.github.dart_lang.jni_gen.apisummarizer.elements.JavaAnnotation;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.FieldVisitor;
+
+public class AsmFieldVisitor extends FieldVisitor implements AsmAnnotatedElementVisitor {
+  Field field;
+
+  public AsmFieldVisitor(Field field) {
+    super(AsmConstants.API);
+    this.field = field;
+  }
+
+  @Override
+  public void addAnnotation(JavaAnnotation annotation) {
+    field.annotations.add(annotation);
+  }
+
+  @Override
+  public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
+    return AsmAnnotatedElementVisitor.super.visitAnnotationDefault(descriptor, visible);
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmMethodVisitor.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmMethodVisitor.java
new file mode 100644
index 0000000..02f56cf
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmMethodVisitor.java
@@ -0,0 +1,61 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.disasm;
+
+import com.github.dart_lang.jni_gen.apisummarizer.elements.JavaAnnotation;
+import com.github.dart_lang.jni_gen.apisummarizer.elements.Method;
+import java.util.ArrayList;
+import java.util.List;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.TypePath;
+
+public class AsmMethodVisitor extends MethodVisitor implements AsmAnnotatedElementVisitor {
+  Method method;
+  List<String> paramNames = new ArrayList<>();
+
+  protected AsmMethodVisitor(Method method) {
+    super(AsmConstants.API);
+    this.method = method;
+  }
+
+  @Override
+  public void visitParameter(String name, int access) {
+    paramNames.add(name);
+  }
+
+  @Override
+  public void addAnnotation(JavaAnnotation annotation) {
+    method.annotations.add(annotation);
+  }
+
+  @Override
+  public AnnotationVisitor visitAnnotationDefault(String descriptor, boolean visible) {
+    return AsmAnnotatedElementVisitor.super.visitAnnotationDefault(descriptor, visible);
+  }
+
+  @Override
+  public AnnotationVisitor visitTypeAnnotation(
+      int typeRef, TypePath typePath, String descriptor, boolean visible) {
+    // TODO(#23): Collect annotation on type parameter
+    return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+  }
+
+  @Override
+  public AnnotationVisitor visitParameterAnnotation(
+      int parameter, String descriptor, boolean visible) {
+    // TODO(#23): collect and attach it to parameters
+    return super.visitParameterAnnotation(parameter, descriptor, visible);
+  }
+
+  @Override
+  public void visitEnd() {
+    if (paramNames.size() == method.params.size()) {
+      for (int i = 0; i < paramNames.size(); i++) {
+        method.params.get(i).name = paramNames.get(i);
+      }
+    }
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmSummarizer.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmSummarizer.java
new file mode 100644
index 0000000..af89a0b
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/AsmSummarizer.java
@@ -0,0 +1,84 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.disasm;
+
+import com.github.dart_lang.jni_gen.apisummarizer.elements.ClassDecl;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.jar.JarFile;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import org.objectweb.asm.ClassReader;
+
+/** Class that summarizes Java APIs in compiled JARs using ASM not working yet. */
+public class AsmSummarizer {
+
+  private static class JarClass {
+    JarFile jar;
+    ZipEntry entry;
+
+    public JarClass(JarFile jar, ZipEntry entry) {
+      this.jar = jar;
+      this.entry = entry;
+    }
+  }
+
+  public static List<JarClass> findJarLocation(
+      String binaryName, List<JarFile> jars, String suffix) {
+    String path = binaryName.replace(".", "/");
+    for (var jar : jars) {
+      var classEntry = jar.getEntry(path + suffix);
+      if (classEntry != null) {
+        return List.of(new JarClass(jar, classEntry));
+      }
+      var dirPath = path.endsWith("/") ? path : path + "/";
+      var dirEntry = jar.getEntry(dirPath);
+      if (dirEntry != null && dirEntry.isDirectory()) {
+        return jar.stream()
+            .map(je -> (ZipEntry) je)
+            .filter(
+                entry -> {
+                  var name = entry.getName();
+                  return name.endsWith(suffix) && name.startsWith(dirPath);
+                })
+            .map(entry -> new JarClass(jar, entry))
+            .collect(Collectors.toList());
+      }
+    }
+    throw new RuntimeException("Cannot find class");
+  }
+
+  public static List<ClassDecl> run(String[] jarPaths, String[] classes) throws IOException {
+    var jars =
+        Arrays.stream(jarPaths)
+            .map(
+                filename -> {
+                  try {
+                    return new JarFile(filename);
+                  } catch (IOException e) {
+                    throw new RuntimeException(e);
+                  }
+                })
+            .collect(Collectors.toList());
+    return Arrays.stream(classes)
+        .flatMap(c -> findJarLocation(c, jars, ".class").stream())
+        .map(
+            classFile -> {
+              try {
+                return new ClassReader(classFile.jar.getInputStream(classFile.entry));
+              } catch (IOException e) {
+                throw new RuntimeException(e);
+              }
+            })
+        .flatMap(
+            reader -> {
+              var visitor = new AsmClassVisitor();
+              reader.accept(visitor, 0);
+              return visitor.getVisited().stream();
+            })
+        .collect(Collectors.toList());
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/TypeUtils.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/TypeUtils.java
new file mode 100644
index 0000000..17dd46e
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/disasm/TypeUtils.java
@@ -0,0 +1,118 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.disasm;
+
+import static org.objectweb.asm.Opcodes.*;
+import static org.objectweb.asm.Type.ARRAY;
+import static org.objectweb.asm.Type.OBJECT;
+
+import com.github.dart_lang.jni_gen.apisummarizer.elements.DeclKind;
+import com.github.dart_lang.jni_gen.apisummarizer.elements.TypeUsage;
+import com.github.dart_lang.jni_gen.apisummarizer.util.SkipException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.objectweb.asm.Type;
+
+class TypeUtils {
+
+  public static String parentName(Type type) {
+    return type.getClassName().split("\\$")[0];
+  }
+
+  public static String packageName(Type type) {
+    var className = type.getClassName();
+    var last = className.lastIndexOf(".");
+    if (last != -1) {
+      return className.substring(0, last);
+    }
+    return null;
+  }
+
+  public static String simpleName(Type type) {
+    var internalName = type.getInternalName();
+    if (type.getInternalName().length() == 1) {
+      return type.getClassName();
+    }
+    var components = internalName.split("[/$]");
+    if (components.length == 0) {
+      throw new SkipException("Cannot derive simple name: " + internalName);
+    }
+    return components[components.length - 1];
+  }
+
+  public static TypeUsage typeUsage(Type type, @SuppressWarnings("unused") String signature) {
+    var usage = new TypeUsage();
+    usage.shorthand = type.getClassName();
+    switch (type.getSort()) {
+      case OBJECT:
+        usage.kind = TypeUsage.Kind.DECLARED;
+        usage.type =
+            new TypeUsage.DeclaredType(type.getClassName(), TypeUtils.simpleName(type), null);
+        break;
+      case ARRAY:
+        usage.kind = TypeUsage.Kind.ARRAY;
+        usage.type = new TypeUsage.Array(TypeUtils.typeUsage(type.getElementType(), null));
+        break;
+      default:
+        usage.kind = TypeUsage.Kind.PRIMITIVE;
+        usage.type = new TypeUsage.PrimitiveType(type.getClassName());
+    }
+    // TODO(#23): generics
+    return usage;
+  }
+
+  public static Set<String> access(int access) {
+    var result = new HashSet<String>();
+    for (var ac : acc.entrySet()) {
+      if ((ac.getValue() & access) != 0) {
+        result.add(ac.getKey());
+      }
+    }
+    return result;
+  }
+
+  private static final Map<String, Integer> acc = new HashMap<>();
+
+  static {
+    acc.put("static", ACC_STATIC);
+    acc.put("private", ACC_PRIVATE);
+    acc.put("protected", ACC_PROTECTED);
+    acc.put("public", ACC_PUBLIC);
+    acc.put("abstract", ACC_ABSTRACT);
+    acc.put("final", ACC_FINAL);
+    acc.put("native", ACC_NATIVE);
+  }
+
+  static DeclKind declKind(int access) {
+    if ((access & ACC_ENUM) != 0) return DeclKind.ENUM;
+    if ((access & ACC_INTERFACE) != 0) return DeclKind.INTERFACE;
+    if ((access & ACC_ANNOTATION) != 0) return DeclKind.ANNOTATION_TYPE;
+    return DeclKind.CLASS;
+  }
+
+  static String defaultParamName(Type type) {
+    switch (type.getSort()) {
+      case ARRAY:
+        return defaultParamName(type.getElementType()) + 's';
+      case OBJECT:
+        return unCapitalize(simpleName(type));
+      case Type.METHOD:
+        throw new SkipException("unexpected method type" + type);
+      default: // Primitive type
+        var typeCh = type.getInternalName().charAt(0);
+        return String.valueOf(Character.toLowerCase(typeCh));
+    }
+  }
+
+  private static String unCapitalize(String s) {
+    var first = Character.toLowerCase(s.charAt(0));
+    if (s.length() == 1) {
+      return String.valueOf(first);
+    }
+    return first + s.substring(1);
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/AnnotationVisitor.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/AnnotationVisitor.java
new file mode 100644
index 0000000..442a944
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/AnnotationVisitor.java
@@ -0,0 +1,100 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.doclet;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.AnnotationValueVisitor;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+
+public class AnnotationVisitor implements AnnotationValueVisitor<Object, Void> {
+  private final ElementBuilders builders;
+  AstEnv env;
+
+  public AnnotationVisitor(ElementBuilders builders) {
+    this.builders = builders;
+    this.env = builders.env;
+  }
+
+  @Override
+  public Object visit(AnnotationValue annotationValue, Void unused) {
+    return null;
+  }
+
+  @Override
+  public Object visitBoolean(boolean b, Void unused) {
+    return b;
+  }
+
+  @Override
+  public Object visitByte(byte b, Void unused) {
+    return b;
+  }
+
+  @Override
+  public Object visitChar(char c, Void unused) {
+    return c;
+  }
+
+  @Override
+  public Object visitDouble(double v, Void unused) {
+    return v;
+  }
+
+  @Override
+  public Object visitFloat(float v, Void unused) {
+    return v;
+  }
+
+  @Override
+  public Object visitInt(int i, Void unused) {
+    return i;
+  }
+
+  @Override
+  public Object visitLong(long l, Void unused) {
+    return l;
+  }
+
+  @Override
+  public Object visitShort(short i, Void unused) {
+    return i;
+  }
+
+  @Override
+  public Object visitString(String s, Void unused) {
+    return s;
+  }
+
+  @Override
+  public Object visitType(TypeMirror typeMirror, Void unused) {
+    return builders.typeUsage(typeMirror);
+  }
+
+  @Override
+  public Object visitEnumConstant(VariableElement variableElement, Void unused) {
+    // TODO(#23): Perhaps simple name is not enough. We need to return qualified
+    // name + enum constant name for completeness.
+    return variableElement.getSimpleName();
+  }
+
+  @Override
+  public Object visitAnnotation(AnnotationMirror mirror, Void unused) {
+    return builders.annotation(mirror);
+  }
+
+  @Override
+  public Object visitArray(List<? extends AnnotationValue> list, Void unused) {
+    return list.stream().map(x -> x.accept(this, null)).collect(Collectors.toList());
+  }
+
+  @Override
+  public Object visitUnknown(AnnotationValue annotationValue, Void unused) {
+    return null;
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/AstEnv.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/AstEnv.java
new file mode 100644
index 0000000..2358a16
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/AstEnv.java
@@ -0,0 +1,27 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.doclet;
+
+import com.sun.source.util.DocTrees;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import jdk.javadoc.doclet.DocletEnvironment;
+
+/** Class to hold utility classes initialized from DocletEnvironment. */
+public class AstEnv {
+  public final Types types;
+  public final Elements elements;
+  public final DocTrees trees;
+
+  public AstEnv(Types types, Elements elements, DocTrees trees) {
+    this.types = types;
+    this.elements = elements;
+    this.trees = trees;
+  }
+
+  public static AstEnv fromEnvironment(DocletEnvironment env) {
+    return new AstEnv(env.getTypeUtils(), env.getElementUtils(), env.getDocTrees());
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/ElementBuilders.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/ElementBuilders.java
new file mode 100644
index 0000000..809174f
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/ElementBuilders.java
@@ -0,0 +1,211 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.doclet;
+
+import com.github.dart_lang.jni_gen.apisummarizer.elements.*;
+import com.github.dart_lang.jni_gen.apisummarizer.util.StreamUtil;
+import com.sun.source.doctree.DocCommentTree;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+public class ElementBuilders {
+  AstEnv env;
+
+  public ElementBuilders(AstEnv env) {
+    this.env = env;
+  }
+
+  private void fillInFromTypeElement(TypeElement e, ClassDecl c) {
+    c.modifiers = e.getModifiers().stream().map(Modifier::toString).collect(Collectors.toSet());
+    c.simpleName = e.getSimpleName().toString();
+    c.binaryName = env.elements.getBinaryName(e).toString();
+    switch (e.getKind()) {
+      case INTERFACE:
+        c.declKind = DeclKind.INTERFACE;
+        break;
+      case CLASS:
+        c.declKind = DeclKind.CLASS;
+        break;
+      case ENUM:
+        c.declKind = DeclKind.ENUM;
+        break;
+      case ANNOTATION_TYPE:
+        c.declKind = DeclKind.ANNOTATION_TYPE;
+        break;
+      default:
+        throw new RuntimeException(
+            "Unexpected element kind " + e.getKind() + " on " + c.binaryName);
+    }
+    var parent = e.getEnclosingElement();
+    if (parent instanceof TypeElement) {
+      c.parentName = env.elements.getBinaryName((TypeElement) parent).toString();
+    }
+    c.packageName = env.elements.getPackageOf(e).getQualifiedName().toString();
+    c.javadoc = docComment(env.trees.getDocCommentTree(e));
+    c.typeParams = StreamUtil.map(e.getTypeParameters(), this::typeParam);
+    var superclass = e.getSuperclass();
+    if (superclass instanceof DeclaredType) {
+      c.superclass = typeUsage(superclass);
+    }
+    c.annotations = StreamUtil.map(e.getAnnotationMirrors(), this::annotation);
+    c.interfaces = StreamUtil.map(e.getInterfaces(), this::typeUsage);
+  }
+
+  public ClassDecl classDecl(TypeElement e) {
+    var c = new ClassDecl();
+    fillInFromTypeElement(e, c);
+    return c;
+  }
+
+  public Field field(VariableElement e) {
+    assert e.getKind() == ElementKind.FIELD;
+    var field = new Field();
+    field.name = e.getSimpleName().toString();
+    field.modifiers = e.getModifiers().stream().map(Modifier::toString).collect(Collectors.toSet());
+    field.defaultValue = e.getConstantValue();
+    field.type = typeUsage(e.asType());
+    field.javadoc = docComment(env.trees.getDocCommentTree(e));
+    field.annotations = annotations(e.getAnnotationMirrors());
+    return field;
+  }
+
+  public List<JavaAnnotation> annotations(List<? extends AnnotationMirror> mirrors) {
+    return mirrors.stream().map(this::annotation).collect(Collectors.toList());
+  }
+
+  public JavaAnnotation annotation(AnnotationMirror mirror) {
+    var annotation = new JavaAnnotation();
+    var type = mirror.getAnnotationType();
+    var typeElement = (TypeElement) (env.types.asElement(type));
+    annotation.simpleName = typeElement.getSimpleName().toString();
+    annotation.binaryName = env.elements.getBinaryName(typeElement).toString();
+    var values = env.elements.getElementValuesWithDefaults(mirror);
+    if (values.isEmpty()) {
+      return annotation;
+    }
+
+    // This is not perfect, but some metadata is better than none.
+    annotation.properties = new HashMap<>();
+    for (var key : values.keySet()) {
+      var val = values.get(key);
+      var obj = val.getValue();
+      // TODO(#23): Accurately represent more complex annotation values
+      if (obj instanceof String || obj instanceof Number) {
+        annotation.properties.put(key.getSimpleName().toString(), obj);
+      } else {
+        annotation.properties.put(
+            key.getSimpleName().toString(), val.accept(new AnnotationVisitor(this), null));
+      }
+    }
+    return annotation;
+  }
+
+  public JavaDocComment docComment(DocCommentTree tree) {
+    if (tree == null) {
+      return null;
+    }
+    // Leave it as is, for now
+    // tree.accept(new TreeScanner(), j);
+    return new JavaDocComment(tree.toString());
+  }
+
+  public TypeParam typeParam(TypeParameterElement tpe) {
+    var tp = new TypeParam();
+    tp.name = tpe.getSimpleName().toString();
+    tp.bounds = tpe.getBounds().stream().map(this::typeUsage).collect(Collectors.toList());
+    return tp;
+  }
+
+  public Param param(VariableElement e) {
+    var param = new Param();
+    param.javadoc = docComment(env.trees.getDocCommentTree(e));
+    param.name = e.getSimpleName().toString();
+    param.type = typeUsage(e.asType());
+    param.annotations = annotations(e.getAnnotationMirrors());
+    return param;
+  }
+
+  public TypeUsage typeUsage(TypeMirror type) {
+    var u = new TypeUsage();
+    u.shorthand = type.toString();
+    var element = env.types.asElement(type);
+    switch (type.getKind()) {
+      case DECLARED:
+        // Unique name that's binary name not qualified name
+        // (It's somewhat confusing but qualified name does not need to be unique,
+        // because of nesting)
+        u.kind = TypeUsage.Kind.DECLARED;
+        var name =
+            element instanceof TypeElement
+                ? env.elements.getBinaryName((TypeElement) element).toString()
+                : element.getSimpleName().toString();
+        List<TypeUsage> params = null;
+        if (type instanceof DeclaredType) { // it will be
+          params =
+              ((DeclaredType) type)
+                  .getTypeArguments().stream().map(this::typeUsage).collect(Collectors.toList());
+        }
+        u.type = new TypeUsage.DeclaredType(name, element.getSimpleName().toString(), params);
+        break;
+      case TYPEVAR:
+        u.kind = TypeUsage.Kind.TYPE_VARIABLE;
+        // TODO(#23): Encode bounds of type variable.
+        // A straightforward approach will cause infinite recursion very
+        // easily. Another approach I can think of is only encoding the
+        // erasure of the type variable per JLS.
+        u.type = new TypeUsage.TypeVar(element.getSimpleName().toString());
+        break;
+      case ARRAY:
+        u.kind = TypeUsage.Kind.ARRAY;
+        var arr = ((ArrayType) type);
+        u.type = new TypeUsage.Array(typeUsage(arr.getComponentType()));
+        break;
+      case VOID:
+        u.type = new TypeUsage.PrimitiveType("void");
+        u.kind = TypeUsage.Kind.PRIMITIVE;
+        break;
+      case WILDCARD:
+        u.kind = TypeUsage.Kind.WILDCARD;
+        var wildcard = ((WildcardType) type);
+        var extendsBound = wildcard.getExtendsBound();
+        var superBound = wildcard.getSuperBound();
+        u.type =
+            new TypeUsage.Wildcard(
+                extendsBound != null ? typeUsage(extendsBound) : null,
+                superBound != null ? typeUsage(superBound) : null);
+        break;
+      case INTERSECTION:
+        u.kind = TypeUsage.Kind.INTERSECTION;
+        u.type =
+            new TypeUsage.Intersection(
+                ((IntersectionType) type)
+                    .getBounds().stream().map(this::typeUsage).collect(Collectors.toList()));
+        break;
+      default:
+        u.kind = TypeUsage.Kind.PRIMITIVE;
+        if (type instanceof PrimitiveType) {
+          u.type = new TypeUsage.PrimitiveType(type.toString());
+        } else {
+          System.out.println("Unsupported type: " + type);
+          // throw exception.
+        }
+    }
+    return u;
+  }
+
+  public Method method(ExecutableElement e) {
+    var m = new Method();
+    m.name = e.getSimpleName().toString();
+    m.modifiers = e.getModifiers().stream().map(Modifier::toString).collect(Collectors.toSet());
+    m.typeParams = e.getTypeParameters().stream().map(this::typeParam).collect(Collectors.toList());
+    m.returnType = typeUsage(e.getReturnType());
+    m.javadoc = docComment(env.trees.getDocCommentTree(e));
+    m.annotations = annotations(e.getAnnotationMirrors());
+    return m;
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/SummarizerDoclet.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/SummarizerDoclet.java
new file mode 100644
index 0000000..b0dfd75
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/SummarizerDoclet.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.doclet;
+
+import com.github.dart_lang.jni_gen.apisummarizer.Main;
+import jdk.javadoc.doclet.DocletEnvironment;
+
+public class SummarizerDoclet extends SummarizerDocletBase {
+  @Override
+  public boolean run(DocletEnvironment docletEnvironment) {
+    var result = super.run(docletEnvironment);
+    Main.writeAll(types);
+    return result;
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/SummarizerDocletBase.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/SummarizerDocletBase.java
new file mode 100644
index 0000000..8e6067d
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/doclet/SummarizerDocletBase.java
@@ -0,0 +1,161 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.doclet;
+
+import com.github.dart_lang.jni_gen.apisummarizer.elements.ClassDecl;
+import com.github.dart_lang.jni_gen.apisummarizer.elements.Method;
+import com.github.dart_lang.jni_gen.apisummarizer.elements.Package;
+import com.github.dart_lang.jni_gen.apisummarizer.util.Log;
+import com.github.dart_lang.jni_gen.apisummarizer.util.SkipException;
+import java.util.*;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.*;
+import javax.lang.model.util.ElementScanner9;
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+
+public class SummarizerDocletBase implements Doclet {
+  private AstEnv utils;
+
+  @Override
+  public void init(Locale locale, Reporter reporter) {}
+
+  @Override
+  public String getName() {
+    return "ApiSummarizer";
+  }
+
+  @Override
+  public Set<? extends Option> getSupportedOptions() {
+    return Collections.emptySet();
+  }
+
+  @Override
+  public SourceVersion getSupportedSourceVersion() {
+    return SourceVersion.RELEASE_11;
+  }
+
+  public static List<ClassDecl> types;
+
+  @Override
+  public boolean run(DocletEnvironment docletEnvironment) {
+    Log.timed("Initializing doclet");
+    utils = AstEnv.fromEnvironment(docletEnvironment);
+    SummarizingScanner p = new SummarizingScanner();
+    docletEnvironment.getSpecifiedElements().forEach(e -> p.scan(e, new SummaryCollector()));
+    types = p.types;
+    return true;
+  }
+
+  public static class SummaryCollector {
+    Stack<Package> packages = new Stack<>();
+    Stack<ClassDecl> types = new Stack<>();
+    Method method;
+  }
+
+  public class SummarizingScanner extends ElementScanner9<Void, SummaryCollector> {
+    List<Package> packages = new ArrayList<>();
+    List<ClassDecl> types = new ArrayList<>();
+    ElementBuilders builders = new ElementBuilders(utils);
+
+    // Each element in collector is a stack
+    // which is used to get topmost element
+    // and append the child to it.
+    // Eg: A variable element is always appended to topmost
+    // class
+    @Override
+    public Void scan(Element e, SummaryCollector collector) {
+      return super.scan(e, collector);
+    }
+
+    @Override
+    public Void visitPackage(PackageElement e, SummaryCollector collector) {
+      Log.verbose("Visiting package: %s", e.getQualifiedName());
+      collector.packages.push(new Package());
+      System.out.println("package: " + e.getQualifiedName());
+      var result = super.visitPackage(e, collector);
+      var collectedPackage = collector.packages.pop();
+      packages.add(collectedPackage);
+      return result;
+    }
+
+    @Override
+    public Void visitType(TypeElement e, SummaryCollector collector) {
+      if (!collector.types.isEmpty()) {
+        return null;
+      }
+      Log.verbose("Visiting class: %s, %s", e.getQualifiedName(), collector.types);
+      switch (e.getKind()) {
+        case CLASS:
+        case INTERFACE:
+        case ENUM:
+          try {
+            var cls = builders.classDecl(e);
+            collector.types.push(cls);
+            super.visitType(e, collector);
+            types.add(collector.types.pop());
+          } catch (SkipException skip) {
+            Log.always("Skip type: %s", e.getQualifiedName());
+          }
+          break;
+        case ANNOTATION_TYPE:
+          Log.always("Skip annotation type: %s", e.getQualifiedName());
+          break;
+      }
+      return null;
+    }
+
+    @Override
+    public Void visitVariable(VariableElement e, SummaryCollector collector) {
+      var vk = e.getKind();
+      var cls = collector.types.peek();
+      switch (vk) {
+        case ENUM_CONSTANT:
+          cls.values.add(e.getSimpleName().toString());
+          break;
+        case FIELD:
+          cls.fields.add(builders.field(e));
+          break;
+        case PARAMETER:
+          if (collector.method == null) {
+            throw new RuntimeException("Parameter encountered outside executable element");
+          }
+          var method = collector.method;
+          method.params.add(builders.param(e));
+          break;
+        default:
+          System.out.println("Unknown type of variable element: " + vk);
+      }
+      return null;
+    }
+
+    @Override
+    public Void visitExecutable(ExecutableElement element, SummaryCollector collector) {
+      var cls = collector.types.peek();
+      switch (element.getKind()) {
+        case METHOD:
+        case CONSTRUCTOR:
+          try {
+            var method = builders.method(element);
+            collector.method = method;
+            super.visitExecutable(element, collector);
+            collector.method = null;
+            cls.methods.add(method);
+          } catch (SkipException skip) {
+            Log.always("Skip method: %s", element.getSimpleName());
+          }
+          break;
+        case STATIC_INIT:
+          cls.hasStaticInit = true;
+          break;
+        case INSTANCE_INIT:
+          cls.hasInstanceInit = true;
+          break;
+      }
+      return null;
+    }
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/ClassDecl.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/ClassDecl.java
new file mode 100644
index 0000000..f838d9c
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/ClassDecl.java
@@ -0,0 +1,47 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.elements;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A class or interface declaration.
+ *
+ * <p>Here's an example for various kinds of names stored in this structure: { simpleName :
+ * "Example", binaryName : "dev.dart.sample.Example", parentName : null, packageName :
+ * "dev.dart.sample", }
+ */
+public class ClassDecl {
+  public DeclKind declKind;
+
+  /** Modifiers eg: static, public and abstract. */
+  public Set<String> modifiers;
+
+  /** Unqualified name of the class. For example `ClassDecl` */
+  public String simpleName;
+
+  /**
+   * Unique, fully qualified name of the class, it's like a qualified name used in a program but
+   * uses $ instead of dot (.) before nested classes.
+   */
+  public String binaryName;
+
+  public String parentName;
+  public String packageName;
+  public List<TypeParam> typeParams;
+  public List<Method> methods = new ArrayList<>();
+  public List<Field> fields = new ArrayList<>();
+  public TypeUsage superclass;
+  public List<TypeUsage> interfaces;
+  public boolean hasStaticInit;
+  public boolean hasInstanceInit;
+  public JavaDocComment javadoc;
+  public List<JavaAnnotation> annotations;
+
+  /** In case of enum, names of enum constants */
+  public List<String> values = new ArrayList<>();
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/DeclKind.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/DeclKind.java
new file mode 100644
index 0000000..376782d
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/DeclKind.java
@@ -0,0 +1,12 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.elements;
+
+public enum DeclKind {
+  CLASS,
+  ENUM,
+  INTERFACE,
+  ANNOTATION_TYPE
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Field.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Field.java
new file mode 100644
index 0000000..c39c301
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Field.java
@@ -0,0 +1,20 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.elements;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class Field {
+  public Set<String> modifiers = new HashSet<>();
+  public String name;
+  public TypeUsage type;
+  public Object defaultValue;
+
+  public JavaDocComment javadoc;
+  public List<JavaAnnotation> annotations = new ArrayList<>();
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/JavaAnnotation.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/JavaAnnotation.java
new file mode 100644
index 0000000..d45ab0a
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/JavaAnnotation.java
@@ -0,0 +1,24 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.elements;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class JavaAnnotation {
+  public String simpleName;
+  public String binaryName;
+  public Map<String, Object> properties = new HashMap<>();
+
+  public static class EnumVal {
+    String enumClass;
+    String value;
+
+    public EnumVal(String enumClass, String value) {
+      this.enumClass = enumClass;
+      this.value = value;
+    }
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/JavaDocComment.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/JavaDocComment.java
new file mode 100644
index 0000000..3f8d55e
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/JavaDocComment.java
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.elements;
+
+public class JavaDocComment {
+  // TODO(#28): Build a detailed tree representation of JavaDocComment
+  // which can be processed by tools in other languages as well.
+  public String comment;
+
+  public JavaDocComment(String comment) {
+    this.comment = comment;
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Method.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Method.java
new file mode 100644
index 0000000..d1c3cca
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Method.java
@@ -0,0 +1,21 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.elements;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class Method {
+  public Set<String> modifiers = new HashSet<>();
+  public String name;
+  public List<TypeParam> typeParams;
+  public List<Param> params = new ArrayList<>();
+  public TypeUsage returnType;
+
+  public JavaDocComment javadoc;
+  public List<JavaAnnotation> annotations = new ArrayList<>();
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Package.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Package.java
new file mode 100644
index 0000000..8e2cc90
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Package.java
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.elements;
+
+public class Package {
+  public String name;
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Param.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Param.java
new file mode 100644
index 0000000..5e50e73
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/Param.java
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.elements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Param {
+  public String name;
+  public TypeUsage type;
+
+  public JavaDocComment javadoc;
+  public List<JavaAnnotation> annotations = new ArrayList<>();
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/TypeParam.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/TypeParam.java
new file mode 100644
index 0000000..17186e5
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/TypeParam.java
@@ -0,0 +1,12 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.elements;
+
+import java.util.List;
+
+public class TypeParam {
+  public String name;
+  public List<TypeUsage> bounds;
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/TypeUsage.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/TypeUsage.java
new file mode 100644
index 0000000..53419ce
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/elements/TypeUsage.java
@@ -0,0 +1,79 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.elements;
+
+import java.util.List;
+
+public class TypeUsage {
+  public enum Kind {
+    DECLARED,
+    TYPE_VARIABLE,
+    WILDCARD,
+    ARRAY,
+    INTERSECTION,
+    PRIMITIVE,
+  }
+
+  // Could've made it just a type hierarchy, but client code parsing JSON
+  // needs to know the type beforehand, before it can deserialize the `type` field.
+  public String shorthand;
+  public Kind kind;
+  public ReferredType type;
+
+  public abstract static class ReferredType {}
+
+  public static class PrimitiveType extends ReferredType {
+    public String name;
+
+    public PrimitiveType(String name) {
+      this.name = name;
+    }
+  }
+
+  public static class DeclaredType extends ReferredType {
+    public String binaryName;
+    public String simpleName;
+    public List<TypeUsage> params;
+
+    public DeclaredType(String binaryName, String simpleName, List<TypeUsage> params) {
+      this.binaryName = binaryName;
+      this.simpleName = simpleName;
+      this.params = params;
+    }
+  }
+
+  public static class TypeVar extends ReferredType {
+    public String name;
+
+    public TypeVar(String name) {
+      this.name = name;
+    }
+  }
+
+  public static class Wildcard extends ReferredType {
+    public TypeUsage extendsBound, superBound;
+
+    public Wildcard(TypeUsage extendsBound, TypeUsage superBound) {
+      this.extendsBound = extendsBound;
+      this.superBound = superBound;
+    }
+  }
+
+  public static class Intersection extends ReferredType {
+    public List<TypeUsage> types;
+
+    public Intersection(List<TypeUsage> types) {
+      this.types = types;
+    }
+  }
+
+  public static class Array extends ReferredType {
+    public TypeUsage type;
+
+    public Array(TypeUsage type) {
+      this.type = type;
+    }
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/util/Log.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/util/Log.java
new file mode 100644
index 0000000..7add36b
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/util/Log.java
@@ -0,0 +1,33 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.util;
+
+public class Log {
+  private static long lastPrinted = System.currentTimeMillis();
+
+  public static void setVerbose(boolean verbose) {
+    Log.verboseLogs = verbose;
+  }
+
+  private static boolean verboseLogs = false;
+
+  public static void verbose(String format, Object... args) {
+    if (!verboseLogs) {
+      return;
+    }
+    System.err.printf(format + "\n", args);
+  }
+
+  public static void timed(String format, Object... args) {
+    long now = System.currentTimeMillis();
+    System.err.printf("[%6d ms] ", now - lastPrinted);
+    lastPrinted = now;
+    System.err.printf(format + "\n", args);
+  }
+
+  public static void always(String format, Object... args) {
+    System.err.printf(format + "\n", args);
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/util/SkipException.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/util/SkipException.java
new file mode 100644
index 0000000..158d819
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/util/SkipException.java
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.util;
+
+// Generic skip exception when the code cannot decide how to handle an element.
+// The caller in some above layer can catch this and skip to appropriate extent.
+public class SkipException extends RuntimeException {
+  public SkipException(String message) {
+    super(message);
+  }
+}
diff --git a/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/util/StreamUtil.java b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/util/StreamUtil.java
new file mode 100644
index 0000000..2fd2b79
--- /dev/null
+++ b/pkgs/jni_gen/java/src/main/java/com/github/dart_lang/jni_gen/apisummarizer/util/StreamUtil.java
@@ -0,0 +1,20 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer.util;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class StreamUtil {
+  public static <T, R> List<R> map(List<T> list, Function<T, R> function) {
+    return list.stream().map(function).collect(Collectors.toList());
+  }
+
+  public static <T, R> List<R> map(T[] array, Function<T, R> function) {
+    return Arrays.stream(array).map(function).collect(Collectors.toList());
+  }
+}
diff --git a/pkgs/jni_gen/java/src/test/java/com/github/dart_lang/jni_gen/apisummarizer/DocletSummarizerTests.java b/pkgs/jni_gen/java/src/test/java/com/github/dart_lang/jni_gen/apisummarizer/DocletSummarizerTests.java
new file mode 100644
index 0000000..afc7a05
--- /dev/null
+++ b/pkgs/jni_gen/java/src/test/java/com/github/dart_lang/jni_gen/apisummarizer/DocletSummarizerTests.java
@@ -0,0 +1,58 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.github.dart_lang.jni_gen.apisummarizer.elements.ClassDecl;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DocletSummarizerTests {
+  private List<ClassDecl> parsedDecls;
+  private final Map<String, ClassDecl> classesByName = new HashMap<>();
+
+  @Before
+  public void setUp() {
+    var opts = new Main.SummarizerOptions();
+    opts.sourcePaths = "src/test/resources/";
+    // javadoc tool API is quite inflexible, in that we cannot pass an doclet object, but a class
+    // So any state we want to access from it has to be either serialized or saved in static fields.
+    // This means we lose lot of control over loading of files etc..
+    // Here, TestDoclet simply stores the result in a static variable which we can get and check
+    // later.
+    Main.runDocletWithClass(TestDoclet.class, List.of("com.example.Example"), opts);
+    parsedDecls = TestDoclet.getClassDecls();
+    for (var decl : parsedDecls) {
+      classesByName.put(decl.binaryName, decl);
+    }
+  }
+
+  @Test
+  public void checkNumberOfClasses() {
+    Assert.assertEquals(2, parsedDecls.size());
+  }
+
+  @Test
+  public void checkNamesOfClasses() {
+    var names = parsedDecls.stream().map(decl -> decl.binaryName).collect(Collectors.toSet());
+    assertTrue(names.contains("com.example.Example"));
+    assertTrue(names.contains("com.example.Example$Aux"));
+  }
+
+  @Test
+  public void checkNumberOfFieldsAndMethods() {
+    var example = classesByName.get("com.example.Example");
+    assertEquals("Example", example.simpleName);
+    assertEquals(3, example.fields.size());
+    assertEquals(3, example.methods.size());
+  }
+}
diff --git a/pkgs/jni_gen/java/src/test/java/com/github/dart_lang/jni_gen/apisummarizer/TestDoclet.java b/pkgs/jni_gen/java/src/test/java/com/github/dart_lang/jni_gen/apisummarizer/TestDoclet.java
new file mode 100644
index 0000000..188cd19
--- /dev/null
+++ b/pkgs/jni_gen/java/src/test/java/com/github/dart_lang/jni_gen/apisummarizer/TestDoclet.java
@@ -0,0 +1,21 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.github.dart_lang.jni_gen.apisummarizer;
+
+import com.github.dart_lang.jni_gen.apisummarizer.doclet.SummarizerDocletBase;
+import com.github.dart_lang.jni_gen.apisummarizer.elements.ClassDecl;
+import java.util.List;
+import jdk.javadoc.doclet.DocletEnvironment;
+
+public class TestDoclet extends SummarizerDocletBase {
+  @Override
+  public boolean run(DocletEnvironment docletEnvironment) {
+    return super.run(docletEnvironment);
+  }
+
+  public static List<ClassDecl> getClassDecls() {
+    return types;
+  }
+}
diff --git a/pkgs/jni_gen/java/src/test/resources/com/example/Example.java b/pkgs/jni_gen/java/src/test/resources/com/example/Example.java
new file mode 100644
index 0000000..98896ac
--- /dev/null
+++ b/pkgs/jni_gen/java/src/test/resources/com/example/Example.java
@@ -0,0 +1,33 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.example;
+
+public class Example {
+  static final boolean staticFinalField = true;
+
+  Example(int instanceField) {
+    this.instanceField = instanceField;
+  }
+
+  static String staticField = "hello";
+
+  static String getStaticField() {
+    return staticField;
+  }
+
+  int instanceField;
+
+  int getInstanceField() {
+    return instanceField;
+  }
+
+  public static class Aux extends Example {
+    static int nothing = 0;
+
+    static Example getAnExample() {
+      return new Example();
+    }
+  }
+}
diff --git a/pkgs/jni_gen/lib/jni_gen.dart b/pkgs/jni_gen/lib/jni_gen.dart
index 34a82dd..0bc7895 100644
--- a/pkgs/jni_gen/lib/jni_gen.dart
+++ b/pkgs/jni_gen/lib/jni_gen.dart
@@ -2,4 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-export 'src/my_sum.dart';
+/// This library exports a high level programmatic API to jni_gen, the entry
+/// point of which is runJniGenTask function, which takes run configuration as
+/// a JniGenTask.
+library jni_gen;
+
+export 'src/elements/elements.dart';
+export 'src/config/config.dart';
+export 'src/writers/writers.dart';
diff --git a/pkgs/jni_gen/lib/src/bindings/bindings.dart b/pkgs/jni_gen/lib/src/bindings/bindings.dart
new file mode 100644
index 0000000..9aa6a08
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/bindings/bindings.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'preprocessor.dart';
+export 'c_bindings.dart';
+export 'dart_bindings.dart';
+export 'symbol_resolver.dart';
diff --git a/pkgs/jni_gen/lib/src/bindings/c_bindings.dart b/pkgs/jni_gen/lib/src/bindings/c_bindings.dart
new file mode 100644
index 0000000..71be9c1
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/bindings/c_bindings.dart
@@ -0,0 +1,361 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:jni_gen/src/elements/elements.dart';
+import 'package:jni_gen/src/config/wrapper_options.dart';
+
+import 'common.dart';
+
+// fullName / mangled name =
+// binaryName with replace('.', '_'), replace('$', '__');
+
+class CBindingGenerator {
+  static const _classVarPrefix = '_c';
+  static const _methodVarPrefix = '_m';
+  static const _fieldVarPrefix = '_f';
+  static const _indent = '    ';
+
+  static const _cTypeKeywords = {
+    'short',
+    'char',
+    'int',
+    'long',
+    'float',
+    'double',
+  };
+
+  String _cParamRename(String paramName) =>
+      _cTypeKeywords.contains(paramName) ? '${paramName}0' : paramName;
+
+  CBindingGenerator(this.options);
+  WrapperOptions options;
+
+  String generateBinding(ClassDecl c) {
+    return _class(c);
+  }
+
+  String _class(ClassDecl c) {
+    final s = StringBuffer();
+
+    final fullName = mangledClassName(c);
+
+    // global variable in C that holds the reference to class
+    final classVar = '${_classVarPrefix}_$fullName';
+    s.write('// ${c.binaryName}\n');
+    s.write('jclass $classVar = NULL;\n\n');
+
+    for (var m in c.methods) {
+      if (!m.isIncluded) {
+        continue;
+      }
+      s.write(_method(c, m));
+      s.writeln();
+    }
+
+    for (var f in c.fields) {
+      if (!f.isIncluded) {
+        continue;
+      }
+      final fieldBinding = _field(c, f);
+      s.write(fieldBinding);
+      // Fields are skipped if they're static final. In that case
+      // do not write too much whitespace.
+      if (fieldBinding.isNotEmpty) s.writeln();
+    }
+    return s.toString();
+  }
+
+  String _method(ClassDecl c, Method m) {
+    final cClassName = mangledClassName(c);
+    final isACtor = isCtor(m);
+    final isStatic = isStaticMethod(m);
+
+    final s = StringBuffer();
+    final name = m.finalName;
+
+    final methodVar = '${_methodVarPrefix}_${cClassName}_$name';
+    s.write('jmethodID $methodVar = NULL;\n');
+
+    final returnType = isCtor(m) ? 'jobject' : m.returnType.name;
+    final cReturnType = cType(returnType);
+    final cMethodName = '${cClassName}_$name';
+    final cParams = _formalArgs(m);
+    s.write('FFI_PLUGIN_EXPORT\n');
+    s.write('$cReturnType $cMethodName($cParams) {\n');
+
+    final classVar = '${_classVarPrefix}_$cClassName';
+    final signature = _signature(m);
+
+    s.write(_loadEnvCall);
+    s.write(_loadClassCall(classVar, _internalName(c.binaryName)));
+
+    final ifStatic = isStatic ? 'static_' : '';
+    s.write('${_indent}load_${ifStatic}method($classVar, '
+        '&$methodVar, "${m.name}", "$signature");\n');
+
+    s.write(_initParams(m));
+
+    var returnTypeName = m.returnType.name;
+    if (isACtor) {
+      returnTypeName = c.binaryName;
+    }
+
+    s.write(_indent);
+    if (returnTypeName != 'void') {
+      s.write('${cType(returnTypeName)} _result = ');
+    }
+
+    final callType = _typeNameAtCallSite(m.returnType);
+    final callArgs = _callArgs(m, classVar, methodVar);
+    if (isACtor) {
+      s.write('(*jniEnv)->NewObject($callArgs);\n');
+    } else {
+      final ifStatic = isStatic ? 'Static' : '';
+      s.write('(*jniEnv)->Call$ifStatic${callType}Method($callArgs);\n');
+    }
+    s.write(_destroyParams(m));
+    if (returnTypeName != 'void') {
+      s.write(_result(m));
+    }
+    s.write('}\n');
+    return s.toString();
+  }
+
+  String _field(ClassDecl c, Field f) {
+    final cClassName = mangledClassName(c);
+    final isStatic = isStaticField(f);
+
+    // If the field is final and default is assigned, then no need to wrap
+    // this field. It should then be a constant in dart code.
+    if (isStatic && isFinalField(f) && f.defaultValue != null) {
+      return "";
+    }
+
+    final s = StringBuffer();
+
+    final fieldName = f.finalName;
+    final fieldVar = "${_fieldVarPrefix}_${cClassName}_$fieldName";
+
+    s.write('jfieldID $fieldVar = NULL;\n');
+    final classVar = '${_classVarPrefix}_$cClassName';
+
+    void writeAccessor({bool isSetter = false}) {
+      final ct = isSetter ? 'void' : cType(f.type.name);
+      // Getter
+      final prefix = isSetter ? 'set' : 'get';
+      s.write('$ct ${prefix}_${memberNameInC(c, fieldName)}(');
+      final formalArgs = <String>[
+        if (!isStatic) 'jobject self_',
+        if (isSetter) '${cType(f.type.name)} value',
+      ];
+      s.write(formalArgs.join(', '));
+      s.write(') {\n');
+      s.write(_loadEnvCall);
+      s.write(_loadClassCall(classVar, _internalName(c.binaryName)));
+
+      var ifStatic = isStatic ? 'static_' : '';
+      s.write(
+          '${_indent}load_${ifStatic}field($classVar, &$fieldVar, "$fieldName",'
+          '"${_fieldSignature(f)}");\n');
+
+      ifStatic = isStatic ? 'Static' : '';
+      final callType = _typeNameAtCallSite(f.type);
+      final acc = isSetter ? 'Set' : 'Get';
+      final ret = isSetter ? '' : 'return ';
+      final conv = !isSetter && !isPrimitive(f.type) ? 'to_global_ref' : '';
+      s.write('$_indent$ret$conv((*jniEnv)->$acc$ifStatic${callType}Field');
+      final secondArg = isStatic ? classVar : 'self_';
+      s.write('(jniEnv, $secondArg, $fieldVar');
+      if (isSetter) {
+        s.write(', value');
+      }
+      s.write('));\n');
+      // TODO(#25): Check Exceptions.
+      s.write('}\n\n');
+    }
+
+    writeAccessor(isSetter: false);
+    if (isFinalField(f)) {
+      return s.toString();
+    }
+    writeAccessor(isSetter: true);
+    return s.toString();
+  }
+
+  final String _loadEnvCall = '${_indent}load_env();\n';
+
+  String _loadClassCall(String classVar, String internalName) {
+    return '${_indent}load_class_gr(&$classVar, '
+        '"$internalName");\n';
+  }
+
+  String _formalArgs(Method m) {
+    final args = <String>[];
+    if (hasSelfParam(m)) {
+      // The underscore-suffixed name prevents accidental collision with
+      // parameter named self, if any.
+      args.add('jobject self_');
+    }
+
+    for (var param in m.params) {
+      final paramName = _cParamRename(param.name);
+      args.add('${cType(param.type.name)} $paramName');
+    }
+
+    return args.join(", ");
+  }
+
+  bool _needsTemporaries(String binaryName) {
+    // currently no type needs temporaries.
+    return false;
+  }
+
+  // arguments at call site
+  String _callArgs(Method m, String classVar, String methodVar) {
+    final args = ['jniEnv'];
+    if (hasSelfParam(m)) {
+      args.add('self_');
+    } else {
+      args.add(classVar);
+    }
+    args.add(methodVar);
+    for (var param in m.params) {
+      final paramName = _cParamRename(param.name);
+      if (_needsTemporaries(param.type.name)) {
+        args.add('_$paramName');
+      } else {
+        args.add(paramName);
+      }
+    }
+    return args.join(', ');
+  }
+
+  String _initParams(Method m) {
+    // currently no type needs temporaries, but in future we may add
+    // some options that require temporaries.
+    return '';
+  }
+
+  String _destroyParams(Method m) {
+    final s = StringBuffer();
+    for (var param in m.params) {
+      final paramName = _cParamRename(param.name);
+      if (_needsTemporaries(param.type.name)) {
+        s.write('$_indent(*jniEnv)->DeleteLocalRef(jniEnv, _$paramName);\n');
+      }
+    }
+    return s.toString();
+  }
+
+  String _result(Method m) {
+    final cReturnType = cType(m.returnType.name);
+    if (cReturnType == 'jobject' || isCtor(m)) {
+      return '${_indent}return to_global_ref(_result);\n';
+    } else {
+      return '${_indent}return _result;\n';
+    }
+  }
+
+  String _fieldSignature(Field f) {
+    final iname = _internalNameOf(f.type);
+    if (iname.length == 1) {
+      return iname;
+    }
+    return 'L$iname;';
+  }
+
+  String _internalName(String binaryName) {
+    switch (binaryName) {
+      case "void":
+        return "V";
+      case "byte":
+        return "B";
+      case "char":
+        return "C";
+      case "double":
+        return "D";
+      case "float":
+        return "F";
+      case "int":
+        return "I";
+      case "long":
+        return "J";
+      case "short":
+        return "S";
+      case "boolean":
+        return "Z";
+      default:
+        return binaryName.replaceAll(".", "/");
+    }
+  }
+
+  String _internalNameOf(TypeUsage usage) {
+    switch (usage.kind) {
+      case Kind.declared:
+        return _internalName((usage.type as DeclaredType).binaryName);
+      case Kind.primitive:
+        return _internalName((usage.type as PrimitiveType).name);
+      case Kind.typeVariable:
+        // It should be possible to compute the erasure of a type
+        // in parser itself.
+        // TODO(#23): Use erasure of the type variable here.
+        // This is just a (wrong) placeholder
+        return "java/lang/Object";
+      case Kind.array:
+        final inner = _internalNameOf((usage.type as ArrayType).type);
+        return "[$inner";
+      case Kind.wildcard:
+        final extendsBound = (usage.type as Wildcard).extendsBound;
+        if (extendsBound != null) {
+          return _internalNameOf(extendsBound);
+        }
+        return 'java/lang/Object';
+    }
+  }
+
+  /// Returns the JNI signature of the method.
+  String _signature(Method m) {
+    final s = StringBuffer();
+    s.write('(');
+    for (var param in m.params) {
+      final type = _internalNameOf(param.type);
+      s.write(type.length == 1 ? type : 'L$type;');
+    }
+    s.write(')');
+    final returnType = _internalNameOf(m.returnType);
+    s.write(returnType.length == 1 ? returnType : 'L$returnType;');
+    return s.toString();
+  }
+
+  // For call<type>Method or get<type>field calls in JNI.
+  String _typeNameAtCallSite(TypeUsage t) {
+    if (isPrimitive(t)) {
+      return t.name.substring(0, 1).toUpperCase() + t.name.substring(1);
+    }
+    return "Object";
+  }
+}
+
+class CPreludes {
+  static const autoGeneratedNotice = '// Autogenerated by jni_gen. '
+      'DO NOT EDIT!\n\n';
+  static const includes = '#include <stdint.h>\n'
+      '#include "jni.h"\n'
+      '#include "dartjni.h"\n'
+      '\n';
+  static const defines = 'thread_local JNIEnv *jniEnv;\n'
+      'struct jni_context jni;\n\n'
+      'struct jni_context (*context_getter)(void);\n'
+      'JNIEnv *(*env_getter)(void);\n'
+      '\n';
+  static const initializers =
+      'void setJniGetters(struct jni_context (*cg)(void),\n'
+      '        JNIEnv *(*eg)(void)) {\n'
+      '    context_getter = cg;\n'
+      '    env_getter = eg;\n'
+      '}\n'
+      '\n';
+  static const prelude =
+      autoGeneratedNotice + includes + defines + initializers;
+}
diff --git a/pkgs/jni_gen/lib/src/bindings/common.dart b/pkgs/jni_gen/lib/src/bindings/common.dart
new file mode 100644
index 0000000..dd46b6b
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/bindings/common.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:jni_gen/src/elements/elements.dart';
+
+String mangledClassName(ClassDecl decl) =>
+    decl.binaryName.replaceAll('.', '_').replaceAll('\$', '__');
+
+String memberNameInC(ClassDecl decl, String name) =>
+    "${mangledClassName(decl)}_$name";
+
+String cType(String binaryName) {
+  switch (binaryName) {
+    case "void":
+      return "void";
+    case "byte":
+      return "int8_t";
+    case "char":
+      return "char";
+    case "double":
+      return "double";
+    case "float":
+      return "float";
+    case "int":
+      return "int32_t";
+    case "long":
+      return "int64_t";
+    case "short":
+      return "int16_t";
+    case "boolean":
+      return "uint8_t";
+    default:
+      return "jobject";
+  }
+}
+
+bool isPrimitive(TypeUsage t) => t.kind == Kind.primitive;
+
+bool isStaticField(Field f) => f.modifiers.contains('static');
+bool isStaticMethod(Method m) => m.modifiers.contains('static');
+
+bool isFinalField(Field f) => f.modifiers.contains('final');
+bool isFinalMethod(Method m) => m.modifiers.contains('final');
+
+bool isCtor(Method m) => m.name == '<init>';
+bool hasSelfParam(Method m) => !isStaticMethod(m) && !isCtor(m);
+
+bool isObjectField(Field f) => !isPrimitive(f.type);
+bool isObjectMethod(Method m) => !isPrimitive(m.returnType);
+
+const ctorNameC = 'new';
+const ctorNameDart = 'ctor';
+
+// Marker exception when a method or class cannot be translated
+// The inner functions may not know how much context has to be skipped in case
+// of an error or unknown element. They throw SkipException.
+class SkipException implements Exception {
+  SkipException(this.message, [this.element]);
+  String message;
+  dynamic element;
+
+  @override
+  String toString() {
+    return '$message;';
+  }
+}
diff --git a/pkgs/jni_gen/lib/src/bindings/dart_bindings.dart b/pkgs/jni_gen/lib/src/bindings/dart_bindings.dart
new file mode 100644
index 0000000..b994441
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/bindings/dart_bindings.dart
@@ -0,0 +1,379 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:jni_gen/src/elements/elements.dart';
+import 'package:jni_gen/src/config/wrapper_options.dart';
+import 'package:jni_gen/src/util/rename_conflict.dart';
+
+import 'symbol_resolver.dart';
+import 'common.dart';
+
+final _indent = ' ' * 2;
+
+class DartBindingsGenerator {
+  // Name for reference in base class.
+  static const _self = 'reference';
+  // symbol lookup function for generated code.
+  static const _jlookup = 'jlookup';
+
+  // import prefixes
+  static const ffi = 'ffi.';
+  static const jni = 'jni.';
+
+  static const String _voidPtr = '${ffi}Pointer<${ffi}Void>';
+
+  static const String _void = '${ffi}Void';
+
+  static const String _jlObject = '${jni}JlObject';
+
+  DartBindingsGenerator(this.options, this.resolver);
+  WrapperOptions options;
+  SymbolResolver resolver;
+
+  String generateBinding(ClassDecl decl) {
+    if (!decl.isPreprocessed) {
+      throw StateError('Java class declaration must be preprocessed before'
+          'being passed to bindings generator');
+    }
+    if (!decl.isIncluded) {
+      return '';
+    }
+    return _class(decl);
+  }
+
+  String _class(ClassDecl decl) {
+    final s = StringBuffer();
+
+    s.write('/// from: ${decl.binaryName}\n');
+    s.write(_breakDocComment(decl.javadoc, depth: ''));
+    final name = _getSimpleName(decl.binaryName);
+
+    var superName = _jlObject;
+    if (decl.superclass != null) {
+      superName = resolver
+              .resolve((decl.superclass!.type as DeclaredType).binaryName) ??
+          _jlObject;
+    }
+
+    s.write('class $name extends $superName {\n');
+    s.write('$_indent$name.fromRef($_voidPtr ref) : '
+        'super.fromRef(ref);\n');
+
+    s.writeln();
+
+    for (var field in decl.fields) {
+      if (!field.isIncluded) {
+        continue;
+      }
+      try {
+        s.write(_field(decl, field));
+        s.writeln();
+      } on SkipException catch (e) {
+        stderr.writeln('skip field ${decl.binaryName}#${field.name}: '
+            '${e.message}');
+      }
+    }
+
+    for (var method in decl.methods) {
+      if (!method.isIncluded) {
+        continue;
+      }
+      try {
+        s.write(_method(decl, method));
+        s.writeln();
+      } on SkipException catch (e) {
+        stderr.writeln('skip field ${decl.binaryName}#${method.name}: '
+            '${e.message}');
+      }
+    }
+    s.write("}\n");
+    return s.toString();
+  }
+
+  static final _deleteInstruction =
+      '$_indent/// The returned object must be deleted after use, '
+      'by calling the `delete` method.\n';
+
+  String _method(ClassDecl c, Method m) {
+    final name = m.finalName;
+    final cName = memberNameInC(c, name);
+    final s = StringBuffer();
+    final sym = '_$name';
+    final ffiSig = dartSigForMethod(m, isFfiSig: true);
+    final dartSig = dartSigForMethod(m, isFfiSig: false);
+    s.write('${_indent}static final $sym = $_jlookup'
+        '<${ffi}NativeFunction<$ffiSig>>("$cName")\n'
+        '.asFunction<$dartSig>();\n');
+    // Different logic for constructor and method;
+    // For constructor, we want return type to be new object.
+    final returnType = dartOuterType(m.returnType);
+    s.write('$_indent/// from: ${_originalMethodHeader(m)}\n');
+    if (!isPrimitive(m.returnType)) {
+      s.write(_deleteInstruction);
+    }
+    s.write(_breakDocComment(m.javadoc));
+    s.write(_indent);
+
+    if (isStaticMethod(m)) {
+      s.write('static ');
+    }
+
+    if (isCtor(m)) {
+      final wrapperExpr = '$sym(${_actualArgs(m)})';
+      final className = _getSimpleName(c.binaryName);
+      final ctorFnName = name == 'ctor' ? className : '$className.$name';
+      s.write('$ctorFnName(${_formalArgs(m)}) : '
+          'super.fromRef($wrapperExpr);\n');
+      return s.toString();
+    }
+
+    var wrapperExpr = '$sym(${_actualArgs(m)})';
+    wrapperExpr = _toDartResult(wrapperExpr, m.returnType, returnType);
+    s.write('$returnType $name(${_formalArgs(m)}) '
+        '=> $wrapperExpr;\n');
+
+    return s.toString();
+  }
+
+  String _formalArgs(Method m) {
+    final List<String> args = [];
+    for (var param in m.params) {
+      args.add('${dartOuterType(param.type)} ${kwRename(param.name)}');
+    }
+    return args.join(', ');
+  }
+
+  String _actualArgs(Method m) {
+    final List<String> args = [if (hasSelfParam(m)) _self];
+    for (var param in m.params) {
+      final paramName = kwRename(param.name);
+      args.add(_toCArg(paramName, param.type));
+    }
+    return args.join(', ');
+  }
+
+  String _field(ClassDecl c, Field f) {
+    final name = f.finalName;
+    final s = StringBuffer();
+
+    void _writeDocs({bool writeDeleteInstruction = true}) {
+      s.write('$_indent/// from: ${_originalFieldDecl(f)}\n');
+      if (!isPrimitive(f.type) && writeDeleteInstruction) {
+        s.write(_deleteInstruction);
+      }
+      s.write(_breakDocComment(f.javadoc));
+    }
+
+    if (isStaticField(f) && isFinalField(f) && f.defaultValue != null) {
+      _writeDocs(writeDeleteInstruction: false);
+      s.write('${_indent}static const $name = ${_literal(f.defaultValue)};\n');
+      return s.toString();
+    }
+    final cName = memberNameInC(c, name);
+
+    void writeAccessor({bool isSetter = false}) {
+      final symPrefix = isSetter ? 'set' : 'get';
+      final sym = '_$symPrefix$name';
+      final ffiSig = dartSigForField(f, isSetter: isSetter, isFfiSig: true);
+      final dartSig = dartSigForField(f, isSetter: isSetter, isFfiSig: false);
+      s.write('${_indent}static final $sym = $_jlookup'
+          '<${ffi}NativeFunction<$ffiSig>>("${symPrefix}_$cName")\n'
+          '.asFunction<$dartSig>();\n');
+      // write original type
+      _writeDocs();
+      s.write(_indent);
+      if (isStaticField(f)) s.write('static ');
+      if (isSetter) {
+        s.write('set $name(${dartOuterType(f.type)} value) => $sym(');
+        if (!isStaticField(f)) {
+          s.write('$_self, ');
+        }
+        s.write(_toCArg('value', f.type));
+        s.write(');\n');
+      } else {
+        // getter
+        final self = isStaticField(f) ? '' : _self;
+        final outer = dartOuterType(f.type);
+        final callExpr = '$sym($self)';
+        final resultExpr = _toDartResult(callExpr, f.type, outer);
+        s.write('$outer get $name => $resultExpr;\n');
+      }
+    }
+
+    writeAccessor(isSetter: false);
+    if (!isFinalField(f)) writeAccessor(isSetter: true);
+    return s.toString();
+  }
+
+  String _getSimpleName(String binaryName) {
+    final components = binaryName.split(".");
+    return components.last.replaceAll("\$", "_");
+  }
+
+  String dartSigForField(Field f,
+      {bool isSetter = false, required bool isFfiSig}) {
+    final conv = isFfiSig ? dartFfiType : dartInnerType;
+    final voidType = isFfiSig ? _void : 'void';
+    final ref = f.modifiers.contains('static') ? '' : '$_voidPtr, ';
+    if (isSetter) {
+      return '$voidType Function($ref${conv(f.type)})';
+    }
+    return '${conv(f.type)} Function($ref)';
+  }
+
+  String dartSigForMethod(Method m, {required bool isFfiSig}) {
+    final conv = isFfiSig ? dartFfiType : dartInnerType;
+    final argTypes = [if (hasSelfParam(m)) _voidPtr];
+    for (var param in m.params) {
+      argTypes.add(conv(param.type));
+    }
+    final retType = isCtor(m) ? _voidPtr : conv(m.returnType);
+    return '$retType Function (${argTypes.join(", ")})';
+  }
+
+  // Type for FFI Function signature
+  String dartFfiType(TypeUsage t) {
+    const primitives = {
+      'byte': 'Int8',
+      'short': 'Int16',
+      'char': 'Int16',
+      'int': 'Int32',
+      'long': 'Int64',
+      'float': 'Float',
+      'double': 'Double',
+      'void': 'Void',
+      'boolean': 'Uint8',
+    };
+    switch (t.kind) {
+      case Kind.primitive:
+        return ffi + primitives[(t.type as PrimitiveType).name]!;
+      case Kind.typeVariable:
+      case Kind.wildcard:
+        throw SkipException(
+            'Generic type parameters are not supported', t.toJson());
+      case Kind.array:
+      case Kind.declared:
+        return _voidPtr;
+    }
+  }
+
+  String _dartType(TypeUsage t, {SymbolResolver? resolver}) {
+    // if resolver == null, looking for inner fn type, type of fn reference
+    // else looking for outer fn type, that's what user of the library sees.
+    const primitives = {
+      'byte': 'int',
+      'short': 'int',
+      'char': 'int',
+      'int': 'int',
+      'long': 'int',
+      'float': 'double',
+      'double': 'double',
+      'void': 'void',
+      'boolean': 'bool',
+    };
+    switch (t.kind) {
+      case Kind.primitive:
+        if (t.name == 'boolean' && resolver == null) return 'int';
+        return primitives[(t.type as PrimitiveType).name]!;
+      case Kind.typeVariable:
+      case Kind.wildcard:
+        throw SkipException('Not supported: generics');
+      case Kind.array:
+        if (resolver != null) {
+          return _jlObject;
+        }
+        return _voidPtr;
+      case Kind.declared:
+        if (resolver != null) {
+          return resolver.resolve((t.type as DeclaredType).binaryName) ??
+              _jlObject;
+        }
+        return _voidPtr;
+    }
+  }
+
+  String dartInnerType(TypeUsage t) => _dartType(t);
+  String dartOuterType(TypeUsage t) => _dartType(t, resolver: resolver);
+
+  String _literal(dynamic value) {
+    if (value is String) {
+      return '"$value"';
+    }
+    if (value is int || value is double || value is bool) {
+      return value.toString();
+    }
+    throw SkipException('Not a constant of a known type.');
+  }
+
+  String _originalFieldDecl(Field f) {
+    final declStmt = '${f.type.shorthand} ${f.name}';
+    return [...f.modifiers, declStmt].join(' ');
+  }
+
+  String _originalMethodHeader(Method m) {
+    final args = <String>[];
+    for (var p in m.params) {
+      args.add('${p.type.shorthand} ${p.name}');
+    }
+    final declStmt = '${m.returnType.shorthand} ${m.name}'
+        '(${args.join(', ')})';
+    return [...m.modifiers, declStmt].join(' ');
+  }
+
+  String _toCArg(String name, TypeUsage type) {
+    if (isPrimitive(type)) {
+      return type.name == 'boolean' ? '$name ? 1 : 0' : name;
+    }
+    return '$name.$_self';
+  }
+
+  String _toDartResult(String expr, TypeUsage type, String dartType) {
+    if (isPrimitive(type)) {
+      return type.name == 'boolean' ? '$expr != 0' : expr;
+    }
+    return '$dartType.fromRef($expr)';
+  }
+
+  static String _breakDocComment(JavaDocComment? javadoc,
+      {String depth = '    '}) {
+    final link = RegExp('{@link ([^{}]+)}');
+    if (javadoc == null) return '';
+    final comment = javadoc.comment
+        .replaceAllMapped(link, (match) => match.group(1) ?? '')
+        .replaceAll('#', '\\#')
+        .replaceAll('<p>', '')
+        .replaceAll('</p>', '\n')
+        .replaceAll('<b>', '__')
+        .replaceAll('</b>', '__')
+        .replaceAll('<em>', '_')
+        .replaceAll('</em>', '_');
+    return '$depth///\n'
+        '$depth/// ${comment.replaceAll('\n', '\n$depth///')}\n';
+  }
+}
+
+class DartPreludes {
+  static String initFile(String libraryName) => 'import "dart:ffi";\n'
+      'import "package:jni/jni.dart";\n'
+      '\n'
+      'final Pointer<T> Function<T extends NativeType>(String sym) '
+      'jlookup = Jni.getInstance().initGeneratedLibrary("$libraryName");\n'
+      '\n';
+  static const autoGeneratedNotice = '// Autogenerated by jni_gen. '
+      'DO NOT EDIT!\n\n';
+  static const defaultImports = 'import "dart:ffi" as ffi;\n\n'
+      'import "package:jni/jni.dart" as jni;\n\n';
+  static const defaultLintSuppressions =
+      '// ignore_for_file: camel_case_types\n'
+      '// ignore_for_file: non_constant_identifier_names\n'
+      '// ignore_for_file: constant_identifier_names\n'
+      '// ignore_for_file: annotate_overrides\n'
+      '// ignore_for_file: no_leading_underscores_for_local_identifiers\n'
+      '// ignore_for_file: unused_element\n'
+      '\n';
+  static const bindingFileHeaders =
+      autoGeneratedNotice + defaultLintSuppressions + defaultImports;
+}
diff --git a/pkgs/jni_gen/lib/src/bindings/preprocessor.dart b/pkgs/jni_gen/lib/src/bindings/preprocessor.dart
new file mode 100644
index 0000000..6fd1ee3
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/bindings/preprocessor.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:jni_gen/src/elements/elements.dart';
+import 'package:jni_gen/src/config/wrapper_options.dart';
+import 'package:jni_gen/src/util/rename_conflict.dart';
+import 'common.dart';
+
+/// Preprocessor which fills information needed by both Dart and C generators.
+class ApiPreprocessor {
+  ApiPreprocessor(this.classes, this.options);
+  final Map<String, ClassDecl> classes;
+  final WrapperOptions options;
+
+  void preprocessAll() {
+    for (var c in classes.values) {
+      _preprocess(c);
+    }
+  }
+
+  void _preprocess(ClassDecl decl) {
+    if (decl.isPreprocessed) return;
+    if (!_isClassIncluded(decl)) {
+      decl.isIncluded = false;
+      stdout.writeln('exclude class ${decl.binaryName}');
+      decl.isPreprocessed = true;
+      return;
+    }
+    ClassDecl? superclass;
+    if (decl.superclass != null && classes.containsKey(decl.superclass?.name)) {
+      superclass = classes[decl.superclass!.name]!;
+      _preprocess(superclass);
+      // again, un-consider superclass if it was excluded through config
+      if (!superclass.isIncluded) {
+        superclass = null;
+      } else {
+        decl.nameCounts.addAll(superclass.nameCounts);
+      }
+    }
+
+    for (var field in decl.fields) {
+      if (!_isFieldIncluded(decl, field)) {
+        field.isIncluded = false;
+        stderr.writeln('exclude ${decl.binaryName}#${field.name}');
+        continue;
+      }
+      field.finalName = renameConflict(decl.nameCounts, field.name);
+    }
+
+    for (var method in decl.methods) {
+      if (!_isMethodIncluded(decl, method)) {
+        method.isIncluded = false;
+        stderr.writeln('exclude method ${decl.binaryName}#${method.name}');
+        continue;
+      }
+      var realName = method.name;
+      if (isCtor(method)) {
+        realName = 'ctor';
+      }
+      final sig = method.javaSig;
+      // if method already in super class, assign its number, overriding it.
+      final superNum = superclass?.methodNumsAfterRenaming[sig];
+      if (superNum != null) {
+        // don't rename if superNum == 0
+        final superNumText = superNum == 0 ? '' : '$superNum';
+        // well, unless the method name is a keyword & superNum == 0.
+        // TODO(#29): this logic would better live in a dedicated renamer class.
+        final methodName = superNum == 0 ? kwRename(realName) : realName;
+        method.finalName = '$methodName$superNumText';
+        decl.methodNumsAfterRenaming[sig] = superNum;
+      } else {
+        method.finalName = renameConflict(decl.nameCounts, realName);
+        // TODO(#29): This is too much coupled with renameConflict impl.
+        // see the above todo.
+        decl.methodNumsAfterRenaming[sig] = decl.nameCounts[realName]! - 1;
+      }
+    }
+    decl.isPreprocessed = true;
+  }
+
+  bool _isFieldIncluded(ClassDecl decl, Field field) =>
+      options.fieldFilter?.included(decl, field) != false;
+  bool _isMethodIncluded(ClassDecl decl, Method method) =>
+      options.methodFilter?.included(decl, method) != false;
+  bool _isClassIncluded(ClassDecl decl) =>
+      options.classFilter?.included(decl) != false;
+}
diff --git a/pkgs/jni_gen/lib/src/bindings/symbol_resolver.dart b/pkgs/jni_gen/lib/src/bindings/symbol_resolver.dart
new file mode 100644
index 0000000..bfaaab4
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/bindings/symbol_resolver.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A symbol resolver is useful mainly to convert a fully qualified name to
+// a locally meaningful name, when creating dart bindings
+
+import 'dart:math';
+import 'package:jni_gen/src/util/name_utils.dart';
+
+abstract class SymbolResolver {
+  /// Resolve the binary name to a String which can be used in dart code.
+  String? resolve(String binaryName);
+  List<String> getImportStrings();
+}
+
+// TODO(#24): resolve all included classes without requiring import mappings.
+
+class PackagePathResolver implements SymbolResolver {
+  PackagePathResolver(this.packages, this.currentPackage, this.inputClassNames,
+      {this.predefined = const {}});
+
+  final String currentPackage;
+  final Map<String, String> packages;
+  final Map<String, String> predefined;
+  final Set<String> inputClassNames;
+
+  final List<String> importStrings = [];
+
+  final Map<String, String> _importedNameToPackage = {};
+  final Map<String, String> _packageToImportedName = {};
+
+  // return null if type's package cannot be resolved
+  // else return the fully qualified name of type
+  @override
+  String? resolve(String binaryName) {
+    if (predefined.containsKey(binaryName)) {
+      return predefined[binaryName];
+    }
+    final parts = cutFromLast(binaryName, '.');
+    final package = parts[0];
+    final typename = parts[1];
+    final simpleTypeName = typename.replaceAll('\$', '_');
+
+    if (package == currentPackage && inputClassNames.contains(binaryName)) {
+      return simpleTypeName;
+    }
+
+    if (_packageToImportedName.containsKey(package)) {
+      // This package was already resolved
+      final importedName = _packageToImportedName[package];
+      return '$importedName.$simpleTypeName';
+    }
+
+    final packageImport = getImport(package, binaryName);
+    if (packageImport == null) {
+      return null;
+    }
+
+    final pkgName = cutFromLast(package, '.')[1];
+    if (pkgName.isEmpty) {
+      throw UnsupportedError('No package could be deduced from '
+          'qualified binaryName');
+    }
+
+    var importedName = '${pkgName}_';
+    int suffix = 0;
+    while (_importedNameToPackage.containsKey(importedName)) {
+      suffix++;
+      importedName = '$pkgName${suffix}_';
+    }
+
+    _importedNameToPackage[importedName] = package;
+    _packageToImportedName[package] = importedName;
+    importStrings.add('import "$packageImport" as $importedName;\n');
+    return '$importedName.$simpleTypeName';
+  }
+
+  /// Returns import string, or `null` if package not found.
+  String? getImport(String packageToResolve, String binaryName) {
+    final right = <String>[];
+    var prefix = packageToResolve;
+
+    if (prefix.isEmpty) {
+      throw UnsupportedError('unexpected: empty package name.');
+    }
+
+    final dest = packageToResolve.split('.');
+    final src = currentPackage.split('.');
+    if (inputClassNames.contains(binaryName)) {
+      int common = 0;
+      for (int i = 0; i < src.length && i < dest.length; i++) {
+        if (src[i] == dest[i]) {
+          common++;
+        }
+      }
+      // a.b.c => a/b/c.dart
+      // from there
+      // a/b.dart => ../b.dart
+      // a.b.d => d.dart
+      // a.b.c.d => c/d.dart
+      var pathToCommon = '';
+      if (common < src.length) {
+        pathToCommon = '../' * (src.length - common);
+      }
+      final pathToPackage = dest.skip(max(common - 1, 0)).join('/');
+      return '$pathToCommon$pathToPackage.dart';
+    }
+
+    while (prefix.isNotEmpty) {
+      final split = cutFromLast(prefix, '.');
+      final left = split[0];
+      right.add(split[1]);
+      // eg: packages[org.apache.pdfbox]/org/apache/pdfbox.dart
+      if (packages.containsKey(prefix)) {
+        final sub = packageToResolve.replaceAll('.', '/');
+        final pkg = _suffix(packages[prefix]!, '/');
+        return '$pkg$sub.dart';
+      }
+      prefix = left;
+    }
+    return null;
+  }
+
+  String _suffix(String str, String suffix) {
+    if (str.endsWith(suffix)) {
+      return str;
+    }
+    return str + suffix;
+  }
+
+  @override
+  List<String> getImportStrings() {
+    return importStrings;
+  }
+}
diff --git a/pkgs/jni_gen/lib/src/config/config.dart b/pkgs/jni_gen/lib/src/config/config.dart
new file mode 100644
index 0000000..03ce6f2
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/config/config.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'summary_source.dart';
+export 'task.dart';
+export 'wrapper_options.dart';
+export 'errors.dart';
diff --git a/pkgs/jni_gen/lib/src/config/errors.dart b/pkgs/jni_gen/lib/src/config/errors.dart
new file mode 100644
index 0000000..516e8f8
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/config/errors.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Base class for all unexpected errors in JniGen (Except Skip)
+abstract class JniGenException implements Exception {}
diff --git a/pkgs/jni_gen/lib/src/config/summary_source.dart b/pkgs/jni_gen/lib/src/config/summary_source.dart
new file mode 100644
index 0000000..622c36b
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/config/summary_source.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'package:jni_gen/src/util/command_output.dart';
+
+abstract class SummarySource {
+  Future<Stream<List<int>>> getInputStream();
+}
+
+/// A command based summary source which calls the ApiSummarizer command.
+/// [sourcePaths] and [classPaths] can be provided for the summarizer to find
+/// required dependencies. The [classes] argument specifies the fully qualified
+/// names of classes or packages included in the generated summary. when a
+/// package is specified, its contents are included recursively.
+///
+/// When the default summarizer scans the [sourcePaths], it assumes that
+/// the directory names reflect actual package paths. For example, a class name
+/// com.example.pkg.Cls will be mapped to com/example/pkg/Cls.java.
+///
+/// The default summarizer needs to be built with `jni_gen:setup`
+/// script before this API is used.
+class SummarizerCommand extends SummarySource {
+  SummarizerCommand({
+    this.command = "java -jar .dart_tool/jni_gen/ApiSummarizer.jar",
+    required this.sourcePaths,
+    this.classPaths = const [],
+    this.extraArgs = const [],
+    required this.classes,
+    this.workingDirectory,
+  });
+
+  static const sourcePathsOption = '-s';
+  static const classPathsOption = '-c';
+
+  String command;
+  List<Uri> sourcePaths, classPaths;
+  List<String> extraArgs;
+  List<String> classes;
+
+  Uri? workingDirectory;
+
+  void _addPathParam(List<String> args, String option, List<Uri> paths) {
+    if (paths.isNotEmpty) {
+      final joined = paths
+          .map((uri) => uri.toFilePath())
+          .join(Platform.isWindows ? ';' : ':');
+      if (option.endsWith("=")) {
+        args.add(option + joined);
+      } else {
+        args.addAll([option, joined]);
+      }
+    }
+  }
+
+  @override
+  Future<Stream<List<int>>> getInputStream() async {
+    final commandSplit = command.split(" ");
+    final exec = commandSplit[0];
+    final List<String> args = commandSplit.sublist(1);
+
+    _addPathParam(args, sourcePathsOption, sourcePaths);
+    _addPathParam(args, classPathsOption, classPaths);
+    args.addAll(extraArgs);
+    args.addAll(classes);
+
+    stderr.writeln('[exec] $exec ${args.join(' ')}');
+    final proc = await Process.start(exec, args,
+        workingDirectory: workingDirectory?.toFilePath() ?? '.');
+    prefixedCommandOutputStream('[ApiSummarizer]', proc.stderr)
+        .forEach(stderr.writeln);
+    return proc.stdout;
+  }
+}
+
+/// A JSON file based summary source.
+// (Did not test it yet)
+class SummaryFile extends SummarySource {
+  Uri path;
+  SummaryFile(this.path);
+  SummaryFile.fromPath(String path) : path = Uri.file(path);
+
+  @override
+  Future<Stream<List<int>>> getInputStream() async =>
+      File.fromUri(path).openRead();
+}
diff --git a/pkgs/jni_gen/lib/src/config/task.dart b/pkgs/jni_gen/lib/src/config/task.dart
new file mode 100644
index 0000000..a5e015d
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/config/task.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:convert';
+
+import 'package:jni_gen/src/writers/bindings_writer.dart';
+import 'package:jni_gen/src/config/config.dart';
+import 'package:jni_gen/src/elements/elements.dart';
+
+/// Represents a complete jni_gen binding generation configuration.
+/// * [summarySource] handles the API summary generation.
+/// * [options] specify any semantic options regarding generated code.
+/// * [outputWriter] handles the output configuration.
+class JniGenTask {
+  JniGenTask({
+    required this.summarySource,
+    this.options = const WrapperOptions(),
+    required this.outputWriter,
+  });
+  BindingsWriter outputWriter;
+  SummarySource summarySource;
+  WrapperOptions options;
+
+  // execute this task
+  Future<void> run({bool dumpJson = false}) async {
+    Stream<List<int>> input;
+    try {
+      input = await summarySource.getInputStream();
+    } on Exception catch (e) {
+      stderr.writeln('error obtaining API summary: $e');
+      return;
+    }
+    final stream = JsonDecoder().bind(Utf8Decoder().bind(input));
+    dynamic json;
+    try {
+      json = await stream.single;
+    } on Exception catch (e) {
+      stderr.writeln('error while parsing summary: $e');
+      return;
+    }
+    if (json == null) {
+      stderr.writeln('error: expected JSON element from summarizer.');
+      return;
+    }
+    if (dumpJson) {
+      stderr.writeln(json);
+    }
+    final list = json as List;
+    try {
+      await outputWriter.writeBindings(
+          list.map((c) => ClassDecl.fromJson(c)), options);
+    } on Exception catch (e, trace) {
+      stderr.writeln(trace);
+      stderr.writeln('error writing bindings: $e');
+    }
+  }
+}
diff --git a/pkgs/jni_gen/lib/src/config/wrapper_options.dart b/pkgs/jni_gen/lib/src/config/wrapper_options.dart
new file mode 100644
index 0000000..7f1101d
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/config/wrapper_options.dart
@@ -0,0 +1,148 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:jni_gen/src/elements/elements.dart';
+
+/// A filter which tells if bindings for given [ClassDecl] are generated.
+abstract class ClassFilter {
+  bool included(ClassDecl decl);
+}
+
+/// This filter includes the declarations for which [predicate] returns true.
+class CustomClassFilter implements ClassFilter {
+  CustomClassFilter(this.predicate);
+  final bool Function(ClassDecl) predicate;
+  @override
+  bool included(ClassDecl decl) {
+    return predicate(decl);
+  }
+}
+
+bool _matchesCompletely(String string, Pattern pattern) {
+  final match = pattern.matchAsPrefix(string);
+  return match != null && match.group(0) == string;
+}
+
+/// Filter to include / exclude classes by matching on the binary name.
+/// A binary name is like qualified name but with a `$` used to indicate nested
+/// class instead of `.`, guaranteeing a unique name.
+class ClassNameFilter implements ClassFilter {
+  ClassNameFilter.include(this.pattern) : onMatch = true;
+  ClassNameFilter.exclude(this.pattern) : onMatch = false;
+  final bool onMatch;
+  final Pattern pattern;
+  @override
+  bool included(ClassDecl decl) {
+    if (_matchesCompletely(decl.binaryName, pattern)) {
+      return onMatch;
+    }
+    return !onMatch;
+  }
+}
+
+abstract class MemberFilter<T extends ClassMember> {
+  bool included(ClassDecl classDecl, T member);
+}
+
+class MemberNameFilter<T extends ClassMember> implements MemberFilter<T> {
+  MemberNameFilter.include(this.classPattern, this.namePattern)
+      : onMatch = true;
+  MemberNameFilter.exclude(this.classPattern, this.namePattern)
+      : onMatch = false;
+  final bool onMatch;
+  final Pattern classPattern, namePattern;
+  @override
+  bool included(ClassDecl classDecl, T member) {
+    final matches = _matchesCompletely(classDecl.binaryName, classPattern) &&
+        _matchesCompletely(member.name, namePattern);
+    return matches ? onMatch : !onMatch;
+  }
+}
+
+class CustomMemberFilter<T extends ClassMember> implements MemberFilter<T> {
+  CustomMemberFilter(this.predicate);
+  bool Function(ClassDecl, T) predicate;
+  @override
+  bool included(ClassDecl classDecl, T member) => predicate(classDecl, member);
+}
+
+class CombinedClassFilter implements ClassFilter {
+  CombinedClassFilter.all(this.filters);
+  final List<ClassFilter> filters;
+  @override
+  bool included(ClassDecl decl) => filters.every((f) => f.included(decl));
+}
+
+class CombinedMemberFilter<T extends ClassMember> implements MemberFilter<T> {
+  CombinedMemberFilter(this.filters);
+
+  final List<MemberFilter<T>> filters;
+
+  @override
+  bool included(ClassDecl decl, T member) {
+    return filters.every((f) => f.included(decl, member));
+  }
+}
+
+typedef FieldFilter = MemberFilter<Field>;
+typedef MethodFilter = MemberFilter<Method>;
+
+/// Filter using binary name of the class and name of the field.
+typedef FieldNameFilter = MemberNameFilter<Field>;
+
+/// Filter using binary name of the class and name of the method.
+typedef MethodNameFilter = MemberNameFilter<Method>;
+
+/// Predicate based filter for field, which can access class declaration
+/// and the field.
+typedef CustomFieldFilter = CustomMemberFilter<Field>;
+
+/// Predicate based filter for method, which can access class declaration
+/// and the method.
+typedef CustomMethodFilter = CustomMemberFilter<Method>;
+
+/// This filter excludes fields if any one of sub-filters returns false.
+typedef CombinedFieldFilter = CombinedMemberFilter<Field>;
+
+/// This filter excludes methods if any one of sub-filters returns false.
+typedef CombinedMethodFilter = CombinedMemberFilter<Method>;
+
+MemberFilter<T> excludeAll<T extends ClassMember>(List<List<Pattern>> names) {
+  return CombinedMemberFilter<T>(
+      names.map((p) => MemberNameFilter<T>.exclude(p[0], p[1])).toList());
+}
+
+/// Options that affect the semantics of the generated code.
+class WrapperOptions {
+  const WrapperOptions({
+    this.classFilter,
+    this.fieldFilter,
+    this.methodFilter,
+    this.classTransformer,
+    this.methodTransformer,
+    this.fieldTransformer,
+    this.importPaths = const {},
+  });
+
+  /// Mapping from java package names to dart packages.
+  /// A mapping `a.b` -> `package:a_b/' means that
+  /// any import `a.b.C` will be resolved as `package:a_b/a/b.dart` in dart.
+  /// Note that dart bindings use the same hierarchy as the java packages.
+  final Map<String, String> importPaths;
+
+  /// [ClassFilter] to decide if bindings for a class should be generated.
+  final ClassFilter? classFilter;
+
+  /// [FieldFilter] to decide if bindings for a field should be generated.
+  final FieldFilter? fieldFilter;
+
+  /// [MethodFilter] to decide if bindings for a method should be generated.
+  final MethodFilter? methodFilter;
+
+  // TODO(#26): This allows us to implement flexible renaming and more customization
+  // via the dart API.
+  final ClassDecl? Function(ClassDecl decl)? classTransformer;
+  final Method? Function(Method method)? methodTransformer;
+  final Field? Function(Field field)? fieldTransformer;
+}
diff --git a/pkgs/jni_gen/lib/src/elements/elements.dart b/pkgs/jni_gen/lib/src/elements/elements.dart
new file mode 100644
index 0000000..2673a4b
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/elements/elements.dart
@@ -0,0 +1,363 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Types to describe java API elements
+
+import 'package:json_annotation/json_annotation.dart';
+
+part 'elements.g.dart';
+
+@JsonEnum()
+
+/// A kind describes the type of a declaration.
+enum DeclKind {
+  @JsonValue('CLASS')
+  classKind,
+  @JsonValue('INTERFACE')
+  interfaceKind,
+  @JsonValue('ENUM')
+  enumKind,
+}
+
+// Note: We give default values in constructor, if the field is nullable in
+// JSON. this allows us to reduce JSON size by providing Include.NON_NULL
+// option in java.
+
+@JsonSerializable(explicitToJson: true)
+class ClassDecl {
+  /// Methods & properties already defined by dart JlObject base class.
+  static const Map<String, int> _definedSyms = {
+    'equals': 1,
+    'toString': 1,
+    'hashCode': 1,
+    'runtimeType': 1,
+    'noSuchMethod': 1,
+    'reference': 1,
+    'delete': 1,
+  };
+
+  ClassDecl({
+    this.annotations = const [],
+    this.javadoc,
+    this.modifiers = const {},
+    required this.simpleName,
+    required this.binaryName,
+    this.parentName,
+    this.packageName,
+    this.typeParams = const [],
+    this.methods = const [],
+    this.fields = const [],
+    this.superclass,
+    this.interfaces = const [],
+    this.hasStaticInit = false,
+    this.hasInstanceInit = false,
+    this.values,
+  });
+
+  List<Annotation> annotations;
+  JavaDocComment? javadoc;
+
+  Set<String> modifiers;
+  String simpleName, binaryName;
+  String? parentName, packageName;
+  List<TypeParam> typeParams;
+  List<Method> methods;
+  List<Field> fields;
+  TypeUsage? superclass;
+  List<TypeUsage> interfaces;
+  bool hasStaticInit, hasInstanceInit;
+
+  // Contains enum constant names if class is an enum,
+  // as obtained by `.values()` method in Java.
+  List<String>? values;
+
+  factory ClassDecl.fromJson(Map<String, dynamic> json) =>
+      _$ClassDeclFromJson(json);
+  Map<String, dynamic> toJson() => _$ClassDeclToJson(this);
+
+  // synthesized attributes
+  @JsonKey(ignore: true)
+  late String finalName;
+
+  @JsonKey(ignore: true)
+  bool isPreprocessed = false;
+  @JsonKey(ignore: true)
+  bool isIncluded = true;
+
+  /// Contains number with which certain overload of a method is renamed to,
+  /// so the overriding method in subclass can be renamed to same final name.
+  @JsonKey(ignore: true)
+  Map<String, int> methodNumsAfterRenaming = {};
+
+  /// Name counts map, it's a field so that it can be later used by subclasses.
+  @JsonKey(ignore: true)
+  Map<String, int> nameCounts = {..._definedSyms};
+
+  @override
+  String toString() {
+    return 'Java class declaration for $binaryName';
+  }
+}
+
+@JsonEnum()
+enum Kind {
+  @JsonValue('PRIMITIVE')
+  primitive,
+  @JsonValue('TYPE_VARIABLE')
+  typeVariable,
+  @JsonValue('WILDCARD')
+  wildcard,
+  @JsonValue('DECLARED')
+  declared,
+  @JsonValue('ARRAY')
+  array,
+}
+
+@JsonSerializable(explicitToJson: true)
+class TypeUsage {
+  TypeUsage({
+    required this.shorthand,
+    required this.kind,
+    required this.typeJson,
+  });
+
+  String shorthand;
+  Kind kind;
+  @JsonKey(ignore: true)
+  late ReferredType type;
+  @JsonKey(name: "type")
+  Map<String, dynamic> typeJson;
+
+  String get name => type.name;
+
+  // Since json_serializable doesn't directly support union types,
+  // we have to temporarily store `type` in a JSON map, and switch on the
+  // enum value received.
+  factory TypeUsage.fromJson(Map<String, dynamic> json) {
+    final t = _$TypeUsageFromJson(json);
+    switch (t.kind) {
+      case Kind.primitive:
+        t.type = PrimitiveType.fromJson(t.typeJson);
+        break;
+      case Kind.typeVariable:
+        t.type = TypeVar.fromJson(t.typeJson);
+        break;
+      case Kind.wildcard:
+        t.type = Wildcard.fromJson(t.typeJson);
+        break;
+      case Kind.declared:
+        t.type = DeclaredType.fromJson(t.typeJson);
+        break;
+      case Kind.array:
+        t.type = ArrayType.fromJson(t.typeJson);
+        break;
+    }
+    return t;
+  }
+  Map<String, dynamic> toJson() => _$TypeUsageToJson(this);
+}
+
+abstract class ReferredType {
+  String get name;
+}
+
+@JsonSerializable(explicitToJson: true)
+class PrimitiveType implements ReferredType {
+  PrimitiveType({required this.name});
+
+  @override
+  String name;
+
+  factory PrimitiveType.fromJson(Map<String, dynamic> json) =>
+      _$PrimitiveTypeFromJson(json);
+  Map<String, dynamic> toJson() => _$PrimitiveTypeToJson(this);
+}
+
+@JsonSerializable(explicitToJson: true)
+class DeclaredType implements ReferredType {
+  DeclaredType({
+    required this.binaryName,
+    required this.simpleName,
+    this.params = const [],
+  });
+  String binaryName, simpleName;
+  List<TypeUsage> params;
+
+  @override
+  String get name => binaryName;
+
+  factory DeclaredType.fromJson(Map<String, dynamic> json) =>
+      _$DeclaredTypeFromJson(json);
+  Map<String, dynamic> toJson() => _$DeclaredTypeToJson(this);
+}
+
+@JsonSerializable(explicitToJson: true)
+class TypeVar implements ReferredType {
+  TypeVar({required this.name});
+  @override
+  String name;
+
+  factory TypeVar.fromJson(Map<String, dynamic> json) =>
+      _$TypeVarFromJson(json);
+  Map<String, dynamic> toJson() => _$TypeVarToJson(this);
+}
+
+@JsonSerializable(explicitToJson: true)
+class Wildcard implements ReferredType {
+  Wildcard({this.extendsBound, this.superBound});
+  TypeUsage? extendsBound, superBound;
+
+  @override
+  String get name => "?";
+
+  factory Wildcard.fromJson(Map<String, dynamic> json) =>
+      _$WildcardFromJson(json);
+  Map<String, dynamic> toJson() => _$WildcardToJson(this);
+}
+
+@JsonSerializable(explicitToJson: true)
+class ArrayType implements ReferredType {
+  ArrayType({required this.type});
+  TypeUsage type;
+
+  @override
+  String get name => "[${type.name}";
+
+  factory ArrayType.fromJson(Map<String, dynamic> json) =>
+      _$ArrayTypeFromJson(json);
+  Map<String, dynamic> toJson() => _$ArrayTypeToJson(this);
+}
+
+abstract class ClassMember {
+  String get name;
+}
+
+@JsonSerializable(explicitToJson: true)
+class Method implements ClassMember {
+  Method(
+      {this.annotations = const [],
+      this.javadoc,
+      this.modifiers = const {},
+      required this.name,
+      this.typeParams = const [],
+      this.params = const [],
+      required this.returnType});
+  List<Annotation> annotations;
+  JavaDocComment? javadoc;
+  Set<String> modifiers;
+
+  @override
+  String name;
+
+  List<TypeParam> typeParams;
+  List<Param> params;
+  TypeUsage returnType;
+
+  @JsonKey(ignore: true)
+  late String finalName;
+  @JsonKey(ignore: true)
+  late bool isOverridden;
+  @JsonKey(ignore: true)
+  bool isIncluded = true;
+
+  @JsonKey(ignore: true)
+  late String javaSig = _javaSig();
+
+  String _javaSig() {
+    final paramNames = params.map((p) => p.type.name).join(', ');
+    return '${returnType.name} $name($paramNames)';
+  }
+
+  factory Method.fromJson(Map<String, dynamic> json) => _$MethodFromJson(json);
+  Map<String, dynamic> toJson() => _$MethodToJson(this);
+}
+
+@JsonSerializable(explicitToJson: true)
+class Param {
+  Param(
+      {this.annotations = const [],
+      this.javadoc,
+      required this.name,
+      required this.type});
+  List<Annotation> annotations;
+  JavaDocComment? javadoc;
+
+  String name;
+  TypeUsage type;
+
+  factory Param.fromJson(Map<String, dynamic> json) => _$ParamFromJson(json);
+  Map<String, dynamic> toJson() => _$ParamToJson(this);
+}
+
+@JsonSerializable(explicitToJson: true)
+class Field implements ClassMember {
+  Field(
+      {this.annotations = const [],
+      this.javadoc,
+      this.modifiers = const {},
+      required this.name,
+      required this.type,
+      this.defaultValue});
+
+  List<Annotation> annotations;
+  JavaDocComment? javadoc;
+
+  Set<String> modifiers;
+
+  @override
+  String name;
+
+  TypeUsage type;
+  Object? defaultValue;
+
+  @JsonKey(ignore: true)
+  late String finalName;
+  @JsonKey(ignore: true)
+  bool isIncluded = true;
+
+  factory Field.fromJson(Map<String, dynamic> json) => _$FieldFromJson(json);
+  Map<String, dynamic> toJson() => _$FieldToJson(this);
+}
+
+@JsonSerializable(explicitToJson: true)
+class TypeParam {
+  TypeParam({required this.name, this.bounds = const []});
+  String name;
+  List<TypeUsage> bounds;
+
+  @JsonKey(ignore: true)
+  late String erasure;
+
+  factory TypeParam.fromJson(Map<String, dynamic> json) =>
+      _$TypeParamFromJson(json);
+  Map<String, dynamic> toJson() => _$TypeParamToJson(this);
+}
+
+@JsonSerializable(explicitToJson: true)
+class JavaDocComment {
+  JavaDocComment({String? comment}) : comment = comment ?? '';
+  String comment;
+
+  @JsonKey(ignore: true)
+  late String dartDoc;
+
+  factory JavaDocComment.fromJson(Map<String, dynamic> json) =>
+      _$JavaDocCommentFromJson(json);
+  Map<String, dynamic> toJson() => _$JavaDocCommentToJson(this);
+}
+
+@JsonSerializable(explicitToJson: true)
+class Annotation {
+  Annotation(
+      {required this.simpleName,
+      required this.binaryName,
+      this.properties = const {}});
+  String simpleName;
+  String binaryName;
+  Map<String, Object> properties;
+
+  factory Annotation.fromJson(Map<String, dynamic> json) =>
+      _$AnnotationFromJson(json);
+  Map<String, dynamic> toJson() => _$AnnotationToJson(this);
+}
diff --git a/pkgs/jni_gen/lib/src/elements/elements.g.dart b/pkgs/jni_gen/lib/src/elements/elements.g.dart
new file mode 100644
index 0000000..95944de
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/elements/elements.g.dart
@@ -0,0 +1,261 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'elements.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ClassDecl _$ClassDeclFromJson(Map<String, dynamic> json) => ClassDecl(
+      annotations: (json['annotations'] as List<dynamic>?)
+              ?.map((e) => Annotation.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+      javadoc: json['javadoc'] == null
+          ? null
+          : JavaDocComment.fromJson(json['javadoc'] as Map<String, dynamic>),
+      modifiers: (json['modifiers'] as List<dynamic>?)
+              ?.map((e) => e as String)
+              .toSet() ??
+          const {},
+      simpleName: json['simpleName'] as String,
+      binaryName: json['binaryName'] as String,
+      parentName: json['parentName'] as String?,
+      packageName: json['packageName'] as String?,
+      typeParams: (json['typeParams'] as List<dynamic>?)
+              ?.map((e) => TypeParam.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+      methods: (json['methods'] as List<dynamic>?)
+              ?.map((e) => Method.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+      fields: (json['fields'] as List<dynamic>?)
+              ?.map((e) => Field.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+      superclass: json['superclass'] == null
+          ? null
+          : TypeUsage.fromJson(json['superclass'] as Map<String, dynamic>),
+      interfaces: (json['interfaces'] as List<dynamic>?)
+              ?.map((e) => TypeUsage.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+      hasStaticInit: json['hasStaticInit'] as bool? ?? false,
+      hasInstanceInit: json['hasInstanceInit'] as bool? ?? false,
+      values:
+          (json['values'] as List<dynamic>?)?.map((e) => e as String).toList(),
+    );
+
+Map<String, dynamic> _$ClassDeclToJson(ClassDecl instance) => <String, dynamic>{
+      'annotations': instance.annotations.map((e) => e.toJson()).toList(),
+      'javadoc': instance.javadoc?.toJson(),
+      'modifiers': instance.modifiers.toList(),
+      'simpleName': instance.simpleName,
+      'binaryName': instance.binaryName,
+      'parentName': instance.parentName,
+      'packageName': instance.packageName,
+      'typeParams': instance.typeParams.map((e) => e.toJson()).toList(),
+      'methods': instance.methods.map((e) => e.toJson()).toList(),
+      'fields': instance.fields.map((e) => e.toJson()).toList(),
+      'superclass': instance.superclass?.toJson(),
+      'interfaces': instance.interfaces.map((e) => e.toJson()).toList(),
+      'hasStaticInit': instance.hasStaticInit,
+      'hasInstanceInit': instance.hasInstanceInit,
+      'values': instance.values,
+    };
+
+TypeUsage _$TypeUsageFromJson(Map<String, dynamic> json) => TypeUsage(
+      shorthand: json['shorthand'] as String,
+      kind: $enumDecode(_$KindEnumMap, json['kind']),
+      typeJson: json['type'] as Map<String, dynamic>,
+    );
+
+Map<String, dynamic> _$TypeUsageToJson(TypeUsage instance) => <String, dynamic>{
+      'shorthand': instance.shorthand,
+      'kind': _$KindEnumMap[instance.kind]!,
+      'type': instance.typeJson,
+    };
+
+const _$KindEnumMap = {
+  Kind.primitive: 'PRIMITIVE',
+  Kind.typeVariable: 'TYPE_VARIABLE',
+  Kind.wildcard: 'WILDCARD',
+  Kind.declared: 'DECLARED',
+  Kind.array: 'ARRAY',
+};
+
+PrimitiveType _$PrimitiveTypeFromJson(Map<String, dynamic> json) =>
+    PrimitiveType(
+      name: json['name'] as String,
+    );
+
+Map<String, dynamic> _$PrimitiveTypeToJson(PrimitiveType instance) =>
+    <String, dynamic>{
+      'name': instance.name,
+    };
+
+DeclaredType _$DeclaredTypeFromJson(Map<String, dynamic> json) => DeclaredType(
+      binaryName: json['binaryName'] as String,
+      simpleName: json['simpleName'] as String,
+      params: (json['params'] as List<dynamic>?)
+              ?.map((e) => TypeUsage.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+    );
+
+Map<String, dynamic> _$DeclaredTypeToJson(DeclaredType instance) =>
+    <String, dynamic>{
+      'binaryName': instance.binaryName,
+      'simpleName': instance.simpleName,
+      'params': instance.params.map((e) => e.toJson()).toList(),
+    };
+
+TypeVar _$TypeVarFromJson(Map<String, dynamic> json) => TypeVar(
+      name: json['name'] as String,
+    );
+
+Map<String, dynamic> _$TypeVarToJson(TypeVar instance) => <String, dynamic>{
+      'name': instance.name,
+    };
+
+Wildcard _$WildcardFromJson(Map<String, dynamic> json) => Wildcard(
+      extendsBound: json['extendsBound'] == null
+          ? null
+          : TypeUsage.fromJson(json['extendsBound'] as Map<String, dynamic>),
+      superBound: json['superBound'] == null
+          ? null
+          : TypeUsage.fromJson(json['superBound'] as Map<String, dynamic>),
+    );
+
+Map<String, dynamic> _$WildcardToJson(Wildcard instance) => <String, dynamic>{
+      'extendsBound': instance.extendsBound?.toJson(),
+      'superBound': instance.superBound?.toJson(),
+    };
+
+ArrayType _$ArrayTypeFromJson(Map<String, dynamic> json) => ArrayType(
+      type: TypeUsage.fromJson(json['type'] as Map<String, dynamic>),
+    );
+
+Map<String, dynamic> _$ArrayTypeToJson(ArrayType instance) => <String, dynamic>{
+      'type': instance.type.toJson(),
+    };
+
+Method _$MethodFromJson(Map<String, dynamic> json) => Method(
+      annotations: (json['annotations'] as List<dynamic>?)
+              ?.map((e) => Annotation.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+      javadoc: json['javadoc'] == null
+          ? null
+          : JavaDocComment.fromJson(json['javadoc'] as Map<String, dynamic>),
+      modifiers: (json['modifiers'] as List<dynamic>?)
+              ?.map((e) => e as String)
+              .toSet() ??
+          const {},
+      name: json['name'] as String,
+      typeParams: (json['typeParams'] as List<dynamic>?)
+              ?.map((e) => TypeParam.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+      params: (json['params'] as List<dynamic>?)
+              ?.map((e) => Param.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+      returnType:
+          TypeUsage.fromJson(json['returnType'] as Map<String, dynamic>),
+    );
+
+Map<String, dynamic> _$MethodToJson(Method instance) => <String, dynamic>{
+      'annotations': instance.annotations.map((e) => e.toJson()).toList(),
+      'javadoc': instance.javadoc?.toJson(),
+      'modifiers': instance.modifiers.toList(),
+      'name': instance.name,
+      'typeParams': instance.typeParams.map((e) => e.toJson()).toList(),
+      'params': instance.params.map((e) => e.toJson()).toList(),
+      'returnType': instance.returnType.toJson(),
+    };
+
+Param _$ParamFromJson(Map<String, dynamic> json) => Param(
+      annotations: (json['annotations'] as List<dynamic>?)
+              ?.map((e) => Annotation.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+      javadoc: json['javadoc'] == null
+          ? null
+          : JavaDocComment.fromJson(json['javadoc'] as Map<String, dynamic>),
+      name: json['name'] as String,
+      type: TypeUsage.fromJson(json['type'] as Map<String, dynamic>),
+    );
+
+Map<String, dynamic> _$ParamToJson(Param instance) => <String, dynamic>{
+      'annotations': instance.annotations.map((e) => e.toJson()).toList(),
+      'javadoc': instance.javadoc?.toJson(),
+      'name': instance.name,
+      'type': instance.type.toJson(),
+    };
+
+Field _$FieldFromJson(Map<String, dynamic> json) => Field(
+      annotations: (json['annotations'] as List<dynamic>?)
+              ?.map((e) => Annotation.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+      javadoc: json['javadoc'] == null
+          ? null
+          : JavaDocComment.fromJson(json['javadoc'] as Map<String, dynamic>),
+      modifiers: (json['modifiers'] as List<dynamic>?)
+              ?.map((e) => e as String)
+              .toSet() ??
+          const {},
+      name: json['name'] as String,
+      type: TypeUsage.fromJson(json['type'] as Map<String, dynamic>),
+      defaultValue: json['defaultValue'],
+    );
+
+Map<String, dynamic> _$FieldToJson(Field instance) => <String, dynamic>{
+      'annotations': instance.annotations.map((e) => e.toJson()).toList(),
+      'javadoc': instance.javadoc?.toJson(),
+      'modifiers': instance.modifiers.toList(),
+      'name': instance.name,
+      'type': instance.type.toJson(),
+      'defaultValue': instance.defaultValue,
+    };
+
+TypeParam _$TypeParamFromJson(Map<String, dynamic> json) => TypeParam(
+      name: json['name'] as String,
+      bounds: (json['bounds'] as List<dynamic>?)
+              ?.map((e) => TypeUsage.fromJson(e as Map<String, dynamic>))
+              .toList() ??
+          const [],
+    );
+
+Map<String, dynamic> _$TypeParamToJson(TypeParam instance) => <String, dynamic>{
+      'name': instance.name,
+      'bounds': instance.bounds.map((e) => e.toJson()).toList(),
+    };
+
+JavaDocComment _$JavaDocCommentFromJson(Map<String, dynamic> json) =>
+    JavaDocComment(
+      comment: json['comment'] as String?,
+    );
+
+Map<String, dynamic> _$JavaDocCommentToJson(JavaDocComment instance) =>
+    <String, dynamic>{
+      'comment': instance.comment,
+    };
+
+Annotation _$AnnotationFromJson(Map<String, dynamic> json) => Annotation(
+      simpleName: json['simpleName'] as String,
+      binaryName: json['binaryName'] as String,
+      properties: (json['properties'] as Map<String, dynamic>?)?.map(
+            (k, e) => MapEntry(k, e as Object),
+          ) ??
+          const {},
+    );
+
+Map<String, dynamic> _$AnnotationToJson(Annotation instance) =>
+    <String, dynamic>{
+      'simpleName': instance.simpleName,
+      'binaryName': instance.binaryName,
+      'properties': instance.properties,
+    };
diff --git a/pkgs/jni_gen/lib/src/my_sum.dart b/pkgs/jni_gen/lib/src/my_sum.dart
deleted file mode 100644
index 5e21504..0000000
--- a/pkgs/jni_gen/lib/src/my_sum.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Computes the sum of its arguments.
-int mySum(int a, int b) => a + b;
diff --git a/pkgs/jni_gen/lib/src/tools/maven_utils.dart b/pkgs/jni_gen/lib/src/tools/maven_utils.dart
new file mode 100644
index 0000000..2c28657
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/tools/maven_utils.dart
@@ -0,0 +1,134 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+/// This class provides some utility methods to download a sources / jars
+/// using maven along with transitive dependencies.
+class MvnTools {
+  static const _tempPom = '__temp_pom.xml';
+  static const _tempClassPath = '__temp_classpath.xml';
+  static const _tempTarget = '__mvn_target';
+
+  static bool _verbose = false;
+  static void setVerbose(bool enabled) => _verbose = enabled;
+
+  static void _verboseLog(Object? value) {
+    if (_verbose) {
+      stderr.writeln(value);
+    }
+  }
+
+  /// Helper method since we can't pass inheritStdio option to [Process.run].
+  static Future<int> _runCmd(String exec, List<String> args,
+      [String? workingDirectory]) async {
+    _verboseLog('[exec] $exec ${args.join(" ")}');
+    final proc = await Process.start(exec, args,
+        workingDirectory: workingDirectory,
+        mode: ProcessStartMode.inheritStdio);
+    return proc.exitCode;
+  }
+
+  static Future<void> _runMavenCommand(
+      List<MvnDep> deps, List<String> mvnArgs) async {
+    final pom = _getStubPom(deps);
+    _verboseLog('using POM stub:\n$pom');
+    await File(_tempPom).writeAsString(pom);
+    await Directory(_tempTarget).create();
+    await _runCmd(
+        'mvn', ['-f', _tempPom, '-DbuildDirectory=$_tempTarget', ...mvnArgs]);
+    await File(_tempPom).delete();
+    await Directory(_tempTarget).delete(recursive: true);
+  }
+
+  /// Create a list of [MvnDep] objects from maven coordinates in string form.
+  static List<MvnDep> makeDependencyList(List<String> depNames) =>
+      depNames.map(MvnDep.fromString).toList();
+
+  /// Downloads and unpacks source files of [deps] into [targetDir].
+  static Future<void> downloadMavenSources(
+      List<MvnDep> deps, String targetDir) async {
+    await _runMavenCommand(deps, [
+      'dependency:unpack-dependencies',
+      '-DoutputDirectory=$targetDir',
+      '-Dclassifier=sources'
+    ]);
+  }
+
+  /// Downloads JAR files of all [deps] transitively into [targetDir].
+  static Future<void> downloadMavenJars(
+      List<MvnDep> deps, String targetDir) async {
+    await _runMavenCommand(deps, [
+      'dependency:copy-dependencies',
+      '-DoutputDirectory=$targetDir',
+    ]);
+  }
+
+  /// Get classpath string using JARs in maven's local repository.
+  static Future<String> getMavenClassPath(List<MvnDep> deps) async {
+    await _runMavenCommand(deps, [
+      'dependency:build-classpath',
+      '-Dmdep.outputFile=$_tempClassPath',
+    ]);
+    final classPathFile = File(_tempClassPath);
+    final classpath = await classPathFile.readAsString();
+    await classPathFile.delete();
+    return classpath;
+  }
+
+  static String _getStubPom(List<MvnDep> deps, {String javaVersion = '11'}) {
+    final i2 = ' ' * 2;
+    final i4 = ' ' * 4;
+    final i6 = ' ' * 6;
+    final i8 = ' ' * 8;
+    final depDecls = <String>[];
+
+    for (var dep in deps) {
+      final otherTags = StringBuffer();
+      for (var entry in dep.otherTags.entries) {
+        otherTags.write('$i6<${entry.key}>\n'
+            '$i8${entry.value}\n'
+            '$i6</${entry.key}>\n');
+      }
+      depDecls.add('$i4<dependency>\n'
+          '$i6<groupId>${dep.groupID}</groupId>\n'
+          '$i6<artifactId>${dep.artifactID}</artifactId>\n'
+          '$i6<version>${dep.version}</version>\n'
+          '${otherTags.toString()}\n'
+          '$i4</dependency>\n');
+    }
+
+    return '<project xmlns="http://maven.apache.org/POM/4.0.0" '
+        'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n'
+        'xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 '
+        'http://maven.apache.org/xsd/maven-4.0.0.xsd">\n'
+        '$i2<modelVersion>4.0.0</modelVersion>\n'
+        '$i2<groupId>com.mycompany.app</groupId>\n'
+        '$i2<artifactId>my-app</artifactId>\n'
+        '$i2<version>1.0-SNAPSHOT</version>\n'
+        '$i2<properties>\n'
+        '$i4<maven.compiler.source>$javaVersion</maven.compiler.source>\n'
+        '$i4<maven.compiler.target>$javaVersion</maven.compiler.target>\n'
+        '$i2</properties>\n'
+        '$i4<dependencies>\n'
+        '${depDecls.join("\n")}'
+        '$i2</dependencies>\n'
+        '</project>';
+  }
+}
+
+/// Maven dependency with group ID, artifact ID, and version.
+class MvnDep {
+  MvnDep(this.groupID, this.artifactID, this.version,
+      {this.otherTags = const {}});
+  factory MvnDep.fromString(String fullName) {
+    final components = fullName.split(':');
+    if (components.length != 3) {
+      throw ArgumentError('invalid name for maven dependency: $fullName');
+    }
+    return MvnDep(components[0], components[1], components[2]);
+  }
+  String groupID, artifactID, version;
+  Map<String, String> otherTags;
+}
diff --git a/pkgs/jni_gen/lib/src/util/command_output.dart b/pkgs/jni_gen/lib/src/util/command_output.dart
new file mode 100644
index 0000000..ba9366a
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/util/command_output.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+
+Stream<String> commandOutputStream(
+        String Function(String) lineMapper, Stream<List<int>> input) =>
+    input.transform(Utf8Decoder()).transform(LineSplitter()).map(lineMapper);
+
+Stream<String> prefixedCommandOutputStream(
+        String prefix, Stream<List<int>> input) =>
+    commandOutputStream((line) => '$prefix $line', input);
diff --git a/pkgs/jni_gen/lib/src/util/find_package.dart b/pkgs/jni_gen/lib/src/util/find_package.dart
new file mode 100644
index 0000000..5c1650c
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/util/find_package.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:package_config/package_config.dart';
+
+Future<Package?> findPackage(String packageName) async {
+  final packageConfig = await findPackageConfig(Directory.current);
+  if (packageConfig == null) {
+    return null;
+  }
+  return packageConfig[packageName];
+}
+
+Future<Uri?> findPackageRoot(String packageName) async {
+  return (await findPackage(packageName))?.root;
+}
+
+Future<bool> isPackageModifiedAfter(String packageName, DateTime time,
+    [String? subDir]) async {
+  final root = await findPackageRoot(packageName);
+  if (root == null) {
+    throw UnsupportedError('package $packageName does not exist');
+  }
+  var checkRoot = root;
+  if (subDir != null) {
+    checkRoot = root.resolve(subDir);
+  }
+  final dir = Directory.fromUri(checkRoot);
+  if (!await dir.exists()) {
+    throw UnsupportedError('can not resolve $subDir in $packageName');
+  }
+  // A directory's modification time is not helpful because one of
+  // internal files may be modified later.
+  // In case of git / pub package we might be able to check pubspec, but no
+  // such technique applies for path packages.
+  await for (final entry in dir.list(recursive: true)) {
+    final stat = await entry.stat();
+    if (stat.modified.isAfter(time)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+Future<Uri?> findPackageJni() => findPackageRoot('jni');
diff --git a/pkgs/jni_gen/lib/src/util/name_utils.dart b/pkgs/jni_gen/lib/src/util/name_utils.dart
new file mode 100644
index 0000000..f75d2db
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/util/name_utils.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:jni_gen/src/elements/elements.dart';
+
+String getPackageName(String binaryName) => cutFromLast(binaryName, '.')[0];
+
+/// splits [str] into 2 from last occurence of [sep]
+List<String> cutFromLast(String str, String sep) {
+  final li = str.lastIndexOf(sep);
+  if (li == -1) {
+    return ['', str];
+  }
+  return [str.substring(0, li), str.substring(li + 1)];
+}
+
+String getLastName(String binaryName) => binaryName.split('.').last;
+
+String getSimpleNameOf(ClassDecl cls) => cls.simpleName;
+
+/// Returns class name as useful in dart.
+///
+/// Eg -> a.b.X.Y -> X_Y
+String simplifiedClassName(String binaryName) =>
+    getLastName(binaryName).replaceAll('\$', '_');
+
+// Utilities to operate on package names.
+
+List<String> getComponents(String packageName) => packageName.split('.');
diff --git a/pkgs/jni_gen/lib/src/util/rename_conflict.dart b/pkgs/jni_gen/lib/src/util/rename_conflict.dart
new file mode 100644
index 0000000..7971d50
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/util/rename_conflict.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String renameConflict(Map<String, int> counts, String name) {
+  if (counts.containsKey(name)) {
+    final count = counts[name]!;
+    final renamed = '$name$count';
+    counts[name] = count + 1;
+    return renamed;
+  }
+  counts[name] = 1;
+  return kwRename(name);
+}
+
+/// Appends 0 to [name] if [name] is a keyword.
+///
+/// Examples:
+/// * `int` -> `int0`
+/// * `i` -> `i`
+String kwRename(String name) => _keywords.contains(name) ? '${name}0' : name;
+
+const Set<String> _keywords = {
+  'abstract',
+  'as',
+  'assert',
+  'async',
+  'await',
+  'break',
+  'case',
+  'catch',
+  'class',
+  'const',
+  'continue',
+  'covariant',
+  'default',
+  'deferred',
+  'do',
+  'dynamic',
+  'else',
+  'enum',
+  'export',
+  'extends',
+  'extension',
+  'external',
+  'factory',
+  'false',
+  'final',
+  'finally',
+  'for',
+  'Function',
+  'get',
+  'hide',
+  'if',
+  'implements',
+  'import',
+  'in',
+  'interface',
+  'is',
+  'late',
+  'library',
+  'mixin',
+  'new',
+  'null',
+  'on',
+  'operator',
+  'part',
+  'required',
+  'rethrow',
+  'return',
+  'set',
+  'show',
+  'static',
+  'super',
+  'switch',
+  'sync',
+  'this',
+  'throw',
+  'true',
+  'try',
+  'typedef',
+  'var',
+  'void',
+  'while',
+  'with',
+  'yield',
+};
diff --git a/pkgs/jni_gen/lib/src/writers/bindings_writer.dart b/pkgs/jni_gen/lib/src/writers/bindings_writer.dart
new file mode 100644
index 0000000..ed50a41
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/writers/bindings_writer.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:jni_gen/src/elements/elements.dart';
+import 'package:jni_gen/src/config/wrapper_options.dart';
+
+abstract class BindingsWriter {
+  Future<void> writeBindings(
+      Iterable<ClassDecl> classes, WrapperOptions options);
+}
diff --git a/pkgs/jni_gen/lib/src/writers/callback_writer.dart b/pkgs/jni_gen/lib/src/writers/callback_writer.dart
new file mode 100644
index 0000000..0ab7ed0
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/writers/callback_writer.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:jni_gen/src/elements/elements.dart';
+import 'package:jni_gen/src/config/wrapper_options.dart';
+
+import 'bindings_writer.dart';
+
+/// A writer for debugging purpose.
+class CallbackWriter extends BindingsWriter {
+  CallbackWriter(this.callback);
+  Future<void> Function(Iterable<ClassDecl>, WrapperOptions) callback;
+
+  @override
+  Future<void> writeBindings(
+      Iterable<ClassDecl> classes, WrapperOptions options) async {
+    callback(classes, options);
+  }
+}
diff --git a/pkgs/jni_gen/lib/src/writers/files_writer.dart b/pkgs/jni_gen/lib/src/writers/files_writer.dart
new file mode 100644
index 0000000..0e8a6ad
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/writers/files_writer.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:jni_gen/src/bindings/bindings.dart';
+
+import 'package:jni_gen/src/elements/elements.dart';
+import 'package:jni_gen/src/config/wrapper_options.dart';
+import 'package:jni_gen/src/util/find_package.dart';
+
+import 'bindings_writer.dart';
+
+/// Writer which takes writes C and Dart bindings to specified directories.
+///
+/// The structure of dart files is determined by package structure of java.
+/// One dart file corresponds to one java package, and it's path is decided by
+/// fully qualified name of the package.
+///
+/// Example:
+/// `android.os` -> `$dartWrappersRoot`/`android/os.dart`
+class FilesWriter extends BindingsWriter {
+  static const _initFileName = 'init.dart';
+
+  FilesWriter(
+      {required this.cWrapperDir,
+      required this.dartWrappersRoot,
+      this.javaWrappersRoot,
+      this.preamble,
+      required this.libraryName});
+  Uri cWrapperDir, dartWrappersRoot;
+  Uri? javaWrappersRoot;
+  String? preamble;
+  String libraryName;
+  @override
+  Future<void> writeBindings(
+      Iterable<ClassDecl> classes, WrapperOptions options) async {
+    // If the file already exists, show warning.
+    // sort classes so that all classes get written at once.
+    final Map<String, List<ClassDecl>> packages = {};
+    final Map<String, ClassDecl> classesByName = {};
+    for (var c in classes) {
+      classesByName.putIfAbsent(c.binaryName, () => c);
+      packages.putIfAbsent(c.packageName!, () => <ClassDecl>[]);
+      packages[c.packageName!]!.add(c);
+    }
+    final classNames = classesByName.keys.toSet();
+
+    stderr.writeln('Creating dart init file ...');
+    final initFileUri = dartWrappersRoot.resolve(_initFileName);
+    final initFile = await File.fromUri(initFileUri).create(recursive: true);
+    await initFile.writeAsString(DartPreludes.initFile(libraryName),
+        flush: true);
+
+    final cFile = await File.fromUri(cWrapperDir.resolve('$libraryName.c'))
+        .create(recursive: true);
+    final cFileStream = cFile.openWrite();
+    if (preamble != null) {
+      cFileStream.writeln(preamble);
+    }
+    cFileStream.write(CPreludes.prelude);
+    final preprocessor = ApiPreprocessor(classesByName, options);
+    preprocessor.preprocessAll();
+    for (var packageName in packages.keys) {
+      final relativeFileName = '${packageName.replaceAll('.', '/')}.dart';
+      final dartFileUri = dartWrappersRoot.resolve(relativeFileName);
+      stderr.writeln('Writing bindings for $packageName...');
+      final dartFile = await File.fromUri(dartFileUri).create(recursive: true);
+      final resolver = PackagePathResolver(
+          options.importPaths, packageName, classNames,
+          predefined: {'java.lang.String': 'jni.JlString'});
+      final cgen = CBindingGenerator(options);
+      final dgen = DartBindingsGenerator(options, resolver);
+
+      final package = packages[packageName]!;
+      final cBindings = package.map(cgen.generateBinding).toList();
+      final dartBindings = package.map(dgen.generateBinding).toList();
+      // write imports from bindings
+      final dartFileStream = dartFile.openWrite();
+      final initImportPath = ('../' *
+              relativeFileName.codeUnits
+                  .where((cu) => '/'.codeUnitAt(0) == cu)
+                  .length) +
+          _initFileName;
+      if (preamble != null) {
+        dartFileStream.writeln(preamble);
+      }
+      dartFileStream
+        ..write(DartPreludes.bindingFileHeaders)
+        ..write(resolver.getImportStrings().join('\n'))
+        ..write('import "$initImportPath" show jlookup;\n\n');
+      // write dart bindings only after all imports are figured out
+      dartBindings.forEach(dartFileStream.write);
+      cBindings.forEach(cFileStream.write);
+      await dartFileStream.close();
+    }
+    await cFileStream.close();
+    stderr.writeln('Running dart format...');
+    final formatRes =
+        await Process.run('dart', ['format', dartWrappersRoot.toFilePath()]);
+    if (formatRes.exitCode != 0) {
+      stderr.writeln('ERROR: dart format completed with '
+          'exit code ${formatRes.exitCode}');
+    }
+
+    stderr.writeln('Copying auxiliary files...');
+    await _copyFileFromPackage(
+        'jni', 'src/dartjni.h', cWrapperDir.resolve('dartjni.h'));
+    await _copyFileFromPackage('jni_gen', 'cmake/CMakeLists.txt.tmpl',
+        cWrapperDir.resolve('CMakeLists.txt'),
+        transform: (s) => s.replaceAll('{{LIBRARY_NAME}}', libraryName));
+    stderr.writeln('Completed.');
+  }
+
+  Future<void> _copyFileFromPackage(String package, String relPath, Uri target,
+      {String Function(String)? transform}) async {
+    final packagePath = await findPackageRoot(package);
+    if (packagePath != null) {
+      final sourceFile = File.fromUri(packagePath.resolve(relPath));
+      final targetFile = await File.fromUri(target).create();
+      var source = await sourceFile.readAsString();
+      if (transform != null) {
+        source = transform(source);
+      }
+      await targetFile.writeAsString(source);
+    } else {
+      stderr.writeln('package $package not found! '
+          'skipped copying ${target.toFilePath()}');
+    }
+  }
+}
diff --git a/pkgs/jni_gen/lib/src/writers/writers.dart b/pkgs/jni_gen/lib/src/writers/writers.dart
new file mode 100644
index 0000000..887e6a9
--- /dev/null
+++ b/pkgs/jni_gen/lib/src/writers/writers.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'bindings_writer.dart';
+export 'files_writer.dart';
+export 'callback_writer.dart';
diff --git a/pkgs/jni_gen/lib/tools.dart b/pkgs/jni_gen/lib/tools.dart
new file mode 100644
index 0000000..19e0eab
--- /dev/null
+++ b/pkgs/jni_gen/lib/tools.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library jni_gen_tools;
+
+export 'src/tools/maven_utils.dart';
diff --git a/pkgs/jni_gen/pubspec.yaml b/pkgs/jni_gen/pubspec.yaml
index f60652b..c75369b 100644
--- a/pkgs/jni_gen/pubspec.yaml
+++ b/pkgs/jni_gen/pubspec.yaml
@@ -11,7 +11,15 @@
   sdk: '>=2.17.0 <3.0.0'
 
 dependencies:
+  json_annotation: ^4.6.0
+  package_config: ^2.1.0
+  path:
 
 dev_dependencies:
   lints: ^2.0.0
+  jni:
+    path: ../jni
   test: ^1.17.5
+  build_runner: ^2.2.0
+  json_serializable: ^6.3.1
+
diff --git a/pkgs/jni_gen/test/bindings_test.dart b/pkgs/jni_gen/test/bindings_test.dart
new file mode 100644
index 0000000..be93be2
--- /dev/null
+++ b/pkgs/jni_gen/test/bindings_test.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests on generated code.
+//
+// Both the simple java example & jackson core classes example have tests in
+// same file, because the test runner will reuse the process, which leads to
+// reuse of the old JVM with old classpath if we have separate tests with
+// different classpaths.
+
+import 'dart:io';
+
+import 'package:jni/jni.dart';
+import 'package:path/path.dart' hide equals;
+import 'package:test/test.dart';
+
+// ignore_for_file: avoid_relative_lib_imports
+import 'simple_package_test/lib/dev/dart/simple_package.dart';
+import 'simple_package_test/lib/dev/dart/pkg2.dart';
+import 'jackson_core_test/third_party/lib/com/fasterxml/jackson/core.dart';
+
+import 'test_util/test_util.dart';
+
+final simplePackagePath = join('test', 'simple_package_test');
+final jacksonCorePath = join('test', 'jackson_core_test');
+final simplePackageJavaPath = join(simplePackagePath, 'java');
+
+Future<void> setupDylibsAndClasses() async {
+  await runCmd('dart', ['run', 'jni:setup']);
+  await runCmd(
+      'dart', ['run', 'jni:setup', '-S', join(simplePackagePath, 'src')]);
+  await runCmd('dart',
+      ['run', 'jni:setup', '-S', join(jacksonCorePath, 'third_party', 'src')]);
+  await runCmd('javac',
+      ['dev/dart/simple_package/Example.java', 'dev/dart/pkg2/C2.java'],
+      workingDirectory: simplePackageJavaPath);
+
+  final jacksonJars = await getJarPaths(join(jacksonCorePath, 'third_party'));
+
+  if (!Platform.isAndroid) {
+    Jni.spawn(
+        helperDir: 'build/jni_libs',
+        classPath: [simplePackageJavaPath, ...jacksonJars]);
+  }
+}
+
+void main() async {
+  await setupDylibsAndClasses();
+
+  test('static final fields', () {
+    expect(Example.ON, equals(1));
+    expect(Example.OFF, equals(0));
+  });
+
+  test('static & instance fields', () {
+    expect(Example.num, equals(121));
+    final aux = Example.aux;
+    expect(aux.value, equals(true));
+    aux.delete();
+    expect(C2.CONSTANT, equals(12));
+  });
+
+  test('static methods', () {
+    expect(Example.addInts(10, 15), equals(25));
+  });
+
+  test('instance methods', () {
+    final ex = Example();
+    expect(ex.getNum(), equals(Example.num));
+    final aux = Example.getAux();
+    expect(aux.getValue(), equals(true));
+    aux.setValue(false);
+    expect(aux.getValue(), equals(false));
+    aux.delete();
+    ex.delete();
+  });
+  test('simple json parsing test', () {
+    final json = JlString.fromString('[1, true, false, 2, 4]');
+    final factory = JsonFactory();
+    final parser = factory.createParser6(json);
+    final values = <bool>[];
+    while (!parser.isClosed()) {
+      final next = parser.nextToken();
+      values.add(next.isNumeric());
+      next.delete();
+    }
+    expect(
+        values, equals([false, true, false, false, true, true, false, false]));
+    parser.delete();
+    factory.delete();
+    json.delete();
+  });
+}
diff --git a/pkgs/jni_gen/test/jackson_core_test/.gitignore b/pkgs/jni_gen/test/jackson_core_test/.gitignore
new file mode 100644
index 0000000..0215812
--- /dev/null
+++ b/pkgs/jni_gen/test/jackson_core_test/.gitignore
@@ -0,0 +1,5 @@
+*.jar
+third_party/jar/**
+third_party/java/**
+third_party/test_lib/
+third_party/test_src/
diff --git a/pkgs/jni_gen/test/jackson_core_test/generate.dart b/pkgs/jni_gen/test/jackson_core_test/generate.dart
new file mode 100644
index 0000000..5d62592
--- /dev/null
+++ b/pkgs/jni_gen/test/jackson_core_test/generate.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:jni_gen/jni_gen.dart';
+import '../test_util/test_util.dart';
+
+const jacksonPreamble = '// Generated from jackson-core which is licensed under'
+    ' the Apache License 2.0.\n'
+    '// The following copyright from the original authors applies.\n'
+    '// See https://github.com/FasterXML/jackson-core/blob/2.14/LICENSE\n'
+    '//\n'
+    '// Copyright (c) 2007 - The Jackson Project Authors\n'
+    '// Licensed under the Apache License, Version 2.0 (the "License")\n'
+    '// you may not use this file except in compliance with the License.\n'
+    '// You may obtain a copy of the License at\n'
+    '//\n'
+    '//     http://www.apache.org/licenses/LICENSE-2.0\n'
+    '//\n'
+    '// Unless required by applicable law or agreed to in writing, software\n'
+    '// distributed under the License is distributed on an "AS IS" BASIS,\n'
+    '// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n'
+    '// See the License for the specific language governing permissions and\n'
+    '// limitations under the License.\n';
+
+Future<void> generate(
+    {bool isTest = false,
+    bool generateFullVersion = false,
+    bool useAsm = false}) async {
+  final deps = ['com.fasterxml.jackson.core:jackson-core:2.13.3'];
+  await generateBindings(
+    testName: 'jackson_core_test',
+    sourceDepNames: deps,
+    jarDepNames: deps,
+    useAsmBackend: useAsm,
+    preamble: jacksonPreamble,
+    isThirdParty: true,
+    classes: (generateFullVersion)
+        ? ['com.fasterxml.jackson.core']
+        : [
+            'com.fasterxml.jackson.core.JsonFactory',
+            'com.fasterxml.jackson.core.JsonParser',
+            'com.fasterxml.jackson.core.JsonToken',
+          ],
+    isGeneratedFileTest: isTest,
+    options: WrapperOptions(
+        fieldFilter: CombinedFieldFilter([
+          excludeAll<Field>([
+            ['com.fasterxml.jackson.core.JsonFactory', 'DEFAULT_QUOTE_CHAR'],
+            ['com.fasterxml.jackson.core.Base64Variant', 'PADDING_CHAR_NONE'],
+            ['com.fasterxml.jackson.core.base.ParserMinimalBase', 'CHAR_NULL'],
+            ['com.fasterxml.jackson.core.io.UTF32Reader', 'NC'],
+          ]),
+          CustomFieldFilter((decl, field) => !field.name.startsWith("_")),
+        ]),
+        methodFilter:
+            CustomMethodFilter((decl, method) => !method.name.startsWith('_'))),
+  );
+}
+
+void main() => generate(isTest: false);
diff --git a/pkgs/jni_gen/test/jackson_core_test/generated_files_test.dart b/pkgs/jni_gen/test/jackson_core_test/generated_files_test.dart
new file mode 100644
index 0000000..b9edc1b
--- /dev/null
+++ b/pkgs/jni_gen/test/jackson_core_test/generated_files_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:path/path.dart' hide equals;
+
+import 'package:test/test.dart';
+
+import '../test_util/test_util.dart';
+import 'generate.dart';
+
+const packageTestsDir = 'test';
+const testName = 'jackson_core_test';
+
+void main() async {
+  final generatedFilesRoot = join(packageTestsDir, testName, 'third_party');
+  await generate(isTest: true);
+  test("compare generated bindings for jackson_core", () {
+    compareDirs(
+        join(generatedFilesRoot, 'lib'), join(generatedFilesRoot, 'test_lib'));
+    compareDirs(
+        join(generatedFilesRoot, 'src'), join(generatedFilesRoot, 'test_src'));
+  });
+  Future<void> analyze() async {
+    final analyzeProc = await Process.start(
+        'dart', ['analyze', join('test', testName, 'third_party', 'test_lib')],
+        mode: ProcessStartMode.inheritStdio);
+    final exitCode = await analyzeProc.exitCode;
+    expect(exitCode, 0);
+  }
+
+  test(
+      'generate and analyze bindings for complete library, '
+      'not just required classes', () async {
+    await generate(isTest: true, generateFullVersion: true);
+    await analyze();
+  }, timeout: Timeout(Duration(minutes: 2)));
+  test('generate and analyze bindings using ASM', () async {
+    await generate(isTest: true, generateFullVersion: true, useAsm: true);
+    await analyze();
+  }, timeout: Timeout(Duration(minutes: 2)));
+  tearDown(() async {
+    for (var dirName in ['test_lib', 'test_src']) {
+      final dir = Directory(join('test', testName, 'third_party', dirName));
+      if (await dir.exists()) {
+        await dir.delete(recursive: true);
+      }
+    }
+  });
+}
diff --git a/pkgs/jni_gen/test/jackson_core_test/third_party/lib/com/fasterxml/jackson/core.dart b/pkgs/jni_gen/test/jackson_core_test/third_party/lib/com/fasterxml/jackson/core.dart
new file mode 100644
index 0000000..ee2de71
--- /dev/null
+++ b/pkgs/jni_gen/test/jackson_core_test/third_party/lib/com/fasterxml/jackson/core.dart
@@ -0,0 +1,4117 @@
+// Generated from jackson-core which is licensed under the Apache License 2.0.
+// The following copyright from the original authors applies.
+// See https://github.com/FasterXML/jackson-core/blob/2.14/LICENSE
+//
+// Copyright (c) 2007 - The Jackson Project Authors
+// Licensed under the Apache License, Version 2.0 (the "License")
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Autogenerated by jni_gen. DO NOT EDIT!
+
+// ignore_for_file: camel_case_types
+// ignore_for_file: non_constant_identifier_names
+// ignore_for_file: constant_identifier_names
+// ignore_for_file: annotate_overrides
+// ignore_for_file: no_leading_underscores_for_local_identifiers
+// ignore_for_file: unused_element
+
+import "dart:ffi" as ffi;
+
+import "package:jni/jni.dart" as jni;
+
+import "../../../init.dart" show jlookup;
+
+/// from: com.fasterxml.jackson.core.JsonFactory
+///
+/// The main factory class of Jackson package, used to configure and
+/// construct reader (aka parser, JsonParser)
+/// and writer (aka generator, JsonGenerator)
+/// instances.
+///
+/// Factory instances are thread-safe and reusable after configuration
+/// (if any). Typically applications and services use only a single
+/// globally shared factory instance, unless they need differently
+/// configured factories. Factory reuse is important if efficiency matters;
+/// most recycling of expensive construct is done on per-factory basis.
+///
+/// Creation of a factory instance is a light-weight operation,
+/// and since there is no need for pluggable alternative implementations
+/// (as there is no "standard" JSON processor API to implement),
+/// the default constructor is used for constructing factory
+/// instances.
+///@author Tatu Saloranta
+class JsonFactory extends jni.JlObject {
+  JsonFactory.fromRef(ffi.Pointer<ffi.Void> ref) : super.fromRef(ref);
+
+  /// from: private static final long serialVersionUID
+  static const serialVersionUID = 2;
+
+  /// from: static public final java.lang.String FORMAT_NAME_JSON
+  ///
+  /// Name used to identify JSON format
+  /// (and returned by \#getFormatName()
+  static const FORMAT_NAME_JSON = "JSON";
+
+  static final _getDEFAULT_FACTORY_FEATURE_FLAGS = jlookup<
+              ffi.NativeFunction<ffi.Int32 Function()>>(
+          "get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_FACTORY_FEATURE_FLAGS")
+      .asFunction<int Function()>();
+
+  /// from: static protected final int DEFAULT_FACTORY_FEATURE_FLAGS
+  ///
+  /// Bitfield (set of flags) of all factory features that are enabled by default.
+  static int get DEFAULT_FACTORY_FEATURE_FLAGS =>
+      _getDEFAULT_FACTORY_FEATURE_FLAGS();
+
+  static final _getDEFAULT_PARSER_FEATURE_FLAGS = jlookup<
+              ffi.NativeFunction<ffi.Int32 Function()>>(
+          "get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_PARSER_FEATURE_FLAGS")
+      .asFunction<int Function()>();
+
+  /// from: static protected final int DEFAULT_PARSER_FEATURE_FLAGS
+  ///
+  /// Bitfield (set of flags) of all parser features that are enabled
+  /// by default.
+  static int get DEFAULT_PARSER_FEATURE_FLAGS =>
+      _getDEFAULT_PARSER_FEATURE_FLAGS();
+
+  static final _getDEFAULT_GENERATOR_FEATURE_FLAGS = jlookup<
+              ffi.NativeFunction<ffi.Int32 Function()>>(
+          "get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_GENERATOR_FEATURE_FLAGS")
+      .asFunction<int Function()>();
+
+  /// from: static protected final int DEFAULT_GENERATOR_FEATURE_FLAGS
+  ///
+  /// Bitfield (set of flags) of all generator features that are enabled
+  /// by default.
+  static int get DEFAULT_GENERATOR_FEATURE_FLAGS =>
+      _getDEFAULT_GENERATOR_FEATURE_FLAGS();
+
+  static final _getDEFAULT_ROOT_VALUE_SEPARATOR = jlookup<
+              ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+          "get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_ROOT_VALUE_SEPARATOR")
+      .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: static public final com.fasterxml.jackson.core.SerializableString DEFAULT_ROOT_VALUE_SEPARATOR
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static jni.JlObject get DEFAULT_ROOT_VALUE_SEPARATOR =>
+      jni.JlObject.fromRef(_getDEFAULT_ROOT_VALUE_SEPARATOR());
+
+  static final _ctor =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "com_fasterxml_jackson_core_JsonFactory_ctor")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: public void <init>()
+  ///
+  /// Default constructor used to create factory instances.
+  /// Creation of a factory instance is a light-weight operation,
+  /// but it is still a good idea to reuse limited number of
+  /// factory instances (and quite often just a single instance):
+  /// factories are used as context for storing some reused
+  /// processing objects (such as symbol tables parsers use)
+  /// and this reuse only works within context of a single
+  /// factory instance.
+  JsonFactory() : super.fromRef(_ctor());
+
+  static final _ctor1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_ctor1")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public void <init>(com.fasterxml.jackson.core.ObjectCodec oc)
+  JsonFactory.ctor1(jni.JlObject oc) : super.fromRef(_ctor1(oc.reference));
+
+  static final _ctor2 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_ctor2")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: protected void <init>(com.fasterxml.jackson.core.JsonFactory src, com.fasterxml.jackson.core.ObjectCodec codec)
+  ///
+  /// Constructor used when copy()ing a factory instance.
+  ///@param src Original factory to copy settings from
+  ///@param codec Databinding-level codec to use, if any
+  ///@since 2.2.1
+  JsonFactory.ctor2(JsonFactory src, jni.JlObject codec)
+      : super.fromRef(_ctor2(src.reference, codec.reference));
+
+  static final _ctor3 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_ctor3")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public void <init>(com.fasterxml.jackson.core.JsonFactoryBuilder b)
+  ///
+  /// Constructor used by JsonFactoryBuilder for instantiation.
+  ///@param b Builder that contains settings to use
+  ///@since 2.10
+  JsonFactory.ctor3(jni.JlObject b) : super.fromRef(_ctor3(b.reference));
+
+  static final _ctor4 = jlookup<
+          ffi.NativeFunction<
+              ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                  ffi.Uint8)>>("com_fasterxml_jackson_core_JsonFactory_ctor4")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: protected void <init>(com.fasterxml.jackson.core.TSFBuilder<?,?> b, boolean bogus)
+  ///
+  /// Constructor for subtypes; needed to work around the fact that before 3.0,
+  /// this factory has cumbersome dual role as generic type as well as actual
+  /// implementation for json.
+  ///@param b Builder that contains settings to use
+  ///@param bogus Argument only needed to separate constructor signature; ignored
+  JsonFactory.ctor4(jni.JlObject b, bool bogus)
+      : super.fromRef(_ctor4(b.reference, bogus ? 1 : 0));
+
+  static final _rebuild = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_rebuild")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.TSFBuilder<?,?> rebuild()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that allows construction of differently configured factory, starting
+  /// with settings of this factory.
+  ///@return Builder instance to use
+  ///@since 2.10
+  jni.JlObject rebuild() => jni.JlObject.fromRef(_rebuild(reference));
+
+  static final _builder =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "com_fasterxml_jackson_core_JsonFactory_builder")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: static public com.fasterxml.jackson.core.TSFBuilder<?,?> builder()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Main factory method to use for constructing JsonFactory instances with
+  /// different configuration: creates and returns a builder for collecting configuration
+  /// settings; instance created by calling {@code build()} after all configuration
+  /// set.
+  ///
+  /// NOTE: signature unfortunately does not expose true implementation type; this
+  /// will be fixed in 3.0.
+  ///@return Builder instance to use
+  static jni.JlObject builder() => jni.JlObject.fromRef(_builder());
+
+  static final _copy = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_copy")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory copy()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing a new JsonFactory that has
+  /// the same settings as this instance, but is otherwise
+  /// independent (i.e. nothing is actually shared, symbol tables
+  /// are separate).
+  /// Note that ObjectCodec reference is not copied but is
+  /// set to null; caller typically needs to set it after calling
+  /// this method. Reason for this is that the codec is used for
+  /// callbacks, and assumption is that there is strict 1-to-1
+  /// mapping between codec, factory. Caller has to, then, explicitly
+  /// set codec after making the copy.
+  ///@return Copy of this factory instance
+  ///@since 2.1
+  JsonFactory copy() => JsonFactory.fromRef(_copy(reference));
+
+  static final _readResolve = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_readResolve")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: protected java.lang.Object readResolve()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that we need to override to actually make restoration go
+  /// through constructors etc: needed to allow JDK serializability of
+  /// factory instances.
+  ///
+  /// Note: must be overridden by sub-classes as well.
+  ///@return Newly constructed instance
+  jni.JlObject readResolve() => jni.JlObject.fromRef(_readResolve(reference));
+
+  static final _requiresPropertyOrdering =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonFactory_requiresPropertyOrdering")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean requiresPropertyOrdering()
+  ///
+  /// Introspection method that higher-level functionality may call
+  /// to see whether underlying data format requires a stable ordering
+  /// of object properties or not.
+  /// This is usually used for determining
+  /// whether to force a stable ordering (like alphabetic ordering by name)
+  /// if no ordering if explicitly specified.
+  ///
+  /// Default implementation returns <code>false</code> as JSON does NOT
+  /// require stable ordering. Formats that require ordering include positional
+  /// textual formats like <code>CSV</code>, and schema-based binary formats
+  /// like <code>Avro</code>.
+  ///@return Whether format supported by this factory
+  ///   requires Object properties to be ordered.
+  ///@since 2.3
+  bool requiresPropertyOrdering() => _requiresPropertyOrdering(reference) != 0;
+
+  static final _canHandleBinaryNatively =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonFactory_canHandleBinaryNatively")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean canHandleBinaryNatively()
+  ///
+  /// Introspection method that higher-level functionality may call
+  /// to see whether underlying data format can read and write binary
+  /// data natively; that is, embeded it as-is without using encodings
+  /// such as Base64.
+  ///
+  /// Default implementation returns <code>false</code> as JSON does not
+  /// support native access: all binary content must use Base64 encoding.
+  /// Most binary formats (like Smile and Avro) support native binary content.
+  ///@return Whether format supported by this factory
+  ///    supports native binary content
+  ///@since 2.3
+  bool canHandleBinaryNatively() => _canHandleBinaryNatively(reference) != 0;
+
+  static final _canUseCharArrays =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonFactory_canUseCharArrays")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean canUseCharArrays()
+  ///
+  /// Introspection method that can be used by base factory to check
+  /// whether access using <code>char[]</code> is something that actual
+  /// parser implementations can take advantage of, over having to
+  /// use java.io.Reader. Sub-types are expected to override
+  /// definition; default implementation (suitable for JSON) alleges
+  /// that optimization are possible; and thereby is likely to try
+  /// to access java.lang.String content by first copying it into
+  /// recyclable intermediate buffer.
+  ///@return Whether access to decoded textual content can be efficiently
+  ///   accessed using parser method {@code getTextCharacters()}.
+  ///@since 2.4
+  bool canUseCharArrays() => _canUseCharArrays(reference) != 0;
+
+  static final _canParseAsync =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonFactory_canParseAsync")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean canParseAsync()
+  ///
+  /// Introspection method that can be used to check whether this
+  /// factory can create non-blocking parsers: parsers that do not
+  /// use blocking I/O abstractions but instead use a
+  /// com.fasterxml.jackson.core.async.NonBlockingInputFeeder.
+  ///@return Whether this factory supports non-blocking ("async") parsing or
+  ///    not (and consequently whether {@code createNonBlockingXxx()} method(s) work)
+  ///@since 2.9
+  bool canParseAsync() => _canParseAsync(reference) != 0;
+
+  static final _getFormatReadFeatureType = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_getFormatReadFeatureType")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.Class<? extends com.fasterxml.jackson.core.FormatFeature> getFormatReadFeatureType()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  jni.JlObject getFormatReadFeatureType() =>
+      jni.JlObject.fromRef(_getFormatReadFeatureType(reference));
+
+  static final _getFormatWriteFeatureType = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_getFormatWriteFeatureType")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.Class<? extends com.fasterxml.jackson.core.FormatFeature> getFormatWriteFeatureType()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  jni.JlObject getFormatWriteFeatureType() =>
+      jni.JlObject.fromRef(_getFormatWriteFeatureType(reference));
+
+  static final _canUseSchema = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_canUseSchema")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean canUseSchema(com.fasterxml.jackson.core.FormatSchema schema)
+  ///
+  /// Method that can be used to quickly check whether given schema
+  /// is something that parsers and/or generators constructed by this
+  /// factory could use. Note that this means possible use, at the level
+  /// of data format (i.e. schema is for same data format as parsers and
+  /// generators this factory constructs); individual schema instances
+  /// may have further usage restrictions.
+  ///@param schema Schema instance to check
+  ///@return Whether parsers and generators constructed by this factory
+  ///   can use specified format schema instance
+  bool canUseSchema(jni.JlObject schema) =>
+      _canUseSchema(reference, schema.reference) != 0;
+
+  static final _getFormatName = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_getFormatName")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.String getFormatName()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that returns short textual id identifying format
+  /// this factory supports.
+  ///
+  /// Note: sub-classes should override this method; default
+  /// implementation will return null for all sub-classes
+  ///@return Name of the format handled by parsers, generators this factory creates
+  jni.JlString getFormatName() =>
+      jni.JlString.fromRef(_getFormatName(reference));
+
+  static final _hasFormat = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_hasFormat")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.format.MatchStrength hasFormat(com.fasterxml.jackson.core.format.InputAccessor acc)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  jni.JlObject hasFormat(jni.JlObject acc) =>
+      jni.JlObject.fromRef(_hasFormat(reference, acc.reference));
+
+  static final _requiresCustomCodec =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonFactory_requiresCustomCodec")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean requiresCustomCodec()
+  ///
+  /// Method that can be called to determine if a custom
+  /// ObjectCodec is needed for binding data parsed
+  /// using JsonParser constructed by this factory
+  /// (which typically also implies the same for serialization
+  /// with JsonGenerator).
+  ///@return True if custom codec is needed with parsers and
+  ///   generators created by this factory; false if a general
+  ///   ObjectCodec is enough
+  ///@since 2.1
+  bool requiresCustomCodec() => _requiresCustomCodec(reference) != 0;
+
+  static final _hasJSONFormat = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_hasJSONFormat")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: protected com.fasterxml.jackson.core.format.MatchStrength hasJSONFormat(com.fasterxml.jackson.core.format.InputAccessor acc)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  jni.JlObject hasJSONFormat(jni.JlObject acc) =>
+      jni.JlObject.fromRef(_hasJSONFormat(reference, acc.reference));
+
+  static final _version = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_version")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.Version version()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  jni.JlObject version() => jni.JlObject.fromRef(_version(reference));
+
+  static final _configure = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Uint8)>>(
+          "com_fasterxml_jackson_core_JsonFactory_configure")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public final com.fasterxml.jackson.core.JsonFactory configure(com.fasterxml.jackson.core.JsonFactory.Feature f, boolean state)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for enabling or disabling specified parser feature
+  /// (check JsonParser.Feature for list of features)
+  ///@param f Feature to enable/disable
+  ///@param state Whether to enable or disable the feature
+  ///@return This factory instance (to allow call chaining)
+  ///@deprecated since 2.10 use JsonFactoryBuilder\#configure(JsonFactory.Feature, boolean) instead
+  JsonFactory configure(JsonFactory_Feature f, bool state) =>
+      JsonFactory.fromRef(_configure(reference, f.reference, state ? 1 : 0));
+
+  static final _enable = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_enable")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory enable(com.fasterxml.jackson.core.JsonFactory.Feature f)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for enabling specified parser feature
+  /// (check JsonFactory.Feature for list of features)
+  ///@param f Feature to enable
+  ///@return This factory instance (to allow call chaining)
+  ///@deprecated since 2.10 use JsonFactoryBuilder\#configure(JsonFactory.Feature, boolean) instead
+  JsonFactory enable(JsonFactory_Feature f) =>
+      JsonFactory.fromRef(_enable(reference, f.reference));
+
+  static final _disable = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_disable")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory disable(com.fasterxml.jackson.core.JsonFactory.Feature f)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for disabling specified parser features
+  /// (check JsonFactory.Feature for list of features)
+  ///@param f Feature to disable
+  ///@return This factory instance (to allow call chaining)
+  ///@deprecated since 2.10 use JsonFactoryBuilder\#configure(JsonFactory.Feature, boolean) instead
+  JsonFactory disable(JsonFactory_Feature f) =>
+      JsonFactory.fromRef(_disable(reference, f.reference));
+
+  static final _isEnabled = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_isEnabled")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final boolean isEnabled(com.fasterxml.jackson.core.JsonFactory.Feature f)
+  ///
+  /// Checked whether specified parser feature is enabled.
+  ///@param f Feature to check
+  ///@return True if the specified feature is enabled
+  bool isEnabled(JsonFactory_Feature f) =>
+      _isEnabled(reference, f.reference) != 0;
+
+  static final _getParserFeatures =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonFactory_getParserFeatures")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final int getParserFeatures()
+  int getParserFeatures() => _getParserFeatures(reference);
+
+  static final _getGeneratorFeatures =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonFactory_getGeneratorFeatures")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final int getGeneratorFeatures()
+  int getGeneratorFeatures() => _getGeneratorFeatures(reference);
+
+  static final _getFormatParserFeatures =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonFactory_getFormatParserFeatures")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int getFormatParserFeatures()
+  int getFormatParserFeatures() => _getFormatParserFeatures(reference);
+
+  static final _getFormatGeneratorFeatures = jlookup<
+              ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_getFormatGeneratorFeatures")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int getFormatGeneratorFeatures()
+  int getFormatGeneratorFeatures() => _getFormatGeneratorFeatures(reference);
+
+  static final _configure1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Uint8)>>(
+          "com_fasterxml_jackson_core_JsonFactory_configure1")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public final com.fasterxml.jackson.core.JsonFactory configure(com.fasterxml.jackson.core.JsonParser.Feature f, boolean state)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for enabling or disabling specified parser feature
+  /// (check JsonParser.Feature for list of features)
+  ///@param f Feature to enable/disable
+  ///@param state Whether to enable or disable the feature
+  ///@return This factory instance (to allow call chaining)
+  JsonFactory configure1(JsonParser_Feature f, bool state) =>
+      JsonFactory.fromRef(_configure1(reference, f.reference, state ? 1 : 0));
+
+  static final _enable1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_enable1")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory enable(com.fasterxml.jackson.core.JsonParser.Feature f)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for enabling specified parser feature
+  /// (check JsonParser.Feature for list of features)
+  ///@param f Feature to enable
+  ///@return This factory instance (to allow call chaining)
+  JsonFactory enable1(JsonParser_Feature f) =>
+      JsonFactory.fromRef(_enable1(reference, f.reference));
+
+  static final _disable1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_disable1")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory disable(com.fasterxml.jackson.core.JsonParser.Feature f)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for disabling specified parser features
+  /// (check JsonParser.Feature for list of features)
+  ///@param f Feature to disable
+  ///@return This factory instance (to allow call chaining)
+  JsonFactory disable1(JsonParser_Feature f) =>
+      JsonFactory.fromRef(_disable1(reference, f.reference));
+
+  static final _isEnabled1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_isEnabled1")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final boolean isEnabled(com.fasterxml.jackson.core.JsonParser.Feature f)
+  ///
+  /// Method for checking if the specified parser feature is enabled.
+  ///@param f Feature to check
+  ///@return True if specified feature is enabled
+  bool isEnabled1(JsonParser_Feature f) =>
+      _isEnabled1(reference, f.reference) != 0;
+
+  static final _isEnabled2 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_isEnabled2")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final boolean isEnabled(com.fasterxml.jackson.core.StreamReadFeature f)
+  ///
+  /// Method for checking if the specified stream read feature is enabled.
+  ///@param f Feature to check
+  ///@return True if specified feature is enabled
+  ///@since 2.10
+  bool isEnabled2(jni.JlObject f) => _isEnabled2(reference, f.reference) != 0;
+
+  static final _getInputDecorator = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_getInputDecorator")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.io.InputDecorator getInputDecorator()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for getting currently configured input decorator (if any;
+  /// there is no default decorator).
+  ///@return InputDecorator configured, if any
+  jni.JlObject getInputDecorator() =>
+      jni.JlObject.fromRef(_getInputDecorator(reference));
+
+  static final _setInputDecorator = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_setInputDecorator")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory setInputDecorator(com.fasterxml.jackson.core.io.InputDecorator d)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for overriding currently configured input decorator
+  ///@param d Decorator to configure for this factory, if any ({@code null} if none)
+  ///@return This factory instance (to allow call chaining)
+  ///@deprecated Since 2.10 use JsonFactoryBuilder\#inputDecorator(InputDecorator) instead
+  JsonFactory setInputDecorator(jni.JlObject d) =>
+      JsonFactory.fromRef(_setInputDecorator(reference, d.reference));
+
+  static final _configure2 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Uint8)>>(
+          "com_fasterxml_jackson_core_JsonFactory_configure2")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public final com.fasterxml.jackson.core.JsonFactory configure(com.fasterxml.jackson.core.JsonGenerator.Feature f, boolean state)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for enabling or disabling specified generator feature
+  /// (check JsonGenerator.Feature for list of features)
+  ///@param f Feature to enable/disable
+  ///@param state Whether to enable or disable the feature
+  ///@return This factory instance (to allow call chaining)
+  JsonFactory configure2(jni.JlObject f, bool state) =>
+      JsonFactory.fromRef(_configure2(reference, f.reference, state ? 1 : 0));
+
+  static final _enable2 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_enable2")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory enable(com.fasterxml.jackson.core.JsonGenerator.Feature f)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for enabling specified generator features
+  /// (check JsonGenerator.Feature for list of features)
+  ///@param f Feature to enable
+  ///@return This factory instance (to allow call chaining)
+  JsonFactory enable2(jni.JlObject f) =>
+      JsonFactory.fromRef(_enable2(reference, f.reference));
+
+  static final _disable2 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_disable2")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory disable(com.fasterxml.jackson.core.JsonGenerator.Feature f)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for disabling specified generator feature
+  /// (check JsonGenerator.Feature for list of features)
+  ///@param f Feature to disable
+  ///@return This factory instance (to allow call chaining)
+  JsonFactory disable2(jni.JlObject f) =>
+      JsonFactory.fromRef(_disable2(reference, f.reference));
+
+  static final _isEnabled3 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_isEnabled3")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final boolean isEnabled(com.fasterxml.jackson.core.JsonGenerator.Feature f)
+  ///
+  /// Check whether specified generator feature is enabled.
+  ///@param f Feature to check
+  ///@return Whether specified feature is enabled
+  bool isEnabled3(jni.JlObject f) => _isEnabled3(reference, f.reference) != 0;
+
+  static final _isEnabled4 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_isEnabled4")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final boolean isEnabled(com.fasterxml.jackson.core.StreamWriteFeature f)
+  ///
+  /// Check whether specified stream write feature is enabled.
+  ///@param f Feature to check
+  ///@return Whether specified feature is enabled
+  ///@since 2.10
+  bool isEnabled4(jni.JlObject f) => _isEnabled4(reference, f.reference) != 0;
+
+  static final _getCharacterEscapes = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_getCharacterEscapes")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.io.CharacterEscapes getCharacterEscapes()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for accessing custom escapes factory uses for JsonGenerators
+  /// it creates.
+  ///@return Configured {@code CharacterEscapes}, if any; {@code null} if none
+  jni.JlObject getCharacterEscapes() =>
+      jni.JlObject.fromRef(_getCharacterEscapes(reference));
+
+  static final _setCharacterEscapes = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_setCharacterEscapes")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory setCharacterEscapes(com.fasterxml.jackson.core.io.CharacterEscapes esc)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for defining custom escapes factory uses for JsonGenerators
+  /// it creates.
+  ///@param esc CharaterEscapes to set (or {@code null} for "none")
+  ///@return This factory instance (to allow call chaining)
+  JsonFactory setCharacterEscapes(jni.JlObject esc) =>
+      JsonFactory.fromRef(_setCharacterEscapes(reference, esc.reference));
+
+  static final _getOutputDecorator = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_getOutputDecorator")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.io.OutputDecorator getOutputDecorator()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for getting currently configured output decorator (if any;
+  /// there is no default decorator).
+  ///@return OutputDecorator configured for generators factory creates, if any;
+  ///    {@code null} if none.
+  jni.JlObject getOutputDecorator() =>
+      jni.JlObject.fromRef(_getOutputDecorator(reference));
+
+  static final _setOutputDecorator = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_setOutputDecorator")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory setOutputDecorator(com.fasterxml.jackson.core.io.OutputDecorator d)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for overriding currently configured output decorator
+  ///@return This factory instance (to allow call chaining)
+  ///@param d Output decorator to use, if any
+  ///@deprecated Since 2.10 use JsonFactoryBuilder\#outputDecorator(OutputDecorator) instead
+  JsonFactory setOutputDecorator(jni.JlObject d) =>
+      JsonFactory.fromRef(_setOutputDecorator(reference, d.reference));
+
+  static final _setRootValueSeparator = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_setRootValueSeparator")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory setRootValueSeparator(java.lang.String sep)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that allows overriding String used for separating root-level
+  /// JSON values (default is single space character)
+  ///@param sep Separator to use, if any; null means that no separator is
+  ///   automatically added
+  ///@return This factory instance (to allow call chaining)
+  JsonFactory setRootValueSeparator(jni.JlString sep) =>
+      JsonFactory.fromRef(_setRootValueSeparator(reference, sep.reference));
+
+  static final _getRootValueSeparator = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_getRootValueSeparator")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.String getRootValueSeparator()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// @return Root value separator configured, if any
+  jni.JlString getRootValueSeparator() =>
+      jni.JlString.fromRef(_getRootValueSeparator(reference));
+
+  static final _setCodec = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_setCodec")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonFactory setCodec(com.fasterxml.jackson.core.ObjectCodec oc)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for associating a ObjectCodec (typically
+  /// a <code>com.fasterxml.jackson.databind.ObjectMapper</code>)
+  /// with this factory (and more importantly, parsers and generators
+  /// it constructs). This is needed to use data-binding methods
+  /// of JsonParser and JsonGenerator instances.
+  ///@param oc Codec to use
+  ///@return This factory instance (to allow call chaining)
+  JsonFactory setCodec(jni.JlObject oc) =>
+      JsonFactory.fromRef(_setCodec(reference, oc.reference));
+
+  static final _getCodec = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_getCodec")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.ObjectCodec getCodec()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  jni.JlObject getCodec() => jni.JlObject.fromRef(_getCodec(reference));
+
+  static final _createParser = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createParser")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.io.File f)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing JSON parser instance to parse
+  /// contents of specified file.
+  ///
+  ///
+  /// Encoding is auto-detected from contents according to JSON
+  /// specification recommended mechanism. Json specification
+  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
+  /// so auto-detection implemented only for this charsets.
+  /// For other charsets use \#createParser(java.io.Reader).
+  ///
+  ///
+  /// Underlying input stream (needed for reading contents)
+  /// will be __owned__ (and managed, i.e. closed as need be) by
+  /// the parser, since caller has no access to it.
+  ///@param f File that contains JSON content to parse
+  ///@since 2.1
+  JsonParser createParser(jni.JlObject f) =>
+      JsonParser.fromRef(_createParser(reference, f.reference));
+
+  static final _createParser1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createParser1")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.net.URL url)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing JSON parser instance to parse
+  /// contents of resource reference by given URL.
+  ///
+  /// Encoding is auto-detected from contents according to JSON
+  /// specification recommended mechanism. Json specification
+  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
+  /// so auto-detection implemented only for this charsets.
+  /// For other charsets use \#createParser(java.io.Reader).
+  ///
+  /// Underlying input stream (needed for reading contents)
+  /// will be __owned__ (and managed, i.e. closed as need be) by
+  /// the parser, since caller has no access to it.
+  ///@param url URL pointing to resource that contains JSON content to parse
+  ///@since 2.1
+  JsonParser createParser1(jni.JlObject url) =>
+      JsonParser.fromRef(_createParser1(reference, url.reference));
+
+  static final _createParser2 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createParser2")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.io.InputStream in)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing JSON parser instance to parse
+  /// the contents accessed via specified input stream.
+  ///
+  /// The input stream will __not be owned__ by
+  /// the parser, it will still be managed (i.e. closed if
+  /// end-of-stream is reacher, or parser close method called)
+  /// if (and only if) com.fasterxml.jackson.core.StreamReadFeature\#AUTO_CLOSE_SOURCE
+  /// is enabled.
+  ///
+  ///
+  /// Note: no encoding argument is taken since it can always be
+  /// auto-detected as suggested by JSON RFC. Json specification
+  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
+  /// so auto-detection implemented only for this charsets.
+  /// For other charsets use \#createParser(java.io.Reader).
+  ///@param in InputStream to use for reading JSON content to parse
+  ///@since 2.1
+  JsonParser createParser2(jni.JlObject in0) =>
+      JsonParser.fromRef(_createParser2(reference, in0.reference));
+
+  static final _createParser3 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createParser3")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.io.Reader r)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing parser for parsing
+  /// the contents accessed via specified Reader.
+  ///
+  /// The read stream will __not be owned__ by
+  /// the parser, it will still be managed (i.e. closed if
+  /// end-of-stream is reacher, or parser close method called)
+  /// if (and only if) com.fasterxml.jackson.core.StreamReadFeature\#AUTO_CLOSE_SOURCE
+  /// is enabled.
+  ///@param r Reader to use for reading JSON content to parse
+  ///@since 2.1
+  JsonParser createParser3(jni.JlObject r) =>
+      JsonParser.fromRef(_createParser3(reference, r.reference));
+
+  static final _createParser4 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createParser4")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createParser(byte[] data)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing parser for parsing
+  /// the contents of given byte array.
+  ///@since 2.1
+  JsonParser createParser4(jni.JlObject data) =>
+      JsonParser.fromRef(_createParser4(reference, data.reference));
+
+  static final _createParser5 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Int32, ffi.Int32)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createParser5")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, int, int)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createParser(byte[] data, int offset, int len)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing parser for parsing
+  /// the contents of given byte array.
+  ///@param data Buffer that contains data to parse
+  ///@param offset Offset of the first data byte within buffer
+  ///@param len Length of contents to parse within buffer
+  ///@since 2.1
+  JsonParser createParser5(jni.JlObject data, int offset, int len) =>
+      JsonParser.fromRef(
+          _createParser5(reference, data.reference, offset, len));
+
+  static final _createParser6 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createParser6")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.lang.String content)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing parser for parsing
+  /// contents of given String.
+  ///@since 2.1
+  JsonParser createParser6(jni.JlString content) =>
+      JsonParser.fromRef(_createParser6(reference, content.reference));
+
+  static final _createParser7 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createParser7")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createParser(char[] content)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing parser for parsing
+  /// contents of given char array.
+  ///@since 2.4
+  JsonParser createParser7(jni.JlObject content) =>
+      JsonParser.fromRef(_createParser7(reference, content.reference));
+
+  static final _createParser8 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Int32, ffi.Int32)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createParser8")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, int, int)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createParser(char[] content, int offset, int len)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing parser for parsing contents of given char array.
+  ///@since 2.4
+  JsonParser createParser8(jni.JlObject content, int offset, int len) =>
+      JsonParser.fromRef(
+          _createParser8(reference, content.reference, offset, len));
+
+  static final _createParser9 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createParser9")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.io.DataInput in)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Optional method for constructing parser for reading contents from specified DataInput
+  /// instance.
+  ///
+  /// If this factory does not support DataInput as source,
+  /// will throw UnsupportedOperationException
+  ///@since 2.8
+  JsonParser createParser9(jni.JlObject in0) =>
+      JsonParser.fromRef(_createParser9(reference, in0.reference));
+
+  static final _createNonBlockingByteArrayParser = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createNonBlockingByteArrayParser")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createNonBlockingByteArrayParser()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Optional method for constructing parser for non-blocking parsing
+  /// via com.fasterxml.jackson.core.async.ByteArrayFeeder
+  /// interface (accessed using JsonParser\#getNonBlockingInputFeeder()
+  /// from constructed instance).
+  ///
+  /// If this factory does not support non-blocking parsing (either at all,
+  /// or from byte array),
+  /// will throw UnsupportedOperationException.
+  ///
+  /// Note that JSON-backed factory only supports parsing of UTF-8 encoded JSON content
+  /// (and US-ASCII since it is proper subset); other encodings are not supported
+  /// at this point.
+  ///@since 2.9
+  JsonParser createNonBlockingByteArrayParser() =>
+      JsonParser.fromRef(_createNonBlockingByteArrayParser(reference));
+
+  static final _createGenerator = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createGenerator")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.OutputStream out, com.fasterxml.jackson.core.JsonEncoding enc)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing JSON generator for writing JSON content
+  /// using specified output stream.
+  /// Encoding to use must be specified, and needs to be one of available
+  /// types (as per JSON specification).
+  ///
+  /// Underlying stream __is NOT owned__ by the generator constructed,
+  /// so that generator will NOT close the output stream when
+  /// JsonGenerator\#close is called (unless auto-closing
+  /// feature,
+  /// com.fasterxml.jackson.core.JsonGenerator.Feature\#AUTO_CLOSE_TARGET
+  /// is enabled).
+  /// Using application needs to close it explicitly if this is the case.
+  ///
+  /// Note: there are formats that use fixed encoding (like most binary data formats)
+  /// and that ignore passed in encoding.
+  ///@param out OutputStream to use for writing JSON content
+  ///@param enc Character encoding to use
+  ///@since 2.1
+  jni.JlObject createGenerator(jni.JlObject out, jni.JlObject enc) =>
+      jni.JlObject.fromRef(
+          _createGenerator(reference, out.reference, enc.reference));
+
+  static final _createGenerator1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createGenerator1")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.OutputStream out)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Convenience method for constructing generator that uses default
+  /// encoding of the format (UTF-8 for JSON and most other data formats).
+  ///
+  /// Note: there are formats that use fixed encoding (like most binary data formats).
+  ///@since 2.1
+  jni.JlObject createGenerator1(jni.JlObject out) =>
+      jni.JlObject.fromRef(_createGenerator1(reference, out.reference));
+
+  static final _createGenerator2 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createGenerator2")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.Writer w)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing JSON generator for writing JSON content
+  /// using specified Writer.
+  ///
+  /// Underlying stream __is NOT owned__ by the generator constructed,
+  /// so that generator will NOT close the Reader when
+  /// JsonGenerator\#close is called (unless auto-closing
+  /// feature,
+  /// com.fasterxml.jackson.core.JsonGenerator.Feature\#AUTO_CLOSE_TARGET is enabled).
+  /// Using application needs to close it explicitly.
+  ///@since 2.1
+  ///@param w Writer to use for writing JSON content
+  jni.JlObject createGenerator2(jni.JlObject w) =>
+      jni.JlObject.fromRef(_createGenerator2(reference, w.reference));
+
+  static final _createGenerator3 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createGenerator3")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.File f, com.fasterxml.jackson.core.JsonEncoding enc)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing JSON generator for writing JSON content
+  /// to specified file, overwriting contents it might have (or creating
+  /// it if such file does not yet exist).
+  /// Encoding to use must be specified, and needs to be one of available
+  /// types (as per JSON specification).
+  ///
+  /// Underlying stream __is owned__ by the generator constructed,
+  /// i.e. generator will handle closing of file when
+  /// JsonGenerator\#close is called.
+  ///@param f File to write contents to
+  ///@param enc Character encoding to use
+  ///@since 2.1
+  jni.JlObject createGenerator3(jni.JlObject f, jni.JlObject enc) =>
+      jni.JlObject.fromRef(
+          _createGenerator3(reference, f.reference, enc.reference));
+
+  static final _createGenerator4 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createGenerator4")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.DataOutput out, com.fasterxml.jackson.core.JsonEncoding enc)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing generator for writing content using specified
+  /// DataOutput instance.
+  ///@since 2.8
+  jni.JlObject createGenerator4(jni.JlObject out, jni.JlObject enc) =>
+      jni.JlObject.fromRef(
+          _createGenerator4(reference, out.reference, enc.reference));
+
+  static final _createGenerator5 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createGenerator5")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.DataOutput out)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Convenience method for constructing generator that uses default
+  /// encoding of the format (UTF-8 for JSON and most other data formats).
+  ///
+  /// Note: there are formats that use fixed encoding (like most binary data formats).
+  ///@since 2.8
+  jni.JlObject createGenerator5(jni.JlObject out) =>
+      jni.JlObject.fromRef(_createGenerator5(reference, out.reference));
+
+  static final _createJsonParser = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createJsonParser")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(java.io.File f)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing JSON parser instance to parse
+  /// contents of specified file.
+  ///
+  /// Encoding is auto-detected from contents according to JSON
+  /// specification recommended mechanism. Json specification
+  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
+  /// so auto-detection implemented only for this charsets.
+  /// For other charsets use \#createParser(java.io.Reader).
+  ///
+  ///
+  /// Underlying input stream (needed for reading contents)
+  /// will be __owned__ (and managed, i.e. closed as need be) by
+  /// the parser, since caller has no access to it.
+  ///@param f File that contains JSON content to parse
+  ///@return Parser constructed
+  ///@throws IOException if parser initialization fails due to I/O (read) problem
+  ///@throws JsonParseException if parser initialization fails due to content decoding problem
+  ///@deprecated Since 2.2, use \#createParser(File) instead.
+  JsonParser createJsonParser(jni.JlObject f) =>
+      JsonParser.fromRef(_createJsonParser(reference, f.reference));
+
+  static final _createJsonParser1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createJsonParser1")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(java.net.URL url)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing JSON parser instance to parse
+  /// contents of resource reference by given URL.
+  ///
+  /// Encoding is auto-detected from contents according to JSON
+  /// specification recommended mechanism. Json specification
+  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
+  /// so auto-detection implemented only for this charsets.
+  /// For other charsets use \#createParser(java.io.Reader).
+  ///
+  /// Underlying input stream (needed for reading contents)
+  /// will be __owned__ (and managed, i.e. closed as need be) by
+  /// the parser, since caller has no access to it.
+  ///@param url URL pointing to resource that contains JSON content to parse
+  ///@return Parser constructed
+  ///@throws IOException if parser initialization fails due to I/O (read) problem
+  ///@throws JsonParseException if parser initialization fails due to content decoding problem
+  ///@deprecated Since 2.2, use \#createParser(URL) instead.
+  JsonParser createJsonParser1(jni.JlObject url) =>
+      JsonParser.fromRef(_createJsonParser1(reference, url.reference));
+
+  static final _createJsonParser2 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createJsonParser2")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(java.io.InputStream in)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing JSON parser instance to parse
+  /// the contents accessed via specified input stream.
+  ///
+  /// The input stream will __not be owned__ by
+  /// the parser, it will still be managed (i.e. closed if
+  /// end-of-stream is reacher, or parser close method called)
+  /// if (and only if) com.fasterxml.jackson.core.JsonParser.Feature\#AUTO_CLOSE_SOURCE
+  /// is enabled.
+  ///
+  ///
+  /// Note: no encoding argument is taken since it can always be
+  /// auto-detected as suggested by JSON RFC. Json specification
+  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
+  /// so auto-detection implemented only for this charsets.
+  /// For other charsets use \#createParser(java.io.Reader).
+  ///@param in InputStream to use for reading JSON content to parse
+  ///@return Parser constructed
+  ///@throws IOException if parser initialization fails due to I/O (read) problem
+  ///@throws JsonParseException if parser initialization fails due to content decoding problem
+  ///@deprecated Since 2.2, use \#createParser(InputStream) instead.
+  JsonParser createJsonParser2(jni.JlObject in0) =>
+      JsonParser.fromRef(_createJsonParser2(reference, in0.reference));
+
+  static final _createJsonParser3 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createJsonParser3")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(java.io.Reader r)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing parser for parsing
+  /// the contents accessed via specified Reader.
+  ///
+  /// The read stream will __not be owned__ by
+  /// the parser, it will still be managed (i.e. closed if
+  /// end-of-stream is reacher, or parser close method called)
+  /// if (and only if) com.fasterxml.jackson.core.JsonParser.Feature\#AUTO_CLOSE_SOURCE
+  /// is enabled.
+  ///@param r Reader to use for reading JSON content to parse
+  ///@return Parser constructed
+  ///@throws IOException if parser initialization fails due to I/O (read) problem
+  ///@throws JsonParseException if parser initialization fails due to content decoding problem
+  ///@deprecated Since 2.2, use \#createParser(Reader) instead.
+  JsonParser createJsonParser3(jni.JlObject r) =>
+      JsonParser.fromRef(_createJsonParser3(reference, r.reference));
+
+  static final _createJsonParser4 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createJsonParser4")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(byte[] data)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing parser for parsing the contents of given byte array.
+  ///@param data Input content to parse
+  ///@return Parser constructed
+  ///@throws IOException if parser initialization fails due to I/O (read) problem
+  ///@throws JsonParseException if parser initialization fails due to content decoding problem
+  ///@deprecated Since 2.2, use \#createParser(byte[]) instead.
+  JsonParser createJsonParser4(jni.JlObject data) =>
+      JsonParser.fromRef(_createJsonParser4(reference, data.reference));
+
+  static final _createJsonParser5 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Int32, ffi.Int32)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createJsonParser5")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, int, int)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(byte[] data, int offset, int len)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing parser for parsing
+  /// the contents of given byte array.
+  ///@param data Buffer that contains data to parse
+  ///@param offset Offset of the first data byte within buffer
+  ///@param len Length of contents to parse within buffer
+  ///@return Parser constructed
+  ///@throws IOException if parser initialization fails due to I/O (read) problem
+  ///@throws JsonParseException if parser initialization fails due to content decoding problem
+  ///@deprecated Since 2.2, use \#createParser(byte[],int,int) instead.
+  JsonParser createJsonParser5(jni.JlObject data, int offset, int len) =>
+      JsonParser.fromRef(
+          _createJsonParser5(reference, data.reference, offset, len));
+
+  static final _createJsonParser6 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createJsonParser6")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(java.lang.String content)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing parser for parsing
+  /// contents of given String.
+  ///@param content Input content to parse
+  ///@return Parser constructed
+  ///@throws IOException if parser initialization fails due to I/O (read) problem
+  ///@throws JsonParseException if parser initialization fails due to content decoding problem
+  ///@deprecated Since 2.2, use \#createParser(String) instead.
+  JsonParser createJsonParser6(jni.JlString content) =>
+      JsonParser.fromRef(_createJsonParser6(reference, content.reference));
+
+  static final _createJsonGenerator = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createJsonGenerator")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonGenerator createJsonGenerator(java.io.OutputStream out, com.fasterxml.jackson.core.JsonEncoding enc)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing JSON generator for writing JSON content
+  /// using specified output stream.
+  /// Encoding to use must be specified, and needs to be one of available
+  /// types (as per JSON specification).
+  ///
+  /// Underlying stream __is NOT owned__ by the generator constructed,
+  /// so that generator will NOT close the output stream when
+  /// JsonGenerator\#close is called (unless auto-closing
+  /// feature,
+  /// com.fasterxml.jackson.core.JsonGenerator.Feature\#AUTO_CLOSE_TARGET
+  /// is enabled).
+  /// Using application needs to close it explicitly if this is the case.
+  ///
+  /// Note: there are formats that use fixed encoding (like most binary data formats)
+  /// and that ignore passed in encoding.
+  ///@param out OutputStream to use for writing JSON content
+  ///@param enc Character encoding to use
+  ///@return Generator constructed
+  ///@throws IOException if parser initialization fails due to I/O (write) problem
+  ///@deprecated Since 2.2, use \#createGenerator(OutputStream, JsonEncoding) instead.
+  jni.JlObject createJsonGenerator(jni.JlObject out, jni.JlObject enc) =>
+      jni.JlObject.fromRef(
+          _createJsonGenerator(reference, out.reference, enc.reference));
+
+  static final _createJsonGenerator1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createJsonGenerator1")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonGenerator createJsonGenerator(java.io.Writer out)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for constructing JSON generator for writing JSON content
+  /// using specified Writer.
+  ///
+  /// Underlying stream __is NOT owned__ by the generator constructed,
+  /// so that generator will NOT close the Reader when
+  /// JsonGenerator\#close is called (unless auto-closing
+  /// feature,
+  /// com.fasterxml.jackson.core.JsonGenerator.Feature\#AUTO_CLOSE_TARGET is enabled).
+  /// Using application needs to close it explicitly.
+  ///@param out Writer to use for writing JSON content
+  ///@return Generator constructed
+  ///@throws IOException if parser initialization fails due to I/O (write) problem
+  ///@deprecated Since 2.2, use \#createGenerator(Writer) instead.
+  jni.JlObject createJsonGenerator1(jni.JlObject out) =>
+      jni.JlObject.fromRef(_createJsonGenerator1(reference, out.reference));
+
+  static final _createJsonGenerator2 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory_createJsonGenerator2")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonGenerator createJsonGenerator(java.io.OutputStream out)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Convenience method for constructing generator that uses default
+  /// encoding of the format (UTF-8 for JSON and most other data formats).
+  ///
+  /// Note: there are formats that use fixed encoding (like most binary data formats).
+  ///@param out OutputStream to use for writing JSON content
+  ///@return Generator constructed
+  ///@throws IOException if parser initialization fails due to I/O (write) problem
+  ///@deprecated Since 2.2, use \#createGenerator(OutputStream) instead.
+  jni.JlObject createJsonGenerator2(jni.JlObject out) =>
+      jni.JlObject.fromRef(_createJsonGenerator2(reference, out.reference));
+}
+
+/// from: com.fasterxml.jackson.core.JsonFactory$Feature
+///
+/// Enumeration that defines all on/off features that can only be
+/// changed for JsonFactory.
+class JsonFactory_Feature extends jni.JlObject {
+  JsonFactory_Feature.fromRef(ffi.Pointer<ffi.Void> ref) : super.fromRef(ref);
+
+  static final _values =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "com_fasterxml_jackson_core_JsonFactory__Feature_values")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: static public com.fasterxml.jackson.core.JsonFactory.Feature[] values()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static jni.JlObject values() => jni.JlObject.fromRef(_values());
+
+  static final _valueOf = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory__Feature_valueOf")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: static public com.fasterxml.jackson.core.JsonFactory.Feature valueOf(java.lang.String name)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static JsonFactory_Feature valueOf(jni.JlString name) =>
+      JsonFactory_Feature.fromRef(_valueOf(name.reference));
+
+  static final _collectDefaults =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function()>>(
+              "com_fasterxml_jackson_core_JsonFactory__Feature_collectDefaults")
+          .asFunction<int Function()>();
+
+  /// from: static public int collectDefaults()
+  ///
+  /// Method that calculates bit set (flags) of all features that
+  /// are enabled by default.
+  ///@return Bit field of features enabled by default
+  static int collectDefaults() => _collectDefaults();
+
+  static final _ctor =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Uint8)>>(
+              "com_fasterxml_jackson_core_JsonFactory__Feature_ctor")
+          .asFunction<ffi.Pointer<ffi.Void> Function(int)>();
+
+  /// from: private void <init>(boolean defaultState)
+  JsonFactory_Feature(bool defaultState)
+      : super.fromRef(_ctor(defaultState ? 1 : 0));
+
+  static final _enabledByDefault = jlookup<
+              ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonFactory__Feature_enabledByDefault")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean enabledByDefault()
+  bool enabledByDefault() => _enabledByDefault(reference) != 0;
+
+  static final _enabledIn = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(ffi.Pointer<ffi.Void>, ffi.Int32)>>(
+          "com_fasterxml_jackson_core_JsonFactory__Feature_enabledIn")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public boolean enabledIn(int flags)
+  bool enabledIn(int flags) => _enabledIn(reference, flags) != 0;
+
+  static final _getMask =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonFactory__Feature_getMask")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int getMask()
+  int getMask() => _getMask(reference);
+}
+
+/// from: com.fasterxml.jackson.core.JsonParser
+///
+/// Base class that defines public API for reading JSON content.
+/// Instances are created using factory methods of
+/// a JsonFactory instance.
+///@author Tatu Saloranta
+class JsonParser extends jni.JlObject {
+  JsonParser.fromRef(ffi.Pointer<ffi.Void> ref) : super.fromRef(ref);
+
+  /// from: private static final int MIN_BYTE_I
+  static const MIN_BYTE_I = -128;
+
+  /// from: private static final int MAX_BYTE_I
+  static const MAX_BYTE_I = 255;
+
+  /// from: private static final int MIN_SHORT_I
+  static const MIN_SHORT_I = -32768;
+
+  /// from: private static final int MAX_SHORT_I
+  static const MAX_SHORT_I = 32767;
+
+  static final _getDEFAULT_READ_CAPABILITIES = jlookup<
+              ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+          "get_com_fasterxml_jackson_core_JsonParser_DEFAULT_READ_CAPABILITIES")
+      .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: static protected final com.fasterxml.jackson.core.util.JacksonFeatureSet<com.fasterxml.jackson.core.StreamReadCapability> DEFAULT_READ_CAPABILITIES
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Default set of StreamReadCapabilityies that may be used as
+  /// basis for format-specific readers (or as bogus instance if non-null
+  /// set needs to be passed).
+  ///@since 2.12
+  static jni.JlObject get DEFAULT_READ_CAPABILITIES =>
+      jni.JlObject.fromRef(_getDEFAULT_READ_CAPABILITIES());
+
+  static final _ctor =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "com_fasterxml_jackson_core_JsonParser_ctor")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: protected void <init>()
+  JsonParser() : super.fromRef(_ctor());
+
+  static final _ctor1 =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Int32)>>(
+              "com_fasterxml_jackson_core_JsonParser_ctor1")
+          .asFunction<ffi.Pointer<ffi.Void> Function(int)>();
+
+  /// from: protected void <init>(int features)
+  JsonParser.ctor1(int features) : super.fromRef(_ctor1(features));
+
+  static final _getCodec = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getCodec")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract com.fasterxml.jackson.core.ObjectCodec getCodec()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Accessor for ObjectCodec associated with this
+  /// parser, if any. Codec is used by \#readValueAs(Class)
+  /// method (and its variants).
+  ///@return Codec assigned to this parser, if any; {@code null} if none
+  jni.JlObject getCodec() => jni.JlObject.fromRef(_getCodec(reference));
+
+  static final _setCodec = jlookup<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_setCodec")
+      .asFunction<
+          void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract void setCodec(com.fasterxml.jackson.core.ObjectCodec oc)
+  ///
+  /// Setter that allows defining ObjectCodec associated with this
+  /// parser, if any. Codec is used by \#readValueAs(Class)
+  /// method (and its variants).
+  ///@param oc Codec to assign, if any; {@code null} if none
+  void setCodec(jni.JlObject oc) => _setCodec(reference, oc.reference);
+
+  static final _getInputSource = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getInputSource")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.Object getInputSource()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that can be used to get access to object that is used
+  /// to access input being parsed; this is usually either
+  /// InputStream or Reader, depending on what
+  /// parser was constructed with.
+  /// Note that returned value may be null in some cases; including
+  /// case where parser implementation does not want to exposed raw
+  /// source to caller.
+  /// In cases where input has been decorated, object returned here
+  /// is the decorated version; this allows some level of interaction
+  /// between users of parser and decorator object.
+  ///
+  /// In general use of this accessor should be considered as
+  /// "last effort", i.e. only used if no other mechanism is applicable.
+  ///@return Input source this parser was configured with
+  jni.JlObject getInputSource() =>
+      jni.JlObject.fromRef(_getInputSource(reference));
+
+  static final _setRequestPayloadOnError = jlookup<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError")
+      .asFunction<
+          void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public void setRequestPayloadOnError(com.fasterxml.jackson.core.util.RequestPayload payload)
+  ///
+  /// Sets the payload to be passed if JsonParseException is thrown.
+  ///@param payload Payload to pass
+  ///@since 2.8
+  void setRequestPayloadOnError(jni.JlObject payload) =>
+      _setRequestPayloadOnError(reference, payload.reference);
+
+  static final _setRequestPayloadOnError1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Void Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError1")
+      .asFunction<
+          void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Void>)>();
+
+  /// from: public void setRequestPayloadOnError(byte[] payload, java.lang.String charset)
+  ///
+  /// Sets the byte[] request payload and the charset
+  ///@param payload Payload to pass
+  ///@param charset Character encoding for (lazily) decoding payload
+  ///@since 2.8
+  void setRequestPayloadOnError1(jni.JlObject payload, jni.JlString charset) =>
+      _setRequestPayloadOnError1(
+          reference, payload.reference, charset.reference);
+
+  static final _setRequestPayloadOnError2 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError2")
+      .asFunction<
+          void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public void setRequestPayloadOnError(java.lang.String payload)
+  ///
+  /// Sets the String request payload
+  ///@param payload Payload to pass
+  ///@since 2.8
+  void setRequestPayloadOnError2(jni.JlString payload) =>
+      _setRequestPayloadOnError2(reference, payload.reference);
+
+  static final _setSchema = jlookup<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_setSchema")
+      .asFunction<
+          void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public void setSchema(com.fasterxml.jackson.core.FormatSchema schema)
+  ///
+  /// Method to call to make this parser use specified schema. Method must
+  /// be called before trying to parse any content, right after parser instance
+  /// has been created.
+  /// Note that not all parsers support schemas; and those that do usually only
+  /// accept specific types of schemas: ones defined for data format parser can read.
+  ///
+  /// If parser does not support specified schema, UnsupportedOperationException
+  /// is thrown.
+  ///@param schema Schema to use
+  ///@throws UnsupportedOperationException if parser does not support schema
+  void setSchema(jni.JlObject schema) =>
+      _setSchema(reference, schema.reference);
+
+  static final _getSchema = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getSchema")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.FormatSchema getSchema()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for accessing Schema that this parser uses, if any.
+  /// Default implementation returns null.
+  ///@return Schema in use by this parser, if any; {@code null} if none
+  ///@since 2.1
+  jni.JlObject getSchema() => jni.JlObject.fromRef(_getSchema(reference));
+
+  static final _canUseSchema = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_canUseSchema")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean canUseSchema(com.fasterxml.jackson.core.FormatSchema schema)
+  ///
+  /// Method that can be used to verify that given schema can be used with
+  /// this parser (using \#setSchema).
+  ///@param schema Schema to check
+  ///@return True if this parser can use given schema; false if not
+  bool canUseSchema(jni.JlObject schema) =>
+      _canUseSchema(reference, schema.reference) != 0;
+
+  static final _requiresCustomCodec =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_requiresCustomCodec")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean requiresCustomCodec()
+  ///
+  /// Method that can be called to determine if a custom
+  /// ObjectCodec is needed for binding data parsed
+  /// using JsonParser constructed by this factory
+  /// (which typically also implies the same for serialization
+  /// with JsonGenerator).
+  ///@return True if format-specific codec is needed with this parser; false if a general
+  ///   ObjectCodec is enough
+  ///@since 2.1
+  bool requiresCustomCodec() => _requiresCustomCodec(reference) != 0;
+
+  static final _canParseAsync =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_canParseAsync")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean canParseAsync()
+  ///
+  /// Method that can be called to determine if this parser instance
+  /// uses non-blocking ("asynchronous") input access for decoding or not.
+  /// Access mode is determined by earlier calls via JsonFactory;
+  /// it may not be changed after construction.
+  ///
+  /// If non-blocking decoding is (@code true}, it is possible to call
+  /// \#getNonBlockingInputFeeder() to obtain object to use
+  /// for feeding input; otherwise (<code>false</code> returned)
+  /// input is read by blocking
+  ///@return True if this is a non-blocking ("asynchronous") parser
+  ///@since 2.9
+  bool canParseAsync() => _canParseAsync(reference) != 0;
+
+  static final _getNonBlockingInputFeeder = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getNonBlockingInputFeeder")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.async.NonBlockingInputFeeder getNonBlockingInputFeeder()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that will either return a feeder instance (if parser uses
+  /// non-blocking, aka asynchronous access); or <code>null</code> for
+  /// parsers that use blocking I/O.
+  ///@return Input feeder to use with non-blocking (async) parsing
+  ///@since 2.9
+  jni.JlObject getNonBlockingInputFeeder() =>
+      jni.JlObject.fromRef(_getNonBlockingInputFeeder(reference));
+
+  static final _getReadCapabilities = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getReadCapabilities")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.util.JacksonFeatureSet<com.fasterxml.jackson.core.StreamReadCapability> getReadCapabilities()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Accessor for getting metadata on capabilities of this parser, based on
+  /// underlying data format being read (directly or indirectly).
+  ///@return Set of read capabilities for content to read via this parser
+  ///@since 2.12
+  jni.JlObject getReadCapabilities() =>
+      jni.JlObject.fromRef(_getReadCapabilities(reference));
+
+  static final _version = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_version")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract com.fasterxml.jackson.core.Version version()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Accessor for getting version of the core package, given a parser instance.
+  /// Left for sub-classes to implement.
+  ///@return Version of this generator (derived from version declared for
+  ///   {@code jackson-core} jar that contains the class
+  jni.JlObject version() => jni.JlObject.fromRef(_version(reference));
+
+  static final _close =
+      jlookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_close")
+          .asFunction<void Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract void close()
+  ///
+  /// Closes the parser so that no further iteration or data access
+  /// can be made; will also close the underlying input source
+  /// if parser either __owns__ the input source, or feature
+  /// Feature\#AUTO_CLOSE_SOURCE is enabled.
+  /// Whether parser owns the input source depends on factory
+  /// method that was used to construct instance (so check
+  /// com.fasterxml.jackson.core.JsonFactory for details,
+  /// but the general
+  /// idea is that if caller passes in closable resource (such
+  /// as InputStream or Reader) parser does NOT
+  /// own the source; but if it passes a reference (such as
+  /// java.io.File or java.net.URL and creates
+  /// stream or reader it does own them.
+  ///@throws IOException if there is either an underlying I/O problem
+  void close() => _close(reference);
+
+  static final _isClosed =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_isClosed")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract boolean isClosed()
+  ///
+  /// Method that can be called to determine whether this parser
+  /// is closed or not. If it is closed, no new tokens can be
+  /// retrieved by calling \#nextToken (and the underlying
+  /// stream may be closed). Closing may be due to an explicit
+  /// call to \#close or because parser has encountered
+  /// end of input.
+  ///@return {@code True} if this parser instance has been closed
+  bool isClosed() => _isClosed(reference) != 0;
+
+  static final _getParsingContext = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getParsingContext")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract com.fasterxml.jackson.core.JsonStreamContext getParsingContext()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that can be used to access current parsing context reader
+  /// is in. There are 3 different types: root, array and object contexts,
+  /// with slightly different available information. Contexts are
+  /// hierarchically nested, and can be used for example for figuring
+  /// out part of the input document that correspond to specific
+  /// array or object (for highlighting purposes, or error reporting).
+  /// Contexts can also be used for simple xpath-like matching of
+  /// input, if so desired.
+  ///@return Stream input context (JsonStreamContext) associated with this parser
+  jni.JlObject getParsingContext() =>
+      jni.JlObject.fromRef(_getParsingContext(reference));
+
+  static final _currentLocation = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_currentLocation")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonLocation currentLocation()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that returns location of the last processed input unit (character
+  /// or byte) from the input;
+  /// usually for error reporting purposes.
+  ///
+  /// Note that the location is not guaranteed to be accurate (although most
+  /// implementation will try their best): some implementations may only
+  /// report specific boundary locations (start or end locations of tokens)
+  /// and others only return JsonLocation\#NA due to not having access
+  /// to input location information (when delegating actual decoding work
+  /// to other library)
+  ///@return Location of the last processed input unit (byte or character)
+  ///@since 2.13
+  jni.JlObject currentLocation() =>
+      jni.JlObject.fromRef(_currentLocation(reference));
+
+  static final _currentTokenLocation = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_currentTokenLocation")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonLocation currentTokenLocation()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that return the __starting__ location of the current
+  /// (most recently returned)
+  /// token; that is, the position of the first input unit (character or byte) from input
+  /// that starts the current token.
+  ///
+  /// Note that the location is not guaranteed to be accurate (although most
+  /// implementation will try their best): some implementations may only
+  /// return JsonLocation\#NA due to not having access
+  /// to input location information (when delegating actual decoding work
+  /// to other library)
+  ///@return Starting location of the token parser currently points to
+  ///@since 2.13 (will eventually replace \#getTokenLocation)
+  jni.JlObject currentTokenLocation() =>
+      jni.JlObject.fromRef(_currentTokenLocation(reference));
+
+  static final _getCurrentLocation = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getCurrentLocation")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract com.fasterxml.jackson.core.JsonLocation getCurrentLocation()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Alias for \#currentLocation(), to be deprecated in later
+  /// Jackson 2.x versions (and removed from Jackson 3.0).
+  ///@return Location of the last processed input unit (byte or character)
+  jni.JlObject getCurrentLocation() =>
+      jni.JlObject.fromRef(_getCurrentLocation(reference));
+
+  static final _getTokenLocation = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getTokenLocation")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract com.fasterxml.jackson.core.JsonLocation getTokenLocation()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Alias for \#currentTokenLocation(), to be deprecated in later
+  /// Jackson 2.x versions (and removed from Jackson 3.0).
+  ///@return Starting location of the token parser currently points to
+  jni.JlObject getTokenLocation() =>
+      jni.JlObject.fromRef(_getTokenLocation(reference));
+
+  static final _currentValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_currentValue")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.Object currentValue()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Helper method, usually equivalent to:
+  ///<code>
+  ///   getParsingContext().getCurrentValue();
+  ///</code>
+  ///
+  /// Note that "current value" is NOT populated (or used) by Streaming parser;
+  /// it is only used by higher-level data-binding functionality.
+  /// The reason it is included here is that it can be stored and accessed hierarchically,
+  /// and gets passed through data-binding.
+  ///@return "Current value" associated with the current input context (state) of this parser
+  ///@since 2.13 (added as replacement for older \#getCurrentValue()
+  jni.JlObject currentValue() => jni.JlObject.fromRef(_currentValue(reference));
+
+  static final _assignCurrentValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_assignCurrentValue")
+      .asFunction<
+          void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public void assignCurrentValue(java.lang.Object v)
+  ///
+  /// Helper method, usually equivalent to:
+  ///<code>
+  ///   getParsingContext().setCurrentValue(v);
+  ///</code>
+  ///@param v Current value to assign for the current input context of this parser
+  ///@since 2.13 (added as replacement for older \#setCurrentValue
+  void assignCurrentValue(jni.JlObject v) =>
+      _assignCurrentValue(reference, v.reference);
+
+  static final _getCurrentValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getCurrentValue")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.Object getCurrentValue()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Alias for \#currentValue(), to be deprecated in later
+  /// Jackson 2.x versions (and removed from Jackson 3.0).
+  ///@return Location of the last processed input unit (byte or character)
+  jni.JlObject getCurrentValue() =>
+      jni.JlObject.fromRef(_getCurrentValue(reference));
+
+  static final _setCurrentValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_setCurrentValue")
+      .asFunction<
+          void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public void setCurrentValue(java.lang.Object v)
+  ///
+  /// Alias for \#assignCurrentValue, to be deprecated in later
+  /// Jackson 2.x versions (and removed from Jackson 3.0).
+  ///@param v Current value to assign for the current input context of this parser
+  void setCurrentValue(jni.JlObject v) =>
+      _setCurrentValue(reference, v.reference);
+
+  static final _releaseBuffered = jlookup<
+              ffi.NativeFunction<
+                  ffi.Int32 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_releaseBuffered")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int releaseBuffered(java.io.OutputStream out)
+  ///
+  /// Method that can be called to push back any content that
+  /// has been read but not consumed by the parser. This is usually
+  /// done after reading all content of interest using parser.
+  /// Content is released by writing it to given stream if possible;
+  /// if underlying input is byte-based it can released, if not (char-based)
+  /// it can not.
+  ///@param out OutputStream to which buffered, undecoded content is written to
+  ///@return -1 if the underlying content source is not byte based
+  ///    (that is, input can not be sent to OutputStream;
+  ///    otherwise number of bytes released (0 if there was nothing to release)
+  ///@throws IOException if write to stream threw exception
+  int releaseBuffered(jni.JlObject out) =>
+      _releaseBuffered(reference, out.reference);
+
+  static final _releaseBuffered1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Int32 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_releaseBuffered1")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int releaseBuffered(java.io.Writer w)
+  ///
+  /// Method that can be called to push back any content that
+  /// has been read but not consumed by the parser.
+  /// This is usually
+  /// done after reading all content of interest using parser.
+  /// Content is released by writing it to given writer if possible;
+  /// if underlying input is char-based it can released, if not (byte-based)
+  /// it can not.
+  ///@param w Writer to which buffered but unprocessed content is written to
+  ///@return -1 if the underlying content source is not char-based
+  ///    (that is, input can not be sent to Writer;
+  ///    otherwise number of chars released (0 if there was nothing to release)
+  ///@throws IOException if write using Writer threw exception
+  int releaseBuffered1(jni.JlObject w) =>
+      _releaseBuffered1(reference, w.reference);
+
+  static final _enable = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_enable")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser enable(com.fasterxml.jackson.core.JsonParser.Feature f)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for enabling specified parser feature
+  /// (check Feature for list of features)
+  ///@param f Feature to enable
+  ///@return This parser, to allow call chaining
+  JsonParser enable(JsonParser_Feature f) =>
+      JsonParser.fromRef(_enable(reference, f.reference));
+
+  static final _disable = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_disable")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser disable(com.fasterxml.jackson.core.JsonParser.Feature f)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for disabling specified  feature
+  /// (check Feature for list of features)
+  ///@param f Feature to disable
+  ///@return This parser, to allow call chaining
+  JsonParser disable(JsonParser_Feature f) =>
+      JsonParser.fromRef(_disable(reference, f.reference));
+
+  static final _configure = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Uint8)>>(
+          "com_fasterxml_jackson_core_JsonParser_configure")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser configure(com.fasterxml.jackson.core.JsonParser.Feature f, boolean state)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for enabling or disabling specified feature
+  /// (check Feature for list of features)
+  ///@param f Feature to enable or disable
+  ///@param state Whether to enable feature ({@code true}) or disable ({@code false})
+  ///@return This parser, to allow call chaining
+  JsonParser configure(JsonParser_Feature f, bool state) =>
+      JsonParser.fromRef(_configure(reference, f.reference, state ? 1 : 0));
+
+  static final _isEnabled = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_isEnabled")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean isEnabled(com.fasterxml.jackson.core.JsonParser.Feature f)
+  ///
+  /// Method for checking whether specified Feature is enabled.
+  ///@param f Feature to check
+  ///@return {@code True} if feature is enabled; {@code false} otherwise
+  bool isEnabled(JsonParser_Feature f) =>
+      _isEnabled(reference, f.reference) != 0;
+
+  static final _isEnabled1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_isEnabled1")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean isEnabled(com.fasterxml.jackson.core.StreamReadFeature f)
+  ///
+  /// Method for checking whether specified Feature is enabled.
+  ///@param f Feature to check
+  ///@return {@code True} if feature is enabled; {@code false} otherwise
+  ///@since 2.10
+  bool isEnabled1(jni.JlObject f) => _isEnabled1(reference, f.reference) != 0;
+
+  static final _getFeatureMask =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getFeatureMask")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int getFeatureMask()
+  ///
+  /// Bulk access method for getting state of all standard Features.
+  ///@return Bit mask that defines current states of all standard Features.
+  ///@since 2.3
+  int getFeatureMask() => _getFeatureMask(reference);
+
+  static final _setFeatureMask = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Int32)>>(
+          "com_fasterxml_jackson_core_JsonParser_setFeatureMask")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser setFeatureMask(int mask)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Bulk set method for (re)setting states of all standard Features
+  ///@param mask Bit mask that defines set of features to enable
+  ///@return This parser, to allow call chaining
+  ///@since 2.3
+  ///@deprecated Since 2.7, use \#overrideStdFeatures(int, int) instead
+  JsonParser setFeatureMask(int mask) =>
+      JsonParser.fromRef(_setFeatureMask(reference, mask));
+
+  static final _overrideStdFeatures = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Int32, ffi.Int32)>>(
+          "com_fasterxml_jackson_core_JsonParser_overrideStdFeatures")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>, int, int)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser overrideStdFeatures(int values, int mask)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Bulk set method for (re)setting states of features specified by <code>mask</code>.
+  /// Functionally equivalent to
+  ///<code>
+  ///    int oldState = getFeatureMask();
+  ///    int newState = (oldState &amp; ~mask) | (values &amp; mask);
+  ///    setFeatureMask(newState);
+  ///</code>
+  /// but preferred as this lets caller more efficiently specify actual changes made.
+  ///@param values Bit mask of set/clear state for features to change
+  ///@param mask Bit mask of features to change
+  ///@return This parser, to allow call chaining
+  ///@since 2.6
+  JsonParser overrideStdFeatures(int values, int mask) =>
+      JsonParser.fromRef(_overrideStdFeatures(reference, values, mask));
+
+  static final _getFormatFeatures =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getFormatFeatures")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int getFormatFeatures()
+  ///
+  /// Bulk access method for getting state of all FormatFeatures, format-specific
+  /// on/off configuration settings.
+  ///@return Bit mask that defines current states of all standard FormatFeatures.
+  ///@since 2.6
+  int getFormatFeatures() => _getFormatFeatures(reference);
+
+  static final _overrideFormatFeatures = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Int32, ffi.Int32)>>(
+          "com_fasterxml_jackson_core_JsonParser_overrideFormatFeatures")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>, int, int)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonParser overrideFormatFeatures(int values, int mask)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Bulk set method for (re)setting states of FormatFeatures,
+  /// by specifying values (set / clear) along with a mask, to determine
+  /// which features to change, if any.
+  ///
+  /// Default implementation will simply throw an exception to indicate that
+  /// the parser implementation does not support any FormatFeatures.
+  ///@param values Bit mask of set/clear state for features to change
+  ///@param mask Bit mask of features to change
+  ///@return This parser, to allow call chaining
+  ///@since 2.6
+  JsonParser overrideFormatFeatures(int values, int mask) =>
+      JsonParser.fromRef(_overrideFormatFeatures(reference, values, mask));
+
+  static final _nextToken = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_nextToken")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract com.fasterxml.jackson.core.JsonToken nextToken()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Main iteration method, which will advance stream enough
+  /// to determine type of the next token, if any. If none
+  /// remaining (stream has no content other than possible
+  /// white space before ending), null will be returned.
+  ///@return Next token from the stream, if any found, or null
+  ///   to indicate end-of-input
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  JsonToken nextToken() => JsonToken.fromRef(_nextToken(reference));
+
+  static final _nextValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_nextValue")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract com.fasterxml.jackson.core.JsonToken nextValue()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Iteration method that will advance stream enough
+  /// to determine type of the next token that is a value type
+  /// (including JSON Array and Object start/end markers).
+  /// Or put another way, nextToken() will be called once,
+  /// and if JsonToken\#FIELD_NAME is returned, another
+  /// time to get the value for the field.
+  /// Method is most useful for iterating over value entries
+  /// of JSON objects; field name will still be available
+  /// by calling \#getCurrentName when parser points to
+  /// the value.
+  ///@return Next non-field-name token from the stream, if any found,
+  ///   or null to indicate end-of-input (or, for non-blocking
+  ///   parsers, JsonToken\#NOT_AVAILABLE if no tokens were
+  ///   available yet)
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  JsonToken nextValue() => JsonToken.fromRef(_nextValue(reference));
+
+  static final _nextFieldName = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_nextFieldName")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean nextFieldName(com.fasterxml.jackson.core.SerializableString str)
+  ///
+  /// Method that fetches next token (as if calling \#nextToken) and
+  /// verifies whether it is JsonToken\#FIELD_NAME with specified name
+  /// and returns result of that comparison.
+  /// It is functionally equivalent to:
+  ///<pre>
+  ///  return (nextToken() == JsonToken.FIELD_NAME) &amp;&amp; str.getValue().equals(getCurrentName());
+  ///</pre>
+  /// but may be faster for parser to verify, and can therefore be used if caller
+  /// expects to get such a property name from input next.
+  ///@param str Property name to compare next token to (if next token is
+  ///   <code>JsonToken.FIELD_NAME</code>)
+  ///@return {@code True} if parser advanced to {@code JsonToken.FIELD_NAME} with
+  ///    specified name; {@code false} otherwise (different token or non-matching name)
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  bool nextFieldName(jni.JlObject str) =>
+      _nextFieldName(reference, str.reference) != 0;
+
+  static final _nextFieldName1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_nextFieldName1")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.String nextFieldName()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that fetches next token (as if calling \#nextToken) and
+  /// verifies whether it is JsonToken\#FIELD_NAME; if it is,
+  /// returns same as \#getCurrentName(), otherwise null.
+  ///@return Name of the the {@code JsonToken.FIELD_NAME} parser advanced to, if any;
+  ///   {@code null} if next token is of some other type
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@since 2.5
+  jni.JlString nextFieldName1() =>
+      jni.JlString.fromRef(_nextFieldName1(reference));
+
+  static final _nextTextValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_nextTextValue")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.String nextTextValue()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that fetches next token (as if calling \#nextToken) and
+  /// if it is JsonToken\#VALUE_STRING returns contained String value;
+  /// otherwise returns null.
+  /// It is functionally equivalent to:
+  ///<pre>
+  ///  return (nextToken() == JsonToken.VALUE_STRING) ? getText() : null;
+  ///</pre>
+  /// but may be faster for parser to process, and can therefore be used if caller
+  /// expects to get a String value next from input.
+  ///@return Text value of the {@code JsonToken.VALUE_STRING} token parser advanced
+  ///   to; or {@code null} if next token is of some other type
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  jni.JlString nextTextValue() =>
+      jni.JlString.fromRef(_nextTextValue(reference));
+
+  static final _nextIntValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Int32 Function(ffi.Pointer<ffi.Void>, ffi.Int32)>>(
+          "com_fasterxml_jackson_core_JsonParser_nextIntValue")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public int nextIntValue(int defaultValue)
+  ///
+  /// Method that fetches next token (as if calling \#nextToken) and
+  /// if it is JsonToken\#VALUE_NUMBER_INT returns 32-bit int value;
+  /// otherwise returns specified default value
+  /// It is functionally equivalent to:
+  ///<pre>
+  ///  return (nextToken() == JsonToken.VALUE_NUMBER_INT) ? getIntValue() : defaultValue;
+  ///</pre>
+  /// but may be faster for parser to process, and can therefore be used if caller
+  /// expects to get an int value next from input.
+  ///
+  /// NOTE: value checks are performed similar to \#getIntValue()
+  ///@param defaultValue Value to return if next token is NOT of type {@code JsonToken.VALUE_NUMBER_INT}
+  ///@return Integer ({@code int}) value of the {@code JsonToken.VALUE_NUMBER_INT} token parser advanced
+  ///   to; or {@code defaultValue} if next token is of some other type
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@throws InputCoercionException if integer number does not fit in Java {@code int}
+  int nextIntValue(int defaultValue) => _nextIntValue(reference, defaultValue);
+
+  static final _nextLongValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Int64 Function(ffi.Pointer<ffi.Void>, ffi.Int64)>>(
+          "com_fasterxml_jackson_core_JsonParser_nextLongValue")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public long nextLongValue(long defaultValue)
+  ///
+  /// Method that fetches next token (as if calling \#nextToken) and
+  /// if it is JsonToken\#VALUE_NUMBER_INT returns 64-bit long value;
+  /// otherwise returns specified default value
+  /// It is functionally equivalent to:
+  ///<pre>
+  ///  return (nextToken() == JsonToken.VALUE_NUMBER_INT) ? getLongValue() : defaultValue;
+  ///</pre>
+  /// but may be faster for parser to process, and can therefore be used if caller
+  /// expects to get a long value next from input.
+  ///
+  /// NOTE: value checks are performed similar to \#getLongValue()
+  ///@param defaultValue Value to return if next token is NOT of type {@code JsonToken.VALUE_NUMBER_INT}
+  ///@return {@code long} value of the {@code JsonToken.VALUE_NUMBER_INT} token parser advanced
+  ///   to; or {@code defaultValue} if next token is of some other type
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@throws InputCoercionException if integer number does not fit in Java {@code long}
+  int nextLongValue(int defaultValue) =>
+      _nextLongValue(reference, defaultValue);
+
+  static final _nextBooleanValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_nextBooleanValue")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.Boolean nextBooleanValue()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that fetches next token (as if calling \#nextToken) and
+  /// if it is JsonToken\#VALUE_TRUE or JsonToken\#VALUE_FALSE
+  /// returns matching Boolean value; otherwise return null.
+  /// It is functionally equivalent to:
+  ///<pre>
+  ///  JsonToken t = nextToken();
+  ///  if (t == JsonToken.VALUE_TRUE) return Boolean.TRUE;
+  ///  if (t == JsonToken.VALUE_FALSE) return Boolean.FALSE;
+  ///  return null;
+  ///</pre>
+  /// but may be faster for parser to process, and can therefore be used if caller
+  /// expects to get a Boolean value next from input.
+  ///@return {@code Boolean} value of the {@code JsonToken.VALUE_TRUE} or {@code JsonToken.VALUE_FALSE}
+  ///   token parser advanced to; or {@code null} if next token is of some other type
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  jni.JlObject nextBooleanValue() =>
+      jni.JlObject.fromRef(_nextBooleanValue(reference));
+
+  static final _skipChildren = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_skipChildren")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract com.fasterxml.jackson.core.JsonParser skipChildren()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that will skip all child tokens of an array or
+  /// object token that the parser currently points to,
+  /// iff stream points to
+  /// JsonToken\#START_OBJECT or JsonToken\#START_ARRAY.
+  /// If not, it will do nothing.
+  /// After skipping, stream will point to __matching__
+  /// JsonToken\#END_OBJECT or JsonToken\#END_ARRAY
+  /// (possibly skipping nested pairs of START/END OBJECT/ARRAY tokens
+  /// as well as value tokens).
+  /// The idea is that after calling this method, application
+  /// will call \#nextToken to point to the next
+  /// available token, if any.
+  ///@return This parser, to allow call chaining
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  JsonParser skipChildren() => JsonParser.fromRef(_skipChildren(reference));
+
+  static final _finishToken =
+      jlookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_finishToken")
+          .asFunction<void Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public void finishToken()
+  ///
+  /// Method that may be used to force full handling of the current token
+  /// so that even if lazy processing is enabled, the whole contents are
+  /// read for possible retrieval. This is usually used to ensure that
+  /// the token end location is available, as well as token contents
+  /// (similar to what calling, say \#getTextCharacters(), would
+  /// achieve).
+  ///
+  /// Note that for many dataformat implementations this method
+  /// will not do anything; this is the default implementation unless
+  /// overridden by sub-classes.
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@since 2.8
+  void finishToken() => _finishToken(reference);
+
+  static final _currentToken = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_currentToken")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public com.fasterxml.jackson.core.JsonToken currentToken()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Accessor to find which token parser currently points to, if any;
+  /// null will be returned if none.
+  /// If return value is non-null, data associated with the token
+  /// is available via other accessor methods.
+  ///@return Type of the token this parser currently points to,
+  ///   if any: null before any tokens have been read, and
+  ///   after end-of-input has been encountered, as well as
+  ///   if the current token has been explicitly cleared.
+  ///@since 2.8
+  JsonToken currentToken() => JsonToken.fromRef(_currentToken(reference));
+
+  static final _currentTokenId =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_currentTokenId")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int currentTokenId()
+  ///
+  /// Method similar to \#getCurrentToken() but that returns an
+  /// <code>int</code> instead of JsonToken (enum value).
+  ///
+  /// Use of int directly is typically more efficient on switch statements,
+  /// so this method may be useful when building low-overhead codecs.
+  /// Note, however, that effect may not be big enough to matter: make sure
+  /// to profile performance before deciding to use this method.
+  ///@since 2.8
+  ///@return {@code int} matching one of constants from JsonTokenId.
+  int currentTokenId() => _currentTokenId(reference);
+
+  static final _getCurrentToken = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getCurrentToken")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract com.fasterxml.jackson.core.JsonToken getCurrentToken()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Alias for \#currentToken(), may be deprecated sometime after
+  /// Jackson 2.13 (will be removed from 3.0).
+  ///@return Type of the token this parser currently points to,
+  ///   if any: null before any tokens have been read, and
+  JsonToken getCurrentToken() => JsonToken.fromRef(_getCurrentToken(reference));
+
+  static final _getCurrentTokenId =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getCurrentTokenId")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract int getCurrentTokenId()
+  ///
+  /// Deprecated alias for \#currentTokenId().
+  ///@return {@code int} matching one of constants from JsonTokenId.
+  ///@deprecated Since 2.12 use \#currentTokenId instead
+  int getCurrentTokenId() => _getCurrentTokenId(reference);
+
+  static final _hasCurrentToken =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_hasCurrentToken")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract boolean hasCurrentToken()
+  ///
+  /// Method for checking whether parser currently points to
+  /// a token (and data for that token is available).
+  /// Equivalent to check for <code>parser.getCurrentToken() != null</code>.
+  ///@return True if the parser just returned a valid
+  ///   token via \#nextToken; false otherwise (parser
+  ///   was just constructed, encountered end-of-input
+  ///   and returned null from \#nextToken, or the token
+  ///   has been consumed)
+  bool hasCurrentToken() => _hasCurrentToken(reference) != 0;
+
+  static final _hasTokenId = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(ffi.Pointer<ffi.Void>, ffi.Int32)>>(
+          "com_fasterxml_jackson_core_JsonParser_hasTokenId")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public abstract boolean hasTokenId(int id)
+  ///
+  /// Method that is functionally equivalent to:
+  ///<code>
+  ///  return currentTokenId() == id
+  ///</code>
+  /// but may be more efficiently implemented.
+  ///
+  /// Note that no traversal or conversion is performed; so in some
+  /// cases calling method like \#isExpectedStartArrayToken()
+  /// is necessary instead.
+  ///@param id Token id to match (from (@link JsonTokenId})
+  ///@return {@code True} if the parser current points to specified token
+  ///@since 2.5
+  bool hasTokenId(int id) => _hasTokenId(reference, id) != 0;
+
+  static final _hasToken = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_hasToken")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract boolean hasToken(com.fasterxml.jackson.core.JsonToken t)
+  ///
+  /// Method that is functionally equivalent to:
+  ///<code>
+  ///  return currentToken() == t
+  ///</code>
+  /// but may be more efficiently implemented.
+  ///
+  /// Note that no traversal or conversion is performed; so in some
+  /// cases calling method like \#isExpectedStartArrayToken()
+  /// is necessary instead.
+  ///@param t Token to match
+  ///@return {@code True} if the parser current points to specified token
+  ///@since 2.6
+  bool hasToken(JsonToken t) => _hasToken(reference, t.reference) != 0;
+
+  static final _isExpectedStartArrayToken =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_isExpectedStartArrayToken")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean isExpectedStartArrayToken()
+  ///
+  /// Specialized accessor that can be used to verify that the current
+  /// token indicates start array (usually meaning that current token
+  /// is JsonToken\#START_ARRAY) when start array is expected.
+  /// For some specialized parsers this can return true for other cases
+  /// as well; this is usually done to emulate arrays in cases underlying
+  /// format is ambiguous (XML, for example, has no format-level difference
+  /// between Objects and Arrays; it just has elements).
+  ///
+  /// Default implementation is equivalent to:
+  ///<pre>
+  ///   currentToken() == JsonToken.START_ARRAY
+  ///</pre>
+  /// but may be overridden by custom parser implementations.
+  ///@return True if the current token can be considered as a
+  ///   start-array marker (such JsonToken\#START_ARRAY);
+  ///   {@code false} if not
+  bool isExpectedStartArrayToken() =>
+      _isExpectedStartArrayToken(reference) != 0;
+
+  static final _isExpectedStartObjectToken = jlookup<
+              ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_isExpectedStartObjectToken")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean isExpectedStartObjectToken()
+  ///
+  /// Similar to \#isExpectedStartArrayToken(), but checks whether stream
+  /// currently points to JsonToken\#START_OBJECT.
+  ///@return True if the current token can be considered as a
+  ///   start-array marker (such JsonToken\#START_OBJECT);
+  ///   {@code false} if not
+  ///@since 2.5
+  bool isExpectedStartObjectToken() =>
+      _isExpectedStartObjectToken(reference) != 0;
+
+  static final _isExpectedNumberIntToken =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_isExpectedNumberIntToken")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean isExpectedNumberIntToken()
+  ///
+  /// Similar to \#isExpectedStartArrayToken(), but checks whether stream
+  /// currently points to JsonToken\#VALUE_NUMBER_INT.
+  ///
+  /// The initial use case is for XML backend to efficiently (attempt to) coerce
+  /// textual content into numbers.
+  ///@return True if the current token can be considered as a
+  ///   start-array marker (such JsonToken\#VALUE_NUMBER_INT);
+  ///   {@code false} if not
+  ///@since 2.12
+  bool isExpectedNumberIntToken() => _isExpectedNumberIntToken(reference) != 0;
+
+  static final _isNaN =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_isNaN")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean isNaN()
+  ///
+  /// Access for checking whether current token is a numeric value token, but
+  /// one that is of "not-a-number" (NaN) variety (including both "NaN" AND
+  /// positive/negative infinity!): not supported by all formats,
+  /// but often supported for JsonToken\#VALUE_NUMBER_FLOAT.
+  /// NOTE: roughly equivalent to calling <code>!Double.isFinite()</code>
+  /// on value you would get from calling \#getDoubleValue().
+  ///@return {@code True} if the current token is of type JsonToken\#VALUE_NUMBER_FLOAT
+  ///   but represents a "Not a Number"; {@code false} for other tokens and regular
+  ///   floating-point numbers
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@since 2.9
+  bool isNaN() => _isNaN(reference) != 0;
+
+  static final _clearCurrentToken =
+      jlookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_clearCurrentToken")
+          .asFunction<void Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract void clearCurrentToken()
+  ///
+  /// Method called to "consume" the current token by effectively
+  /// removing it so that \#hasCurrentToken returns false, and
+  /// \#getCurrentToken null).
+  /// Cleared token value can still be accessed by calling
+  /// \#getLastClearedToken (if absolutely needed), but
+  /// usually isn't.
+  ///
+  /// Method was added to be used by the optional data binder, since
+  /// it has to be able to consume last token used for binding (so that
+  /// it will not be used again).
+  void clearCurrentToken() => _clearCurrentToken(reference);
+
+  static final _getLastClearedToken = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getLastClearedToken")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract com.fasterxml.jackson.core.JsonToken getLastClearedToken()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that can be called to get the last token that was
+  /// cleared using \#clearCurrentToken. This is not necessarily
+  /// the latest token read.
+  /// Will return null if no tokens have been cleared,
+  /// or if parser has been closed.
+  ///@return Last cleared token, if any; {@code null} otherwise
+  JsonToken getLastClearedToken() =>
+      JsonToken.fromRef(_getLastClearedToken(reference));
+
+  static final _overrideCurrentName = jlookup<
+              ffi.NativeFunction<
+                  ffi.Void Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_overrideCurrentName")
+      .asFunction<
+          void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract void overrideCurrentName(java.lang.String name)
+  ///
+  /// Method that can be used to change what is considered to be
+  /// the current (field) name.
+  /// May be needed to support non-JSON data formats or unusual binding
+  /// conventions; not needed for typical processing.
+  ///
+  /// Note that use of this method should only be done as sort of last
+  /// resort, as it is a work-around for regular operation.
+  ///@param name Name to use as the current name; may be null.
+  void overrideCurrentName(jni.JlString name) =>
+      _overrideCurrentName(reference, name.reference);
+
+  static final _getCurrentName = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getCurrentName")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract java.lang.String getCurrentName()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Alias of \#currentName().
+  ///@return Name of the current field in the parsing context
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  jni.JlString getCurrentName() =>
+      jni.JlString.fromRef(_getCurrentName(reference));
+
+  static final _currentName = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_currentName")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.String currentName()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that can be called to get the name associated with
+  /// the current token: for JsonToken\#FIELD_NAMEs it will
+  /// be the same as what \#getText returns;
+  /// for field values it will be preceding field name;
+  /// and for others (array values, root-level values) null.
+  ///@return Name of the current field in the parsing context
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@since 2.10
+  jni.JlString currentName() => jni.JlString.fromRef(_currentName(reference));
+
+  static final _getText = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getText")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract java.lang.String getText()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for accessing textual representation of the current token;
+  /// if no current token (before first call to \#nextToken, or
+  /// after encountering end-of-input), returns null.
+  /// Method can be called for any token type.
+  ///@return Textual value associated with the current token (one returned
+  ///   by \#nextToken() or other iteration methods)
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  jni.JlString getText() => jni.JlString.fromRef(_getText(reference));
+
+  static final _getText1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Int32 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getText1")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int getText(java.io.Writer writer)
+  ///
+  /// Method to read the textual representation of the current token in chunks and
+  /// pass it to the given Writer.
+  /// Conceptually same as calling:
+  ///<pre>
+  ///  writer.write(parser.getText());
+  ///</pre>
+  /// but should typically be more efficient as longer content does need to
+  /// be combined into a single <code>String</code> to return, and write
+  /// can occur directly from intermediate buffers Jackson uses.
+  ///@param writer Writer to write textual content to
+  ///@return The number of characters written to the Writer
+  ///@throws IOException for low-level read issues or writes using passed
+  ///   {@code writer}, or
+  ///   JsonParseException for decoding problems
+  ///@since 2.8
+  int getText1(jni.JlObject writer) => _getText1(reference, writer.reference);
+
+  static final _getTextCharacters = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getTextCharacters")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract char[] getTextCharacters()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method similar to \#getText, but that will return
+  /// underlying (unmodifiable) character array that contains
+  /// textual value, instead of constructing a String object
+  /// to contain this information.
+  /// Note, however, that:
+  ///<ul>
+  /// <li>Textual contents are not guaranteed to start at
+  ///   index 0 (rather, call \#getTextOffset) to
+  ///   know the actual offset
+  ///  </li>
+  /// <li>Length of textual contents may be less than the
+  ///  length of returned buffer: call \#getTextLength
+  ///  for actual length of returned content.
+  ///  </li>
+  /// </ul>
+  ///
+  /// Note that caller __MUST NOT__ modify the returned
+  /// character array in any way -- doing so may corrupt
+  /// current parser state and render parser instance useless.
+  ///
+  /// The only reason to call this method (over \#getText)
+  /// is to avoid construction of a String object (which
+  /// will make a copy of contents).
+  ///@return Buffer that contains the current textual value (but not necessarily
+  ///    at offset 0, and not necessarily until the end of buffer)
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  jni.JlObject getTextCharacters() =>
+      jni.JlObject.fromRef(_getTextCharacters(reference));
+
+  static final _getTextLength =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getTextLength")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract int getTextLength()
+  ///
+  /// Accessor used with \#getTextCharacters, to know length
+  /// of String stored in returned buffer.
+  ///@return Number of characters within buffer returned
+  ///   by \#getTextCharacters that are part of
+  ///   textual content of the current token.
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  int getTextLength() => _getTextLength(reference);
+
+  static final _getTextOffset =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getTextOffset")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract int getTextOffset()
+  ///
+  /// Accessor used with \#getTextCharacters, to know offset
+  /// of the first text content character within buffer.
+  ///@return Offset of the first character within buffer returned
+  ///   by \#getTextCharacters that is part of
+  ///   textual content of the current token.
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  int getTextOffset() => _getTextOffset(reference);
+
+  static final _hasTextCharacters =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_hasTextCharacters")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract boolean hasTextCharacters()
+  ///
+  /// Method that can be used to determine whether calling of
+  /// \#getTextCharacters would be the most efficient
+  /// way to access textual content for the event parser currently
+  /// points to.
+  ///
+  /// Default implementation simply returns false since only actual
+  /// implementation class has knowledge of its internal buffering
+  /// state.
+  /// Implementations are strongly encouraged to properly override
+  /// this method, to allow efficient copying of content by other
+  /// code.
+  ///@return True if parser currently has character array that can
+  ///   be efficiently returned via \#getTextCharacters; false
+  ///   means that it may or may not exist
+  bool hasTextCharacters() => _hasTextCharacters(reference) != 0;
+
+  static final _getNumberValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getNumberValue")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract java.lang.Number getNumberValue()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Generic number value accessor method that will work for
+  /// all kinds of numeric values. It will return the optimal
+  /// (simplest/smallest possible) wrapper object that can
+  /// express the numeric value just parsed.
+  ///@return Numeric value of the current token in its most optimal
+  ///   representation
+  ///@throws IOException Problem with access: JsonParseException if
+  ///    the current token is not numeric, or if decoding of the value fails
+  ///    (invalid format for numbers); plain IOException if underlying
+  ///    content read fails (possible if values are extracted lazily)
+  jni.JlObject getNumberValue() =>
+      jni.JlObject.fromRef(_getNumberValue(reference));
+
+  static final _getNumberValueExact = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getNumberValueExact")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.Number getNumberValueExact()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method similar to \#getNumberValue with the difference that
+  /// for floating-point numbers value returned may be BigDecimal
+  /// if the underlying format does not store floating-point numbers using
+  /// native representation: for example, textual formats represent numbers
+  /// as Strings (which are 10-based), and conversion to java.lang.Double
+  /// is potentially lossy operation.
+  ///
+  /// Default implementation simply returns \#getNumberValue()
+  ///@return Numeric value of the current token using most accurate representation
+  ///@throws IOException Problem with access: JsonParseException if
+  ///    the current token is not numeric, or if decoding of the value fails
+  ///    (invalid format for numbers); plain IOException if underlying
+  ///    content read fails (possible if values are extracted lazily)
+  ///@since 2.12
+  jni.JlObject getNumberValueExact() =>
+      jni.JlObject.fromRef(_getNumberValueExact(reference));
+
+  static final _getNumberType = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getNumberType")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract com.fasterxml.jackson.core.JsonParser.NumberType getNumberType()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// If current token is of type
+  /// JsonToken\#VALUE_NUMBER_INT or
+  /// JsonToken\#VALUE_NUMBER_FLOAT, returns
+  /// one of NumberType constants; otherwise returns null.
+  ///@return Type of current number, if parser points to numeric token; {@code null} otherwise
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  JsonParser_NumberType getNumberType() =>
+      JsonParser_NumberType.fromRef(_getNumberType(reference));
+
+  static final _getByteValue =
+      jlookup<ffi.NativeFunction<ffi.Int8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getByteValue")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public byte getByteValue()
+  ///
+  /// Numeric accessor that can be called when the current
+  /// token is of type JsonToken\#VALUE_NUMBER_INT and
+  /// it can be expressed as a value of Java byte primitive type.
+  /// Note that in addition to "natural" input range of {@code [-128, 127]},
+  /// this also allows "unsigned 8-bit byte" values {@code [128, 255]}:
+  /// but for this range value will be translated by truncation, leading
+  /// to sign change.
+  ///
+  /// It can also be called for JsonToken\#VALUE_NUMBER_FLOAT;
+  /// if so, it is equivalent to calling \#getDoubleValue
+  /// and then casting; except for possible overflow/underflow
+  /// exception.
+  ///
+  /// Note: if the resulting integer value falls outside range of
+  /// {@code [-128, 255]},
+  /// a InputCoercionException
+  /// will be thrown to indicate numeric overflow/underflow.
+  ///@return Current number value as {@code byte} (if numeric token within
+  ///   range of {@code [-128, 255]}); otherwise exception thrown
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  int getByteValue() => _getByteValue(reference);
+
+  static final _getShortValue =
+      jlookup<ffi.NativeFunction<ffi.Int16 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getShortValue")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public short getShortValue()
+  ///
+  /// Numeric accessor that can be called when the current
+  /// token is of type JsonToken\#VALUE_NUMBER_INT and
+  /// it can be expressed as a value of Java short primitive type.
+  /// It can also be called for JsonToken\#VALUE_NUMBER_FLOAT;
+  /// if so, it is equivalent to calling \#getDoubleValue
+  /// and then casting; except for possible overflow/underflow
+  /// exception.
+  ///
+  /// Note: if the resulting integer value falls outside range of
+  /// Java short, a InputCoercionException
+  /// will be thrown to indicate numeric overflow/underflow.
+  ///@return Current number value as {@code short} (if numeric token within
+  ///   Java 16-bit signed {@code short} range); otherwise exception thrown
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  int getShortValue() => _getShortValue(reference);
+
+  static final _getIntValue =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getIntValue")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract int getIntValue()
+  ///
+  /// Numeric accessor that can be called when the current
+  /// token is of type JsonToken\#VALUE_NUMBER_INT and
+  /// it can be expressed as a value of Java int primitive type.
+  /// It can also be called for JsonToken\#VALUE_NUMBER_FLOAT;
+  /// if so, it is equivalent to calling \#getDoubleValue
+  /// and then casting; except for possible overflow/underflow
+  /// exception.
+  ///
+  /// Note: if the resulting integer value falls outside range of
+  /// Java {@code int}, a InputCoercionException
+  /// may be thrown to indicate numeric overflow/underflow.
+  ///@return Current number value as {@code int} (if numeric token within
+  ///   Java 32-bit signed {@code int} range); otherwise exception thrown
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  int getIntValue() => _getIntValue(reference);
+
+  static final _getLongValue =
+      jlookup<ffi.NativeFunction<ffi.Int64 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getLongValue")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract long getLongValue()
+  ///
+  /// Numeric accessor that can be called when the current
+  /// token is of type JsonToken\#VALUE_NUMBER_INT and
+  /// it can be expressed as a Java long primitive type.
+  /// It can also be called for JsonToken\#VALUE_NUMBER_FLOAT;
+  /// if so, it is equivalent to calling \#getDoubleValue
+  /// and then casting to int; except for possible overflow/underflow
+  /// exception.
+  ///
+  /// Note: if the token is an integer, but its value falls
+  /// outside of range of Java long, a InputCoercionException
+  /// may be thrown to indicate numeric overflow/underflow.
+  ///@return Current number value as {@code long} (if numeric token within
+  ///   Java 32-bit signed {@code long} range); otherwise exception thrown
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  int getLongValue() => _getLongValue(reference);
+
+  static final _getBigIntegerValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getBigIntegerValue")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract java.math.BigInteger getBigIntegerValue()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Numeric accessor that can be called when the current
+  /// token is of type JsonToken\#VALUE_NUMBER_INT and
+  /// it can not be used as a Java long primitive type due to its
+  /// magnitude.
+  /// It can also be called for JsonToken\#VALUE_NUMBER_FLOAT;
+  /// if so, it is equivalent to calling \#getDecimalValue
+  /// and then constructing a BigInteger from that value.
+  ///@return Current number value as BigInteger (if numeric token);
+  ///     otherwise exception thrown
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  jni.JlObject getBigIntegerValue() =>
+      jni.JlObject.fromRef(_getBigIntegerValue(reference));
+
+  static final _getFloatValue =
+      jlookup<ffi.NativeFunction<ffi.Float Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getFloatValue")
+          .asFunction<double Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract float getFloatValue()
+  ///
+  /// Numeric accessor that can be called when the current
+  /// token is of type JsonToken\#VALUE_NUMBER_FLOAT and
+  /// it can be expressed as a Java float primitive type.
+  /// It can also be called for JsonToken\#VALUE_NUMBER_INT;
+  /// if so, it is equivalent to calling \#getLongValue
+  /// and then casting; except for possible overflow/underflow
+  /// exception.
+  ///
+  /// Note: if the value falls
+  /// outside of range of Java float, a InputCoercionException
+  /// will be thrown to indicate numeric overflow/underflow.
+  ///@return Current number value as {@code float} (if numeric token within
+  ///   Java {@code float} range); otherwise exception thrown
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  double getFloatValue() => _getFloatValue(reference);
+
+  static final _getDoubleValue =
+      jlookup<ffi.NativeFunction<ffi.Double Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getDoubleValue")
+          .asFunction<double Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract double getDoubleValue()
+  ///
+  /// Numeric accessor that can be called when the current
+  /// token is of type JsonToken\#VALUE_NUMBER_FLOAT and
+  /// it can be expressed as a Java double primitive type.
+  /// It can also be called for JsonToken\#VALUE_NUMBER_INT;
+  /// if so, it is equivalent to calling \#getLongValue
+  /// and then casting; except for possible overflow/underflow
+  /// exception.
+  ///
+  /// Note: if the value falls
+  /// outside of range of Java double, a InputCoercionException
+  /// will be thrown to indicate numeric overflow/underflow.
+  ///@return Current number value as {@code double} (if numeric token within
+  ///   Java {@code double} range); otherwise exception thrown
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  double getDoubleValue() => _getDoubleValue(reference);
+
+  static final _getDecimalValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getDecimalValue")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract java.math.BigDecimal getDecimalValue()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Numeric accessor that can be called when the current
+  /// token is of type JsonToken\#VALUE_NUMBER_FLOAT or
+  /// JsonToken\#VALUE_NUMBER_INT. No under/overflow exceptions
+  /// are ever thrown.
+  ///@return Current number value as BigDecimal (if numeric token);
+  ///   otherwise exception thrown
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  jni.JlObject getDecimalValue() =>
+      jni.JlObject.fromRef(_getDecimalValue(reference));
+
+  static final _getBooleanValue =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getBooleanValue")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean getBooleanValue()
+  ///
+  /// Convenience accessor that can be called when the current
+  /// token is JsonToken\#VALUE_TRUE or
+  /// JsonToken\#VALUE_FALSE, to return matching {@code boolean}
+  /// value.
+  /// If the current token is of some other type, JsonParseException
+  /// will be thrown
+  ///@return {@code True} if current token is {@code JsonToken.VALUE_TRUE},
+  ///   {@code false} if current token is {@code JsonToken.VALUE_FALSE};
+  ///   otherwise throws JsonParseException
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  bool getBooleanValue() => _getBooleanValue(reference) != 0;
+
+  static final _getEmbeddedObject = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getEmbeddedObject")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.Object getEmbeddedObject()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Accessor that can be called if (and only if) the current token
+  /// is JsonToken\#VALUE_EMBEDDED_OBJECT. For other token types,
+  /// null is returned.
+  ///
+  /// Note: only some specialized parser implementations support
+  /// embedding of objects (usually ones that are facades on top
+  /// of non-streaming sources, such as object trees). One exception
+  /// is access to binary content (whether via base64 encoding or not)
+  /// which typically is accessible using this method, as well as
+  /// \#getBinaryValue().
+  ///@return Embedded value (usually of "native" type supported by format)
+  ///   for the current token, if any; {@code null otherwise}
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  jni.JlObject getEmbeddedObject() =>
+      jni.JlObject.fromRef(_getEmbeddedObject(reference));
+
+  static final _getBinaryValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getBinaryValue")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract byte[] getBinaryValue(com.fasterxml.jackson.core.Base64Variant bv)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that can be used to read (and consume -- results
+  /// may not be accessible using other methods after the call)
+  /// base64-encoded binary data
+  /// included in the current textual JSON value.
+  /// It works similar to getting String value via \#getText
+  /// and decoding result (except for decoding part),
+  /// but should be significantly more performant.
+  ///
+  /// Note that non-decoded textual contents of the current token
+  /// are not guaranteed to be accessible after this method
+  /// is called. Current implementation, for example, clears up
+  /// textual content during decoding.
+  /// Decoded binary content, however, will be retained until
+  /// parser is advanced to the next event.
+  ///@param bv Expected variant of base64 encoded
+  ///   content (see Base64Variants for definitions
+  ///   of "standard" variants).
+  ///@return Decoded binary data
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  jni.JlObject getBinaryValue(jni.JlObject bv) =>
+      jni.JlObject.fromRef(_getBinaryValue(reference, bv.reference));
+
+  static final _getBinaryValue1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getBinaryValue1")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public byte[] getBinaryValue()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Convenience alternative to \#getBinaryValue(Base64Variant)
+  /// that defaults to using
+  /// Base64Variants\#getDefaultVariant as the default encoding.
+  ///@return Decoded binary data
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  jni.JlObject getBinaryValue1() =>
+      jni.JlObject.fromRef(_getBinaryValue1(reference));
+
+  static final _readBinaryValue = jlookup<
+              ffi.NativeFunction<
+                  ffi.Int32 Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_readBinaryValue")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int readBinaryValue(java.io.OutputStream out)
+  ///
+  /// Method that can be used as an alternative to \#getBigIntegerValue(),
+  /// especially when value can be large. The main difference (beyond method
+  /// of returning content using OutputStream instead of as byte array)
+  /// is that content will NOT remain accessible after method returns: any content
+  /// processed will be consumed and is not buffered in any way. If caller needs
+  /// buffering, it has to implement it.
+  ///@param out Output stream to use for passing decoded binary data
+  ///@return Number of bytes that were decoded and written via OutputStream
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@since 2.1
+  int readBinaryValue(jni.JlObject out) =>
+      _readBinaryValue(reference, out.reference);
+
+  static final _readBinaryValue1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Int32 Function(ffi.Pointer<ffi.Void>,
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_readBinaryValue1")
+      .asFunction<
+          int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>,
+              ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int readBinaryValue(com.fasterxml.jackson.core.Base64Variant bv, java.io.OutputStream out)
+  ///
+  /// Similar to \#readBinaryValue(OutputStream) but allows explicitly
+  /// specifying base64 variant to use.
+  ///@param bv base64 variant to use
+  ///@param out Output stream to use for passing decoded binary data
+  ///@return Number of bytes that were decoded and written via OutputStream
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@since 2.1
+  int readBinaryValue1(jni.JlObject bv, jni.JlObject out) =>
+      _readBinaryValue1(reference, bv.reference, out.reference);
+
+  static final _getValueAsInt =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getValueAsInt")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int getValueAsInt()
+  ///
+  /// Method that will try to convert value of current token to a
+  /// Java {@code int} value.
+  /// Numbers are coerced using default Java rules; booleans convert to 0 (false)
+  /// and 1 (true), and Strings are parsed using default Java language integer
+  /// parsing rules.
+  ///
+  /// If representation can not be converted to an int (including structured type
+  /// markers like start/end Object/Array)
+  /// default value of __0__ will be returned; no exceptions are thrown.
+  ///@return {@code int} value current token is converted to, if possible; exception thrown
+  ///    otherwise
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  int getValueAsInt() => _getValueAsInt(reference);
+
+  static final _getValueAsInt1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Int32 Function(ffi.Pointer<ffi.Void>, ffi.Int32)>>(
+          "com_fasterxml_jackson_core_JsonParser_getValueAsInt1")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public int getValueAsInt(int def)
+  ///
+  /// Method that will try to convert value of current token to a
+  /// __int__.
+  /// Numbers are coerced using default Java rules; booleans convert to 0 (false)
+  /// and 1 (true), and Strings are parsed using default Java language integer
+  /// parsing rules.
+  ///
+  /// If representation can not be converted to an int (including structured type
+  /// markers like start/end Object/Array)
+  /// specified __def__ will be returned; no exceptions are thrown.
+  ///@param def Default value to return if conversion to {@code int} is not possible
+  ///@return {@code int} value current token is converted to, if possible; {@code def} otherwise
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  int getValueAsInt1(int def) => _getValueAsInt1(reference, def);
+
+  static final _getValueAsLong =
+      jlookup<ffi.NativeFunction<ffi.Int64 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getValueAsLong")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public long getValueAsLong()
+  ///
+  /// Method that will try to convert value of current token to a
+  /// __long__.
+  /// Numbers are coerced using default Java rules; booleans convert to 0 (false)
+  /// and 1 (true), and Strings are parsed using default Java language integer
+  /// parsing rules.
+  ///
+  /// If representation can not be converted to a long (including structured type
+  /// markers like start/end Object/Array)
+  /// default value of __0L__ will be returned; no exceptions are thrown.
+  ///@return {@code long} value current token is converted to, if possible; exception thrown
+  ///    otherwise
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  int getValueAsLong() => _getValueAsLong(reference);
+
+  static final _getValueAsLong1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Int64 Function(ffi.Pointer<ffi.Void>, ffi.Int64)>>(
+          "com_fasterxml_jackson_core_JsonParser_getValueAsLong1")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public long getValueAsLong(long def)
+  ///
+  /// Method that will try to convert value of current token to a
+  /// __long__.
+  /// Numbers are coerced using default Java rules; booleans convert to 0 (false)
+  /// and 1 (true), and Strings are parsed using default Java language integer
+  /// parsing rules.
+  ///
+  /// If representation can not be converted to a long (including structured type
+  /// markers like start/end Object/Array)
+  /// specified __def__ will be returned; no exceptions are thrown.
+  ///@param def Default value to return if conversion to {@code long} is not possible
+  ///@return {@code long} value current token is converted to, if possible; {@code def} otherwise
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  int getValueAsLong1(int def) => _getValueAsLong1(reference, def);
+
+  static final _getValueAsDouble =
+      jlookup<ffi.NativeFunction<ffi.Double Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getValueAsDouble")
+          .asFunction<double Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public double getValueAsDouble()
+  ///
+  /// Method that will try to convert value of current token to a Java
+  /// __double__.
+  /// Numbers are coerced using default Java rules; booleans convert to 0.0 (false)
+  /// and 1.0 (true), and Strings are parsed using default Java language floating
+  /// point parsing rules.
+  ///
+  /// If representation can not be converted to a double (including structured types
+  /// like Objects and Arrays),
+  /// default value of __0.0__ will be returned; no exceptions are thrown.
+  ///@return {@code double} value current token is converted to, if possible; exception thrown
+  ///    otherwise
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  double getValueAsDouble() => _getValueAsDouble(reference);
+
+  static final _getValueAsDouble1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Double Function(ffi.Pointer<ffi.Void>, ffi.Double)>>(
+          "com_fasterxml_jackson_core_JsonParser_getValueAsDouble1")
+      .asFunction<double Function(ffi.Pointer<ffi.Void>, double)>();
+
+  /// from: public double getValueAsDouble(double def)
+  ///
+  /// Method that will try to convert value of current token to a
+  /// Java __double__.
+  /// Numbers are coerced using default Java rules; booleans convert to 0.0 (false)
+  /// and 1.0 (true), and Strings are parsed using default Java language floating
+  /// point parsing rules.
+  ///
+  /// If representation can not be converted to a double (including structured types
+  /// like Objects and Arrays),
+  /// specified __def__ will be returned; no exceptions are thrown.
+  ///@param def Default value to return if conversion to {@code double} is not possible
+  ///@return {@code double} value current token is converted to, if possible; {@code def} otherwise
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  double getValueAsDouble1(double def) => _getValueAsDouble1(reference, def);
+
+  static final _getValueAsBoolean =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_getValueAsBoolean")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean getValueAsBoolean()
+  ///
+  /// Method that will try to convert value of current token to a
+  /// __boolean__.
+  /// JSON booleans map naturally; integer numbers other than 0 map to true, and
+  /// 0 maps to false
+  /// and Strings 'true' and 'false' map to corresponding values.
+  ///
+  /// If representation can not be converted to a boolean value (including structured types
+  /// like Objects and Arrays),
+  /// default value of __false__ will be returned; no exceptions are thrown.
+  ///@return {@code boolean} value current token is converted to, if possible; exception thrown
+  ///    otherwise
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  bool getValueAsBoolean() => _getValueAsBoolean(reference) != 0;
+
+  static final _getValueAsBoolean1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(ffi.Pointer<ffi.Void>, ffi.Uint8)>>(
+          "com_fasterxml_jackson_core_JsonParser_getValueAsBoolean1")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public boolean getValueAsBoolean(boolean def)
+  ///
+  /// Method that will try to convert value of current token to a
+  /// __boolean__.
+  /// JSON booleans map naturally; integer numbers other than 0 map to true, and
+  /// 0 maps to false
+  /// and Strings 'true' and 'false' map to corresponding values.
+  ///
+  /// If representation can not be converted to a boolean value (including structured types
+  /// like Objects and Arrays),
+  /// specified __def__ will be returned; no exceptions are thrown.
+  ///@param def Default value to return if conversion to {@code boolean} is not possible
+  ///@return {@code boolean} value current token is converted to, if possible; {@code def} otherwise
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  bool getValueAsBoolean1(bool def) =>
+      _getValueAsBoolean1(reference, def ? 1 : 0) != 0;
+
+  static final _getValueAsString = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getValueAsString")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.String getValueAsString()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that will try to convert value of current token to a
+  /// java.lang.String.
+  /// JSON Strings map naturally; scalar values get converted to
+  /// their textual representation.
+  /// If representation can not be converted to a String value (including structured types
+  /// like Objects and Arrays and {@code null} token), default value of
+  /// __null__ will be returned; no exceptions are thrown.
+  ///@return String value current token is converted to, if possible; {@code null} otherwise
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@since 2.1
+  jni.JlString getValueAsString() =>
+      jni.JlString.fromRef(_getValueAsString(reference));
+
+  static final _getValueAsString1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getValueAsString1")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public abstract java.lang.String getValueAsString(java.lang.String def)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that will try to convert value of current token to a
+  /// java.lang.String.
+  /// JSON Strings map naturally; scalar values get converted to
+  /// their textual representation.
+  /// If representation can not be converted to a String value (including structured types
+  /// like Objects and Arrays and {@code null} token), specified default value
+  /// will be returned; no exceptions are thrown.
+  ///@param def Default value to return if conversion to {@code String} is not possible
+  ///@return String value current token is converted to, if possible; {@code def} otherwise
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@since 2.1
+  jni.JlString getValueAsString1(jni.JlString def) =>
+      jni.JlString.fromRef(_getValueAsString1(reference, def.reference));
+
+  static final _canReadObjectId =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_canReadObjectId")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean canReadObjectId()
+  ///
+  /// Introspection method that may be called to see if the underlying
+  /// data format supports some kind of Object Ids natively (many do not;
+  /// for example, JSON doesn't).
+  ///
+  /// Default implementation returns true; overridden by data formats
+  /// that do support native Object Ids. Caller is expected to either
+  /// use a non-native notation (explicit property or such), or fail,
+  /// in case it can not use native object ids.
+  ///@return {@code True} if the format being read supports native Object Ids;
+  ///    {@code false} if not
+  ///@since 2.3
+  bool canReadObjectId() => _canReadObjectId(reference) != 0;
+
+  static final _canReadTypeId =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser_canReadTypeId")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean canReadTypeId()
+  ///
+  /// Introspection method that may be called to see if the underlying
+  /// data format supports some kind of Type Ids natively (many do not;
+  /// for example, JSON doesn't).
+  ///
+  /// Default implementation returns true; overridden by data formats
+  /// that do support native Type Ids. Caller is expected to either
+  /// use a non-native notation (explicit property or such), or fail,
+  /// in case it can not use native type ids.
+  ///@return {@code True} if the format being read supports native Type Ids;
+  ///    {@code false} if not
+  ///@since 2.3
+  bool canReadTypeId() => _canReadTypeId(reference) != 0;
+
+  static final _getObjectId = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getObjectId")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.Object getObjectId()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that can be called to check whether current token
+  /// (one that was just read) has an associated Object id, and if
+  /// so, return it.
+  /// Note that while typically caller should check with \#canReadObjectId
+  /// first, it is not illegal to call this method even if that method returns
+  /// true; but if so, it will return null. This may be used to simplify calling
+  /// code.
+  ///
+  /// Default implementation will simply return null.
+  ///@return Native Object id associated with the current token, if any; {@code null} if none
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@since 2.3
+  jni.JlObject getObjectId() => jni.JlObject.fromRef(_getObjectId(reference));
+
+  static final _getTypeId = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_getTypeId")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.lang.Object getTypeId()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method that can be called to check whether current token
+  /// (one that was just read) has an associated type id, and if
+  /// so, return it.
+  /// Note that while typically caller should check with \#canReadTypeId
+  /// first, it is not illegal to call this method even if that method returns
+  /// true; but if so, it will return null. This may be used to simplify calling
+  /// code.
+  ///
+  /// Default implementation will simply return null.
+  ///@return Native Type Id associated with the current token, if any; {@code null} if none
+  ///@throws IOException for low-level read issues, or
+  ///   JsonParseException for decoding problems
+  ///@since 2.3
+  jni.JlObject getTypeId() => jni.JlObject.fromRef(_getTypeId(reference));
+
+  static final _readValuesAs = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_readValuesAs")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.util.Iterator<T> readValuesAs(java.lang.Class<T> valueType)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for reading sequence of Objects from parser stream,
+  /// all with same specified value type.
+  ///@param <T> Nominal type parameter for value type
+  ///@param valueType Java type to read content as (passed to ObjectCodec that
+  ///    deserializes content)
+  ///@return Iterator for reading multiple Java values from content
+  ///@throws IOException if there is either an underlying I/O problem or decoding
+  ///    issue at format layer
+  jni.JlObject readValuesAs(jni.JlObject valueType) =>
+      jni.JlObject.fromRef(_readValuesAs(reference, valueType.reference));
+
+  static final _readValuesAs1 = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(
+                      ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser_readValuesAs1")
+      .asFunction<
+          ffi.Pointer<ffi.Void> Function(
+              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();
+
+  /// from: public java.util.Iterator<T> readValuesAs(com.fasterxml.jackson.core.type.TypeReference<T> valueTypeRef)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  ///
+  /// Method for reading sequence of Objects from parser stream,
+  /// all with same specified value type.
+  ///@param <T> Nominal type parameter for value type
+  ///@param valueTypeRef Java type to read content as (passed to ObjectCodec that
+  ///    deserializes content)
+  ///@return Iterator for reading multiple Java values from content
+  ///@throws IOException if there is either an underlying I/O problem or decoding
+  ///    issue at format layer
+  jni.JlObject readValuesAs1(jni.JlObject valueTypeRef) =>
+      jni.JlObject.fromRef(_readValuesAs1(reference, valueTypeRef.reference));
+}
+
+/// from: com.fasterxml.jackson.core.JsonParser$Feature
+///
+/// Enumeration that defines all on/off features for parsers.
+class JsonParser_Feature extends jni.JlObject {
+  JsonParser_Feature.fromRef(ffi.Pointer<ffi.Void> ref) : super.fromRef(ref);
+
+  static final _values =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "com_fasterxml_jackson_core_JsonParser__Feature_values")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: static public com.fasterxml.jackson.core.JsonParser.Feature[] values()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static jni.JlObject values() => jni.JlObject.fromRef(_values());
+
+  static final _valueOf = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser__Feature_valueOf")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: static public com.fasterxml.jackson.core.JsonParser.Feature valueOf(java.lang.String name)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static JsonParser_Feature valueOf(jni.JlString name) =>
+      JsonParser_Feature.fromRef(_valueOf(name.reference));
+
+  static final _collectDefaults =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function()>>(
+              "com_fasterxml_jackson_core_JsonParser__Feature_collectDefaults")
+          .asFunction<int Function()>();
+
+  /// from: static public int collectDefaults()
+  ///
+  /// Method that calculates bit set (flags) of all features that
+  /// are enabled by default.
+  ///@return Bit mask of all features that are enabled by default
+  static int collectDefaults() => _collectDefaults();
+
+  static final _ctor =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Uint8)>>(
+              "com_fasterxml_jackson_core_JsonParser__Feature_ctor")
+          .asFunction<ffi.Pointer<ffi.Void> Function(int)>();
+
+  /// from: private void <init>(boolean defaultState)
+  JsonParser_Feature(bool defaultState)
+      : super.fromRef(_ctor(defaultState ? 1 : 0));
+
+  static final _enabledByDefault =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser__Feature_enabledByDefault")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean enabledByDefault()
+  bool enabledByDefault() => _enabledByDefault(reference) != 0;
+
+  static final _enabledIn = jlookup<
+              ffi.NativeFunction<
+                  ffi.Uint8 Function(ffi.Pointer<ffi.Void>, ffi.Int32)>>(
+          "com_fasterxml_jackson_core_JsonParser__Feature_enabledIn")
+      .asFunction<int Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public boolean enabledIn(int flags)
+  bool enabledIn(int flags) => _enabledIn(reference, flags) != 0;
+
+  static final _getMask =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonParser__Feature_getMask")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int getMask()
+  int getMask() => _getMask(reference);
+}
+
+/// from: com.fasterxml.jackson.core.JsonParser$NumberType
+///
+/// Enumeration of possible "native" (optimal) types that can be
+/// used for numbers.
+class JsonParser_NumberType extends jni.JlObject {
+  JsonParser_NumberType.fromRef(ffi.Pointer<ffi.Void> ref) : super.fromRef(ref);
+
+  static final _values =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "com_fasterxml_jackson_core_JsonParser__NumberType_values")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: static public com.fasterxml.jackson.core.JsonParser.NumberType[] values()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static jni.JlObject values() => jni.JlObject.fromRef(_values());
+
+  static final _valueOf = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonParser__NumberType_valueOf")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: static public com.fasterxml.jackson.core.JsonParser.NumberType valueOf(java.lang.String name)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static JsonParser_NumberType valueOf(jni.JlString name) =>
+      JsonParser_NumberType.fromRef(_valueOf(name.reference));
+
+  static final _ctor =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "com_fasterxml_jackson_core_JsonParser__NumberType_ctor")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: private void <init>()
+  JsonParser_NumberType() : super.fromRef(_ctor());
+}
+
+/// from: com.fasterxml.jackson.core.JsonToken
+///
+/// Enumeration for basic token types used for returning results
+/// of parsing JSON content.
+class JsonToken extends jni.JlObject {
+  JsonToken.fromRef(ffi.Pointer<ffi.Void> ref) : super.fromRef(ref);
+
+  static final _values =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "com_fasterxml_jackson_core_JsonToken_values")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: static public com.fasterxml.jackson.core.JsonToken[] values()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static jni.JlObject values() => jni.JlObject.fromRef(_values());
+
+  static final _valueOf = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonToken_valueOf")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: static public com.fasterxml.jackson.core.JsonToken valueOf(java.lang.String name)
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static JsonToken valueOf(jni.JlString name) =>
+      JsonToken.fromRef(_valueOf(name.reference));
+
+  static final _ctor = jlookup<
+          ffi.NativeFunction<
+              ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>,
+                  ffi.Int32)>>("com_fasterxml_jackson_core_JsonToken_ctor")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: private void <init>(java.lang.String token, int id)
+  ///
+  /// @param token representation for this token, if there is a
+  ///   single static representation; null otherwise
+  ///@param id Numeric id from JsonTokenId
+  JsonToken(jni.JlString token, int id)
+      : super.fromRef(_ctor(token.reference, id));
+
+  static final _id =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonToken_id")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final int id()
+  int id() => _id(reference);
+
+  static final _asString = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonToken_asString")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final java.lang.String asString()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  jni.JlString asString() => jni.JlString.fromRef(_asString(reference));
+
+  static final _asCharArray = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonToken_asCharArray")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final char[] asCharArray()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  jni.JlObject asCharArray() => jni.JlObject.fromRef(_asCharArray(reference));
+
+  static final _asByteArray = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "com_fasterxml_jackson_core_JsonToken_asByteArray")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final byte[] asByteArray()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  jni.JlObject asByteArray() => jni.JlObject.fromRef(_asByteArray(reference));
+
+  static final _isNumeric =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonToken_isNumeric")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final boolean isNumeric()
+  ///
+  /// @return {@code True} if this token is {@code VALUE_NUMBER_INT} or {@code VALUE_NUMBER_FLOAT},
+  ///   {@code false} otherwise
+  bool isNumeric() => _isNumeric(reference) != 0;
+
+  static final _isStructStart =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonToken_isStructStart")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final boolean isStructStart()
+  ///
+  /// Accessor that is functionally equivalent to:
+  /// <code>
+  ///    this == JsonToken.START_OBJECT || this == JsonToken.START_ARRAY
+  /// </code>
+  ///@return {@code True} if this token is {@code START_OBJECT} or {@code START_ARRAY},
+  ///   {@code false} otherwise
+  ///@since 2.3
+  bool isStructStart() => _isStructStart(reference) != 0;
+
+  static final _isStructEnd =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonToken_isStructEnd")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final boolean isStructEnd()
+  ///
+  /// Accessor that is functionally equivalent to:
+  /// <code>
+  ///    this == JsonToken.END_OBJECT || this == JsonToken.END_ARRAY
+  /// </code>
+  ///@return {@code True} if this token is {@code END_OBJECT} or {@code END_ARRAY},
+  ///   {@code false} otherwise
+  ///@since 2.3
+  bool isStructEnd() => _isStructEnd(reference) != 0;
+
+  static final _isScalarValue =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonToken_isScalarValue")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final boolean isScalarValue()
+  ///
+  /// Method that can be used to check whether this token represents
+  /// a valid non-structured value. This means all {@code VALUE_xxx} tokens;
+  /// excluding {@code START_xxx} and {@code END_xxx} tokens as well
+  /// {@code FIELD_NAME}.
+  ///@return {@code True} if this token is a scalar value token (one of
+  ///   {@code VALUE_xxx} tokens), {@code false} otherwise
+  bool isScalarValue() => _isScalarValue(reference) != 0;
+
+  static final _isBoolean =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "com_fasterxml_jackson_core_JsonToken_isBoolean")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public final boolean isBoolean()
+  ///
+  /// @return {@code True} if this token is {@code VALUE_TRUE} or {@code VALUE_FALSE},
+  ///   {@code false} otherwise
+  bool isBoolean() => _isBoolean(reference) != 0;
+}
diff --git a/pkgs/jni_gen/test/jackson_core_test/third_party/lib/init.dart b/pkgs/jni_gen/test/jackson_core_test/third_party/lib/init.dart
new file mode 100644
index 0000000..062c5a8
--- /dev/null
+++ b/pkgs/jni_gen/test/jackson_core_test/third_party/lib/init.dart
@@ -0,0 +1,5 @@
+import "dart:ffi";
+import "package:jni/jni.dart";
+
+final Pointer<T> Function<T extends NativeType>(String sym) jlookup =
+    Jni.getInstance().initGeneratedLibrary("jackson_core_test");
diff --git a/pkgs/jni_gen/test/jackson_core_test/third_party/src/CMakeLists.txt b/pkgs/jni_gen/test/jackson_core_test/third_party/src/CMakeLists.txt
new file mode 100644
index 0000000..657e001
--- /dev/null
+++ b/pkgs/jni_gen/test/jackson_core_test/third_party/src/CMakeLists.txt
@@ -0,0 +1,30 @@
+# The Flutter tooling requires that developers have CMake 3.10 or later
+# installed. You should not increase this version, as doing so will cause
+# the plugin to fail to compile for some customers of the plugin.
+cmake_minimum_required(VERSION 3.10)
+
+project(jackson_core_test VERSION 0.0.1 LANGUAGES C)
+
+add_library(jackson_core_test SHARED
+  "jackson_core_test.c"
+)
+
+set_target_properties(jackson_core_test PROPERTIES
+  OUTPUT_NAME "jackson_core_test"
+)
+
+target_compile_definitions(jackson_core_test PUBLIC DART_SHARED_LIB)
+
+if(WIN32)
+	set_target_properties(${TARGET_NAME} PROPERTIES
+		LINK_FLAGS "/DELAYLOAD:jvm.dll")
+endif()
+
+if (ANDROID)
+	target_link_libraries(jackson_core_test log)
+else()
+	find_package(Java REQUIRED)
+	find_package(JNI REQUIRED)
+	include_directories(${JNI_INCLUDE_DIRS})
+	target_link_libraries(jackson_core_test ${JNI_LIBRARIES})
+endif()
diff --git a/pkgs/jni_gen/test/jackson_core_test/third_party/src/dartjni.h b/pkgs/jni_gen/test/jackson_core_test/third_party/src/dartjni.h
new file mode 100644
index 0000000..407312b
--- /dev/null
+++ b/pkgs/jni_gen/test/jackson_core_test/third_party/src/dartjni.h
@@ -0,0 +1,173 @@
+#include <jni.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if _WIN32
+#include <windows.h>
+#else
+#include <pthread.h>
+#include <unistd.h>
+#endif
+
+#if _WIN32
+#define FFI_PLUGIN_EXPORT __declspec(dllexport)
+#else
+#define FFI_PLUGIN_EXPORT
+#endif
+
+#if defined _WIN32
+#define thread_local __declspec(thread)
+#else
+#define thread_local __thread
+#endif
+
+#ifdef __ANDROID__
+#include <android/log.h>
+#endif
+
+#define JNI_LOG_TAG "Dart-JNI"
+
+#ifdef __ANDROID__
+#define __ENVP_CAST (JNIEnv **)
+#else
+#define __ENVP_CAST (void **)
+#endif
+
+struct jni_context {
+	JavaVM *jvm;
+	jobject classLoader;
+	jmethodID loadClassMethod;
+	jobject currentActivity;
+	jobject appContext;
+};
+
+extern thread_local JNIEnv *jniEnv;
+
+extern struct jni_context jni;
+
+enum DartJniLogLevel {
+	JNI_VERBOSE = 2,
+	JNI_DEBUG,
+	JNI_INFO,
+	JNI_WARN,
+	JNI_ERROR
+};
+
+FFI_PLUGIN_EXPORT struct jni_context GetJniContext();
+
+FFI_PLUGIN_EXPORT JavaVM *GetJavaVM(void);
+
+FFI_PLUGIN_EXPORT JNIEnv *GetJniEnv(void);
+
+FFI_PLUGIN_EXPORT JNIEnv *SpawnJvm(JavaVMInitArgs *args);
+
+FFI_PLUGIN_EXPORT jclass LoadClass(const char *name);
+
+FFI_PLUGIN_EXPORT jobject GetClassLoader(void);
+
+FFI_PLUGIN_EXPORT jobject GetApplicationContext(void);
+
+FFI_PLUGIN_EXPORT jobject GetCurrentActivity(void);
+
+FFI_PLUGIN_EXPORT void SetJNILogging(int level);
+
+FFI_PLUGIN_EXPORT jstring ToJavaString(char *str);
+
+FFI_PLUGIN_EXPORT const char *GetJavaStringChars(jstring jstr);
+
+FFI_PLUGIN_EXPORT void ReleaseJavaStringChars(jstring jstr, const char *buf);
+
+// These 2 are the function pointer variables defined and exported by
+// the generated C files.
+//
+// initGeneratedLibrary function in Jni class will set these to
+// corresponding functions to the implementations from `dartjni` base library
+// which initializes and manages the JNI.
+extern struct jni_context (*context_getter)(void);
+extern JNIEnv *(*env_getter)(void);
+
+// This function will be exported by generated code library and will set the
+// above 2 variables.
+FFI_PLUGIN_EXPORT void setJniGetters(struct jni_context (*cg)(void),
+		JNIEnv *(*eg)(void));
+
+// `static inline` because `inline` doesn't work, it may still not
+// inline the function in which case a linker error may be produced.
+//
+// There has to be a better way to do this. Either to force inlining on target
+// platforms, or just leave it as normal function.
+static inline void __load_class_into(jclass *cls, const char *name) {
+#ifdef __ANDROID__
+	jstring className = (*jniEnv)->NewStringUTF(jniEnv, name);
+	*cls = (*jniEnv)->CallObjectMethod(jniEnv, jni.classLoader,
+	                                   jni.loadClassMethod, className);
+	(*jniEnv)->DeleteLocalRef(jniEnv, className);
+#else
+	*cls = (*jniEnv)->FindClass(jniEnv, name);
+#endif
+}
+
+static inline void load_class(jclass *cls, const char *name) {
+	if (*cls == NULL) {
+		__load_class_into(cls, name);
+	}
+}
+
+static inline void load_class_gr(jclass *cls, const char *name) {
+	if (*cls == NULL) {
+		jclass tmp;
+		__load_class_into(&tmp, name);
+		*cls = (*jniEnv)->NewGlobalRef(jniEnv, tmp);
+		(*jniEnv)->DeleteLocalRef(jniEnv, tmp);
+	}
+}
+
+static inline void attach_thread() {
+	if (jniEnv == NULL) {
+		(*jni.jvm)->AttachCurrentThread(jni.jvm, __ENVP_CAST & jniEnv,
+		                                NULL);
+	}
+}
+
+static inline void load_env() {
+	if (jniEnv == NULL) {
+		jni = context_getter();
+		jniEnv = env_getter();
+	}
+}
+
+static inline void load_method(jclass cls, jmethodID *res, const char *name,
+                               const char *sig) {
+	if (*res == NULL) {
+		*res = (*jniEnv)->GetMethodID(jniEnv, cls, name, sig);
+	}
+}
+
+static inline void load_static_method(jclass cls, jmethodID *res,
+                                      const char *name, const char *sig) {
+	if (*res == NULL) {
+		*res = (*jniEnv)->GetStaticMethodID(jniEnv, cls, name, sig);
+	}
+}
+
+static inline void load_field(jclass cls, jfieldID *res, const char *name,
+                              const char *sig) {
+	if (*res == NULL) {
+		*res = (*jniEnv)->GetFieldID(jniEnv, cls, name, sig);
+	}
+}
+
+static inline void load_static_field(jclass cls, jfieldID *res,
+                                     const char *name, const char *sig) {
+	if (*res == NULL) {
+		*res = (*jniEnv)->GetStaticFieldID(jniEnv, cls, name, sig);
+	}
+}
+
+static inline jobject to_global_ref(jobject ref) {
+	jobject g = (*jniEnv)->NewGlobalRef(jniEnv, ref);
+	(*jniEnv)->DeleteLocalRef(jniEnv, ref);
+	return g;
+}
+
diff --git a/pkgs/jni_gen/test/jackson_core_test/third_party/src/jackson_core_test.c b/pkgs/jni_gen/test/jackson_core_test/third_party/src/jackson_core_test.c
new file mode 100644
index 0000000..f91f6c0
--- /dev/null
+++ b/pkgs/jni_gen/test/jackson_core_test/third_party/src/jackson_core_test.c
@@ -0,0 +1,2207 @@
+// Generated from jackson-core which is licensed under the Apache License 2.0.
+// The following copyright from the original authors applies.
+// See https://github.com/FasterXML/jackson-core/blob/2.14/LICENSE
+//
+// Copyright (c) 2007 - The Jackson Project Authors
+// Licensed under the Apache License, Version 2.0 (the "License")
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Autogenerated by jni_gen. DO NOT EDIT!
+
+#include <stdint.h>
+#include "jni.h"
+#include "dartjni.h"
+
+thread_local JNIEnv *jniEnv;
+struct jni_context jni;
+
+struct jni_context (*context_getter)(void);
+JNIEnv *(*env_getter)(void);
+
+void setJniGetters(struct jni_context (*cg)(void),
+        JNIEnv *(*eg)(void)) {
+    context_getter = cg;
+    env_getter = eg;
+}
+
+// com.fasterxml.jackson.core.JsonFactory
+jclass _c_com_fasterxml_jackson_core_JsonFactory = NULL;
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_ctor = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_ctor() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_ctor, "<init>", "()V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory, _m_com_fasterxml_jackson_core_JsonFactory_ctor);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_ctor1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_ctor1(jobject oc) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_ctor1, "<init>", "(Lcom/fasterxml/jackson/core/ObjectCodec;)V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory, _m_com_fasterxml_jackson_core_JsonFactory_ctor1, oc);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_ctor2 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_ctor2(jobject src, jobject codec) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_ctor2, "<init>", "(Lcom/fasterxml/jackson/core/JsonFactory;Lcom/fasterxml/jackson/core/ObjectCodec;)V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory, _m_com_fasterxml_jackson_core_JsonFactory_ctor2, src, codec);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_ctor3 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_ctor3(jobject b) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_ctor3, "<init>", "(Lcom/fasterxml/jackson/core/JsonFactoryBuilder;)V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory, _m_com_fasterxml_jackson_core_JsonFactory_ctor3, b);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_ctor4 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_ctor4(jobject b, uint8_t bogus) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_ctor4, "<init>", "(Lcom/fasterxml/jackson/core/TSFBuilder;Z)V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory, _m_com_fasterxml_jackson_core_JsonFactory_ctor4, b, bogus);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_rebuild = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_rebuild(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_rebuild, "rebuild", "()Lcom/fasterxml/jackson/core/TSFBuilder;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_rebuild);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_builder = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_builder() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_static_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_builder, "builder", "()Lcom/fasterxml/jackson/core/TSFBuilder;");
+    jobject _result = (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory, _m_com_fasterxml_jackson_core_JsonFactory_builder);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_copy = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_copy(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_copy, "copy", "()Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_copy);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_readResolve = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_readResolve(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_readResolve, "readResolve", "()Ljava/lang/Object;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_readResolve);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_requiresPropertyOrdering = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory_requiresPropertyOrdering(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_requiresPropertyOrdering, "requiresPropertyOrdering", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_requiresPropertyOrdering);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_canHandleBinaryNatively = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory_canHandleBinaryNatively(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_canHandleBinaryNatively, "canHandleBinaryNatively", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_canHandleBinaryNatively);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_canUseCharArrays = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory_canUseCharArrays(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_canUseCharArrays, "canUseCharArrays", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_canUseCharArrays);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_canParseAsync = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory_canParseAsync(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_canParseAsync, "canParseAsync", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_canParseAsync);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getFormatReadFeatureType = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_getFormatReadFeatureType(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getFormatReadFeatureType, "getFormatReadFeatureType", "()Ljava/lang/Class;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getFormatReadFeatureType);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getFormatWriteFeatureType = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_getFormatWriteFeatureType(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getFormatWriteFeatureType, "getFormatWriteFeatureType", "()Ljava/lang/Class;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getFormatWriteFeatureType);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_canUseSchema = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory_canUseSchema(jobject self_, jobject schema) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_canUseSchema, "canUseSchema", "(Lcom/fasterxml/jackson/core/FormatSchema;)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_canUseSchema, schema);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getFormatName = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_getFormatName(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getFormatName, "getFormatName", "()Ljava/lang/String;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getFormatName);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_hasFormat = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_hasFormat(jobject self_, jobject acc) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_hasFormat, "hasFormat", "(Lcom/fasterxml/jackson/core/format/InputAccessor;)Lcom/fasterxml/jackson/core/format/MatchStrength;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_hasFormat, acc);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_requiresCustomCodec = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory_requiresCustomCodec(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_requiresCustomCodec, "requiresCustomCodec", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_requiresCustomCodec);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_hasJSONFormat = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_hasJSONFormat(jobject self_, jobject acc) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_hasJSONFormat, "hasJSONFormat", "(Lcom/fasterxml/jackson/core/format/InputAccessor;)Lcom/fasterxml/jackson/core/format/MatchStrength;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_hasJSONFormat, acc);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_version = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_version(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_version, "version", "()Lcom/fasterxml/jackson/core/Version;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_version);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_configure = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_configure(jobject self_, jobject f, uint8_t state) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_configure, "configure", "(Lcom/fasterxml/jackson/core/JsonFactory$Feature;Z)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_configure, f, state);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_enable = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_enable(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_enable, "enable", "(Lcom/fasterxml/jackson/core/JsonFactory$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_enable, f);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_disable = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_disable(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_disable, "disable", "(Lcom/fasterxml/jackson/core/JsonFactory$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_disable, f);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_isEnabled = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory_isEnabled(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_isEnabled, "isEnabled", "(Lcom/fasterxml/jackson/core/JsonFactory$Feature;)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_isEnabled, f);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getParserFeatures = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonFactory_getParserFeatures(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getParserFeatures, "getParserFeatures", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getParserFeatures);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getGeneratorFeatures = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonFactory_getGeneratorFeatures(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getGeneratorFeatures, "getGeneratorFeatures", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getGeneratorFeatures);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getFormatParserFeatures = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonFactory_getFormatParserFeatures(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getFormatParserFeatures, "getFormatParserFeatures", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getFormatParserFeatures);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getFormatGeneratorFeatures = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonFactory_getFormatGeneratorFeatures(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getFormatGeneratorFeatures, "getFormatGeneratorFeatures", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getFormatGeneratorFeatures);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_configure1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_configure1(jobject self_, jobject f, uint8_t state) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_configure1, "configure", "(Lcom/fasterxml/jackson/core/JsonParser$Feature;Z)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_configure1, f, state);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_enable1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_enable1(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_enable1, "enable", "(Lcom/fasterxml/jackson/core/JsonParser$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_enable1, f);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_disable1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_disable1(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_disable1, "disable", "(Lcom/fasterxml/jackson/core/JsonParser$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_disable1, f);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_isEnabled1 = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory_isEnabled1(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_isEnabled1, "isEnabled", "(Lcom/fasterxml/jackson/core/JsonParser$Feature;)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_isEnabled1, f);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_isEnabled2 = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory_isEnabled2(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_isEnabled2, "isEnabled", "(Lcom/fasterxml/jackson/core/StreamReadFeature;)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_isEnabled2, f);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getInputDecorator = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_getInputDecorator(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getInputDecorator, "getInputDecorator", "()Lcom/fasterxml/jackson/core/io/InputDecorator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getInputDecorator);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_setInputDecorator = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_setInputDecorator(jobject self_, jobject d) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_setInputDecorator, "setInputDecorator", "(Lcom/fasterxml/jackson/core/io/InputDecorator;)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_setInputDecorator, d);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_configure2 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_configure2(jobject self_, jobject f, uint8_t state) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_configure2, "configure", "(Lcom/fasterxml/jackson/core/JsonGenerator$Feature;Z)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_configure2, f, state);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_enable2 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_enable2(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_enable2, "enable", "(Lcom/fasterxml/jackson/core/JsonGenerator$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_enable2, f);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_disable2 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_disable2(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_disable2, "disable", "(Lcom/fasterxml/jackson/core/JsonGenerator$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_disable2, f);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_isEnabled3 = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory_isEnabled3(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_isEnabled3, "isEnabled", "(Lcom/fasterxml/jackson/core/JsonGenerator$Feature;)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_isEnabled3, f);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_isEnabled4 = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory_isEnabled4(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_isEnabled4, "isEnabled", "(Lcom/fasterxml/jackson/core/StreamWriteFeature;)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_isEnabled4, f);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getCharacterEscapes = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_getCharacterEscapes(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getCharacterEscapes, "getCharacterEscapes", "()Lcom/fasterxml/jackson/core/io/CharacterEscapes;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getCharacterEscapes);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_setCharacterEscapes = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_setCharacterEscapes(jobject self_, jobject esc) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_setCharacterEscapes, "setCharacterEscapes", "(Lcom/fasterxml/jackson/core/io/CharacterEscapes;)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_setCharacterEscapes, esc);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getOutputDecorator = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_getOutputDecorator(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getOutputDecorator, "getOutputDecorator", "()Lcom/fasterxml/jackson/core/io/OutputDecorator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getOutputDecorator);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_setOutputDecorator = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_setOutputDecorator(jobject self_, jobject d) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_setOutputDecorator, "setOutputDecorator", "(Lcom/fasterxml/jackson/core/io/OutputDecorator;)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_setOutputDecorator, d);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_setRootValueSeparator = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_setRootValueSeparator(jobject self_, jobject sep) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_setRootValueSeparator, "setRootValueSeparator", "(Ljava/lang/String;)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_setRootValueSeparator, sep);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getRootValueSeparator = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_getRootValueSeparator(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getRootValueSeparator, "getRootValueSeparator", "()Ljava/lang/String;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getRootValueSeparator);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_setCodec = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_setCodec(jobject self_, jobject oc) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_setCodec, "setCodec", "(Lcom/fasterxml/jackson/core/ObjectCodec;)Lcom/fasterxml/jackson/core/JsonFactory;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_setCodec, oc);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_getCodec = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_getCodec(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_getCodec, "getCodec", "()Lcom/fasterxml/jackson/core/ObjectCodec;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_getCodec);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createParser = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createParser(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createParser, "createParser", "(Ljava/io/File;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createParser, f);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createParser1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createParser1(jobject self_, jobject url) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createParser1, "createParser", "(Ljava/net/URL;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createParser1, url);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createParser2 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createParser2(jobject self_, jobject in) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createParser2, "createParser", "(Ljava/io/InputStream;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createParser2, in);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createParser3 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createParser3(jobject self_, jobject r) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createParser3, "createParser", "(Ljava/io/Reader;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createParser3, r);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createParser4 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createParser4(jobject self_, jobject data) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createParser4, "createParser", "(L[B;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createParser4, data);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createParser5 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createParser5(jobject self_, jobject data, int32_t offset, int32_t len) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createParser5, "createParser", "(L[B;II)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createParser5, data, offset, len);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createParser6 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createParser6(jobject self_, jobject content) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createParser6, "createParser", "(Ljava/lang/String;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createParser6, content);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createParser7 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createParser7(jobject self_, jobject content) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createParser7, "createParser", "(L[C;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createParser7, content);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createParser8 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createParser8(jobject self_, jobject content, int32_t offset, int32_t len) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createParser8, "createParser", "(L[C;II)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createParser8, content, offset, len);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createParser9 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createParser9(jobject self_, jobject in) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createParser9, "createParser", "(Ljava/io/DataInput;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createParser9, in);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createNonBlockingByteArrayParser = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createNonBlockingByteArrayParser(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createNonBlockingByteArrayParser, "createNonBlockingByteArrayParser", "()Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createNonBlockingByteArrayParser);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createGenerator = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createGenerator(jobject self_, jobject out, jobject enc) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createGenerator, "createGenerator", "(Ljava/io/OutputStream;Lcom/fasterxml/jackson/core/JsonEncoding;)Lcom/fasterxml/jackson/core/JsonGenerator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createGenerator, out, enc);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createGenerator1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createGenerator1(jobject self_, jobject out) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createGenerator1, "createGenerator", "(Ljava/io/OutputStream;)Lcom/fasterxml/jackson/core/JsonGenerator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createGenerator1, out);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createGenerator2 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createGenerator2(jobject self_, jobject w) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createGenerator2, "createGenerator", "(Ljava/io/Writer;)Lcom/fasterxml/jackson/core/JsonGenerator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createGenerator2, w);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createGenerator3 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createGenerator3(jobject self_, jobject f, jobject enc) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createGenerator3, "createGenerator", "(Ljava/io/File;Lcom/fasterxml/jackson/core/JsonEncoding;)Lcom/fasterxml/jackson/core/JsonGenerator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createGenerator3, f, enc);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createGenerator4 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createGenerator4(jobject self_, jobject out, jobject enc) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createGenerator4, "createGenerator", "(Ljava/io/DataOutput;Lcom/fasterxml/jackson/core/JsonEncoding;)Lcom/fasterxml/jackson/core/JsonGenerator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createGenerator4, out, enc);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createGenerator5 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createGenerator5(jobject self_, jobject out) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createGenerator5, "createGenerator", "(Ljava/io/DataOutput;)Lcom/fasterxml/jackson/core/JsonGenerator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createGenerator5, out);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createJsonParser(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createJsonParser, "createJsonParser", "(Ljava/io/File;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser, f);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createJsonParser1(jobject self_, jobject url) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createJsonParser1, "createJsonParser", "(Ljava/net/URL;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser1, url);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser2 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createJsonParser2(jobject self_, jobject in) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createJsonParser2, "createJsonParser", "(Ljava/io/InputStream;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser2, in);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser3 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createJsonParser3(jobject self_, jobject r) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createJsonParser3, "createJsonParser", "(Ljava/io/Reader;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser3, r);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser4 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createJsonParser4(jobject self_, jobject data) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createJsonParser4, "createJsonParser", "(L[B;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser4, data);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser5 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createJsonParser5(jobject self_, jobject data, int32_t offset, int32_t len) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createJsonParser5, "createJsonParser", "(L[B;II)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser5, data, offset, len);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser6 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createJsonParser6(jobject self_, jobject content) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createJsonParser6, "createJsonParser", "(Ljava/lang/String;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createJsonParser6, content);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createJsonGenerator = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createJsonGenerator(jobject self_, jobject out, jobject enc) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createJsonGenerator, "createJsonGenerator", "(Ljava/io/OutputStream;Lcom/fasterxml/jackson/core/JsonEncoding;)Lcom/fasterxml/jackson/core/JsonGenerator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createJsonGenerator, out, enc);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createJsonGenerator1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createJsonGenerator1(jobject self_, jobject out) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createJsonGenerator1, "createJsonGenerator", "(Ljava/io/Writer;)Lcom/fasterxml/jackson/core/JsonGenerator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createJsonGenerator1, out);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory_createJsonGenerator2 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory_createJsonGenerator2(jobject self_, jobject out) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory, &_m_com_fasterxml_jackson_core_JsonFactory_createJsonGenerator2, "createJsonGenerator", "(Ljava/io/OutputStream;)Lcom/fasterxml/jackson/core/JsonGenerator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory_createJsonGenerator2, out);
+    return to_global_ref(_result);
+}
+
+jfieldID _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_FACTORY_FEATURE_FLAGS = NULL;
+int32_t get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_FACTORY_FEATURE_FLAGS() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_static_field(_c_com_fasterxml_jackson_core_JsonFactory, &_f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_FACTORY_FEATURE_FLAGS, "DEFAULT_FACTORY_FEATURE_FLAGS","I");
+    return ((*jniEnv)->GetStaticIntField(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory, _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_FACTORY_FEATURE_FLAGS));
+}
+
+
+jfieldID _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_PARSER_FEATURE_FLAGS = NULL;
+int32_t get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_PARSER_FEATURE_FLAGS() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_static_field(_c_com_fasterxml_jackson_core_JsonFactory, &_f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_PARSER_FEATURE_FLAGS, "DEFAULT_PARSER_FEATURE_FLAGS","I");
+    return ((*jniEnv)->GetStaticIntField(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory, _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_PARSER_FEATURE_FLAGS));
+}
+
+
+jfieldID _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_GENERATOR_FEATURE_FLAGS = NULL;
+int32_t get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_GENERATOR_FEATURE_FLAGS() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_static_field(_c_com_fasterxml_jackson_core_JsonFactory, &_f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_GENERATOR_FEATURE_FLAGS, "DEFAULT_GENERATOR_FEATURE_FLAGS","I");
+    return ((*jniEnv)->GetStaticIntField(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory, _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_GENERATOR_FEATURE_FLAGS));
+}
+
+
+jfieldID _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_ROOT_VALUE_SEPARATOR = NULL;
+jobject get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_ROOT_VALUE_SEPARATOR() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
+    load_static_field(_c_com_fasterxml_jackson_core_JsonFactory, &_f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_ROOT_VALUE_SEPARATOR, "DEFAULT_ROOT_VALUE_SEPARATOR","Lcom/fasterxml/jackson/core/SerializableString;");
+    return to_global_ref((*jniEnv)->GetStaticObjectField(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory, _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_ROOT_VALUE_SEPARATOR));
+}
+
+
+// com.fasterxml.jackson.core.JsonFactory$Feature
+jclass _c_com_fasterxml_jackson_core_JsonFactory__Feature = NULL;
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory__Feature_values = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory__Feature_values() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory__Feature, "com/fasterxml/jackson/core/JsonFactory$Feature");
+    load_static_method(_c_com_fasterxml_jackson_core_JsonFactory__Feature, &_m_com_fasterxml_jackson_core_JsonFactory__Feature_values, "values", "()L[com/fasterxml/jackson/core/JsonFactory$Feature;");
+    jobject _result = (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory__Feature, _m_com_fasterxml_jackson_core_JsonFactory__Feature_values);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory__Feature_valueOf = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory__Feature_valueOf(jobject name) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory__Feature, "com/fasterxml/jackson/core/JsonFactory$Feature");
+    load_static_method(_c_com_fasterxml_jackson_core_JsonFactory__Feature, &_m_com_fasterxml_jackson_core_JsonFactory__Feature_valueOf, "valueOf", "(Ljava/lang/String;)Lcom/fasterxml/jackson/core/JsonFactory$Feature;");
+    jobject _result = (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory__Feature, _m_com_fasterxml_jackson_core_JsonFactory__Feature_valueOf, name);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory__Feature_collectDefaults = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonFactory__Feature_collectDefaults() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory__Feature, "com/fasterxml/jackson/core/JsonFactory$Feature");
+    load_static_method(_c_com_fasterxml_jackson_core_JsonFactory__Feature, &_m_com_fasterxml_jackson_core_JsonFactory__Feature_collectDefaults, "collectDefaults", "()I");
+    int32_t _result = (*jniEnv)->CallStaticIntMethod(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory__Feature, _m_com_fasterxml_jackson_core_JsonFactory__Feature_collectDefaults);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory__Feature_ctor = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonFactory__Feature_ctor(uint8_t defaultState) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory__Feature, "com/fasterxml/jackson/core/JsonFactory$Feature");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory__Feature, &_m_com_fasterxml_jackson_core_JsonFactory__Feature_ctor, "<init>", "(Z)V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_com_fasterxml_jackson_core_JsonFactory__Feature, _m_com_fasterxml_jackson_core_JsonFactory__Feature_ctor, defaultState);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory__Feature_enabledByDefault = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory__Feature_enabledByDefault(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory__Feature, "com/fasterxml/jackson/core/JsonFactory$Feature");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory__Feature, &_m_com_fasterxml_jackson_core_JsonFactory__Feature_enabledByDefault, "enabledByDefault", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory__Feature_enabledByDefault);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory__Feature_enabledIn = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonFactory__Feature_enabledIn(jobject self_, int32_t flags) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory__Feature, "com/fasterxml/jackson/core/JsonFactory$Feature");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory__Feature, &_m_com_fasterxml_jackson_core_JsonFactory__Feature_enabledIn, "enabledIn", "(I)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory__Feature_enabledIn, flags);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonFactory__Feature_getMask = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonFactory__Feature_getMask(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory__Feature, "com/fasterxml/jackson/core/JsonFactory$Feature");
+    load_method(_c_com_fasterxml_jackson_core_JsonFactory__Feature, &_m_com_fasterxml_jackson_core_JsonFactory__Feature_getMask, "getMask", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonFactory__Feature_getMask);
+    return _result;
+}
+
+// com.fasterxml.jackson.core.JsonParser
+jclass _c_com_fasterxml_jackson_core_JsonParser = NULL;
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_ctor = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_ctor() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_ctor, "<init>", "()V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_com_fasterxml_jackson_core_JsonParser, _m_com_fasterxml_jackson_core_JsonParser_ctor);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_ctor1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_ctor1(int32_t features) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_ctor1, "<init>", "(I)V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_com_fasterxml_jackson_core_JsonParser, _m_com_fasterxml_jackson_core_JsonParser_ctor1, features);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getCodec = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getCodec(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getCodec, "getCodec", "()Lcom/fasterxml/jackson/core/ObjectCodec;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getCodec);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_setCodec = NULL;
+FFI_PLUGIN_EXPORT
+void com_fasterxml_jackson_core_JsonParser_setCodec(jobject self_, jobject oc) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_setCodec, "setCodec", "(Lcom/fasterxml/jackson/core/ObjectCodec;)V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_setCodec, oc);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getInputSource = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getInputSource(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getInputSource, "getInputSource", "()Ljava/lang/Object;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getInputSource);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError = NULL;
+FFI_PLUGIN_EXPORT
+void com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError(jobject self_, jobject payload) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError, "setRequestPayloadOnError", "(Lcom/fasterxml/jackson/core/util/RequestPayload;)V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError, payload);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError1 = NULL;
+FFI_PLUGIN_EXPORT
+void com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError1(jobject self_, jobject payload, jobject charset) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError1, "setRequestPayloadOnError", "(L[B;Ljava/lang/String;)V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError1, payload, charset);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError2 = NULL;
+FFI_PLUGIN_EXPORT
+void com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError2(jobject self_, jobject payload) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError2, "setRequestPayloadOnError", "(Ljava/lang/String;)V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_setRequestPayloadOnError2, payload);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_setSchema = NULL;
+FFI_PLUGIN_EXPORT
+void com_fasterxml_jackson_core_JsonParser_setSchema(jobject self_, jobject schema) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_setSchema, "setSchema", "(Lcom/fasterxml/jackson/core/FormatSchema;)V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_setSchema, schema);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getSchema = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getSchema(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getSchema, "getSchema", "()Lcom/fasterxml/jackson/core/FormatSchema;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getSchema);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_canUseSchema = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_canUseSchema(jobject self_, jobject schema) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_canUseSchema, "canUseSchema", "(Lcom/fasterxml/jackson/core/FormatSchema;)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_canUseSchema, schema);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_requiresCustomCodec = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_requiresCustomCodec(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_requiresCustomCodec, "requiresCustomCodec", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_requiresCustomCodec);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_canParseAsync = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_canParseAsync(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_canParseAsync, "canParseAsync", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_canParseAsync);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getNonBlockingInputFeeder = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getNonBlockingInputFeeder(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getNonBlockingInputFeeder, "getNonBlockingInputFeeder", "()Lcom/fasterxml/jackson/core/async/NonBlockingInputFeeder;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getNonBlockingInputFeeder);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getReadCapabilities = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getReadCapabilities(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getReadCapabilities, "getReadCapabilities", "()Lcom/fasterxml/jackson/core/util/JacksonFeatureSet;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getReadCapabilities);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_version = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_version(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_version, "version", "()Lcom/fasterxml/jackson/core/Version;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_version);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_close = NULL;
+FFI_PLUGIN_EXPORT
+void com_fasterxml_jackson_core_JsonParser_close(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_close, "close", "()V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_close);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_isClosed = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_isClosed(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_isClosed, "isClosed", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_isClosed);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getParsingContext = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getParsingContext(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getParsingContext, "getParsingContext", "()Lcom/fasterxml/jackson/core/JsonStreamContext;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getParsingContext);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_currentLocation = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_currentLocation(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_currentLocation, "currentLocation", "()Lcom/fasterxml/jackson/core/JsonLocation;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_currentLocation);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_currentTokenLocation = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_currentTokenLocation(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_currentTokenLocation, "currentTokenLocation", "()Lcom/fasterxml/jackson/core/JsonLocation;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_currentTokenLocation);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getCurrentLocation = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getCurrentLocation(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getCurrentLocation, "getCurrentLocation", "()Lcom/fasterxml/jackson/core/JsonLocation;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getCurrentLocation);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getTokenLocation = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getTokenLocation(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getTokenLocation, "getTokenLocation", "()Lcom/fasterxml/jackson/core/JsonLocation;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getTokenLocation);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_currentValue = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_currentValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_currentValue, "currentValue", "()Ljava/lang/Object;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_currentValue);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_assignCurrentValue = NULL;
+FFI_PLUGIN_EXPORT
+void com_fasterxml_jackson_core_JsonParser_assignCurrentValue(jobject self_, jobject v) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_assignCurrentValue, "assignCurrentValue", "(Ljava/lang/Object;)V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_assignCurrentValue, v);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getCurrentValue = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getCurrentValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getCurrentValue, "getCurrentValue", "()Ljava/lang/Object;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getCurrentValue);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_setCurrentValue = NULL;
+FFI_PLUGIN_EXPORT
+void com_fasterxml_jackson_core_JsonParser_setCurrentValue(jobject self_, jobject v) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_setCurrentValue, "setCurrentValue", "(Ljava/lang/Object;)V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_setCurrentValue, v);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_releaseBuffered = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_releaseBuffered(jobject self_, jobject out) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_releaseBuffered, "releaseBuffered", "(Ljava/io/OutputStream;)I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_releaseBuffered, out);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_releaseBuffered1 = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_releaseBuffered1(jobject self_, jobject w) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_releaseBuffered1, "releaseBuffered", "(Ljava/io/Writer;)I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_releaseBuffered1, w);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_enable = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_enable(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_enable, "enable", "(Lcom/fasterxml/jackson/core/JsonParser$Feature;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_enable, f);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_disable = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_disable(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_disable, "disable", "(Lcom/fasterxml/jackson/core/JsonParser$Feature;)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_disable, f);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_configure = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_configure(jobject self_, jobject f, uint8_t state) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_configure, "configure", "(Lcom/fasterxml/jackson/core/JsonParser$Feature;Z)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_configure, f, state);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_isEnabled = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_isEnabled(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_isEnabled, "isEnabled", "(Lcom/fasterxml/jackson/core/JsonParser$Feature;)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_isEnabled, f);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_isEnabled1 = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_isEnabled1(jobject self_, jobject f) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_isEnabled1, "isEnabled", "(Lcom/fasterxml/jackson/core/StreamReadFeature;)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_isEnabled1, f);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getFeatureMask = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_getFeatureMask(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getFeatureMask, "getFeatureMask", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getFeatureMask);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_setFeatureMask = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_setFeatureMask(jobject self_, int32_t mask) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_setFeatureMask, "setFeatureMask", "(I)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_setFeatureMask, mask);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_overrideStdFeatures = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_overrideStdFeatures(jobject self_, int32_t values, int32_t mask) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_overrideStdFeatures, "overrideStdFeatures", "(II)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_overrideStdFeatures, values, mask);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getFormatFeatures = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_getFormatFeatures(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getFormatFeatures, "getFormatFeatures", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getFormatFeatures);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_overrideFormatFeatures = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_overrideFormatFeatures(jobject self_, int32_t values, int32_t mask) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_overrideFormatFeatures, "overrideFormatFeatures", "(II)Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_overrideFormatFeatures, values, mask);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_nextToken = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_nextToken(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_nextToken, "nextToken", "()Lcom/fasterxml/jackson/core/JsonToken;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_nextToken);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_nextValue = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_nextValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_nextValue, "nextValue", "()Lcom/fasterxml/jackson/core/JsonToken;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_nextValue);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_nextFieldName = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_nextFieldName(jobject self_, jobject str) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_nextFieldName, "nextFieldName", "(Lcom/fasterxml/jackson/core/SerializableString;)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_nextFieldName, str);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_nextFieldName1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_nextFieldName1(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_nextFieldName1, "nextFieldName", "()Ljava/lang/String;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_nextFieldName1);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_nextTextValue = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_nextTextValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_nextTextValue, "nextTextValue", "()Ljava/lang/String;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_nextTextValue);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_nextIntValue = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_nextIntValue(jobject self_, int32_t defaultValue) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_nextIntValue, "nextIntValue", "(I)I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_nextIntValue, defaultValue);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_nextLongValue = NULL;
+FFI_PLUGIN_EXPORT
+int64_t com_fasterxml_jackson_core_JsonParser_nextLongValue(jobject self_, int64_t defaultValue) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_nextLongValue, "nextLongValue", "(J)J");
+    int64_t _result = (*jniEnv)->CallLongMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_nextLongValue, defaultValue);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_nextBooleanValue = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_nextBooleanValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_nextBooleanValue, "nextBooleanValue", "()Ljava/lang/Boolean;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_nextBooleanValue);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_skipChildren = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_skipChildren(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_skipChildren, "skipChildren", "()Lcom/fasterxml/jackson/core/JsonParser;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_skipChildren);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_finishToken = NULL;
+FFI_PLUGIN_EXPORT
+void com_fasterxml_jackson_core_JsonParser_finishToken(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_finishToken, "finishToken", "()V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_finishToken);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_currentToken = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_currentToken(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_currentToken, "currentToken", "()Lcom/fasterxml/jackson/core/JsonToken;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_currentToken);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_currentTokenId = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_currentTokenId(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_currentTokenId, "currentTokenId", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_currentTokenId);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getCurrentToken = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getCurrentToken(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getCurrentToken, "getCurrentToken", "()Lcom/fasterxml/jackson/core/JsonToken;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getCurrentToken);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getCurrentTokenId = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_getCurrentTokenId(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getCurrentTokenId, "getCurrentTokenId", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getCurrentTokenId);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_hasCurrentToken = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_hasCurrentToken(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_hasCurrentToken, "hasCurrentToken", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_hasCurrentToken);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_hasTokenId = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_hasTokenId(jobject self_, int32_t id) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_hasTokenId, "hasTokenId", "(I)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_hasTokenId, id);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_hasToken = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_hasToken(jobject self_, jobject t) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_hasToken, "hasToken", "(Lcom/fasterxml/jackson/core/JsonToken;)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_hasToken, t);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_isExpectedStartArrayToken = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_isExpectedStartArrayToken(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_isExpectedStartArrayToken, "isExpectedStartArrayToken", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_isExpectedStartArrayToken);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_isExpectedStartObjectToken = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_isExpectedStartObjectToken(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_isExpectedStartObjectToken, "isExpectedStartObjectToken", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_isExpectedStartObjectToken);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_isExpectedNumberIntToken = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_isExpectedNumberIntToken(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_isExpectedNumberIntToken, "isExpectedNumberIntToken", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_isExpectedNumberIntToken);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_isNaN = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_isNaN(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_isNaN, "isNaN", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_isNaN);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_clearCurrentToken = NULL;
+FFI_PLUGIN_EXPORT
+void com_fasterxml_jackson_core_JsonParser_clearCurrentToken(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_clearCurrentToken, "clearCurrentToken", "()V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_clearCurrentToken);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getLastClearedToken = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getLastClearedToken(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getLastClearedToken, "getLastClearedToken", "()Lcom/fasterxml/jackson/core/JsonToken;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getLastClearedToken);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_overrideCurrentName = NULL;
+FFI_PLUGIN_EXPORT
+void com_fasterxml_jackson_core_JsonParser_overrideCurrentName(jobject self_, jobject name) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_overrideCurrentName, "overrideCurrentName", "(Ljava/lang/String;)V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_overrideCurrentName, name);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getCurrentName = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getCurrentName(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getCurrentName, "getCurrentName", "()Ljava/lang/String;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getCurrentName);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_currentName = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_currentName(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_currentName, "currentName", "()Ljava/lang/String;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_currentName);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getText = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getText(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getText, "getText", "()Ljava/lang/String;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getText);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getText1 = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_getText1(jobject self_, jobject writer) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getText1, "getText", "(Ljava/io/Writer;)I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getText1, writer);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getTextCharacters = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getTextCharacters(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getTextCharacters, "getTextCharacters", "()L[C;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getTextCharacters);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getTextLength = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_getTextLength(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getTextLength, "getTextLength", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getTextLength);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getTextOffset = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_getTextOffset(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getTextOffset, "getTextOffset", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getTextOffset);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_hasTextCharacters = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_hasTextCharacters(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_hasTextCharacters, "hasTextCharacters", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_hasTextCharacters);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getNumberValue = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getNumberValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getNumberValue, "getNumberValue", "()Ljava/lang/Number;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getNumberValue);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getNumberValueExact = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getNumberValueExact(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getNumberValueExact, "getNumberValueExact", "()Ljava/lang/Number;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getNumberValueExact);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getNumberType = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getNumberType(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getNumberType, "getNumberType", "()Lcom/fasterxml/jackson/core/JsonParser$NumberType;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getNumberType);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getByteValue = NULL;
+FFI_PLUGIN_EXPORT
+int8_t com_fasterxml_jackson_core_JsonParser_getByteValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getByteValue, "getByteValue", "()B");
+    int8_t _result = (*jniEnv)->CallByteMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getByteValue);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getShortValue = NULL;
+FFI_PLUGIN_EXPORT
+int16_t com_fasterxml_jackson_core_JsonParser_getShortValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getShortValue, "getShortValue", "()S");
+    int16_t _result = (*jniEnv)->CallShortMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getShortValue);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getIntValue = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_getIntValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getIntValue, "getIntValue", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getIntValue);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getLongValue = NULL;
+FFI_PLUGIN_EXPORT
+int64_t com_fasterxml_jackson_core_JsonParser_getLongValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getLongValue, "getLongValue", "()J");
+    int64_t _result = (*jniEnv)->CallLongMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getLongValue);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getBigIntegerValue = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getBigIntegerValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getBigIntegerValue, "getBigIntegerValue", "()Ljava/math/BigInteger;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getBigIntegerValue);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getFloatValue = NULL;
+FFI_PLUGIN_EXPORT
+float com_fasterxml_jackson_core_JsonParser_getFloatValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getFloatValue, "getFloatValue", "()F");
+    float _result = (*jniEnv)->CallFloatMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getFloatValue);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getDoubleValue = NULL;
+FFI_PLUGIN_EXPORT
+double com_fasterxml_jackson_core_JsonParser_getDoubleValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getDoubleValue, "getDoubleValue", "()D");
+    double _result = (*jniEnv)->CallDoubleMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getDoubleValue);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getDecimalValue = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getDecimalValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getDecimalValue, "getDecimalValue", "()Ljava/math/BigDecimal;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getDecimalValue);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getBooleanValue = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_getBooleanValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getBooleanValue, "getBooleanValue", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getBooleanValue);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getEmbeddedObject = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getEmbeddedObject(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getEmbeddedObject, "getEmbeddedObject", "()Ljava/lang/Object;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getEmbeddedObject);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getBinaryValue = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getBinaryValue(jobject self_, jobject bv) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getBinaryValue, "getBinaryValue", "(Lcom/fasterxml/jackson/core/Base64Variant;)L[B;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getBinaryValue, bv);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getBinaryValue1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getBinaryValue1(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getBinaryValue1, "getBinaryValue", "()L[B;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getBinaryValue1);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_readBinaryValue = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_readBinaryValue(jobject self_, jobject out) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_readBinaryValue, "readBinaryValue", "(Ljava/io/OutputStream;)I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_readBinaryValue, out);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_readBinaryValue1 = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_readBinaryValue1(jobject self_, jobject bv, jobject out) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_readBinaryValue1, "readBinaryValue", "(Lcom/fasterxml/jackson/core/Base64Variant;Ljava/io/OutputStream;)I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_readBinaryValue1, bv, out);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getValueAsInt = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_getValueAsInt(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getValueAsInt, "getValueAsInt", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getValueAsInt);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getValueAsInt1 = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser_getValueAsInt1(jobject self_, int32_t def) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getValueAsInt1, "getValueAsInt", "(I)I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getValueAsInt1, def);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getValueAsLong = NULL;
+FFI_PLUGIN_EXPORT
+int64_t com_fasterxml_jackson_core_JsonParser_getValueAsLong(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getValueAsLong, "getValueAsLong", "()J");
+    int64_t _result = (*jniEnv)->CallLongMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getValueAsLong);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getValueAsLong1 = NULL;
+FFI_PLUGIN_EXPORT
+int64_t com_fasterxml_jackson_core_JsonParser_getValueAsLong1(jobject self_, int64_t def) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getValueAsLong1, "getValueAsLong", "(J)J");
+    int64_t _result = (*jniEnv)->CallLongMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getValueAsLong1, def);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getValueAsDouble = NULL;
+FFI_PLUGIN_EXPORT
+double com_fasterxml_jackson_core_JsonParser_getValueAsDouble(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getValueAsDouble, "getValueAsDouble", "()D");
+    double _result = (*jniEnv)->CallDoubleMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getValueAsDouble);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getValueAsDouble1 = NULL;
+FFI_PLUGIN_EXPORT
+double com_fasterxml_jackson_core_JsonParser_getValueAsDouble1(jobject self_, double def) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getValueAsDouble1, "getValueAsDouble", "(D)D");
+    double _result = (*jniEnv)->CallDoubleMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getValueAsDouble1, def);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getValueAsBoolean = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_getValueAsBoolean(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getValueAsBoolean, "getValueAsBoolean", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getValueAsBoolean);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getValueAsBoolean1 = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_getValueAsBoolean1(jobject self_, uint8_t def) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getValueAsBoolean1, "getValueAsBoolean", "(Z)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getValueAsBoolean1, def);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getValueAsString = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getValueAsString(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getValueAsString, "getValueAsString", "()Ljava/lang/String;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getValueAsString);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getValueAsString1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getValueAsString1(jobject self_, jobject def) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getValueAsString1, "getValueAsString", "(Ljava/lang/String;)Ljava/lang/String;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getValueAsString1, def);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_canReadObjectId = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_canReadObjectId(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_canReadObjectId, "canReadObjectId", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_canReadObjectId);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_canReadTypeId = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser_canReadTypeId(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_canReadTypeId, "canReadTypeId", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_canReadTypeId);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getObjectId = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getObjectId(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getObjectId, "getObjectId", "()Ljava/lang/Object;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getObjectId);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_getTypeId = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_getTypeId(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_getTypeId, "getTypeId", "()Ljava/lang/Object;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_getTypeId);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_readValueAs = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_readValueAs(jobject self_, jobject valueType) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_readValueAs, "readValueAs", "(Ljava/lang/Class;)Ljava/lang/Object;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_readValueAs, valueType);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_readValueAs1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_readValueAs1(jobject self_, jobject valueTypeRef) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_readValueAs1, "readValueAs", "(Lcom/fasterxml/jackson/core/type/TypeReference;)Ljava/lang/Object;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_readValueAs1, valueTypeRef);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_readValuesAs = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_readValuesAs(jobject self_, jobject valueType) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_readValuesAs, "readValuesAs", "(Ljava/lang/Class;)Ljava/util/Iterator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_readValuesAs, valueType);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_readValuesAs1 = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_readValuesAs1(jobject self_, jobject valueTypeRef) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_readValuesAs1, "readValuesAs", "(Lcom/fasterxml/jackson/core/type/TypeReference;)Ljava/util/Iterator;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_readValuesAs1, valueTypeRef);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser_readValueAsTree = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser_readValueAsTree(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser, &_m_com_fasterxml_jackson_core_JsonParser_readValueAsTree, "readValueAsTree", "()Ljava/lang/Object;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser_readValueAsTree);
+    return to_global_ref(_result);
+}
+
+jfieldID _f_com_fasterxml_jackson_core_JsonParser_DEFAULT_READ_CAPABILITIES = NULL;
+jobject get_com_fasterxml_jackson_core_JsonParser_DEFAULT_READ_CAPABILITIES() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
+    load_static_field(_c_com_fasterxml_jackson_core_JsonParser, &_f_com_fasterxml_jackson_core_JsonParser_DEFAULT_READ_CAPABILITIES, "DEFAULT_READ_CAPABILITIES","Lcom/fasterxml/jackson/core/util/JacksonFeatureSet;");
+    return to_global_ref((*jniEnv)->GetStaticObjectField(jniEnv, _c_com_fasterxml_jackson_core_JsonParser, _f_com_fasterxml_jackson_core_JsonParser_DEFAULT_READ_CAPABILITIES));
+}
+
+
+// com.fasterxml.jackson.core.JsonParser$Feature
+jclass _c_com_fasterxml_jackson_core_JsonParser__Feature = NULL;
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser__Feature_values = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser__Feature_values() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser__Feature, "com/fasterxml/jackson/core/JsonParser$Feature");
+    load_static_method(_c_com_fasterxml_jackson_core_JsonParser__Feature, &_m_com_fasterxml_jackson_core_JsonParser__Feature_values, "values", "()L[com/fasterxml/jackson/core/JsonParser$Feature;");
+    jobject _result = (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_com_fasterxml_jackson_core_JsonParser__Feature, _m_com_fasterxml_jackson_core_JsonParser__Feature_values);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser__Feature_valueOf = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser__Feature_valueOf(jobject name) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser__Feature, "com/fasterxml/jackson/core/JsonParser$Feature");
+    load_static_method(_c_com_fasterxml_jackson_core_JsonParser__Feature, &_m_com_fasterxml_jackson_core_JsonParser__Feature_valueOf, "valueOf", "(Ljava/lang/String;)Lcom/fasterxml/jackson/core/JsonParser$Feature;");
+    jobject _result = (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_com_fasterxml_jackson_core_JsonParser__Feature, _m_com_fasterxml_jackson_core_JsonParser__Feature_valueOf, name);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser__Feature_collectDefaults = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser__Feature_collectDefaults() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser__Feature, "com/fasterxml/jackson/core/JsonParser$Feature");
+    load_static_method(_c_com_fasterxml_jackson_core_JsonParser__Feature, &_m_com_fasterxml_jackson_core_JsonParser__Feature_collectDefaults, "collectDefaults", "()I");
+    int32_t _result = (*jniEnv)->CallStaticIntMethod(jniEnv, _c_com_fasterxml_jackson_core_JsonParser__Feature, _m_com_fasterxml_jackson_core_JsonParser__Feature_collectDefaults);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser__Feature_ctor = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser__Feature_ctor(uint8_t defaultState) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser__Feature, "com/fasterxml/jackson/core/JsonParser$Feature");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser__Feature, &_m_com_fasterxml_jackson_core_JsonParser__Feature_ctor, "<init>", "(Z)V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_com_fasterxml_jackson_core_JsonParser__Feature, _m_com_fasterxml_jackson_core_JsonParser__Feature_ctor, defaultState);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser__Feature_enabledByDefault = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser__Feature_enabledByDefault(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser__Feature, "com/fasterxml/jackson/core/JsonParser$Feature");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser__Feature, &_m_com_fasterxml_jackson_core_JsonParser__Feature_enabledByDefault, "enabledByDefault", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser__Feature_enabledByDefault);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser__Feature_enabledIn = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonParser__Feature_enabledIn(jobject self_, int32_t flags) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser__Feature, "com/fasterxml/jackson/core/JsonParser$Feature");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser__Feature, &_m_com_fasterxml_jackson_core_JsonParser__Feature_enabledIn, "enabledIn", "(I)Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser__Feature_enabledIn, flags);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser__Feature_getMask = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonParser__Feature_getMask(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser__Feature, "com/fasterxml/jackson/core/JsonParser$Feature");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser__Feature, &_m_com_fasterxml_jackson_core_JsonParser__Feature_getMask, "getMask", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonParser__Feature_getMask);
+    return _result;
+}
+
+// com.fasterxml.jackson.core.JsonParser$NumberType
+jclass _c_com_fasterxml_jackson_core_JsonParser__NumberType = NULL;
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser__NumberType_values = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser__NumberType_values() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser__NumberType, "com/fasterxml/jackson/core/JsonParser$NumberType");
+    load_static_method(_c_com_fasterxml_jackson_core_JsonParser__NumberType, &_m_com_fasterxml_jackson_core_JsonParser__NumberType_values, "values", "()L[com/fasterxml/jackson/core/JsonParser$NumberType;");
+    jobject _result = (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_com_fasterxml_jackson_core_JsonParser__NumberType, _m_com_fasterxml_jackson_core_JsonParser__NumberType_values);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser__NumberType_valueOf = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser__NumberType_valueOf(jobject name) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser__NumberType, "com/fasterxml/jackson/core/JsonParser$NumberType");
+    load_static_method(_c_com_fasterxml_jackson_core_JsonParser__NumberType, &_m_com_fasterxml_jackson_core_JsonParser__NumberType_valueOf, "valueOf", "(Ljava/lang/String;)Lcom/fasterxml/jackson/core/JsonParser$NumberType;");
+    jobject _result = (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_com_fasterxml_jackson_core_JsonParser__NumberType, _m_com_fasterxml_jackson_core_JsonParser__NumberType_valueOf, name);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonParser__NumberType_ctor = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonParser__NumberType_ctor() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser__NumberType, "com/fasterxml/jackson/core/JsonParser$NumberType");
+    load_method(_c_com_fasterxml_jackson_core_JsonParser__NumberType, &_m_com_fasterxml_jackson_core_JsonParser__NumberType_ctor, "<init>", "()V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_com_fasterxml_jackson_core_JsonParser__NumberType, _m_com_fasterxml_jackson_core_JsonParser__NumberType_ctor);
+    return to_global_ref(_result);
+}
+
+// com.fasterxml.jackson.core.JsonToken
+jclass _c_com_fasterxml_jackson_core_JsonToken = NULL;
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_values = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonToken_values() {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_static_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_values, "values", "()L[com/fasterxml/jackson/core/JsonToken;");
+    jobject _result = (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_com_fasterxml_jackson_core_JsonToken, _m_com_fasterxml_jackson_core_JsonToken_values);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_valueOf = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonToken_valueOf(jobject name) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_static_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_valueOf, "valueOf", "(Ljava/lang/String;)Lcom/fasterxml/jackson/core/JsonToken;");
+    jobject _result = (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_com_fasterxml_jackson_core_JsonToken, _m_com_fasterxml_jackson_core_JsonToken_valueOf, name);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_ctor = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonToken_ctor(jobject token, int32_t id) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_ctor, "<init>", "(Ljava/lang/String;I)V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_com_fasterxml_jackson_core_JsonToken, _m_com_fasterxml_jackson_core_JsonToken_ctor, token, id);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_id = NULL;
+FFI_PLUGIN_EXPORT
+int32_t com_fasterxml_jackson_core_JsonToken_id(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_id, "id", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonToken_id);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_asString = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonToken_asString(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_asString, "asString", "()Ljava/lang/String;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonToken_asString);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_asCharArray = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonToken_asCharArray(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_asCharArray, "asCharArray", "()L[C;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonToken_asCharArray);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_asByteArray = NULL;
+FFI_PLUGIN_EXPORT
+jobject com_fasterxml_jackson_core_JsonToken_asByteArray(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_asByteArray, "asByteArray", "()L[B;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonToken_asByteArray);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_isNumeric = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonToken_isNumeric(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_isNumeric, "isNumeric", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonToken_isNumeric);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_isStructStart = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonToken_isStructStart(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_isStructStart, "isStructStart", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonToken_isStructStart);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_isStructEnd = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonToken_isStructEnd(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_isStructEnd, "isStructEnd", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonToken_isStructEnd);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_isScalarValue = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonToken_isScalarValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_isScalarValue, "isScalarValue", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonToken_isScalarValue);
+    return _result;
+}
+
+jmethodID _m_com_fasterxml_jackson_core_JsonToken_isBoolean = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t com_fasterxml_jackson_core_JsonToken_isBoolean(jobject self_) {
+    load_env();
+    load_class_gr(&_c_com_fasterxml_jackson_core_JsonToken, "com/fasterxml/jackson/core/JsonToken");
+    load_method(_c_com_fasterxml_jackson_core_JsonToken, &_m_com_fasterxml_jackson_core_JsonToken_isBoolean, "isBoolean", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_com_fasterxml_jackson_core_JsonToken_isBoolean);
+    return _result;
+}
+
diff --git a/pkgs/jni_gen/test/my_test.dart b/pkgs/jni_gen/test/my_test.dart
deleted file mode 100644
index 647cfd3..0000000
--- a/pkgs/jni_gen/test/my_test.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test/test.dart';
-import 'package:jni_gen/jni_gen.dart';
-
-void main() {
-  test('dummy test', () {
-    final result = mySum(2, 40);
-    expect(result, 42);
-  });
-}
diff --git a/pkgs/jni_gen/test/package_resolver_test.dart b/pkgs/jni_gen/test/package_resolver_test.dart
new file mode 100644
index 0000000..ac58090
--- /dev/null
+++ b/pkgs/jni_gen/test/package_resolver_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:jni_gen/src/bindings/symbol_resolver.dart';
+import 'package:jni_gen/src/util/name_utils.dart';
+import 'package:test/test.dart';
+
+class ResolverTest {
+  ResolverTest(this.binaryName, this.expectedImport, this.expectedName);
+  String binaryName;
+  String expectedImport;
+  String expectedName;
+}
+
+void main() {
+  final resolver = PackagePathResolver(
+      {
+        'org.apache.pdfbox': 'package:pdfbox',
+        'org.apache.fontbox': 'package:fontbox',
+        'java.lang': 'package:java_lang',
+        'java.util': 'package:java_util',
+        'org.me.package': 'package:my_package/src/',
+      },
+      'a.b',
+      {'a.b.C', 'a.b.c.D', 'a.b.c.d.E', 'a.X', 'a.g.Y'});
+
+  final tests = [
+    // Simple example
+    ResolverTest('org.apache.pdfbox.PDF',
+        'package:pdfbox/org/apache/pdfbox.dart', 'pdfbox_.PDF'),
+    // Nested classes
+    ResolverTest('org.apache.fontbox.Font\$FontFile',
+        'package:fontbox/org/apache/fontbox.dart', 'fontbox_.Font_FontFile'),
+    // slightly deeper package
+    ResolverTest('java.lang.ref.WeakReference',
+        'package:java_lang/java/lang/ref.dart', 'ref_.WeakReference'),
+    // Renaming
+    ResolverTest('java.util.U', 'package:java_util/java/util.dart', 'util_.U'),
+    ResolverTest('org.me.package.util.U',
+        'package:my_package/src/org/me/package/util.dart', 'util1_.U'),
+    // Relative imports
+    ResolverTest('a.b.c.D', 'b/c.dart', 'c_.D'),
+    ResolverTest('a.b.c.d.E', 'b/c/d.dart', 'd_.E'),
+    ResolverTest('a.X', '../a.dart', 'a_.X'),
+    ResolverTest('a.g.Y', '../a/g.dart', 'g_.Y'),
+  ];
+
+  for (var testCase in tests) {
+    final binaryName = testCase.binaryName;
+    final packageName = cutFromLast(binaryName, '.')[0];
+    test(
+        'getImport $binaryName',
+        () => expect(resolver.getImport(packageName, binaryName),
+            equals(testCase.expectedImport)));
+    test(
+        'resolve $binaryName',
+        () => expect(
+            resolver.resolve(binaryName), equals(testCase.expectedName)));
+  }
+  test('resolve in same package',
+      () => expect(resolver.resolve('a.b.C'), equals('C')));
+}
diff --git a/pkgs/jni_gen/test/simple_package_test/.gitignore b/pkgs/jni_gen/test/simple_package_test/.gitignore
new file mode 100644
index 0000000..cbd7ab3
--- /dev/null
+++ b/pkgs/jni_gen/test/simple_package_test/.gitignore
@@ -0,0 +1,5 @@
+build/
+*.class
+test_lib/
+test_src/
+
diff --git a/pkgs/jni_gen/test/simple_package_test/generate.dart b/pkgs/jni_gen/test/simple_package_test/generate.dart
new file mode 100644
index 0000000..427098d
--- /dev/null
+++ b/pkgs/jni_gen/test/simple_package_test/generate.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:path/path.dart';
+import 'package:jni_gen/jni_gen.dart';
+
+import '../test_util/test_util.dart';
+
+const testName = 'simple_package_test';
+final testRoot = join('test', testName);
+final javaPath = join(testRoot, 'java');
+
+var javaFiles = ['dev/dart/$testName/Example.java', 'dev/dart/pkg2/C2.java'];
+
+Future<void> compileJavaSources(String workingDir, List<String> files) async {
+  await runCmd('javac', files, workingDirectory: workingDir);
+}
+
+Future<void> generateSources(String lib, String src) async {
+  await runCmd('dart', ['run', 'jni_gen:setup']);
+  await compileJavaSources(javaPath, javaFiles);
+  final cWrapperDir = Uri.directory(join(testRoot, src));
+  final dartWrappersRoot = Uri.directory(join(testRoot, lib));
+  final cDir = Directory.fromUri(cWrapperDir);
+  final dartDir = Directory.fromUri(dartWrappersRoot);
+  for (var dir in [cDir, dartDir]) {
+    if (await dir.exists()) {
+      await dir.delete(recursive: true);
+    }
+  }
+  await JniGenTask(
+    summarySource: SummarizerCommand(
+      sourcePaths: [Uri.directory(javaPath)],
+      classPaths: [Uri.directory(javaPath)],
+      classes: ['dev.dart.simple_package', 'dev.dart.pkg2'],
+    ),
+    outputWriter: FilesWriter(
+        cWrapperDir: cWrapperDir,
+        dartWrappersRoot: dartWrappersRoot,
+        libraryName: 'simple_package'),
+  ).run();
+}
+
+void main() async => await generateSources('lib', 'src');
diff --git a/pkgs/jni_gen/test/simple_package_test/generated_files_test.dart b/pkgs/jni_gen/test/simple_package_test/generated_files_test.dart
new file mode 100644
index 0000000..c77a898
--- /dev/null
+++ b/pkgs/jni_gen/test/simple_package_test/generated_files_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+import 'package:path/path.dart' hide equals;
+
+import 'generate.dart';
+import '../test_util/test_util.dart';
+
+void main() async {
+  await generateSources('test_lib', 'test_src');
+  // test if generated file == expected file
+  test('compare generated files', () {
+    compareDirs(join(testRoot, 'lib'), join(testRoot, 'test_lib'));
+    compareDirs(join(testRoot, 'src'), join(testRoot, 'test_src'));
+  });
+}
diff --git a/pkgs/jni_gen/test/simple_package_test/java/dev/dart/pkg2/C2.java b/pkgs/jni_gen/test/simple_package_test/java/dev/dart/pkg2/C2.java
new file mode 100644
index 0000000..67f543e
--- /dev/null
+++ b/pkgs/jni_gen/test/simple_package_test/java/dev/dart/pkg2/C2.java
@@ -0,0 +1,5 @@
+package dev.dart.pkg2;
+
+public class C2 {
+  public static int CONSTANT = 12;
+}
diff --git a/pkgs/jni_gen/test/simple_package_test/java/dev/dart/simple_package/Example.java b/pkgs/jni_gen/test/simple_package_test/java/dev/dart/simple_package/Example.java
new file mode 100644
index 0000000..116deed
--- /dev/null
+++ b/pkgs/jni_gen/test/simple_package_test/java/dev/dart/simple_package/Example.java
@@ -0,0 +1,50 @@
+package dev.dart.simple_package;
+
+public class Example {
+  public static final int ON = 1;
+  public static final int OFF = 0;
+
+  public static Aux aux;
+  public static int num;
+
+  static {
+    aux = new Aux(true);
+    num = 121;
+  }
+
+  public static Aux getAux() {
+    return aux;
+  }
+
+  public static int addInts(int a, int b) {
+    return a + b;
+  }
+
+  public Example getSelf() {
+    return this;
+  }
+
+  public int getNum() {
+    return num;
+  }
+
+  public void setNum(int num) {
+    this.num = num;
+  }
+
+  public static class Aux {
+    public boolean value;
+
+    public Aux(boolean value) {
+      this.value = value;
+    }
+
+    public boolean getValue() {
+      return value;
+    }
+
+    public void setValue(boolean value) {
+      this.value = value;
+    }
+  }
+}
diff --git a/pkgs/jni_gen/test/simple_package_test/lib/dev/dart/pkg2.dart b/pkgs/jni_gen/test/simple_package_test/lib/dev/dart/pkg2.dart
new file mode 100644
index 0000000..618b175
--- /dev/null
+++ b/pkgs/jni_gen/test/simple_package_test/lib/dev/dart/pkg2.dart
@@ -0,0 +1,41 @@
+// Autogenerated by jni_gen. DO NOT EDIT!
+
+// ignore_for_file: camel_case_types
+// ignore_for_file: non_constant_identifier_names
+// ignore_for_file: constant_identifier_names
+// ignore_for_file: annotate_overrides
+// ignore_for_file: no_leading_underscores_for_local_identifiers
+// ignore_for_file: unused_element
+
+import "dart:ffi" as ffi;
+
+import "package:jni/jni.dart" as jni;
+
+import "../../init.dart" show jlookup;
+
+/// from: dev.dart.pkg2.C2
+class C2 extends jni.JlObject {
+  C2.fromRef(ffi.Pointer<ffi.Void> ref) : super.fromRef(ref);
+
+  static final _getCONSTANT = jlookup<ffi.NativeFunction<ffi.Int32 Function()>>(
+          "get_dev_dart_pkg2_C2_CONSTANT")
+      .asFunction<int Function()>();
+
+  /// from: static public int CONSTANT
+  static int get CONSTANT => _getCONSTANT();
+  static final _setCONSTANT =
+      jlookup<ffi.NativeFunction<ffi.Void Function(ffi.Int32)>>(
+              "set_dev_dart_pkg2_C2_CONSTANT")
+          .asFunction<void Function(int)>();
+
+  /// from: static public int CONSTANT
+  static set CONSTANT(int value) => _setCONSTANT(value);
+
+  static final _ctor =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "dev_dart_pkg2_C2_ctor")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: public void <init>()
+  C2() : super.fromRef(_ctor());
+}
diff --git a/pkgs/jni_gen/test/simple_package_test/lib/dev/dart/simple_package.dart b/pkgs/jni_gen/test/simple_package_test/lib/dev/dart/simple_package.dart
new file mode 100644
index 0000000..da6ec32
--- /dev/null
+++ b/pkgs/jni_gen/test/simple_package_test/lib/dev/dart/simple_package.dart
@@ -0,0 +1,159 @@
+// Autogenerated by jni_gen. DO NOT EDIT!
+
+// ignore_for_file: camel_case_types
+// ignore_for_file: non_constant_identifier_names
+// ignore_for_file: constant_identifier_names
+// ignore_for_file: annotate_overrides
+// ignore_for_file: no_leading_underscores_for_local_identifiers
+// ignore_for_file: unused_element
+
+import "dart:ffi" as ffi;
+
+import "package:jni/jni.dart" as jni;
+
+import "../../init.dart" show jlookup;
+
+/// from: dev.dart.simple_package.Example
+class Example extends jni.JlObject {
+  Example.fromRef(ffi.Pointer<ffi.Void> ref) : super.fromRef(ref);
+
+  /// from: static public final int ON
+  static const ON = 1;
+
+  /// from: static public final int OFF
+  static const OFF = 0;
+
+  static final _getaux =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "get_dev_dart_simple_package_Example_aux")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: static public dev.dart.simple_package.Example.Aux aux
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static Example_Aux get aux => Example_Aux.fromRef(_getaux());
+  static final _setaux =
+      jlookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
+              "set_dev_dart_simple_package_Example_aux")
+          .asFunction<void Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: static public dev.dart.simple_package.Example.Aux aux
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static set aux(Example_Aux value) => _setaux(value.reference);
+
+  static final _getnum = jlookup<ffi.NativeFunction<ffi.Int32 Function()>>(
+          "get_dev_dart_simple_package_Example_num")
+      .asFunction<int Function()>();
+
+  /// from: static public int num
+  static int get num => _getnum();
+  static final _setnum =
+      jlookup<ffi.NativeFunction<ffi.Void Function(ffi.Int32)>>(
+              "set_dev_dart_simple_package_Example_num")
+          .asFunction<void Function(int)>();
+
+  /// from: static public int num
+  static set num(int value) => _setnum(value);
+
+  static final _ctor =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "dev_dart_simple_package_Example_ctor")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: public void <init>()
+  Example() : super.fromRef(_ctor());
+
+  static final _getAux =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
+              "dev_dart_simple_package_Example_getAux")
+          .asFunction<ffi.Pointer<ffi.Void> Function()>();
+
+  /// from: static public dev.dart.simple_package.Example.Aux getAux()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  static Example_Aux getAux() => Example_Aux.fromRef(_getAux());
+
+  static final _addInts =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Int32, ffi.Int32)>>(
+              "dev_dart_simple_package_Example_addInts")
+          .asFunction<int Function(int, int)>();
+
+  /// from: static public int addInts(int a, int b)
+  static int addInts(int a, int b) => _addInts(a, b);
+
+  static final _getSelf = jlookup<
+              ffi.NativeFunction<
+                  ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>>(
+          "dev_dart_simple_package_Example_getSelf")
+      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public dev.dart.simple_package.Example getSelf()
+  /// The returned object must be deleted after use, by calling the `delete` method.
+  Example getSelf() => Example.fromRef(_getSelf(reference));
+
+  static final _getNum =
+      jlookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Pointer<ffi.Void>)>>(
+              "dev_dart_simple_package_Example_getNum")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public int getNum()
+  int getNum() => _getNum(reference);
+
+  static final _setNum = jlookup<
+          ffi.NativeFunction<
+              ffi.Void Function(ffi.Pointer<ffi.Void>,
+                  ffi.Int32)>>("dev_dart_simple_package_Example_setNum")
+      .asFunction<void Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public void setNum(int num)
+  void setNum(int num) => _setNum(reference, num);
+}
+
+/// from: dev.dart.simple_package.Example$Aux
+class Example_Aux extends jni.JlObject {
+  Example_Aux.fromRef(ffi.Pointer<ffi.Void> ref) : super.fromRef(ref);
+
+  static final _getvalue = jlookup<
+          ffi.NativeFunction<
+              ffi.Uint8 Function(
+    ffi.Pointer<ffi.Void>,
+  )>>("get_dev_dart_simple_package_Example__Aux_value")
+      .asFunction<
+          int Function(
+    ffi.Pointer<ffi.Void>,
+  )>();
+
+  /// from: public boolean value
+  bool get value => _getvalue(reference) != 0;
+  static final _setvalue = jlookup<
+          ffi.NativeFunction<
+              ffi.Void Function(ffi.Pointer<ffi.Void>,
+                  ffi.Uint8)>>("set_dev_dart_simple_package_Example__Aux_value")
+      .asFunction<void Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public boolean value
+  set value(bool value) => _setvalue(reference, value ? 1 : 0);
+
+  static final _ctor =
+      jlookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Uint8)>>(
+              "dev_dart_simple_package_Example__Aux_ctor")
+          .asFunction<ffi.Pointer<ffi.Void> Function(int)>();
+
+  /// from: public void <init>(boolean value)
+  Example_Aux(bool value) : super.fromRef(_ctor(value ? 1 : 0));
+
+  static final _getValue =
+      jlookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Pointer<ffi.Void>)>>(
+              "dev_dart_simple_package_Example__Aux_getValue")
+          .asFunction<int Function(ffi.Pointer<ffi.Void>)>();
+
+  /// from: public boolean getValue()
+  bool getValue() => _getValue(reference) != 0;
+
+  static final _setValue = jlookup<
+          ffi.NativeFunction<
+              ffi.Void Function(ffi.Pointer<ffi.Void>,
+                  ffi.Uint8)>>("dev_dart_simple_package_Example__Aux_setValue")
+      .asFunction<void Function(ffi.Pointer<ffi.Void>, int)>();
+
+  /// from: public void setValue(boolean value)
+  void setValue(bool value) => _setValue(reference, value ? 1 : 0);
+}
diff --git a/pkgs/jni_gen/test/simple_package_test/lib/init.dart b/pkgs/jni_gen/test/simple_package_test/lib/init.dart
new file mode 100644
index 0000000..4b5537c
--- /dev/null
+++ b/pkgs/jni_gen/test/simple_package_test/lib/init.dart
@@ -0,0 +1,5 @@
+import "dart:ffi";
+import "package:jni/jni.dart";
+
+final Pointer<T> Function<T extends NativeType>(String sym) jlookup =
+    Jni.getInstance().initGeneratedLibrary("simple_package");
diff --git a/pkgs/jni_gen/test/simple_package_test/src/CMakeLists.txt b/pkgs/jni_gen/test/simple_package_test/src/CMakeLists.txt
new file mode 100644
index 0000000..ef0660b
--- /dev/null
+++ b/pkgs/jni_gen/test/simple_package_test/src/CMakeLists.txt
@@ -0,0 +1,30 @@
+# The Flutter tooling requires that developers have CMake 3.10 or later
+# installed. You should not increase this version, as doing so will cause
+# the plugin to fail to compile for some customers of the plugin.
+cmake_minimum_required(VERSION 3.10)
+
+project(simple_package VERSION 0.0.1 LANGUAGES C)
+
+add_library(simple_package SHARED
+  "simple_package.c"
+)
+
+set_target_properties(simple_package PROPERTIES
+  OUTPUT_NAME "simple_package"
+)
+
+target_compile_definitions(simple_package PUBLIC DART_SHARED_LIB)
+
+if(WIN32)
+	set_target_properties(${TARGET_NAME} PROPERTIES
+		LINK_FLAGS "/DELAYLOAD:jvm.dll")
+endif()
+
+if (ANDROID)
+	target_link_libraries(simple_package log)
+else()
+	find_package(Java REQUIRED)
+	find_package(JNI REQUIRED)
+	include_directories(${JNI_INCLUDE_DIRS})
+	target_link_libraries(simple_package ${JNI_LIBRARIES})
+endif()
diff --git a/pkgs/jni_gen/test/simple_package_test/src/dartjni.h b/pkgs/jni_gen/test/simple_package_test/src/dartjni.h
new file mode 100644
index 0000000..407312b
--- /dev/null
+++ b/pkgs/jni_gen/test/simple_package_test/src/dartjni.h
@@ -0,0 +1,173 @@
+#include <jni.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if _WIN32
+#include <windows.h>
+#else
+#include <pthread.h>
+#include <unistd.h>
+#endif
+
+#if _WIN32
+#define FFI_PLUGIN_EXPORT __declspec(dllexport)
+#else
+#define FFI_PLUGIN_EXPORT
+#endif
+
+#if defined _WIN32
+#define thread_local __declspec(thread)
+#else
+#define thread_local __thread
+#endif
+
+#ifdef __ANDROID__
+#include <android/log.h>
+#endif
+
+#define JNI_LOG_TAG "Dart-JNI"
+
+#ifdef __ANDROID__
+#define __ENVP_CAST (JNIEnv **)
+#else
+#define __ENVP_CAST (void **)
+#endif
+
+struct jni_context {
+	JavaVM *jvm;
+	jobject classLoader;
+	jmethodID loadClassMethod;
+	jobject currentActivity;
+	jobject appContext;
+};
+
+extern thread_local JNIEnv *jniEnv;
+
+extern struct jni_context jni;
+
+enum DartJniLogLevel {
+	JNI_VERBOSE = 2,
+	JNI_DEBUG,
+	JNI_INFO,
+	JNI_WARN,
+	JNI_ERROR
+};
+
+FFI_PLUGIN_EXPORT struct jni_context GetJniContext();
+
+FFI_PLUGIN_EXPORT JavaVM *GetJavaVM(void);
+
+FFI_PLUGIN_EXPORT JNIEnv *GetJniEnv(void);
+
+FFI_PLUGIN_EXPORT JNIEnv *SpawnJvm(JavaVMInitArgs *args);
+
+FFI_PLUGIN_EXPORT jclass LoadClass(const char *name);
+
+FFI_PLUGIN_EXPORT jobject GetClassLoader(void);
+
+FFI_PLUGIN_EXPORT jobject GetApplicationContext(void);
+
+FFI_PLUGIN_EXPORT jobject GetCurrentActivity(void);
+
+FFI_PLUGIN_EXPORT void SetJNILogging(int level);
+
+FFI_PLUGIN_EXPORT jstring ToJavaString(char *str);
+
+FFI_PLUGIN_EXPORT const char *GetJavaStringChars(jstring jstr);
+
+FFI_PLUGIN_EXPORT void ReleaseJavaStringChars(jstring jstr, const char *buf);
+
+// These 2 are the function pointer variables defined and exported by
+// the generated C files.
+//
+// initGeneratedLibrary function in Jni class will set these to
+// corresponding functions to the implementations from `dartjni` base library
+// which initializes and manages the JNI.
+extern struct jni_context (*context_getter)(void);
+extern JNIEnv *(*env_getter)(void);
+
+// This function will be exported by generated code library and will set the
+// above 2 variables.
+FFI_PLUGIN_EXPORT void setJniGetters(struct jni_context (*cg)(void),
+		JNIEnv *(*eg)(void));
+
+// `static inline` because `inline` doesn't work, it may still not
+// inline the function in which case a linker error may be produced.
+//
+// There has to be a better way to do this. Either to force inlining on target
+// platforms, or just leave it as normal function.
+static inline void __load_class_into(jclass *cls, const char *name) {
+#ifdef __ANDROID__
+	jstring className = (*jniEnv)->NewStringUTF(jniEnv, name);
+	*cls = (*jniEnv)->CallObjectMethod(jniEnv, jni.classLoader,
+	                                   jni.loadClassMethod, className);
+	(*jniEnv)->DeleteLocalRef(jniEnv, className);
+#else
+	*cls = (*jniEnv)->FindClass(jniEnv, name);
+#endif
+}
+
+static inline void load_class(jclass *cls, const char *name) {
+	if (*cls == NULL) {
+		__load_class_into(cls, name);
+	}
+}
+
+static inline void load_class_gr(jclass *cls, const char *name) {
+	if (*cls == NULL) {
+		jclass tmp;
+		__load_class_into(&tmp, name);
+		*cls = (*jniEnv)->NewGlobalRef(jniEnv, tmp);
+		(*jniEnv)->DeleteLocalRef(jniEnv, tmp);
+	}
+}
+
+static inline void attach_thread() {
+	if (jniEnv == NULL) {
+		(*jni.jvm)->AttachCurrentThread(jni.jvm, __ENVP_CAST & jniEnv,
+		                                NULL);
+	}
+}
+
+static inline void load_env() {
+	if (jniEnv == NULL) {
+		jni = context_getter();
+		jniEnv = env_getter();
+	}
+}
+
+static inline void load_method(jclass cls, jmethodID *res, const char *name,
+                               const char *sig) {
+	if (*res == NULL) {
+		*res = (*jniEnv)->GetMethodID(jniEnv, cls, name, sig);
+	}
+}
+
+static inline void load_static_method(jclass cls, jmethodID *res,
+                                      const char *name, const char *sig) {
+	if (*res == NULL) {
+		*res = (*jniEnv)->GetStaticMethodID(jniEnv, cls, name, sig);
+	}
+}
+
+static inline void load_field(jclass cls, jfieldID *res, const char *name,
+                              const char *sig) {
+	if (*res == NULL) {
+		*res = (*jniEnv)->GetFieldID(jniEnv, cls, name, sig);
+	}
+}
+
+static inline void load_static_field(jclass cls, jfieldID *res,
+                                     const char *name, const char *sig) {
+	if (*res == NULL) {
+		*res = (*jniEnv)->GetStaticFieldID(jniEnv, cls, name, sig);
+	}
+}
+
+static inline jobject to_global_ref(jobject ref) {
+	jobject g = (*jniEnv)->NewGlobalRef(jniEnv, ref);
+	(*jniEnv)->DeleteLocalRef(jniEnv, ref);
+	return g;
+}
+
diff --git a/pkgs/jni_gen/test/simple_package_test/src/simple_package.c b/pkgs/jni_gen/test/simple_package_test/src/simple_package.c
new file mode 100644
index 0000000..4cc5e42
--- /dev/null
+++ b/pkgs/jni_gen/test/simple_package_test/src/simple_package.c
@@ -0,0 +1,189 @@
+// Autogenerated by jni_gen. DO NOT EDIT!
+
+#include <stdint.h>
+#include "jni.h"
+#include "dartjni.h"
+
+thread_local JNIEnv *jniEnv;
+struct jni_context jni;
+
+struct jni_context (*context_getter)(void);
+JNIEnv *(*env_getter)(void);
+
+void setJniGetters(struct jni_context (*cg)(void),
+        JNIEnv *(*eg)(void)) {
+    context_getter = cg;
+    env_getter = eg;
+}
+
+// dev.dart.simple_package.Example
+jclass _c_dev_dart_simple_package_Example = NULL;
+
+jmethodID _m_dev_dart_simple_package_Example_ctor = NULL;
+FFI_PLUGIN_EXPORT
+jobject dev_dart_simple_package_Example_ctor() {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example, "dev/dart/simple_package/Example");
+    load_method(_c_dev_dart_simple_package_Example, &_m_dev_dart_simple_package_Example_ctor, "<init>", "()V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_dev_dart_simple_package_Example, _m_dev_dart_simple_package_Example_ctor);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_dev_dart_simple_package_Example_getAux = NULL;
+FFI_PLUGIN_EXPORT
+jobject dev_dart_simple_package_Example_getAux() {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example, "dev/dart/simple_package/Example");
+    load_static_method(_c_dev_dart_simple_package_Example, &_m_dev_dart_simple_package_Example_getAux, "getAux", "()Ldev/dart/simple_package/Example$Aux;");
+    jobject _result = (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_dev_dart_simple_package_Example, _m_dev_dart_simple_package_Example_getAux);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_dev_dart_simple_package_Example_addInts = NULL;
+FFI_PLUGIN_EXPORT
+int32_t dev_dart_simple_package_Example_addInts(int32_t a, int32_t b) {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example, "dev/dart/simple_package/Example");
+    load_static_method(_c_dev_dart_simple_package_Example, &_m_dev_dart_simple_package_Example_addInts, "addInts", "(II)I");
+    int32_t _result = (*jniEnv)->CallStaticIntMethod(jniEnv, _c_dev_dart_simple_package_Example, _m_dev_dart_simple_package_Example_addInts, a, b);
+    return _result;
+}
+
+jmethodID _m_dev_dart_simple_package_Example_getSelf = NULL;
+FFI_PLUGIN_EXPORT
+jobject dev_dart_simple_package_Example_getSelf(jobject self_) {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example, "dev/dart/simple_package/Example");
+    load_method(_c_dev_dart_simple_package_Example, &_m_dev_dart_simple_package_Example_getSelf, "getSelf", "()Ldev/dart/simple_package/Example;");
+    jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, _m_dev_dart_simple_package_Example_getSelf);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_dev_dart_simple_package_Example_getNum = NULL;
+FFI_PLUGIN_EXPORT
+int32_t dev_dart_simple_package_Example_getNum(jobject self_) {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example, "dev/dart/simple_package/Example");
+    load_method(_c_dev_dart_simple_package_Example, &_m_dev_dart_simple_package_Example_getNum, "getNum", "()I");
+    int32_t _result = (*jniEnv)->CallIntMethod(jniEnv, self_, _m_dev_dart_simple_package_Example_getNum);
+    return _result;
+}
+
+jmethodID _m_dev_dart_simple_package_Example_setNum = NULL;
+FFI_PLUGIN_EXPORT
+void dev_dart_simple_package_Example_setNum(jobject self_, int32_t num) {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example, "dev/dart/simple_package/Example");
+    load_method(_c_dev_dart_simple_package_Example, &_m_dev_dart_simple_package_Example_setNum, "setNum", "(I)V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_dev_dart_simple_package_Example_setNum, num);
+}
+
+jfieldID _f_dev_dart_simple_package_Example_aux = NULL;
+jobject get_dev_dart_simple_package_Example_aux() {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example, "dev/dart/simple_package/Example");
+    load_static_field(_c_dev_dart_simple_package_Example, &_f_dev_dart_simple_package_Example_aux, "aux","Ldev/dart/simple_package/Example$Aux;");
+    return to_global_ref((*jniEnv)->GetStaticObjectField(jniEnv, _c_dev_dart_simple_package_Example, _f_dev_dart_simple_package_Example_aux));
+}
+
+void set_dev_dart_simple_package_Example_aux(jobject value) {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example, "dev/dart/simple_package/Example");
+    load_static_field(_c_dev_dart_simple_package_Example, &_f_dev_dart_simple_package_Example_aux, "aux","Ldev/dart/simple_package/Example$Aux;");
+    ((*jniEnv)->SetStaticObjectField(jniEnv, _c_dev_dart_simple_package_Example, _f_dev_dart_simple_package_Example_aux, value));
+}
+
+
+jfieldID _f_dev_dart_simple_package_Example_num = NULL;
+int32_t get_dev_dart_simple_package_Example_num() {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example, "dev/dart/simple_package/Example");
+    load_static_field(_c_dev_dart_simple_package_Example, &_f_dev_dart_simple_package_Example_num, "num","I");
+    return ((*jniEnv)->GetStaticIntField(jniEnv, _c_dev_dart_simple_package_Example, _f_dev_dart_simple_package_Example_num));
+}
+
+void set_dev_dart_simple_package_Example_num(int32_t value) {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example, "dev/dart/simple_package/Example");
+    load_static_field(_c_dev_dart_simple_package_Example, &_f_dev_dart_simple_package_Example_num, "num","I");
+    ((*jniEnv)->SetStaticIntField(jniEnv, _c_dev_dart_simple_package_Example, _f_dev_dart_simple_package_Example_num, value));
+}
+
+
+// dev.dart.simple_package.Example$Aux
+jclass _c_dev_dart_simple_package_Example__Aux = NULL;
+
+jmethodID _m_dev_dart_simple_package_Example__Aux_ctor = NULL;
+FFI_PLUGIN_EXPORT
+jobject dev_dart_simple_package_Example__Aux_ctor(uint8_t value) {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example__Aux, "dev/dart/simple_package/Example$Aux");
+    load_method(_c_dev_dart_simple_package_Example__Aux, &_m_dev_dart_simple_package_Example__Aux_ctor, "<init>", "(Z)V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_dev_dart_simple_package_Example__Aux, _m_dev_dart_simple_package_Example__Aux_ctor, value);
+    return to_global_ref(_result);
+}
+
+jmethodID _m_dev_dart_simple_package_Example__Aux_getValue = NULL;
+FFI_PLUGIN_EXPORT
+uint8_t dev_dart_simple_package_Example__Aux_getValue(jobject self_) {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example__Aux, "dev/dart/simple_package/Example$Aux");
+    load_method(_c_dev_dart_simple_package_Example__Aux, &_m_dev_dart_simple_package_Example__Aux_getValue, "getValue", "()Z");
+    uint8_t _result = (*jniEnv)->CallBooleanMethod(jniEnv, self_, _m_dev_dart_simple_package_Example__Aux_getValue);
+    return _result;
+}
+
+jmethodID _m_dev_dart_simple_package_Example__Aux_setValue = NULL;
+FFI_PLUGIN_EXPORT
+void dev_dart_simple_package_Example__Aux_setValue(jobject self_, uint8_t value) {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example__Aux, "dev/dart/simple_package/Example$Aux");
+    load_method(_c_dev_dart_simple_package_Example__Aux, &_m_dev_dart_simple_package_Example__Aux_setValue, "setValue", "(Z)V");
+    (*jniEnv)->CallVoidMethod(jniEnv, self_, _m_dev_dart_simple_package_Example__Aux_setValue, value);
+}
+
+jfieldID _f_dev_dart_simple_package_Example__Aux_value = NULL;
+uint8_t get_dev_dart_simple_package_Example__Aux_value(jobject self_) {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example__Aux, "dev/dart/simple_package/Example$Aux");
+    load_field(_c_dev_dart_simple_package_Example__Aux, &_f_dev_dart_simple_package_Example__Aux_value, "value","Z");
+    return ((*jniEnv)->GetBooleanField(jniEnv, self_, _f_dev_dart_simple_package_Example__Aux_value));
+}
+
+void set_dev_dart_simple_package_Example__Aux_value(jobject self_, uint8_t value) {
+    load_env();
+    load_class_gr(&_c_dev_dart_simple_package_Example__Aux, "dev/dart/simple_package/Example$Aux");
+    load_field(_c_dev_dart_simple_package_Example__Aux, &_f_dev_dart_simple_package_Example__Aux_value, "value","Z");
+    ((*jniEnv)->SetBooleanField(jniEnv, self_, _f_dev_dart_simple_package_Example__Aux_value, value));
+}
+
+
+// dev.dart.pkg2.C2
+jclass _c_dev_dart_pkg2_C2 = NULL;
+
+jmethodID _m_dev_dart_pkg2_C2_ctor = NULL;
+FFI_PLUGIN_EXPORT
+jobject dev_dart_pkg2_C2_ctor() {
+    load_env();
+    load_class_gr(&_c_dev_dart_pkg2_C2, "dev/dart/pkg2/C2");
+    load_method(_c_dev_dart_pkg2_C2, &_m_dev_dart_pkg2_C2_ctor, "<init>", "()V");
+    jobject _result = (*jniEnv)->NewObject(jniEnv, _c_dev_dart_pkg2_C2, _m_dev_dart_pkg2_C2_ctor);
+    return to_global_ref(_result);
+}
+
+jfieldID _f_dev_dart_pkg2_C2_CONSTANT = NULL;
+int32_t get_dev_dart_pkg2_C2_CONSTANT() {
+    load_env();
+    load_class_gr(&_c_dev_dart_pkg2_C2, "dev/dart/pkg2/C2");
+    load_static_field(_c_dev_dart_pkg2_C2, &_f_dev_dart_pkg2_C2_CONSTANT, "CONSTANT","I");
+    return ((*jniEnv)->GetStaticIntField(jniEnv, _c_dev_dart_pkg2_C2, _f_dev_dart_pkg2_C2_CONSTANT));
+}
+
+void set_dev_dart_pkg2_C2_CONSTANT(int32_t value) {
+    load_env();
+    load_class_gr(&_c_dev_dart_pkg2_C2, "dev/dart/pkg2/C2");
+    load_static_field(_c_dev_dart_pkg2_C2, &_f_dev_dart_pkg2_C2_CONSTANT, "CONSTANT","I");
+    ((*jniEnv)->SetStaticIntField(jniEnv, _c_dev_dart_pkg2_C2, _f_dev_dart_pkg2_C2_CONSTANT, value));
+}
+
+
diff --git a/pkgs/jni_gen/test/test_util/test_util.dart b/pkgs/jni_gen/test/test_util/test_util.dart
new file mode 100644
index 0000000..c0a1681
--- /dev/null
+++ b/pkgs/jni_gen/test/test_util/test_util.dart
@@ -0,0 +1,107 @@
+import 'dart:io';
+
+import 'package:path/path.dart' hide equals;
+import 'package:jni_gen/jni_gen.dart';
+import 'package:jni_gen/tools.dart';
+import 'package:test/test.dart';
+
+const packageTestsDir = 'test';
+
+Future<bool> isEmptyDir(String path) async {
+  final dir = Directory(path);
+  return (!await dir.exists()) || (await dir.list().length == 0);
+}
+
+Future<int> runCmd(String exec, List<String> args,
+    {String? workingDirectory}) async {
+  stderr.writeln('[exec] $exec ${args.join(" ")}');
+  final proc = await Process.start(exec, args,
+      workingDirectory: workingDirectory,
+      runInShell: true,
+      mode: ProcessStartMode.inheritStdio);
+  return proc.exitCode;
+}
+
+Future<void> buildNativeLibs(String testName) async {
+  final testRoot = join(packageTestsDir, testName);
+  await runCmd('dart', ['run', 'jni:setup']);
+  await runCmd('dart', ['run', 'jni:setup', '-S', join(testRoot, 'src')]);
+}
+
+Future<List<String>> getJarPaths(String testRoot) {
+  final jarPath = join(testRoot, 'jar');
+  return Directory(jarPath)
+      .list()
+      .map((entry) => entry.path)
+      .where((path) => path.endsWith('jar'))
+      .toList();
+}
+
+/// Download dependencies using maven and generate bindings.
+Future<void> generateBindings({
+  required String testName,
+  required List<String> sourceDepNames,
+  required List<String> jarDepNames,
+  required List<String> classes,
+  required WrapperOptions options,
+  required bool isGeneratedFileTest,
+  bool useAsmBackend = false,
+  bool isThirdParty = false,
+  String? preamble,
+}) async {
+  final testRoot =
+      join(packageTestsDir, testName, isThirdParty ? 'third_party' : '');
+  final jarPath = join(testRoot, 'jar');
+  final javaPath = join(testRoot, 'java');
+  final src = join(testRoot, isGeneratedFileTest ? 'test_src' : 'src');
+  final lib = join(testRoot, isGeneratedFileTest ? 'test_lib' : 'lib');
+
+  final sourceDeps = MvnTools.makeDependencyList(sourceDepNames);
+  final jarDeps = MvnTools.makeDependencyList(jarDepNames);
+
+  await runCmd('dart', ['run', 'jni_gen:setup']);
+
+  MvnTools.setVerbose(true);
+  if (await isEmptyDir(jarPath)) {
+    await Directory(jarPath).create(recursive: true);
+    await MvnTools.downloadMavenJars(jarDeps, jarPath);
+  }
+  if (await isEmptyDir(javaPath)) {
+    await Directory(javaPath).create(recursive: true);
+    await MvnTools.downloadMavenSources(sourceDeps, javaPath);
+  }
+  final jars = await getJarPaths(testRoot);
+  stderr.writeln('using classpath: $jars');
+  await JniGenTask(
+          summarySource: SummarizerCommand(
+            sourcePaths: [Uri.directory(javaPath)],
+            classPaths: jars.map(Uri.file).toList(),
+            classes: classes,
+            extraArgs: useAsmBackend ? ['--backend', 'asm'] : [],
+          ),
+          options: options,
+          outputWriter: FilesWriter(
+              cWrapperDir: Uri.directory(src),
+              dartWrappersRoot: Uri.directory(lib),
+              preamble: preamble,
+              libraryName: testName))
+      .run();
+}
+
+/// compares 2 hierarchies, with and without prefix 'test_'
+void compareDirs(String path1, String path2) {
+  final list1 = Directory(path1).listSync(recursive: true);
+  final list2 = Directory(path2).listSync(recursive: true);
+  expect(list1.length, equals(list2.length));
+  for (var list in [list1, list2]) {
+    list.sort((a, b) => a.path.compareTo(b.path));
+  }
+  for (int i = 0; i < list1.length; i++) {
+    if (list1[i].statSync().type != FileSystemEntityType.file) {
+      continue;
+    }
+    final a = File(list1[i].path);
+    final b = File(list2[i].path);
+    expect(a.readAsStringSync(), equals(b.readAsStringSync()));
+  }
+}
diff --git a/pkgs/jnigen/README.md b/pkgs/jnigen/README.md
index c274826..a9be656 100644
--- a/pkgs/jnigen/README.md
+++ b/pkgs/jnigen/README.md
@@ -2,7 +2,7 @@
 
 ## jni_gen
 
-This project intends to provide 2 packages to enable JNI interop from Dart & Flutter.
+This project intends to provide 2 packages to enable JNI interop from Dart & Flutter. Currently this package is highly experimental.
 
 | Package | Description |
 | ------- | --------- |