diff --git a/pkgs/ok_http/CHANGELOG.md b/pkgs/ok_http/CHANGELOG.md
index f3d0114..581e155 100644
--- a/pkgs/ok_http/CHANGELOG.md
+++ b/pkgs/ok_http/CHANGELOG.md
@@ -1,9 +1,10 @@
 ## 0.1.1-wip
 
+- Fix Android release mode crash due to missing OkHttp classes by explicitly keeping the classes that are consumed.
 - `OkHttpClient` now receives an `OkHttpClientConfiguration` to configure the client on a per-call basis.
 - `OkHttpClient` supports setting four types of timeouts: [`connectTimeout`](https://square.github.io/okhttp/5.x/okhttp/okhttp3/-ok-http-client/-builder/connect-timeout.html), [`readTimeout`](https://square.github.io/okhttp/5.x/okhttp/okhttp3/-ok-http-client/-builder/read-timeout.html), [`writeTimeout`](https://square.github.io/okhttp/5.x/okhttp/okhttp3/-ok-http-client/-builder/write-timeout.html), and [`callTimeout`](https://square.github.io/okhttp/5.x/okhttp/okhttp3/-ok-http-client/-builder/call-timeout.html), using the `OkHttpClientConfiguration`.
-- Upgrade to `jni` 0.14.0
-- Upgrade to `jnigen` 0.14.0
+- Upgrade to `jni` 1.0.0
+- Upgrade to `jnigen` 0.16.0
 - `OKHttpClient` supports client certificates.
 - Support `package:web_socket` 1.0.0.
 - Set `minSdk=24`.
diff --git a/pkgs/ok_http/android/build.gradle b/pkgs/ok_http/android/build.gradle
index bf0282e..691f0c7 100644
--- a/pkgs/ok_http/android/build.gradle
+++ b/pkgs/ok_http/android/build.gradle
@@ -57,6 +57,7 @@
 
     defaultConfig {
         minSdk = 24
+        consumerProguardFiles("proguard.txt")
     }
 }
 
diff --git a/pkgs/ok_http/android/proguard.txt b/pkgs/ok_http/android/proguard.txt
new file mode 100644
index 0000000..5ffba89
--- /dev/null
+++ b/pkgs/ok_http/android/proguard.txt
@@ -0,0 +1,35 @@
+# IMPORTANT: Keep this file in sync with the OkHttp classes
+# declared in jnigen.yaml. JNI loads these classes by name,
+# so they must not be removed in Android release builds.
+
+-keep class okhttp3.Request** { *; }
+-keep class okhttp3.RequestBody { *; }
+-keep class okhttp3.Response { *; }
+-keep class okhttp3.ResponseBody { *; }
+-keep class okhttp3.OkHttpClient** { *; }
+-keep class okhttp3.Call { *; }
+-keep class okhttp3.Headers { *; }
+-keep class okhttp3.Callback { *; }
+-keep class okhttp3.ConnectionPool { *; }
+-keep class okhttp3.Dispatcher { *; }
+-keep class okhttp3.Cache { *; }
+-keep class okhttp3.WebSocket { *; }
+
+-keep class okio.ByteString { *; }
+
+-keep class com.example.ok_http.RedirectReceivedCallback { *; }
+-keep class com.example.ok_http.AsyncInputStreamReader { *; }
+-keep class com.example.ok_http.DataCallback { *; }
+-keep class com.example.ok_http.WebSocketInterceptor** { *; }
+-keep class com.example.ok_http.WebSocketListenerProxy** { *; }
+-keep class com.example.ok_http.FixedResponseX509ExtendedKeyManager { *; }
+
+-keepclassmembers class com.example.ok_http.RedirectInterceptor {
+    public static com.example.ok_http.RedirectInterceptor$Companion Companion;
+}
+
+-keepclassmembers class com.example.ok_http.WebSocketInterceptor {
+    public static com.example.ok_http.WebSocketInterceptor$Companion Companion;
+}
+
+-keep class com.example.ok_http.RedirectInterceptor** { *; }
diff --git a/pkgs/ok_http/example/android/.gitignore b/pkgs/ok_http/example/android/.gitignore
index 55afd91..812de98 100644
--- a/pkgs/ok_http/example/android/.gitignore
+++ b/pkgs/ok_http/example/android/.gitignore
@@ -11,3 +11,5 @@
 key.properties
 **/*.keystore
 **/*.jks
+
+.kotlin
diff --git a/pkgs/ok_http/example/android/app/src/main/AndroidManifest.xml b/pkgs/ok_http/example/android/app/src/main/AndroidManifest.xml
index 8670e67..df114bf 100644
--- a/pkgs/ok_http/example/android/app/src/main/AndroidManifest.xml
+++ b/pkgs/ok_http/example/android/app/src/main/AndroidManifest.xml
@@ -1,4 +1,5 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <uses-permission android:name="android.permission.INTERNET"/>
     <application
         android:label="ok_http_example"
         android:name="${applicationName}"
diff --git a/pkgs/ok_http/example/android/gradle.properties b/pkgs/ok_http/example/android/gradle.properties
index 3b5b324..1551eb0 100644
--- a/pkgs/ok_http/example/android/gradle.properties
+++ b/pkgs/ok_http/example/android/gradle.properties
@@ -1,3 +1,7 @@
 org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError
 android.useAndroidX=true
 android.enableJetifier=true
+# This builtInKotlin flag was added automatically by Flutter migrator
+android.builtInKotlin=false
+# This newDsl flag was added automatically by Flutter migrator
+android.newDsl=false
diff --git a/pkgs/ok_http/example/android/gradle/wrapper/gradle-wrapper.properties b/pkgs/ok_http/example/android/gradle/wrapper/gradle-wrapper.properties
index b836b84..20014ed 100644
--- a/pkgs/ok_http/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/pkgs/ok_http/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
diff --git a/pkgs/ok_http/example/android/settings.gradle b/pkgs/ok_http/example/android/settings.gradle
index 6943dc9..abf1648 100644
--- a/pkgs/ok_http/example/android/settings.gradle
+++ b/pkgs/ok_http/example/android/settings.gradle
@@ -18,7 +18,7 @@
 
 plugins {
     id "dev.flutter.flutter-plugin-loader" version "1.0.0"
-    id "com.android.application" version "8.2.1" apply false
+    id "com.android.application" version "8.6.0" apply false
     id "org.jetbrains.kotlin.android" version "1.9.23" apply false
 }
 
diff --git a/pkgs/ok_http/example/integration_test/certificate_test.dart b/pkgs/ok_http/example/integration_test/certificate_test.dart
index da2d29b..d07ef73 100644
--- a/pkgs/ok_http/example/integration_test/certificate_test.dart
+++ b/pkgs/ok_http/example/integration_test/certificate_test.dart
@@ -9,9 +9,9 @@
 import 'package:flutter/services.dart' show rootBundle;
 import 'package:http/http.dart';
 import 'package:integration_test/integration_test.dart';
+import 'package:jni/jni.dart' show JStringExtension;
 import 'package:ok_http/ok_http.dart';
 import 'package:ok_http/src/jni/bindings.dart' as bindings;
-
 import 'package:test/test.dart';
 
 Future<Uint8List> loadCertificateBytes(String path) async {
@@ -28,14 +28,9 @@
             await loadCertificateBytes('test_certs/test-combined.p12');
         final (key, chain) =
             loadPrivateKeyAndCertificateChainFromPKCS12(certBytes, '1234');
-        expect(
-            key
-                .as(bindings.Key.type)
-                .getFormat()!
-                .toDartString(releaseOriginal: true),
-            'PKCS#8');
+        expect(key.getFormat()!.toDartString(releaseOriginal: true), 'PKCS#8');
         expect(chain.length, 1);
-        expect(chain[0].getType()!.toDartString(), 'X.509');
+        expect(chain[0].type$1!.toDartString(), 'X.509');
       });
 
       test('no key', () async {
diff --git a/pkgs/ok_http/example/pubspec.yaml b/pkgs/ok_http/example/pubspec.yaml
index 319c5fa..8f0ef33 100644
--- a/pkgs/ok_http/example/pubspec.yaml
+++ b/pkgs/ok_http/example/pubspec.yaml
@@ -27,6 +27,7 @@
   http_profile: ^0.1.0
   integration_test:
     sdk: flutter
+  jni: ^1.0.0 # Used in integration tests.
   test: ^1.23.1
   web_socket_conformance_tests:
     path: ../../web_socket_conformance_tests/
diff --git a/pkgs/ok_http/jnigen.yaml b/pkgs/ok_http/jnigen.yaml
index e52b289..aa3dc1c 100644
--- a/pkgs/ok_http/jnigen.yaml
+++ b/pkgs/ok_http/jnigen.yaml
@@ -12,6 +12,9 @@
   add_gradle_deps: true
   android_example: "example/"
 
+# IMPORTANT: OkHttp classes declared here
+# must be kept in sync with android/proguard.txt
+# to support Android release builds.
 classes:
 - "okhttp3.Request"
 - "okhttp3.RequestBody"
diff --git a/pkgs/ok_http/lib/src/jni/bindings.dart b/pkgs/ok_http/lib/src/jni/bindings.dart
index 06df646..0daa785 100644
--- a/pkgs/ok_http/lib/src/jni/bindings.dart
+++ b/pkgs/ok_http/lib/src/jni/bindings.dart
@@ -1,12 +1,13 @@
-// ignore_for_file: prefer_expression_function_bodies
+// AUTO GENERATED BY JNIGEN 0.16.0. DO NOT EDIT!
 
-// Autogenerated by jnigen. DO NOT EDIT!
+// ignore_for_file: prefer_expression_function_bodies
 
 // ignore_for_file: annotate_overrides
 // ignore_for_file: argument_type_not_assignable
 // ignore_for_file: camel_case_extensions
 // ignore_for_file: camel_case_types
 // ignore_for_file: constant_identifier_names
+// ignore_for_file: comment_references
 // ignore_for_file: doc_directive_unknown
 // ignore_for_file: file_names
 // ignore_for_file: inference_failure_on_untyped_parameter
@@ -31,29 +32,21 @@
 // ignore_for_file: unused_shown_name
 // ignore_for_file: use_super_parameters
 
-import 'dart:core' show Object, String, bool, double, int;
 import 'dart:core' as core$_;
+import 'dart:core' show Object, String;
 
 import 'package:jni/_internal.dart' as jni$_;
 import 'package:jni/jni.dart' as jni$_;
 
+const _$jniVersionCheck = jni$_.JniVersionCheck(1, 0);
+
 /// from: `okhttp3.Request$Builder`
-class Request$Builder extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Request$Builder> $type;
-
-  @jni$_.internal
-  Request$Builder.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Request$Builder._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Request$Builder');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Request$Builder$NullableType();
-  static const type = $Request$Builder$Type();
+  static const jni$_.JType<Request$Builder> type = $Request$Builder$Type$();
   static final _id_new$ = _class.constructorId(
     r'()V',
   );
@@ -73,9 +66,8 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory Request$Builder() {
-    return Request$Builder.fromReference(
-        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
-            .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer)
+        .object<Request$Builder>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -99,12 +91,14 @@
     Request request,
   ) {
     final _$request = request.reference;
-    return Request$Builder.fromReference(_new$1(_class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr, _$request.pointer)
-        .reference);
+    return _new$1(
+            _class.reference.pointer, _id_new$1.pointer, _$request.pointer)
+        .object<Request$Builder>();
   }
+}
 
-  static final _id_url = _class.instanceMethodId(
+extension Request$Builder$$Methods on Request$Builder {
+  static final _id_url = Request$Builder._class.instanceMethodId(
     r'url',
     r'(Lokhttp3/HttpUrl;)Lokhttp3/Request$Builder;',
   );
@@ -120,18 +114,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder url(okhttp3.HttpUrl httpUrl)`
+  /// from: `public fun url(url: okhttp3.HttpUrl): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder url(
     jni$_.JObject httpUrl,
   ) {
     final _$httpUrl = httpUrl.reference;
-    return _url(
-            reference.pointer, _id_url as jni$_.JMethodIDPtr, _$httpUrl.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _url(reference.pointer, _id_url.pointer, _$httpUrl.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_url$1 = _class.instanceMethodId(
+  static final _id_url$1 = Request$Builder._class.instanceMethodId(
     r'url',
     r'(Ljava/lang/String;)Lokhttp3/Request$Builder;',
   );
@@ -147,18 +140,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder url(java.lang.String string)`
+  /// from: `public fun url(url: kotlin.String): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder url$1(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _url$1(reference.pointer, _id_url$1 as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _url$1(reference.pointer, _id_url$1.pointer, _$string.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_url$2 = _class.instanceMethodId(
+  static final _id_url$2 = Request$Builder._class.instanceMethodId(
     r'url',
     r'(Ljava/net/URL;)Lokhttp3/Request$Builder;',
   );
@@ -174,18 +166,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder url(java.net.URL uRL)`
+  /// from: `public fun url(url: java.net.URL): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder url$2(
     jni$_.JObject uRL,
   ) {
     final _$uRL = uRL.reference;
-    return _url$2(
-            reference.pointer, _id_url$2 as jni$_.JMethodIDPtr, _$uRL.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _url$2(reference.pointer, _id_url$2.pointer, _$uRL.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_header = _class.instanceMethodId(
+  static final _id_header = Request$Builder._class.instanceMethodId(
     r'header',
     r'(Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Request$Builder;',
   );
@@ -207,7 +198,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder header(java.lang.String string, java.lang.String string1)`
+  /// from: `public fun header(name: kotlin.String, value: kotlin.String): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder header(
     jni$_.JString string,
@@ -215,12 +206,12 @@
   ) {
     final _$string = string.reference;
     final _$string1 = string1.reference;
-    return _header(reference.pointer, _id_header as jni$_.JMethodIDPtr,
-            _$string.pointer, _$string1.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _header(reference.pointer, _id_header.pointer, _$string.pointer,
+            _$string1.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_addHeader = _class.instanceMethodId(
+  static final _id_addHeader = Request$Builder._class.instanceMethodId(
     r'addHeader',
     r'(Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Request$Builder;',
   );
@@ -242,7 +233,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder addHeader(java.lang.String string, java.lang.String string1)`
+  /// from: `public fun addHeader(name: kotlin.String, value: kotlin.String): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder addHeader(
     jni$_.JString string,
@@ -250,12 +241,12 @@
   ) {
     final _$string = string.reference;
     final _$string1 = string1.reference;
-    return _addHeader(reference.pointer, _id_addHeader as jni$_.JMethodIDPtr,
+    return _addHeader(reference.pointer, _id_addHeader.pointer,
             _$string.pointer, _$string1.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+        .object<Request$Builder>();
   }
 
-  static final _id_removeHeader = _class.instanceMethodId(
+  static final _id_removeHeader = Request$Builder._class.instanceMethodId(
     r'removeHeader',
     r'(Ljava/lang/String;)Lokhttp3/Request$Builder;',
   );
@@ -271,18 +262,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder removeHeader(java.lang.String string)`
+  /// from: `public fun removeHeader(name: kotlin.String): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder removeHeader(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _removeHeader(reference.pointer,
-            _id_removeHeader as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _removeHeader(
+            reference.pointer, _id_removeHeader.pointer, _$string.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_headers = _class.instanceMethodId(
+  static final _id_headers = Request$Builder._class.instanceMethodId(
     r'headers',
     r'(Lokhttp3/Headers;)Lokhttp3/Request$Builder;',
   );
@@ -298,18 +289,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder headers(okhttp3.Headers headers)`
+  /// from: `public fun headers(headers: okhttp3.Headers): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder headers(
     Headers headers,
   ) {
     final _$headers = headers.reference;
-    return _headers(reference.pointer, _id_headers as jni$_.JMethodIDPtr,
-            _$headers.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _headers(reference.pointer, _id_headers.pointer, _$headers.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_cacheControl = _class.instanceMethodId(
+  static final _id_cacheControl = Request$Builder._class.instanceMethodId(
     r'cacheControl',
     r'(Lokhttp3/CacheControl;)Lokhttp3/Request$Builder;',
   );
@@ -325,18 +315,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder cacheControl(okhttp3.CacheControl cacheControl)`
+  /// from: `public fun cacheControl(cacheControl: okhttp3.CacheControl): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder cacheControl(
     jni$_.JObject cacheControl,
   ) {
     final _$cacheControl = cacheControl.reference;
-    return _cacheControl(reference.pointer,
-            _id_cacheControl as jni$_.JMethodIDPtr, _$cacheControl.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _cacheControl(
+            reference.pointer, _id_cacheControl.pointer, _$cacheControl.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_get = _class.instanceMethodId(
+  static final _id_get = Request$Builder._class.instanceMethodId(
     r'get',
     r'()Lokhttp3/Request$Builder;',
   );
@@ -353,14 +343,13 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public okhttp3.Request$Builder get()`
+  /// from: `public fun get(): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder get() {
-    return _get(reference.pointer, _id_get as jni$_.JMethodIDPtr)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _get(reference.pointer, _id_get.pointer).object<Request$Builder>();
   }
 
-  static final _id_head = _class.instanceMethodId(
+  static final _id_head = Request$Builder._class.instanceMethodId(
     r'head',
     r'()Lokhttp3/Request$Builder;',
   );
@@ -377,14 +366,13 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public okhttp3.Request$Builder head()`
+  /// from: `public fun head(): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder head() {
-    return _head(reference.pointer, _id_head as jni$_.JMethodIDPtr)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _head(reference.pointer, _id_head.pointer).object<Request$Builder>();
   }
 
-  static final _id_post = _class.instanceMethodId(
+  static final _id_post = Request$Builder._class.instanceMethodId(
     r'post',
     r'(Lokhttp3/RequestBody;)Lokhttp3/Request$Builder;',
   );
@@ -400,18 +388,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder post(okhttp3.RequestBody requestBody)`
+  /// from: `public fun post(body: okhttp3.RequestBody): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder post(
     RequestBody requestBody,
   ) {
     final _$requestBody = requestBody.reference;
-    return _post(reference.pointer, _id_post as jni$_.JMethodIDPtr,
-            _$requestBody.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _post(reference.pointer, _id_post.pointer, _$requestBody.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_delete = _class.instanceMethodId(
+  static final _id_delete = Request$Builder._class.instanceMethodId(
     r'delete',
     r'(Lokhttp3/RequestBody;)Lokhttp3/Request$Builder;',
   );
@@ -427,18 +414,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder delete(okhttp3.RequestBody requestBody)`
+  /// from: `public fun delete(body: okhttp3.RequestBody?): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder delete(
     RequestBody? requestBody,
   ) {
     final _$requestBody = requestBody?.reference ?? jni$_.jNullReference;
-    return _delete(reference.pointer, _id_delete as jni$_.JMethodIDPtr,
-            _$requestBody.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _delete(reference.pointer, _id_delete.pointer, _$requestBody.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_put = _class.instanceMethodId(
+  static final _id_put = Request$Builder._class.instanceMethodId(
     r'put',
     r'(Lokhttp3/RequestBody;)Lokhttp3/Request$Builder;',
   );
@@ -454,18 +440,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder put(okhttp3.RequestBody requestBody)`
+  /// from: `public fun put(body: okhttp3.RequestBody): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder put(
     RequestBody requestBody,
   ) {
     final _$requestBody = requestBody.reference;
-    return _put(reference.pointer, _id_put as jni$_.JMethodIDPtr,
-            _$requestBody.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _put(reference.pointer, _id_put.pointer, _$requestBody.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_patch = _class.instanceMethodId(
+  static final _id_patch = Request$Builder._class.instanceMethodId(
     r'patch',
     r'(Lokhttp3/RequestBody;)Lokhttp3/Request$Builder;',
   );
@@ -481,18 +466,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder patch(okhttp3.RequestBody requestBody)`
+  /// from: `public fun patch(body: okhttp3.RequestBody): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder patch(
     RequestBody requestBody,
   ) {
     final _$requestBody = requestBody.reference;
-    return _patch(reference.pointer, _id_patch as jni$_.JMethodIDPtr,
-            _$requestBody.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _patch(reference.pointer, _id_patch.pointer, _$requestBody.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_method = _class.instanceMethodId(
+  static final _id_method = Request$Builder._class.instanceMethodId(
     r'method',
     r'(Ljava/lang/String;Lokhttp3/RequestBody;)Lokhttp3/Request$Builder;',
   );
@@ -514,7 +498,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder method(java.lang.String string, okhttp3.RequestBody requestBody)`
+  /// from: `public fun method(method: kotlin.String, body: okhttp3.RequestBody?): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder method(
     jni$_.JString string,
@@ -522,12 +506,12 @@
   ) {
     final _$string = string.reference;
     final _$requestBody = requestBody?.reference ?? jni$_.jNullReference;
-    return _method(reference.pointer, _id_method as jni$_.JMethodIDPtr,
-            _$string.pointer, _$requestBody.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _method(reference.pointer, _id_method.pointer, _$string.pointer,
+            _$requestBody.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_tag = _class.instanceMethodId(
+  static final _id_tag = Request$Builder._class.instanceMethodId(
     r'tag',
     r'(Ljava/lang/Object;)Lokhttp3/Request$Builder;',
   );
@@ -543,18 +527,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder tag(java.lang.Object object)`
+  /// from: `public fun tag(tag: kotlin.Any?): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder tag(
     jni$_.JObject? object,
   ) {
     final _$object = object?.reference ?? jni$_.jNullReference;
-    return _tag(
-            reference.pointer, _id_tag as jni$_.JMethodIDPtr, _$object.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _tag(reference.pointer, _id_tag.pointer, _$object.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_tag$1 = _class.instanceMethodId(
+  static final _id_tag$1 = Request$Builder._class.instanceMethodId(
     r'tag',
     r'(Ljava/lang/Class;Ljava/lang/Object;)Lokhttp3/Request$Builder;',
   );
@@ -576,21 +559,20 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Request$Builder tag(java.lang.Class class, T object)`
+  /// from: `public fun <T> tag(type: java.lang.Class<T>, tag: T?): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder tag$1<$T extends jni$_.JObject?>(
     jni$_.JObject class$,
-    $T? object, {
-    required jni$_.JObjType<$T> T,
-  }) {
+    $T? object,
+  ) {
     final _$class$ = class$.reference;
     final _$object = object?.reference ?? jni$_.jNullReference;
-    return _tag$1(reference.pointer, _id_tag$1 as jni$_.JMethodIDPtr,
-            _$class$.pointer, _$object.pointer)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _tag$1(reference.pointer, _id_tag$1.pointer, _$class$.pointer,
+            _$object.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_build = _class.instanceMethodId(
+  static final _id_build = Request$Builder._class.instanceMethodId(
     r'build',
     r'()Lokhttp3/Request;',
   );
@@ -607,14 +589,13 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public okhttp3.Request build()`
+  /// from: `public fun build(): okhttp3.Request`
   /// The returned object must be released after use, by calling the [release] method.
   Request build() {
-    return _build(reference.pointer, _id_build as jni$_.JMethodIDPtr)
-        .object<Request>(const $Request$Type());
+    return _build(reference.pointer, _id_build.pointer).object<Request>();
   }
 
-  static final _id_delete$1 = _class.instanceMethodId(
+  static final _id_delete$1 = Request$Builder._class.instanceMethodId(
     r'delete',
     r'()Lokhttp3/Request$Builder;',
   );
@@ -634,103 +615,26 @@
   /// from: `public final okhttp3.Request$Builder delete()`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder delete$1() {
-    return _delete$1(reference.pointer, _id_delete$1 as jni$_.JMethodIDPtr)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _delete$1(reference.pointer, _id_delete$1.pointer)
+        .object<Request$Builder>();
   }
 }
 
-final class $Request$Builder$NullableType
-    extends jni$_.JObjType<Request$Builder?> {
+final class $Request$Builder$Type$ extends jni$_.JType<Request$Builder> {
   @jni$_.internal
-  const $Request$Builder$NullableType();
+  const $Request$Builder$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Request$Builder;';
-
-  @jni$_.internal
-  @core$_.override
-  Request$Builder? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Request$Builder.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Request$Builder?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Request$Builder$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Request$Builder$NullableType) &&
-        other is $Request$Builder$NullableType;
-  }
-}
-
-final class $Request$Builder$Type extends jni$_.JObjType<Request$Builder> {
-  @jni$_.internal
-  const $Request$Builder$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Request$Builder;';
-
-  @jni$_.internal
-  @core$_.override
-  Request$Builder fromReference(jni$_.JReference reference) =>
-      Request$Builder.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Request$Builder?> get nullableType =>
-      const $Request$Builder$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Request$Builder$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Request$Builder$Type) &&
-        other is $Request$Builder$Type;
-  }
 }
 
 /// from: `okhttp3.Request`
-class Request extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Request> $type;
-
-  @jni$_.internal
-  Request.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Request._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Request');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Request$NullableType();
-  static const type = $Request$Type();
+  static const jni$_.JType<Request> type = $Request$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Lokhttp3/HttpUrl;Ljava/lang/String;Lokhttp3/Headers;Lokhttp3/RequestBody;Ljava/util/Map;)V',
   );
@@ -758,7 +662,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public void <init>(okhttp3.HttpUrl httpUrl, java.lang.String string, okhttp3.Headers headers, okhttp3.RequestBody requestBody, java.util.Map map)`
+  /// from: `public void <init>(okhttp3.HttpUrl httpUrl, java.lang.String string, okhttp3.Headers headers, okhttp3.RequestBody requestBody, java.util.Map<java.lang.Class<?>, ? extends java.lang.Object> map)`
   /// The returned object must be released after use, by calling the [release] method.
   factory Request(
     jni$_.JObject httpUrl,
@@ -772,18 +676,20 @@
     final _$headers = headers.reference;
     final _$requestBody = requestBody?.reference ?? jni$_.jNullReference;
     final _$map = map.reference;
-    return Request.fromReference(_new$(
+    return _new$(
             _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
+            _id_new$.pointer,
             _$httpUrl.pointer,
             _$string.pointer,
             _$headers.pointer,
             _$requestBody.pointer,
             _$map.pointer)
-        .reference);
+        .object<Request>();
   }
+}
 
-  static final _id_url = _class.instanceMethodId(
+extension Request$$Methods on Request {
+  static final _id_url = Request._class.instanceMethodId(
     r'url',
     r'()Lokhttp3/HttpUrl;',
   );
@@ -803,11 +709,10 @@
   /// from: `public final okhttp3.HttpUrl url()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject url() {
-    return _url(reference.pointer, _id_url as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
+    return _url(reference.pointer, _id_url.pointer).object<jni$_.JObject>();
   }
 
-  static final _id_method = _class.instanceMethodId(
+  static final _id_method = Request._class.instanceMethodId(
     r'method',
     r'()Ljava/lang/String;',
   );
@@ -827,11 +732,11 @@
   /// from: `public final java.lang.String method()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString method() {
-    return _method(reference.pointer, _id_method as jni$_.JMethodIDPtr)
-        .object<jni$_.JString>(const jni$_.JStringType());
+    return _method(reference.pointer, _id_method.pointer)
+        .object<jni$_.JString>();
   }
 
-  static final _id_headers = _class.instanceMethodId(
+  static final _id_headers = Request._class.instanceMethodId(
     r'headers',
     r'()Lokhttp3/Headers;',
   );
@@ -851,11 +756,10 @@
   /// from: `public final okhttp3.Headers headers()`
   /// The returned object must be released after use, by calling the [release] method.
   Headers headers() {
-    return _headers(reference.pointer, _id_headers as jni$_.JMethodIDPtr)
-        .object<Headers>(const $Headers$Type());
+    return _headers(reference.pointer, _id_headers.pointer).object<Headers>();
   }
 
-  static final _id_body = _class.instanceMethodId(
+  static final _id_body = Request._class.instanceMethodId(
     r'body',
     r'()Lokhttp3/RequestBody;',
   );
@@ -875,16 +779,15 @@
   /// from: `public final okhttp3.RequestBody body()`
   /// The returned object must be released after use, by calling the [release] method.
   RequestBody? body() {
-    return _body(reference.pointer, _id_body as jni$_.JMethodIDPtr)
-        .object<RequestBody?>(const $RequestBody$NullableType());
+    return _body(reference.pointer, _id_body.pointer).object<RequestBody?>();
   }
 
-  static final _id_isHttps = _class.instanceMethodId(
+  static final _id_get$isHttps = Request._class.instanceMethodId(
     r'isHttps',
     r'()Z',
   );
 
-  static final _isHttps = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$isHttps = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -897,12 +800,11 @@
           )>();
 
   /// from: `public final boolean isHttps()`
-  bool isHttps() {
-    return _isHttps(reference.pointer, _id_isHttps as jni$_.JMethodIDPtr)
-        .boolean;
+  core$_.bool get isHttps {
+    return _get$isHttps(reference.pointer, _id_get$isHttps.pointer).boolean;
   }
 
-  static final _id_header = _class.instanceMethodId(
+  static final _id_header = Request._class.instanceMethodId(
     r'header',
     r'(Ljava/lang/String;)Ljava/lang/String;',
   );
@@ -918,18 +820,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final java.lang.String header(java.lang.String string)`
+  /// from: `public fun header(name: kotlin.String): kotlin.String?`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString? header(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _header(reference.pointer, _id_header as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+    return _header(reference.pointer, _id_header.pointer, _$string.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_headers$1 = _class.instanceMethodId(
+  static final _id_headers$1 = Request._class.instanceMethodId(
     r'headers',
     r'(Ljava/lang/String;)Ljava/util/List;',
   );
@@ -945,19 +846,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final java.util.List headers(java.lang.String string)`
+  /// from: `public fun headers(name: kotlin.String): kotlin.collections.List<kotlin.String>`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JList<jni$_.JString> headers$1(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _headers$1(reference.pointer, _id_headers$1 as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<jni$_.JList<jni$_.JString>>(
-            const jni$_.JListType<jni$_.JString>(jni$_.JStringType()));
+    return _headers$1(
+            reference.pointer, _id_headers$1.pointer, _$string.pointer)
+        .object<jni$_.JList<jni$_.JString>>();
   }
 
-  static final _id_tag = _class.instanceMethodId(
+  static final _id_tag = Request._class.instanceMethodId(
     r'tag',
     r'()Ljava/lang/Object;',
   );
@@ -974,14 +874,13 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final java.lang.Object tag()`
+  /// from: `public fun tag(): kotlin.Any?`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject? tag() {
-    return _tag(reference.pointer, _id_tag as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _tag(reference.pointer, _id_tag.pointer).object<jni$_.JObject?>();
   }
 
-  static final _id_tag$1 = _class.instanceMethodId(
+  static final _id_tag$1 = Request._class.instanceMethodId(
     r'tag',
     r'(Ljava/lang/Class;)Ljava/lang/Object;',
   );
@@ -997,19 +896,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final T tag(java.lang.Class class)`
+  /// from: `public fun <T> tag(type: java.lang.Class<T>): T?`
   /// The returned object must be released after use, by calling the [release] method.
   $T? tag$1<$T extends jni$_.JObject?>(
-    jni$_.JObject class$, {
-    required jni$_.JObjType<$T> T,
-  }) {
+    jni$_.JObject class$,
+  ) {
     final _$class$ = class$.reference;
-    return _tag$1(reference.pointer, _id_tag$1 as jni$_.JMethodIDPtr,
-            _$class$.pointer)
-        .object<$T?>(T.nullableType);
+    return _tag$1(reference.pointer, _id_tag$1.pointer, _$class$.pointer)
+        .object<$T?>();
   }
 
-  static final _id_newBuilder = _class.instanceMethodId(
+  static final _id_newBuilder = Request._class.instanceMethodId(
     r'newBuilder',
     r'()Lokhttp3/Request$Builder;',
   );
@@ -1026,14 +923,14 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final okhttp3.Request$Builder newBuilder()`
+  /// from: `public fun newBuilder(): okhttp3.Request.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Request$Builder newBuilder() {
-    return _newBuilder(reference.pointer, _id_newBuilder as jni$_.JMethodIDPtr)
-        .object<Request$Builder>(const $Request$Builder$Type());
+    return _newBuilder(reference.pointer, _id_newBuilder.pointer)
+        .object<Request$Builder>();
   }
 
-  static final _id_cacheControl = _class.instanceMethodId(
+  static final _id_cacheControl = Request._class.instanceMethodId(
     r'cacheControl',
     r'()Lokhttp3/CacheControl;',
   );
@@ -1053,12 +950,11 @@
   /// from: `public final okhttp3.CacheControl cacheControl()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject cacheControl() {
-    return _cacheControl(
-            reference.pointer, _id_cacheControl as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
+    return _cacheControl(reference.pointer, _id_cacheControl.pointer)
+        .object<jni$_.JObject>();
   }
 
-  static final _id_toString$1 = _class.instanceMethodId(
+  static final _id_toString$1 = Request._class.instanceMethodId(
     r'toString',
     r'()Ljava/lang/String;',
   );
@@ -1075,103 +971,61 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public java.lang.String toString()`
+  /// from: `public fun toString(): kotlin.String`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString toString$1() {
-    return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr)
-        .object<jni$_.JString>(const jni$_.JStringType());
+    return _toString$1(reference.pointer, _id_toString$1.pointer)
+        .object<jni$_.JString>();
   }
 }
 
-final class $Request$NullableType extends jni$_.JObjType<Request?> {
+final class $Request$Type$ extends jni$_.JType<Request> {
   @jni$_.internal
-  const $Request$NullableType();
+  const $Request$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Request;';
-
-  @jni$_.internal
-  @core$_.override
-  Request? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Request.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Request?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Request$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Request$NullableType) &&
-        other is $Request$NullableType;
-  }
-}
-
-final class $Request$Type extends jni$_.JObjType<Request> {
-  @jni$_.internal
-  const $Request$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Request;';
-
-  @jni$_.internal
-  @core$_.override
-  Request fromReference(jni$_.JReference reference) => Request.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Request?> get nullableType => const $Request$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Request$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Request$Type) && other is $Request$Type;
-  }
 }
 
 /// from: `okhttp3.RequestBody$Companion`
-class RequestBody$Companion extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<RequestBody$Companion> $type;
-
-  @jni$_.internal
-  RequestBody$Companion.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type RequestBody$Companion._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/RequestBody$Companion');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $RequestBody$Companion$NullableType();
-  static const type = $RequestBody$Companion$Type();
-  static final _id_create = _class.instanceMethodId(
+  static const jni$_.JType<RequestBody$Companion> type =
+      $RequestBody$Companion$Type$();
+  static final _id_new$ = _class.constructorId(
+    r'(Lkotlin/jvm/internal/DefaultConstructorMarker;)V',
+  );
+
+  static final _new$ = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `synthetic public void <init>(kotlin.jvm.internal.DefaultConstructorMarker defaultConstructorMarker)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory RequestBody$Companion(
+    jni$_.JObject? defaultConstructorMarker,
+  ) {
+    final _$defaultConstructorMarker =
+        defaultConstructorMarker?.reference ?? jni$_.jNullReference;
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$defaultConstructorMarker.pointer)
+        .object<RequestBody$Companion>();
+  }
+}
+
+extension RequestBody$Companion$$Methods on RequestBody$Companion {
+  static final _id_create = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'(Ljava/lang/String;Lokhttp3/MediaType;)Lokhttp3/RequestBody;',
   );
@@ -1193,7 +1047,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.RequestBody create(java.lang.String string, okhttp3.MediaType mediaType)`
+  /// from: `public fun toRequestBody(contentType: okhttp3.MediaType?): okhttp3.RequestBody`
   /// The returned object must be released after use, by calling the [release] method.
   RequestBody create(
     jni$_.JString string,
@@ -1201,12 +1055,12 @@
   ) {
     final _$string = string.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create(reference.pointer, _id_create as jni$_.JMethodIDPtr,
-            _$string.pointer, _$mediaType.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create(reference.pointer, _id_create.pointer, _$string.pointer,
+            _$mediaType.pointer)
+        .object<RequestBody>();
   }
 
-  static final _id_create$1 = _class.instanceMethodId(
+  static final _id_create$1 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'(Lokio/ByteString;Lokhttp3/MediaType;)Lokhttp3/RequestBody;',
   );
@@ -1228,7 +1082,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.RequestBody create(okio.ByteString byteString, okhttp3.MediaType mediaType)`
+  /// from: `public fun toRequestBody(contentType: okhttp3.MediaType?): okhttp3.RequestBody`
   /// The returned object must be released after use, by calling the [release] method.
   RequestBody create$1(
     ByteString byteString,
@@ -1236,12 +1090,12 @@
   ) {
     final _$byteString = byteString.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$1(reference.pointer, _id_create$1 as jni$_.JMethodIDPtr,
+    return _create$1(reference.pointer, _id_create$1.pointer,
             _$byteString.pointer, _$mediaType.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+        .object<RequestBody>();
   }
 
-  static final _id_create$2 = _class.instanceMethodId(
+  static final _id_create$2 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'([BLokhttp3/MediaType;II)Lokhttp3/RequestBody;',
   );
@@ -1264,25 +1118,25 @@
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `public final okhttp3.RequestBody create(byte[] bs, okhttp3.MediaType mediaType, int i, int i1)`
+  /// from: `public fun toRequestBody(contentType: okhttp3.MediaType?, offset: kotlin.Int, byteCount: kotlin.Int): okhttp3.RequestBody`
   /// The returned object must be released after use, by calling the [release] method.
   RequestBody create$2(
     jni$_.JByteArray bs,
     jni$_.JObject? mediaType,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$bs = bs.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$2(reference.pointer, _id_create$2 as jni$_.JMethodIDPtr,
-            _$bs.pointer, _$mediaType.pointer, i, i1)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$2(reference.pointer, _id_create$2.pointer, _$bs.pointer,
+            _$mediaType.pointer, i, i1)
+        .object<RequestBody>();
   }
 
-  static final _id_create$3 = _class.instanceMethodId(
+  static final _id_create$3 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'(Ljava/io/File;Lokhttp3/MediaType;)Lokhttp3/RequestBody;',
   );
@@ -1304,7 +1158,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.RequestBody create(java.io.File file, okhttp3.MediaType mediaType)`
+  /// from: `public fun asRequestBody(contentType: okhttp3.MediaType?): okhttp3.RequestBody`
   /// The returned object must be released after use, by calling the [release] method.
   RequestBody create$3(
     jni$_.JObject file,
@@ -1312,12 +1166,12 @@
   ) {
     final _$file = file.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$3(reference.pointer, _id_create$3 as jni$_.JMethodIDPtr,
-            _$file.pointer, _$mediaType.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$3(reference.pointer, _id_create$3.pointer, _$file.pointer,
+            _$mediaType.pointer)
+        .object<RequestBody>();
   }
 
-  static final _id_create$4 = _class.instanceMethodId(
+  static final _id_create$4 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'(Lokhttp3/MediaType;Ljava/lang/String;)Lokhttp3/RequestBody;',
   );
@@ -1339,7 +1193,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.RequestBody create(okhttp3.MediaType mediaType, java.lang.String string)`
+  /// from: `public fun create(contentType: okhttp3.MediaType?, content: kotlin.String): okhttp3.RequestBody`
   /// The returned object must be released after use, by calling the [release] method.
   RequestBody create$4(
     jni$_.JObject? mediaType,
@@ -1347,12 +1201,12 @@
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$string = string.reference;
-    return _create$4(reference.pointer, _id_create$4 as jni$_.JMethodIDPtr,
+    return _create$4(reference.pointer, _id_create$4.pointer,
             _$mediaType.pointer, _$string.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+        .object<RequestBody>();
   }
 
-  static final _id_create$5 = _class.instanceMethodId(
+  static final _id_create$5 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'(Lokhttp3/MediaType;Lokio/ByteString;)Lokhttp3/RequestBody;',
   );
@@ -1374,7 +1228,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.RequestBody create(okhttp3.MediaType mediaType, okio.ByteString byteString)`
+  /// from: `public fun create(contentType: okhttp3.MediaType?, content: okio.ByteString): okhttp3.RequestBody`
   /// The returned object must be released after use, by calling the [release] method.
   RequestBody create$5(
     jni$_.JObject? mediaType,
@@ -1382,12 +1236,12 @@
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$byteString = byteString.reference;
-    return _create$5(reference.pointer, _id_create$5 as jni$_.JMethodIDPtr,
+    return _create$5(reference.pointer, _id_create$5.pointer,
             _$mediaType.pointer, _$byteString.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+        .object<RequestBody>();
   }
 
-  static final _id_create$6 = _class.instanceMethodId(
+  static final _id_create$6 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'(Lokhttp3/MediaType;[BII)Lokhttp3/RequestBody;',
   );
@@ -1410,25 +1264,25 @@
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `public final okhttp3.RequestBody create(okhttp3.MediaType mediaType, byte[] bs, int i, int i1)`
+  /// from: `public fun create(contentType: okhttp3.MediaType?, content: kotlin.ByteArray, offset: kotlin.Int, byteCount: kotlin.Int): okhttp3.RequestBody`
   /// The returned object must be released after use, by calling the [release] method.
   RequestBody create$6(
     jni$_.JObject? mediaType,
     jni$_.JByteArray bs,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$bs = bs.reference;
-    return _create$6(reference.pointer, _id_create$6 as jni$_.JMethodIDPtr,
+    return _create$6(reference.pointer, _id_create$6.pointer,
             _$mediaType.pointer, _$bs.pointer, i, i1)
-        .object<RequestBody>(const $RequestBody$Type());
+        .object<RequestBody>();
   }
 
-  static final _id_create$7 = _class.instanceMethodId(
+  static final _id_create$7 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'(Lokhttp3/MediaType;Ljava/io/File;)Lokhttp3/RequestBody;',
   );
@@ -1450,7 +1304,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.RequestBody create(okhttp3.MediaType mediaType, java.io.File file)`
+  /// from: `public fun create(contentType: okhttp3.MediaType?, file: java.io.File): okhttp3.RequestBody`
   /// The returned object must be released after use, by calling the [release] method.
   RequestBody create$7(
     jni$_.JObject? mediaType,
@@ -1458,12 +1312,12 @@
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$file = file.reference;
-    return _create$7(reference.pointer, _id_create$7 as jni$_.JMethodIDPtr,
+    return _create$7(reference.pointer, _id_create$7.pointer,
             _$mediaType.pointer, _$file.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+        .object<RequestBody>();
   }
 
-  static final _id_create$8 = _class.instanceMethodId(
+  static final _id_create$8 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'([BLokhttp3/MediaType;I)Lokhttp3/RequestBody;',
   );
@@ -1485,23 +1339,23 @@
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int)>();
+              core$_.int)>();
 
   /// from: `public final okhttp3.RequestBody create(byte[] bs, okhttp3.MediaType mediaType, int i)`
   /// The returned object must be released after use, by calling the [release] method.
   RequestBody create$8(
     jni$_.JByteArray bs,
     jni$_.JObject? mediaType,
-    int i,
+    core$_.int i,
   ) {
     final _$bs = bs.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$8(reference.pointer, _id_create$8 as jni$_.JMethodIDPtr,
-            _$bs.pointer, _$mediaType.pointer, i)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$8(reference.pointer, _id_create$8.pointer, _$bs.pointer,
+            _$mediaType.pointer, i)
+        .object<RequestBody>();
   }
 
-  static final _id_create$9 = _class.instanceMethodId(
+  static final _id_create$9 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'([BLokhttp3/MediaType;)Lokhttp3/RequestBody;',
   );
@@ -1531,12 +1385,12 @@
   ) {
     final _$bs = bs.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$9(reference.pointer, _id_create$9 as jni$_.JMethodIDPtr,
-            _$bs.pointer, _$mediaType.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$9(reference.pointer, _id_create$9.pointer, _$bs.pointer,
+            _$mediaType.pointer)
+        .object<RequestBody>();
   }
 
-  static final _id_create$10 = _class.instanceMethodId(
+  static final _id_create$10 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'([B)Lokhttp3/RequestBody;',
   );
@@ -1558,12 +1412,11 @@
     jni$_.JByteArray bs,
   ) {
     final _$bs = bs.reference;
-    return _create$10(reference.pointer, _id_create$10 as jni$_.JMethodIDPtr,
-            _$bs.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$10(reference.pointer, _id_create$10.pointer, _$bs.pointer)
+        .object<RequestBody>();
   }
 
-  static final _id_create$11 = _class.instanceMethodId(
+  static final _id_create$11 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'(Lokhttp3/MediaType;[BI)Lokhttp3/RequestBody;',
   );
@@ -1585,23 +1438,23 @@
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int)>();
+              core$_.int)>();
 
   /// from: `public final okhttp3.RequestBody create(okhttp3.MediaType mediaType, byte[] bs, int i)`
   /// The returned object must be released after use, by calling the [release] method.
   RequestBody create$11(
     jni$_.JObject? mediaType,
     jni$_.JByteArray bs,
-    int i,
+    core$_.int i,
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$bs = bs.reference;
-    return _create$11(reference.pointer, _id_create$11 as jni$_.JMethodIDPtr,
+    return _create$11(reference.pointer, _id_create$11.pointer,
             _$mediaType.pointer, _$bs.pointer, i)
-        .object<RequestBody>(const $RequestBody$Type());
+        .object<RequestBody>();
   }
 
-  static final _id_create$12 = _class.instanceMethodId(
+  static final _id_create$12 = RequestBody$Companion._class.instanceMethodId(
     r'create',
     r'(Lokhttp3/MediaType;[B)Lokhttp3/RequestBody;',
   );
@@ -1631,133 +1484,28 @@
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$bs = bs.reference;
-    return _create$12(reference.pointer, _id_create$12 as jni$_.JMethodIDPtr,
+    return _create$12(reference.pointer, _id_create$12.pointer,
             _$mediaType.pointer, _$bs.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
-  }
-
-  static final _id_new$ = _class.constructorId(
-    r'(Lkotlin/jvm/internal/DefaultConstructorMarker;)V',
-  );
-
-  static final _new$ = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_NewObject')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `synthetic public void <init>(kotlin.jvm.internal.DefaultConstructorMarker defaultConstructorMarker)`
-  /// The returned object must be released after use, by calling the [release] method.
-  factory RequestBody$Companion(
-    jni$_.JObject? defaultConstructorMarker,
-  ) {
-    final _$defaultConstructorMarker =
-        defaultConstructorMarker?.reference ?? jni$_.jNullReference;
-    return RequestBody$Companion.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$defaultConstructorMarker.pointer)
-        .reference);
+        .object<RequestBody>();
   }
 }
 
-final class $RequestBody$Companion$NullableType
-    extends jni$_.JObjType<RequestBody$Companion?> {
+final class $RequestBody$Companion$Type$
+    extends jni$_.JType<RequestBody$Companion> {
   @jni$_.internal
-  const $RequestBody$Companion$NullableType();
+  const $RequestBody$Companion$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/RequestBody$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  RequestBody$Companion? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : RequestBody$Companion.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<RequestBody$Companion?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($RequestBody$Companion$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($RequestBody$Companion$NullableType) &&
-        other is $RequestBody$Companion$NullableType;
-  }
-}
-
-final class $RequestBody$Companion$Type
-    extends jni$_.JObjType<RequestBody$Companion> {
-  @jni$_.internal
-  const $RequestBody$Companion$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/RequestBody$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  RequestBody$Companion fromReference(jni$_.JReference reference) =>
-      RequestBody$Companion.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<RequestBody$Companion?> get nullableType =>
-      const $RequestBody$Companion$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($RequestBody$Companion$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($RequestBody$Companion$Type) &&
-        other is $RequestBody$Companion$Type;
-  }
 }
 
 /// from: `okhttp3.RequestBody`
-class RequestBody extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<RequestBody> $type;
-
-  @jni$_.internal
-  RequestBody.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type RequestBody._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/RequestBody');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $RequestBody$NullableType();
-  static const type = $RequestBody$Type();
+  static const jni$_.JType<RequestBody> type = $RequestBody$Type$();
   static final _id_Companion = _class.staticFieldId(
     r'Companion',
     r'Lokhttp3/RequestBody$Companion;',
@@ -1766,128 +1514,8 @@
   /// from: `static public final okhttp3.RequestBody$Companion Companion`
   /// The returned object must be released after use, by calling the [release] method.
   static RequestBody$Companion get Companion =>
-      _id_Companion.get(_class, const $RequestBody$Companion$Type());
-
-  static final _id_contentType = _class.instanceMethodId(
-    r'contentType',
-    r'()Lokhttp3/MediaType;',
-  );
-
-  static final _contentType = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract okhttp3.MediaType contentType()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? contentType() {
-    return _contentType(
-            reference.pointer, _id_contentType as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_contentLength = _class.instanceMethodId(
-    r'contentLength',
-    r'()J',
-  );
-
-  static final _contentLength = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public long contentLength()`
-  int contentLength() {
-    return _contentLength(
-            reference.pointer, _id_contentLength as jni$_.JMethodIDPtr)
-        .long;
-  }
-
-  static final _id_writeTo = _class.instanceMethodId(
-    r'writeTo',
-    r'(Lokio/BufferedSink;)V',
-  );
-
-  static final _writeTo = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void writeTo(okio.BufferedSink bufferedSink)`
-  void writeTo(
-    jni$_.JObject bufferedSink,
-  ) {
-    final _$bufferedSink = bufferedSink.reference;
-    _writeTo(reference.pointer, _id_writeTo as jni$_.JMethodIDPtr,
-            _$bufferedSink.pointer)
-        .check();
-  }
-
-  static final _id_isDuplex = _class.instanceMethodId(
-    r'isDuplex',
-    r'()Z',
-  );
-
-  static final _isDuplex = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public boolean isDuplex()`
-  bool isDuplex() {
-    return _isDuplex(reference.pointer, _id_isDuplex as jni$_.JMethodIDPtr)
-        .boolean;
-  }
-
-  static final _id_isOneShot = _class.instanceMethodId(
-    r'isOneShot',
-    r'()Z',
-  );
-
-  static final _isOneShot = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public boolean isOneShot()`
-  bool isOneShot() {
-    return _isOneShot(reference.pointer, _id_isOneShot as jni$_.JMethodIDPtr)
-        .boolean;
-  }
+      _id_Companion.get(_class, RequestBody$Companion.type)
+          as RequestBody$Companion;
 
   static final _id_create = _class.staticMethodId(
     r'create',
@@ -1919,9 +1547,9 @@
   ) {
     final _$string = string.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create(_class.reference.pointer, _id_create as jni$_.JMethodIDPtr,
+    return _create(_class.reference.pointer, _id_create.pointer,
             _$string.pointer, _$mediaType.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+        .object<RequestBody>();
   }
 
   static final _id_create$1 = _class.staticMethodId(
@@ -1954,12 +1582,9 @@
   ) {
     final _$byteString = byteString.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$1(
-            _class.reference.pointer,
-            _id_create$1 as jni$_.JMethodIDPtr,
-            _$byteString.pointer,
-            _$mediaType.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$1(_class.reference.pointer, _id_create$1.pointer,
+            _$byteString.pointer, _$mediaType.pointer)
+        .object<RequestBody>();
   }
 
   static final _id_create$2 = _class.staticMethodId(
@@ -1985,27 +1610,22 @@
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+              core$_.int,
+              core$_.int)>();
 
   /// from: `static public final okhttp3.RequestBody create(byte[] bs, okhttp3.MediaType mediaType, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
   static RequestBody create$2(
     jni$_.JByteArray bs,
     jni$_.JObject? mediaType,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$bs = bs.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$2(
-            _class.reference.pointer,
-            _id_create$2 as jni$_.JMethodIDPtr,
-            _$bs.pointer,
-            _$mediaType.pointer,
-            i,
-            i1)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$2(_class.reference.pointer, _id_create$2.pointer,
+            _$bs.pointer, _$mediaType.pointer, i, i1)
+        .object<RequestBody>();
   }
 
   static final _id_create$3 = _class.staticMethodId(
@@ -2038,12 +1658,9 @@
   ) {
     final _$file = file.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$3(
-            _class.reference.pointer,
-            _id_create$3 as jni$_.JMethodIDPtr,
-            _$file.pointer,
-            _$mediaType.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$3(_class.reference.pointer, _id_create$3.pointer,
+            _$file.pointer, _$mediaType.pointer)
+        .object<RequestBody>();
   }
 
   static final _id_create$4 = _class.staticMethodId(
@@ -2076,12 +1693,9 @@
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$string = string.reference;
-    return _create$4(
-            _class.reference.pointer,
-            _id_create$4 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer,
-            _$string.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$4(_class.reference.pointer, _id_create$4.pointer,
+            _$mediaType.pointer, _$string.pointer)
+        .object<RequestBody>();
   }
 
   static final _id_create$5 = _class.staticMethodId(
@@ -2114,12 +1728,9 @@
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$byteString = byteString.reference;
-    return _create$5(
-            _class.reference.pointer,
-            _id_create$5 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer,
-            _$byteString.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$5(_class.reference.pointer, _id_create$5.pointer,
+            _$mediaType.pointer, _$byteString.pointer)
+        .object<RequestBody>();
   }
 
   static final _id_create$6 = _class.staticMethodId(
@@ -2145,27 +1756,22 @@
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+              core$_.int,
+              core$_.int)>();
 
   /// from: `static public final okhttp3.RequestBody create(okhttp3.MediaType mediaType, byte[] bs, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
   static RequestBody create$6(
     jni$_.JObject? mediaType,
     jni$_.JByteArray bs,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$bs = bs.reference;
-    return _create$6(
-            _class.reference.pointer,
-            _id_create$6 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer,
-            _$bs.pointer,
-            i,
-            i1)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$6(_class.reference.pointer, _id_create$6.pointer,
+            _$mediaType.pointer, _$bs.pointer, i, i1)
+        .object<RequestBody>();
   }
 
   static final _id_create$7 = _class.staticMethodId(
@@ -2198,12 +1804,9 @@
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$file = file.reference;
-    return _create$7(
-            _class.reference.pointer,
-            _id_create$7 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer,
-            _$file.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$7(_class.reference.pointer, _id_create$7.pointer,
+            _$mediaType.pointer, _$file.pointer)
+        .object<RequestBody>();
   }
 
   static final _id_create$8 = _class.staticMethodId(
@@ -2228,24 +1831,20 @@
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int)>();
+              core$_.int)>();
 
   /// from: `static public final okhttp3.RequestBody create(byte[] bs, okhttp3.MediaType mediaType, int i)`
   /// The returned object must be released after use, by calling the [release] method.
   static RequestBody create$8(
     jni$_.JByteArray bs,
     jni$_.JObject? mediaType,
-    int i,
+    core$_.int i,
   ) {
     final _$bs = bs.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$8(
-            _class.reference.pointer,
-            _id_create$8 as jni$_.JMethodIDPtr,
-            _$bs.pointer,
-            _$mediaType.pointer,
-            i)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$8(_class.reference.pointer, _id_create$8.pointer,
+            _$bs.pointer, _$mediaType.pointer, i)
+        .object<RequestBody>();
   }
 
   static final _id_create$9 = _class.staticMethodId(
@@ -2278,12 +1877,9 @@
   ) {
     final _$bs = bs.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$9(
-            _class.reference.pointer,
-            _id_create$9 as jni$_.JMethodIDPtr,
-            _$bs.pointer,
-            _$mediaType.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$9(_class.reference.pointer, _id_create$9.pointer,
+            _$bs.pointer, _$mediaType.pointer)
+        .object<RequestBody>();
   }
 
   static final _id_create$10 = _class.staticMethodId(
@@ -2308,9 +1904,9 @@
     jni$_.JByteArray bs,
   ) {
     final _$bs = bs.reference;
-    return _create$10(_class.reference.pointer,
-            _id_create$10 as jni$_.JMethodIDPtr, _$bs.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$10(
+            _class.reference.pointer, _id_create$10.pointer, _$bs.pointer)
+        .object<RequestBody>();
   }
 
   static final _id_create$11 = _class.staticMethodId(
@@ -2335,24 +1931,20 @@
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int)>();
+              core$_.int)>();
 
   /// from: `static public final okhttp3.RequestBody create(okhttp3.MediaType mediaType, byte[] bs, int i)`
   /// The returned object must be released after use, by calling the [release] method.
   static RequestBody create$11(
     jni$_.JObject? mediaType,
     jni$_.JByteArray bs,
-    int i,
+    core$_.int i,
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$bs = bs.reference;
-    return _create$11(
-            _class.reference.pointer,
-            _id_create$11 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer,
-            _$bs.pointer,
-            i)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$11(_class.reference.pointer, _id_create$11.pointer,
+            _$mediaType.pointer, _$bs.pointer, i)
+        .object<RequestBody>();
   }
 
   static final _id_create$12 = _class.staticMethodId(
@@ -2385,106 +1977,145 @@
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$bs = bs.reference;
-    return _create$12(
-            _class.reference.pointer,
-            _id_create$12 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer,
-            _$bs.pointer)
-        .object<RequestBody>(const $RequestBody$Type());
+    return _create$12(_class.reference.pointer, _id_create$12.pointer,
+            _$mediaType.pointer, _$bs.pointer)
+        .object<RequestBody>();
   }
 }
 
-final class $RequestBody$NullableType extends jni$_.JObjType<RequestBody?> {
+extension RequestBody$$Methods on RequestBody {
+  static final _id_contentType = RequestBody._class.instanceMethodId(
+    r'contentType',
+    r'()Lokhttp3/MediaType;',
+  );
+
+  static final _contentType = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun contentType(): okhttp3.MediaType?`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? contentType() {
+    return _contentType(reference.pointer, _id_contentType.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_contentLength = RequestBody._class.instanceMethodId(
+    r'contentLength',
+    r'()J',
+  );
+
+  static final _contentLength = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun contentLength(): kotlin.Long`
+  core$_.int contentLength() {
+    return _contentLength(reference.pointer, _id_contentLength.pointer).long;
+  }
+
+  static final _id_writeTo = RequestBody._class.instanceMethodId(
+    r'writeTo',
+    r'(Lokio/BufferedSink;)V',
+  );
+
+  static final _writeTo = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun writeTo(sink: okio.BufferedSink): kotlin.Unit`
+  void writeTo(
+    jni$_.JObject bufferedSink,
+  ) {
+    final _$bufferedSink = bufferedSink.reference;
+    _writeTo(reference.pointer, _id_writeTo.pointer, _$bufferedSink.pointer)
+        .check();
+  }
+
+  static final _id_get$isDuplex = RequestBody._class.instanceMethodId(
+    r'isDuplex',
+    r'()Z',
+  );
+
+  static final _get$isDuplex = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun isDuplex(): kotlin.Boolean`
+  core$_.bool get isDuplex {
+    return _get$isDuplex(reference.pointer, _id_get$isDuplex.pointer).boolean;
+  }
+
+  static final _id_get$isOneShot = RequestBody._class.instanceMethodId(
+    r'isOneShot',
+    r'()Z',
+  );
+
+  static final _get$isOneShot = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun isOneShot(): kotlin.Boolean`
+  core$_.bool get isOneShot {
+    return _get$isOneShot(reference.pointer, _id_get$isOneShot.pointer).boolean;
+  }
+}
+
+final class $RequestBody$Type$ extends jni$_.JType<RequestBody> {
   @jni$_.internal
-  const $RequestBody$NullableType();
+  const $RequestBody$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/RequestBody;';
-
-  @jni$_.internal
-  @core$_.override
-  RequestBody? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : RequestBody.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<RequestBody?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($RequestBody$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($RequestBody$NullableType) &&
-        other is $RequestBody$NullableType;
-  }
-}
-
-final class $RequestBody$Type extends jni$_.JObjType<RequestBody> {
-  @jni$_.internal
-  const $RequestBody$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/RequestBody;';
-
-  @jni$_.internal
-  @core$_.override
-  RequestBody fromReference(jni$_.JReference reference) =>
-      RequestBody.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<RequestBody?> get nullableType =>
-      const $RequestBody$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($RequestBody$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($RequestBody$Type) &&
-        other is $RequestBody$Type;
-  }
 }
 
 /// from: `okhttp3.Response$Builder`
-class Response$Builder extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Response$Builder> $type;
-
-  @jni$_.internal
-  Response$Builder.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Response$Builder._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Response$Builder');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Response$Builder$NullableType();
-  static const type = $Response$Builder$Type();
+  static const jni$_.JType<Response$Builder> type = $Response$Builder$Type$();
   static final _id_new$ = _class.constructorId(
     r'()V',
   );
@@ -2504,9 +2135,8 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory Response$Builder() {
-    return Response$Builder.fromReference(
-        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
-            .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer)
+        .object<Response$Builder>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -2530,12 +2160,14 @@
     Response response,
   ) {
     final _$response = response.reference;
-    return Response$Builder.fromReference(_new$1(_class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr, _$response.pointer)
-        .reference);
+    return _new$1(
+            _class.reference.pointer, _id_new$1.pointer, _$response.pointer)
+        .object<Response$Builder>();
   }
+}
 
-  static final _id_request = _class.instanceMethodId(
+extension Response$Builder$$Methods on Response$Builder {
+  static final _id_request = Response$Builder._class.instanceMethodId(
     r'request',
     r'(Lokhttp3/Request;)Lokhttp3/Response$Builder;',
   );
@@ -2551,18 +2183,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder request(okhttp3.Request request)`
+  /// from: `public fun request(request: okhttp3.Request): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder request(
     Request request,
   ) {
     final _$request = request.reference;
-    return _request(reference.pointer, _id_request as jni$_.JMethodIDPtr,
-            _$request.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _request(reference.pointer, _id_request.pointer, _$request.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_protocol = _class.instanceMethodId(
+  static final _id_protocol = Response$Builder._class.instanceMethodId(
     r'protocol',
     r'(Lokhttp3/Protocol;)Lokhttp3/Response$Builder;',
   );
@@ -2578,18 +2209,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder protocol(okhttp3.Protocol protocol)`
+  /// from: `public fun protocol(protocol: okhttp3.Protocol): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder protocol(
     jni$_.JObject protocol,
   ) {
     final _$protocol = protocol.reference;
-    return _protocol(reference.pointer, _id_protocol as jni$_.JMethodIDPtr,
-            _$protocol.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _protocol(
+            reference.pointer, _id_protocol.pointer, _$protocol.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_code = _class.instanceMethodId(
+  static final _id_code = Response$Builder._class.instanceMethodId(
     r'code',
     r'(I)Lokhttp3/Response$Builder;',
   );
@@ -2602,18 +2233,18 @@
                   jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
 
-  /// from: `public okhttp3.Response$Builder code(int i)`
+  /// from: `public fun code(code: kotlin.Int): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder code(
-    int i,
+    core$_.int i,
   ) {
-    return _code(reference.pointer, _id_code as jni$_.JMethodIDPtr, i)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _code(reference.pointer, _id_code.pointer, i)
+        .object<Response$Builder>();
   }
 
-  static final _id_message = _class.instanceMethodId(
+  static final _id_message = Response$Builder._class.instanceMethodId(
     r'message',
     r'(Ljava/lang/String;)Lokhttp3/Response$Builder;',
   );
@@ -2629,18 +2260,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder message(java.lang.String string)`
+  /// from: `public fun message(message: kotlin.String): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder message(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _message(reference.pointer, _id_message as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _message(reference.pointer, _id_message.pointer, _$string.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_handshake = _class.instanceMethodId(
+  static final _id_handshake = Response$Builder._class.instanceMethodId(
     r'handshake',
     r'(Lokhttp3/Handshake;)Lokhttp3/Response$Builder;',
   );
@@ -2656,18 +2286,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder handshake(okhttp3.Handshake handshake)`
+  /// from: `public fun handshake(handshake: okhttp3.Handshake?): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder handshake(
     jni$_.JObject? handshake,
   ) {
     final _$handshake = handshake?.reference ?? jni$_.jNullReference;
-    return _handshake(reference.pointer, _id_handshake as jni$_.JMethodIDPtr,
-            _$handshake.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _handshake(
+            reference.pointer, _id_handshake.pointer, _$handshake.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_header = _class.instanceMethodId(
+  static final _id_header = Response$Builder._class.instanceMethodId(
     r'header',
     r'(Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Response$Builder;',
   );
@@ -2689,7 +2319,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder header(java.lang.String string, java.lang.String string1)`
+  /// from: `public fun header(name: kotlin.String, value: kotlin.String): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder header(
     jni$_.JString string,
@@ -2697,12 +2327,12 @@
   ) {
     final _$string = string.reference;
     final _$string1 = string1.reference;
-    return _header(reference.pointer, _id_header as jni$_.JMethodIDPtr,
-            _$string.pointer, _$string1.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _header(reference.pointer, _id_header.pointer, _$string.pointer,
+            _$string1.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_addHeader = _class.instanceMethodId(
+  static final _id_addHeader = Response$Builder._class.instanceMethodId(
     r'addHeader',
     r'(Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Response$Builder;',
   );
@@ -2724,7 +2354,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder addHeader(java.lang.String string, java.lang.String string1)`
+  /// from: `public fun addHeader(name: kotlin.String, value: kotlin.String): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder addHeader(
     jni$_.JString string,
@@ -2732,12 +2362,12 @@
   ) {
     final _$string = string.reference;
     final _$string1 = string1.reference;
-    return _addHeader(reference.pointer, _id_addHeader as jni$_.JMethodIDPtr,
+    return _addHeader(reference.pointer, _id_addHeader.pointer,
             _$string.pointer, _$string1.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+        .object<Response$Builder>();
   }
 
-  static final _id_removeHeader = _class.instanceMethodId(
+  static final _id_removeHeader = Response$Builder._class.instanceMethodId(
     r'removeHeader',
     r'(Ljava/lang/String;)Lokhttp3/Response$Builder;',
   );
@@ -2753,18 +2383,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder removeHeader(java.lang.String string)`
+  /// from: `public fun removeHeader(name: kotlin.String): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder removeHeader(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _removeHeader(reference.pointer,
-            _id_removeHeader as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _removeHeader(
+            reference.pointer, _id_removeHeader.pointer, _$string.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_headers = _class.instanceMethodId(
+  static final _id_headers = Response$Builder._class.instanceMethodId(
     r'headers',
     r'(Lokhttp3/Headers;)Lokhttp3/Response$Builder;',
   );
@@ -2780,18 +2410,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder headers(okhttp3.Headers headers)`
+  /// from: `public fun headers(headers: okhttp3.Headers): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder headers(
     Headers headers,
   ) {
     final _$headers = headers.reference;
-    return _headers(reference.pointer, _id_headers as jni$_.JMethodIDPtr,
-            _$headers.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _headers(reference.pointer, _id_headers.pointer, _$headers.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_body = _class.instanceMethodId(
+  static final _id_body = Response$Builder._class.instanceMethodId(
     r'body',
     r'(Lokhttp3/ResponseBody;)Lokhttp3/Response$Builder;',
   );
@@ -2807,18 +2436,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder body(okhttp3.ResponseBody responseBody)`
+  /// from: `public fun body(body: okhttp3.ResponseBody?): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder body(
     ResponseBody? responseBody,
   ) {
     final _$responseBody = responseBody?.reference ?? jni$_.jNullReference;
-    return _body(reference.pointer, _id_body as jni$_.JMethodIDPtr,
-            _$responseBody.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _body(reference.pointer, _id_body.pointer, _$responseBody.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_networkResponse = _class.instanceMethodId(
+  static final _id_networkResponse = Response$Builder._class.instanceMethodId(
     r'networkResponse',
     r'(Lokhttp3/Response;)Lokhttp3/Response$Builder;',
   );
@@ -2834,18 +2462,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder networkResponse(okhttp3.Response response)`
+  /// from: `public fun networkResponse(networkResponse: okhttp3.Response?): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder networkResponse(
     Response? response,
   ) {
     final _$response = response?.reference ?? jni$_.jNullReference;
-    return _networkResponse(reference.pointer,
-            _id_networkResponse as jni$_.JMethodIDPtr, _$response.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _networkResponse(
+            reference.pointer, _id_networkResponse.pointer, _$response.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_cacheResponse = _class.instanceMethodId(
+  static final _id_cacheResponse = Response$Builder._class.instanceMethodId(
     r'cacheResponse',
     r'(Lokhttp3/Response;)Lokhttp3/Response$Builder;',
   );
@@ -2861,18 +2489,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder cacheResponse(okhttp3.Response response)`
+  /// from: `public fun cacheResponse(cacheResponse: okhttp3.Response?): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder cacheResponse(
     Response? response,
   ) {
     final _$response = response?.reference ?? jni$_.jNullReference;
-    return _cacheResponse(reference.pointer,
-            _id_cacheResponse as jni$_.JMethodIDPtr, _$response.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _cacheResponse(
+            reference.pointer, _id_cacheResponse.pointer, _$response.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_priorResponse = _class.instanceMethodId(
+  static final _id_priorResponse = Response$Builder._class.instanceMethodId(
     r'priorResponse',
     r'(Lokhttp3/Response;)Lokhttp3/Response$Builder;',
   );
@@ -2888,18 +2516,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Response$Builder priorResponse(okhttp3.Response response)`
+  /// from: `public fun priorResponse(priorResponse: okhttp3.Response?): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder priorResponse(
     Response? response,
   ) {
     final _$response = response?.reference ?? jni$_.jNullReference;
-    return _priorResponse(reference.pointer,
-            _id_priorResponse as jni$_.JMethodIDPtr, _$response.pointer)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _priorResponse(
+            reference.pointer, _id_priorResponse.pointer, _$response.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_sentRequestAtMillis = _class.instanceMethodId(
+  static final _id_sentRequestAtMillis =
+      Response$Builder._class.instanceMethodId(
     r'sentRequestAtMillis',
     r'(J)Lokhttp3/Response$Builder;',
   );
@@ -2912,19 +2541,20 @@
                   jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
 
-  /// from: `public okhttp3.Response$Builder sentRequestAtMillis(long j)`
+  /// from: `public fun sentRequestAtMillis(sentRequestAtMillis: kotlin.Long): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder sentRequestAtMillis(
-    int j,
+    core$_.int j,
   ) {
     return _sentRequestAtMillis(
-            reference.pointer, _id_sentRequestAtMillis as jni$_.JMethodIDPtr, j)
-        .object<Response$Builder>(const $Response$Builder$Type());
+            reference.pointer, _id_sentRequestAtMillis.pointer, j)
+        .object<Response$Builder>();
   }
 
-  static final _id_receivedResponseAtMillis = _class.instanceMethodId(
+  static final _id_receivedResponseAtMillis =
+      Response$Builder._class.instanceMethodId(
     r'receivedResponseAtMillis',
     r'(J)Lokhttp3/Response$Builder;',
   );
@@ -2937,19 +2567,19 @@
                   jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
 
-  /// from: `public okhttp3.Response$Builder receivedResponseAtMillis(long j)`
+  /// from: `public fun receivedResponseAtMillis(receivedResponseAtMillis: kotlin.Long): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder receivedResponseAtMillis(
-    int j,
+    core$_.int j,
   ) {
-    return _receivedResponseAtMillis(reference.pointer,
-            _id_receivedResponseAtMillis as jni$_.JMethodIDPtr, j)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _receivedResponseAtMillis(
+            reference.pointer, _id_receivedResponseAtMillis.pointer, j)
+        .object<Response$Builder>();
   }
 
-  static final _id_build = _class.instanceMethodId(
+  static final _id_build = Response$Builder._class.instanceMethodId(
     r'build',
     r'()Lokhttp3/Response;',
   );
@@ -2966,107 +2596,28 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public okhttp3.Response build()`
+  /// from: `public fun build(): okhttp3.Response`
   /// The returned object must be released after use, by calling the [release] method.
   Response build() {
-    return _build(reference.pointer, _id_build as jni$_.JMethodIDPtr)
-        .object<Response>(const $Response$Type());
+    return _build(reference.pointer, _id_build.pointer).object<Response>();
   }
 }
 
-final class $Response$Builder$NullableType
-    extends jni$_.JObjType<Response$Builder?> {
+final class $Response$Builder$Type$ extends jni$_.JType<Response$Builder> {
   @jni$_.internal
-  const $Response$Builder$NullableType();
+  const $Response$Builder$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Response$Builder;';
-
-  @jni$_.internal
-  @core$_.override
-  Response$Builder? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : Response$Builder.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Response$Builder?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Response$Builder$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Response$Builder$NullableType) &&
-        other is $Response$Builder$NullableType;
-  }
-}
-
-final class $Response$Builder$Type extends jni$_.JObjType<Response$Builder> {
-  @jni$_.internal
-  const $Response$Builder$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Response$Builder;';
-
-  @jni$_.internal
-  @core$_.override
-  Response$Builder fromReference(jni$_.JReference reference) =>
-      Response$Builder.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Response$Builder?> get nullableType =>
-      const $Response$Builder$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Response$Builder$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Response$Builder$Type) &&
-        other is $Response$Builder$Type;
-  }
 }
 
 /// from: `okhttp3.Response`
-class Response extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Response> $type;
-
-  @jni$_.internal
-  Response.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Response._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Response');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Response$NullableType();
-  static const type = $Response$Type();
+  static const jni$_.JType<Response> type = $Response$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Lokhttp3/Request;Lokhttp3/Protocol;Ljava/lang/String;ILokhttp3/Handshake;Lokhttp3/Headers;Lokhttp3/ResponseBody;Lokhttp3/Response;Lokhttp3/Response;Lokhttp3/Response;JJLokhttp3/internal/connection/Exchange;)V',
   );
@@ -3099,15 +2650,15 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
+              core$_.int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>)>();
 
   /// from: `public void <init>(okhttp3.Request request, okhttp3.Protocol protocol, java.lang.String string, int i, okhttp3.Handshake handshake, okhttp3.Headers headers, okhttp3.ResponseBody responseBody, okhttp3.Response response, okhttp3.Response response1, okhttp3.Response response2, long j, long j1, okhttp3.internal.connection.Exchange exchange)`
@@ -3116,15 +2667,15 @@
     Request request,
     jni$_.JObject protocol,
     jni$_.JString string,
-    int i,
+    core$_.int i,
     jni$_.JObject? handshake,
     Headers headers,
     ResponseBody? responseBody,
     Response? response,
     Response? response1,
     Response? response2,
-    int j,
-    int j1,
+    core$_.int j,
+    core$_.int j1,
     jni$_.JObject? exchange,
   ) {
     final _$request = request.reference;
@@ -3137,9 +2688,9 @@
     final _$response1 = response1?.reference ?? jni$_.jNullReference;
     final _$response2 = response2?.reference ?? jni$_.jNullReference;
     final _$exchange = exchange?.reference ?? jni$_.jNullReference;
-    return Response.fromReference(_new$(
+    return _new$(
             _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
+            _id_new$.pointer,
             _$request.pointer,
             _$protocol.pointer,
             _$string.pointer,
@@ -3153,10 +2704,12 @@
             j,
             j1,
             _$exchange.pointer)
-        .reference);
+        .object<Response>();
   }
+}
 
-  static final _id_request = _class.instanceMethodId(
+extension Response$$Methods on Response {
+  static final _id_request = Response._class.instanceMethodId(
     r'request',
     r'()Lokhttp3/Request;',
   );
@@ -3176,11 +2729,10 @@
   /// from: `public final okhttp3.Request request()`
   /// The returned object must be released after use, by calling the [release] method.
   Request request() {
-    return _request(reference.pointer, _id_request as jni$_.JMethodIDPtr)
-        .object<Request>(const $Request$Type());
+    return _request(reference.pointer, _id_request.pointer).object<Request>();
   }
 
-  static final _id_protocol = _class.instanceMethodId(
+  static final _id_protocol = Response._class.instanceMethodId(
     r'protocol',
     r'()Lokhttp3/Protocol;',
   );
@@ -3200,11 +2752,11 @@
   /// from: `public final okhttp3.Protocol protocol()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject protocol() {
-    return _protocol(reference.pointer, _id_protocol as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
+    return _protocol(reference.pointer, _id_protocol.pointer)
+        .object<jni$_.JObject>();
   }
 
-  static final _id_message = _class.instanceMethodId(
+  static final _id_message = Response._class.instanceMethodId(
     r'message',
     r'()Ljava/lang/String;',
   );
@@ -3224,11 +2776,11 @@
   /// from: `public final java.lang.String message()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString message() {
-    return _message(reference.pointer, _id_message as jni$_.JMethodIDPtr)
-        .object<jni$_.JString>(const jni$_.JStringType());
+    return _message(reference.pointer, _id_message.pointer)
+        .object<jni$_.JString>();
   }
 
-  static final _id_code = _class.instanceMethodId(
+  static final _id_code = Response._class.instanceMethodId(
     r'code',
     r'()I',
   );
@@ -3246,11 +2798,11 @@
           )>();
 
   /// from: `public final int code()`
-  int code() {
-    return _code(reference.pointer, _id_code as jni$_.JMethodIDPtr).integer;
+  core$_.int code() {
+    return _code(reference.pointer, _id_code.pointer).integer;
   }
 
-  static final _id_handshake = _class.instanceMethodId(
+  static final _id_handshake = Response._class.instanceMethodId(
     r'handshake',
     r'()Lokhttp3/Handshake;',
   );
@@ -3270,11 +2822,11 @@
   /// from: `public final okhttp3.Handshake handshake()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject? handshake() {
-    return _handshake(reference.pointer, _id_handshake as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _handshake(reference.pointer, _id_handshake.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_headers = _class.instanceMethodId(
+  static final _id_headers = Response._class.instanceMethodId(
     r'headers',
     r'()Lokhttp3/Headers;',
   );
@@ -3294,11 +2846,10 @@
   /// from: `public final okhttp3.Headers headers()`
   /// The returned object must be released after use, by calling the [release] method.
   Headers headers() {
-    return _headers(reference.pointer, _id_headers as jni$_.JMethodIDPtr)
-        .object<Headers>(const $Headers$Type());
+    return _headers(reference.pointer, _id_headers.pointer).object<Headers>();
   }
 
-  static final _id_body = _class.instanceMethodId(
+  static final _id_body = Response._class.instanceMethodId(
     r'body',
     r'()Lokhttp3/ResponseBody;',
   );
@@ -3318,11 +2869,10 @@
   /// from: `public final okhttp3.ResponseBody body()`
   /// The returned object must be released after use, by calling the [release] method.
   ResponseBody? body() {
-    return _body(reference.pointer, _id_body as jni$_.JMethodIDPtr)
-        .object<ResponseBody?>(const $ResponseBody$NullableType());
+    return _body(reference.pointer, _id_body.pointer).object<ResponseBody?>();
   }
 
-  static final _id_networkResponse = _class.instanceMethodId(
+  static final _id_networkResponse = Response._class.instanceMethodId(
     r'networkResponse',
     r'()Lokhttp3/Response;',
   );
@@ -3342,12 +2892,11 @@
   /// from: `public final okhttp3.Response networkResponse()`
   /// The returned object must be released after use, by calling the [release] method.
   Response? networkResponse() {
-    return _networkResponse(
-            reference.pointer, _id_networkResponse as jni$_.JMethodIDPtr)
-        .object<Response?>(const $Response$NullableType());
+    return _networkResponse(reference.pointer, _id_networkResponse.pointer)
+        .object<Response?>();
   }
 
-  static final _id_cacheResponse = _class.instanceMethodId(
+  static final _id_cacheResponse = Response._class.instanceMethodId(
     r'cacheResponse',
     r'()Lokhttp3/Response;',
   );
@@ -3367,12 +2916,11 @@
   /// from: `public final okhttp3.Response cacheResponse()`
   /// The returned object must be released after use, by calling the [release] method.
   Response? cacheResponse() {
-    return _cacheResponse(
-            reference.pointer, _id_cacheResponse as jni$_.JMethodIDPtr)
-        .object<Response?>(const $Response$NullableType());
+    return _cacheResponse(reference.pointer, _id_cacheResponse.pointer)
+        .object<Response?>();
   }
 
-  static final _id_priorResponse = _class.instanceMethodId(
+  static final _id_priorResponse = Response._class.instanceMethodId(
     r'priorResponse',
     r'()Lokhttp3/Response;',
   );
@@ -3392,12 +2940,11 @@
   /// from: `public final okhttp3.Response priorResponse()`
   /// The returned object must be released after use, by calling the [release] method.
   Response? priorResponse() {
-    return _priorResponse(
-            reference.pointer, _id_priorResponse as jni$_.JMethodIDPtr)
-        .object<Response?>(const $Response$NullableType());
+    return _priorResponse(reference.pointer, _id_priorResponse.pointer)
+        .object<Response?>();
   }
 
-  static final _id_sentRequestAtMillis = _class.instanceMethodId(
+  static final _id_sentRequestAtMillis = Response._class.instanceMethodId(
     r'sentRequestAtMillis',
     r'()J',
   );
@@ -3415,13 +2962,13 @@
           )>();
 
   /// from: `public final long sentRequestAtMillis()`
-  int sentRequestAtMillis() {
+  core$_.int sentRequestAtMillis() {
     return _sentRequestAtMillis(
-            reference.pointer, _id_sentRequestAtMillis as jni$_.JMethodIDPtr)
+            reference.pointer, _id_sentRequestAtMillis.pointer)
         .long;
   }
 
-  static final _id_receivedResponseAtMillis = _class.instanceMethodId(
+  static final _id_receivedResponseAtMillis = Response._class.instanceMethodId(
     r'receivedResponseAtMillis',
     r'()J',
   );
@@ -3439,13 +2986,13 @@
           )>();
 
   /// from: `public final long receivedResponseAtMillis()`
-  int receivedResponseAtMillis() {
-    return _receivedResponseAtMillis(reference.pointer,
-            _id_receivedResponseAtMillis as jni$_.JMethodIDPtr)
+  core$_.int receivedResponseAtMillis() {
+    return _receivedResponseAtMillis(
+            reference.pointer, _id_receivedResponseAtMillis.pointer)
         .long;
   }
 
-  static final _id_exchange = _class.instanceMethodId(
+  static final _id_exchange = Response._class.instanceMethodId(
     r'exchange',
     r'()Lokhttp3/internal/connection/Exchange;',
   );
@@ -3465,16 +3012,16 @@
   /// from: `public final okhttp3.internal.connection.Exchange exchange()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject? exchange() {
-    return _exchange(reference.pointer, _id_exchange as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _exchange(reference.pointer, _id_exchange.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_isSuccessful = _class.instanceMethodId(
+  static final _id_get$isSuccessful = Response._class.instanceMethodId(
     r'isSuccessful',
     r'()Z',
   );
 
-  static final _isSuccessful = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$isSuccessful = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -3487,13 +3034,12 @@
           )>();
 
   /// from: `public final boolean isSuccessful()`
-  bool isSuccessful() {
-    return _isSuccessful(
-            reference.pointer, _id_isSuccessful as jni$_.JMethodIDPtr)
+  core$_.bool get isSuccessful {
+    return _get$isSuccessful(reference.pointer, _id_get$isSuccessful.pointer)
         .boolean;
   }
 
-  static final _id_headers$1 = _class.instanceMethodId(
+  static final _id_headers$1 = Response._class.instanceMethodId(
     r'headers',
     r'(Ljava/lang/String;)Ljava/util/List;',
   );
@@ -3509,19 +3055,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final java.util.List headers(java.lang.String string)`
+  /// from: `public fun headers(name: kotlin.String): kotlin.collections.List<kotlin.String>`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JList<jni$_.JString> headers$1(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _headers$1(reference.pointer, _id_headers$1 as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<jni$_.JList<jni$_.JString>>(
-            const jni$_.JListType<jni$_.JString>(jni$_.JStringType()));
+    return _headers$1(
+            reference.pointer, _id_headers$1.pointer, _$string.pointer)
+        .object<jni$_.JList<jni$_.JString>>();
   }
 
-  static final _id_header = _class.instanceMethodId(
+  static final _id_header = Response._class.instanceMethodId(
     r'header',
     r'(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;',
   );
@@ -3543,7 +3088,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final java.lang.String header(java.lang.String string, java.lang.String string1)`
+  /// from: `public fun header(name: kotlin.String, defaultValue: kotlin.String?): kotlin.String?`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString? header(
     jni$_.JString string,
@@ -3551,12 +3096,12 @@
   ) {
     final _$string = string.reference;
     final _$string1 = string1?.reference ?? jni$_.jNullReference;
-    return _header(reference.pointer, _id_header as jni$_.JMethodIDPtr,
-            _$string.pointer, _$string1.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+    return _header(reference.pointer, _id_header.pointer, _$string.pointer,
+            _$string1.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_trailers = _class.instanceMethodId(
+  static final _id_trailers = Response._class.instanceMethodId(
     r'trailers',
     r'()Lokhttp3/Headers;',
   );
@@ -3573,14 +3118,13 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final okhttp3.Headers trailers()`
+  /// from: `public fun trailers(): okhttp3.Headers`
   /// The returned object must be released after use, by calling the [release] method.
   Headers trailers() {
-    return _trailers(reference.pointer, _id_trailers as jni$_.JMethodIDPtr)
-        .object<Headers>(const $Headers$Type());
+    return _trailers(reference.pointer, _id_trailers.pointer).object<Headers>();
   }
 
-  static final _id_peekBody = _class.instanceMethodId(
+  static final _id_peekBody = Response._class.instanceMethodId(
     r'peekBody',
     r'(J)Lokhttp3/ResponseBody;',
   );
@@ -3593,18 +3137,18 @@
                   jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
 
-  /// from: `public final okhttp3.ResponseBody peekBody(long j)`
+  /// from: `public fun peekBody(byteCount: kotlin.Long): okhttp3.ResponseBody`
   /// The returned object must be released after use, by calling the [release] method.
   ResponseBody peekBody(
-    int j,
+    core$_.int j,
   ) {
-    return _peekBody(reference.pointer, _id_peekBody as jni$_.JMethodIDPtr, j)
-        .object<ResponseBody>(const $ResponseBody$Type());
+    return _peekBody(reference.pointer, _id_peekBody.pointer, j)
+        .object<ResponseBody>();
   }
 
-  static final _id_newBuilder = _class.instanceMethodId(
+  static final _id_newBuilder = Response._class.instanceMethodId(
     r'newBuilder',
     r'()Lokhttp3/Response$Builder;',
   );
@@ -3621,19 +3165,19 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final okhttp3.Response$Builder newBuilder()`
+  /// from: `public fun newBuilder(): okhttp3.Response.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Response$Builder newBuilder() {
-    return _newBuilder(reference.pointer, _id_newBuilder as jni$_.JMethodIDPtr)
-        .object<Response$Builder>(const $Response$Builder$Type());
+    return _newBuilder(reference.pointer, _id_newBuilder.pointer)
+        .object<Response$Builder>();
   }
 
-  static final _id_isRedirect = _class.instanceMethodId(
+  static final _id_get$isRedirect = Response._class.instanceMethodId(
     r'isRedirect',
     r'()Z',
   );
 
-  static final _isRedirect = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$isRedirect = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -3646,12 +3190,12 @@
           )>();
 
   /// from: `public final boolean isRedirect()`
-  bool isRedirect() {
-    return _isRedirect(reference.pointer, _id_isRedirect as jni$_.JMethodIDPtr)
+  core$_.bool get isRedirect {
+    return _get$isRedirect(reference.pointer, _id_get$isRedirect.pointer)
         .boolean;
   }
 
-  static final _id_challenges = _class.instanceMethodId(
+  static final _id_challenges = Response._class.instanceMethodId(
     r'challenges',
     r'()Ljava/util/List;',
   );
@@ -3668,15 +3212,14 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final java.util.List challenges()`
+  /// from: `public fun challenges(): kotlin.collections.List<okhttp3.Challenge>`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JList<jni$_.JObject> challenges() {
-    return _challenges(reference.pointer, _id_challenges as jni$_.JMethodIDPtr)
-        .object<jni$_.JList<jni$_.JObject>>(
-            const jni$_.JListType<jni$_.JObject>(jni$_.JObjectType()));
+    return _challenges(reference.pointer, _id_challenges.pointer)
+        .object<jni$_.JList<jni$_.JObject>>();
   }
 
-  static final _id_cacheControl = _class.instanceMethodId(
+  static final _id_cacheControl = Response._class.instanceMethodId(
     r'cacheControl',
     r'()Lokhttp3/CacheControl;',
   );
@@ -3696,12 +3239,11 @@
   /// from: `public final okhttp3.CacheControl cacheControl()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject cacheControl() {
-    return _cacheControl(
-            reference.pointer, _id_cacheControl as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
+    return _cacheControl(reference.pointer, _id_cacheControl.pointer)
+        .object<jni$_.JObject>();
   }
 
-  static final _id_close = _class.instanceMethodId(
+  static final _id_close = Response._class.instanceMethodId(
     r'close',
     r'()V',
   );
@@ -3718,12 +3260,12 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public void close()`
+  /// from: `public fun close(): kotlin.Unit`
   void close() {
-    _close(reference.pointer, _id_close as jni$_.JMethodIDPtr).check();
+    _close(reference.pointer, _id_close.pointer).check();
   }
 
-  static final _id_toString$1 = _class.instanceMethodId(
+  static final _id_toString$1 = Response._class.instanceMethodId(
     r'toString',
     r'()Ljava/lang/String;',
   );
@@ -3740,14 +3282,14 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public java.lang.String toString()`
+  /// from: `public fun toString(): kotlin.String`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString toString$1() {
-    return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr)
-        .object<jni$_.JString>(const jni$_.JStringType());
+    return _toString$1(reference.pointer, _id_toString$1.pointer)
+        .object<jni$_.JString>();
   }
 
-  static final _id_header$1 = _class.instanceMethodId(
+  static final _id_header$1 = Response._class.instanceMethodId(
     r'header',
     r'(Ljava/lang/String;)Ljava/lang/String;',
   );
@@ -3769,101 +3311,29 @@
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _header$1(reference.pointer, _id_header$1 as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+    return _header$1(reference.pointer, _id_header$1.pointer, _$string.pointer)
+        .object<jni$_.JString?>();
   }
 }
 
-final class $Response$NullableType extends jni$_.JObjType<Response?> {
+final class $Response$Type$ extends jni$_.JType<Response> {
   @jni$_.internal
-  const $Response$NullableType();
+  const $Response$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Response;';
-
-  @jni$_.internal
-  @core$_.override
-  Response? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Response.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Response?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Response$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Response$NullableType) &&
-        other is $Response$NullableType;
-  }
-}
-
-final class $Response$Type extends jni$_.JObjType<Response> {
-  @jni$_.internal
-  const $Response$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Response;';
-
-  @jni$_.internal
-  @core$_.override
-  Response fromReference(jni$_.JReference reference) => Response.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Response?> get nullableType => const $Response$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Response$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Response$Type) && other is $Response$Type;
-  }
 }
 
 /// from: `okhttp3.ResponseBody$BomAwareReader`
-class ResponseBody$BomAwareReader extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<ResponseBody$BomAwareReader> $type;
-
-  @jni$_.internal
-  ResponseBody$BomAwareReader.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type ResponseBody$BomAwareReader._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'okhttp3/ResponseBody$BomAwareReader');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $ResponseBody$BomAwareReader$NullableType();
-  static const type = $ResponseBody$BomAwareReader$Type();
+  static const jni$_.JType<ResponseBody$BomAwareReader> type =
+      $ResponseBody$BomAwareReader$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Lokio/BufferedSource;Ljava/nio/charset/Charset;)V',
   );
@@ -3893,15 +3363,14 @@
   ) {
     final _$bufferedSource = bufferedSource.reference;
     final _$charset = charset.reference;
-    return ResponseBody$BomAwareReader.fromReference(_new$(
-            _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
-            _$bufferedSource.pointer,
-            _$charset.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$bufferedSource.pointer, _$charset.pointer)
+        .object<ResponseBody$BomAwareReader>();
   }
+}
 
-  static final _id_read = _class.instanceMethodId(
+extension ResponseBody$BomAwareReader$$Methods on ResponseBody$BomAwareReader {
+  static final _id_read = ResponseBody$BomAwareReader._class.instanceMethodId(
     r'read',
     r'([CII)I',
   );
@@ -3918,22 +3387,25 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallIntMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `public int read(char[] cs, int i, int i1)`
-  int read(
+  /// from: `public fun read(cbuf: kotlin.CharArray, off: kotlin.Int, len: kotlin.Int): kotlin.Int`
+  core$_.int read(
     jni$_.JCharArray cs,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$cs = cs.reference;
-    return _read(reference.pointer, _id_read as jni$_.JMethodIDPtr,
-            _$cs.pointer, i, i1)
+    return _read(reference.pointer, _id_read.pointer, _$cs.pointer, i, i1)
         .integer;
   }
 
-  static final _id_close = _class.instanceMethodId(
+  static final _id_close = ResponseBody$BomAwareReader._class.instanceMethodId(
     r'close',
     r'()V',
   );
@@ -3950,392 +3422,30 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public void close()`
+  /// from: `public fun close(): kotlin.Unit`
   void close() {
-    _close(reference.pointer, _id_close as jni$_.JMethodIDPtr).check();
+    _close(reference.pointer, _id_close.pointer).check();
   }
 }
 
-final class $ResponseBody$BomAwareReader$NullableType
-    extends jni$_.JObjType<ResponseBody$BomAwareReader?> {
+final class $ResponseBody$BomAwareReader$Type$
+    extends jni$_.JType<ResponseBody$BomAwareReader> {
   @jni$_.internal
-  const $ResponseBody$BomAwareReader$NullableType();
+  const $ResponseBody$BomAwareReader$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/ResponseBody$BomAwareReader;';
-
-  @jni$_.internal
-  @core$_.override
-  ResponseBody$BomAwareReader? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : ResponseBody$BomAwareReader.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ResponseBody$BomAwareReader?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ResponseBody$BomAwareReader$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ResponseBody$BomAwareReader$NullableType) &&
-        other is $ResponseBody$BomAwareReader$NullableType;
-  }
-}
-
-final class $ResponseBody$BomAwareReader$Type
-    extends jni$_.JObjType<ResponseBody$BomAwareReader> {
-  @jni$_.internal
-  const $ResponseBody$BomAwareReader$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/ResponseBody$BomAwareReader;';
-
-  @jni$_.internal
-  @core$_.override
-  ResponseBody$BomAwareReader fromReference(jni$_.JReference reference) =>
-      ResponseBody$BomAwareReader.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ResponseBody$BomAwareReader?> get nullableType =>
-      const $ResponseBody$BomAwareReader$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ResponseBody$BomAwareReader$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ResponseBody$BomAwareReader$Type) &&
-        other is $ResponseBody$BomAwareReader$Type;
-  }
 }
 
 /// from: `okhttp3.ResponseBody$Companion`
-class ResponseBody$Companion extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<ResponseBody$Companion> $type;
-
-  @jni$_.internal
-  ResponseBody$Companion.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type ResponseBody$Companion._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/ResponseBody$Companion');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $ResponseBody$Companion$NullableType();
-  static const type = $ResponseBody$Companion$Type();
-  static final _id_create = _class.instanceMethodId(
-    r'create',
-    r'(Ljava/lang/String;Lokhttp3/MediaType;)Lokhttp3/ResponseBody;',
-  );
-
-  static final _create = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okhttp3.ResponseBody create(java.lang.String string, okhttp3.MediaType mediaType)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ResponseBody create(
-    jni$_.JString string,
-    jni$_.JObject? mediaType,
-  ) {
-    final _$string = string.reference;
-    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create(reference.pointer, _id_create as jni$_.JMethodIDPtr,
-            _$string.pointer, _$mediaType.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
-  }
-
-  static final _id_create$1 = _class.instanceMethodId(
-    r'create',
-    r'([BLokhttp3/MediaType;)Lokhttp3/ResponseBody;',
-  );
-
-  static final _create$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okhttp3.ResponseBody create(byte[] bs, okhttp3.MediaType mediaType)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ResponseBody create$1(
-    jni$_.JByteArray bs,
-    jni$_.JObject? mediaType,
-  ) {
-    final _$bs = bs.reference;
-    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$1(reference.pointer, _id_create$1 as jni$_.JMethodIDPtr,
-            _$bs.pointer, _$mediaType.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
-  }
-
-  static final _id_create$2 = _class.instanceMethodId(
-    r'create',
-    r'(Lokio/ByteString;Lokhttp3/MediaType;)Lokhttp3/ResponseBody;',
-  );
-
-  static final _create$2 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okhttp3.ResponseBody create(okio.ByteString byteString, okhttp3.MediaType mediaType)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ResponseBody create$2(
-    ByteString byteString,
-    jni$_.JObject? mediaType,
-  ) {
-    final _$byteString = byteString.reference;
-    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$2(reference.pointer, _id_create$2 as jni$_.JMethodIDPtr,
-            _$byteString.pointer, _$mediaType.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
-  }
-
-  static final _id_create$3 = _class.instanceMethodId(
-    r'create',
-    r'(Lokio/BufferedSource;Lokhttp3/MediaType;J)Lokhttp3/ResponseBody;',
-  );
-
-  static final _create$3 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int64
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              int)>();
-
-  /// from: `public final okhttp3.ResponseBody create(okio.BufferedSource bufferedSource, okhttp3.MediaType mediaType, long j)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ResponseBody create$3(
-    jni$_.JObject bufferedSource,
-    jni$_.JObject? mediaType,
-    int j,
-  ) {
-    final _$bufferedSource = bufferedSource.reference;
-    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$3(reference.pointer, _id_create$3 as jni$_.JMethodIDPtr,
-            _$bufferedSource.pointer, _$mediaType.pointer, j)
-        .object<ResponseBody>(const $ResponseBody$Type());
-  }
-
-  static final _id_create$4 = _class.instanceMethodId(
-    r'create',
-    r'(Lokhttp3/MediaType;Ljava/lang/String;)Lokhttp3/ResponseBody;',
-  );
-
-  static final _create$4 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okhttp3.ResponseBody create(okhttp3.MediaType mediaType, java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ResponseBody create$4(
-    jni$_.JObject? mediaType,
-    jni$_.JString string,
-  ) {
-    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    final _$string = string.reference;
-    return _create$4(reference.pointer, _id_create$4 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer, _$string.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
-  }
-
-  static final _id_create$5 = _class.instanceMethodId(
-    r'create',
-    r'(Lokhttp3/MediaType;[B)Lokhttp3/ResponseBody;',
-  );
-
-  static final _create$5 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okhttp3.ResponseBody create(okhttp3.MediaType mediaType, byte[] bs)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ResponseBody create$5(
-    jni$_.JObject? mediaType,
-    jni$_.JByteArray bs,
-  ) {
-    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    final _$bs = bs.reference;
-    return _create$5(reference.pointer, _id_create$5 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer, _$bs.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
-  }
-
-  static final _id_create$6 = _class.instanceMethodId(
-    r'create',
-    r'(Lokhttp3/MediaType;Lokio/ByteString;)Lokhttp3/ResponseBody;',
-  );
-
-  static final _create$6 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okhttp3.ResponseBody create(okhttp3.MediaType mediaType, okio.ByteString byteString)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ResponseBody create$6(
-    jni$_.JObject? mediaType,
-    ByteString byteString,
-  ) {
-    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    final _$byteString = byteString.reference;
-    return _create$6(reference.pointer, _id_create$6 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer, _$byteString.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
-  }
-
-  static final _id_create$7 = _class.instanceMethodId(
-    r'create',
-    r'(Lokhttp3/MediaType;JLokio/BufferedSource;)Lokhttp3/ResponseBody;',
-  );
-
-  static final _create$7 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int64,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okhttp3.ResponseBody create(okhttp3.MediaType mediaType, long j, okio.BufferedSource bufferedSource)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ResponseBody create$7(
-    jni$_.JObject? mediaType,
-    int j,
-    jni$_.JObject bufferedSource,
-  ) {
-    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    final _$bufferedSource = bufferedSource.reference;
-    return _create$7(reference.pointer, _id_create$7 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer, j, _$bufferedSource.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
-  }
-
+  static const jni$_.JType<ResponseBody$Companion> type =
+      $ResponseBody$Companion$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Lkotlin/jvm/internal/DefaultConstructorMarker;)V',
   );
@@ -4358,106 +3468,316 @@
   ) {
     final _$defaultConstructorMarker =
         defaultConstructorMarker?.reference ?? jni$_.jNullReference;
-    return ResponseBody$Companion.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$defaultConstructorMarker.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$defaultConstructorMarker.pointer)
+        .object<ResponseBody$Companion>();
   }
 }
 
-final class $ResponseBody$Companion$NullableType
-    extends jni$_.JObjType<ResponseBody$Companion?> {
+extension ResponseBody$Companion$$Methods on ResponseBody$Companion {
+  static final _id_create = ResponseBody$Companion._class.instanceMethodId(
+    r'create',
+    r'(Ljava/lang/String;Lokhttp3/MediaType;)Lokhttp3/ResponseBody;',
+  );
+
+  static final _create = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun toResponseBody(contentType: okhttp3.MediaType?): okhttp3.ResponseBody`
+  /// The returned object must be released after use, by calling the [release] method.
+  ResponseBody create(
+    jni$_.JString string,
+    jni$_.JObject? mediaType,
+  ) {
+    final _$string = string.reference;
+    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
+    return _create(reference.pointer, _id_create.pointer, _$string.pointer,
+            _$mediaType.pointer)
+        .object<ResponseBody>();
+  }
+
+  static final _id_create$1 = ResponseBody$Companion._class.instanceMethodId(
+    r'create',
+    r'([BLokhttp3/MediaType;)Lokhttp3/ResponseBody;',
+  );
+
+  static final _create$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun toResponseBody(contentType: okhttp3.MediaType?): okhttp3.ResponseBody`
+  /// The returned object must be released after use, by calling the [release] method.
+  ResponseBody create$1(
+    jni$_.JByteArray bs,
+    jni$_.JObject? mediaType,
+  ) {
+    final _$bs = bs.reference;
+    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
+    return _create$1(reference.pointer, _id_create$1.pointer, _$bs.pointer,
+            _$mediaType.pointer)
+        .object<ResponseBody>();
+  }
+
+  static final _id_create$2 = ResponseBody$Companion._class.instanceMethodId(
+    r'create',
+    r'(Lokio/ByteString;Lokhttp3/MediaType;)Lokhttp3/ResponseBody;',
+  );
+
+  static final _create$2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun toResponseBody(contentType: okhttp3.MediaType?): okhttp3.ResponseBody`
+  /// The returned object must be released after use, by calling the [release] method.
+  ResponseBody create$2(
+    ByteString byteString,
+    jni$_.JObject? mediaType,
+  ) {
+    final _$byteString = byteString.reference;
+    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
+    return _create$2(reference.pointer, _id_create$2.pointer,
+            _$byteString.pointer, _$mediaType.pointer)
+        .object<ResponseBody>();
+  }
+
+  static final _id_create$3 = ResponseBody$Companion._class.instanceMethodId(
+    r'create',
+    r'(Lokio/BufferedSource;Lokhttp3/MediaType;J)Lokhttp3/ResponseBody;',
+  );
+
+  static final _create$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int64
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int)>();
+
+  /// from: `public fun asResponseBody(contentType: okhttp3.MediaType?, contentLength: kotlin.Long): okhttp3.ResponseBody`
+  /// The returned object must be released after use, by calling the [release] method.
+  ResponseBody create$3(
+    jni$_.JObject bufferedSource,
+    jni$_.JObject? mediaType,
+    core$_.int j,
+  ) {
+    final _$bufferedSource = bufferedSource.reference;
+    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
+    return _create$3(reference.pointer, _id_create$3.pointer,
+            _$bufferedSource.pointer, _$mediaType.pointer, j)
+        .object<ResponseBody>();
+  }
+
+  static final _id_create$4 = ResponseBody$Companion._class.instanceMethodId(
+    r'create',
+    r'(Lokhttp3/MediaType;Ljava/lang/String;)Lokhttp3/ResponseBody;',
+  );
+
+  static final _create$4 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun create(contentType: okhttp3.MediaType?, content: kotlin.String): okhttp3.ResponseBody`
+  /// The returned object must be released after use, by calling the [release] method.
+  ResponseBody create$4(
+    jni$_.JObject? mediaType,
+    jni$_.JString string,
+  ) {
+    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
+    final _$string = string.reference;
+    return _create$4(reference.pointer, _id_create$4.pointer,
+            _$mediaType.pointer, _$string.pointer)
+        .object<ResponseBody>();
+  }
+
+  static final _id_create$5 = ResponseBody$Companion._class.instanceMethodId(
+    r'create',
+    r'(Lokhttp3/MediaType;[B)Lokhttp3/ResponseBody;',
+  );
+
+  static final _create$5 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun create(contentType: okhttp3.MediaType?, content: kotlin.ByteArray): okhttp3.ResponseBody`
+  /// The returned object must be released after use, by calling the [release] method.
+  ResponseBody create$5(
+    jni$_.JObject? mediaType,
+    jni$_.JByteArray bs,
+  ) {
+    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
+    final _$bs = bs.reference;
+    return _create$5(reference.pointer, _id_create$5.pointer,
+            _$mediaType.pointer, _$bs.pointer)
+        .object<ResponseBody>();
+  }
+
+  static final _id_create$6 = ResponseBody$Companion._class.instanceMethodId(
+    r'create',
+    r'(Lokhttp3/MediaType;Lokio/ByteString;)Lokhttp3/ResponseBody;',
+  );
+
+  static final _create$6 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun create(contentType: okhttp3.MediaType?, content: okio.ByteString): okhttp3.ResponseBody`
+  /// The returned object must be released after use, by calling the [release] method.
+  ResponseBody create$6(
+    jni$_.JObject? mediaType,
+    ByteString byteString,
+  ) {
+    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
+    final _$byteString = byteString.reference;
+    return _create$6(reference.pointer, _id_create$6.pointer,
+            _$mediaType.pointer, _$byteString.pointer)
+        .object<ResponseBody>();
+  }
+
+  static final _id_create$7 = ResponseBody$Companion._class.instanceMethodId(
+    r'create',
+    r'(Lokhttp3/MediaType;JLokio/BufferedSource;)Lokhttp3/ResponseBody;',
+  );
+
+  static final _create$7 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int64,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun create(contentType: okhttp3.MediaType?, contentLength: kotlin.Long, content: okio.BufferedSource): okhttp3.ResponseBody`
+  /// The returned object must be released after use, by calling the [release] method.
+  ResponseBody create$7(
+    jni$_.JObject? mediaType,
+    core$_.int j,
+    jni$_.JObject bufferedSource,
+  ) {
+    final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
+    final _$bufferedSource = bufferedSource.reference;
+    return _create$7(reference.pointer, _id_create$7.pointer,
+            _$mediaType.pointer, j, _$bufferedSource.pointer)
+        .object<ResponseBody>();
+  }
+}
+
+final class $ResponseBody$Companion$Type$
+    extends jni$_.JType<ResponseBody$Companion> {
   @jni$_.internal
-  const $ResponseBody$Companion$NullableType();
+  const $ResponseBody$Companion$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/ResponseBody$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  ResponseBody$Companion? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : ResponseBody$Companion.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ResponseBody$Companion?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ResponseBody$Companion$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ResponseBody$Companion$NullableType) &&
-        other is $ResponseBody$Companion$NullableType;
-  }
-}
-
-final class $ResponseBody$Companion$Type
-    extends jni$_.JObjType<ResponseBody$Companion> {
-  @jni$_.internal
-  const $ResponseBody$Companion$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/ResponseBody$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  ResponseBody$Companion fromReference(jni$_.JReference reference) =>
-      ResponseBody$Companion.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ResponseBody$Companion?> get nullableType =>
-      const $ResponseBody$Companion$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ResponseBody$Companion$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ResponseBody$Companion$Type) &&
-        other is $ResponseBody$Companion$Type;
-  }
 }
 
 /// from: `okhttp3.ResponseBody`
-class ResponseBody extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<ResponseBody> $type;
-
-  @jni$_.internal
-  ResponseBody.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type ResponseBody._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/ResponseBody');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $ResponseBody$NullableType();
-  static const type = $ResponseBody$Type();
+  static const jni$_.JType<ResponseBody> type = $ResponseBody$Type$();
   static final _id_Companion = _class.staticFieldId(
     r'Companion',
     r'Lokhttp3/ResponseBody$Companion;',
@@ -4466,222 +3786,8 @@
   /// from: `static public final okhttp3.ResponseBody$Companion Companion`
   /// The returned object must be released after use, by calling the [release] method.
   static ResponseBody$Companion get Companion =>
-      _id_Companion.get(_class, const $ResponseBody$Companion$Type());
-
-  static final _id_contentType = _class.instanceMethodId(
-    r'contentType',
-    r'()Lokhttp3/MediaType;',
-  );
-
-  static final _contentType = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract okhttp3.MediaType contentType()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? contentType() {
-    return _contentType(
-            reference.pointer, _id_contentType as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_contentLength = _class.instanceMethodId(
-    r'contentLength',
-    r'()J',
-  );
-
-  static final _contentLength = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract long contentLength()`
-  int contentLength() {
-    return _contentLength(
-            reference.pointer, _id_contentLength as jni$_.JMethodIDPtr)
-        .long;
-  }
-
-  static final _id_byteStream = _class.instanceMethodId(
-    r'byteStream',
-    r'()Ljava/io/InputStream;',
-  );
-
-  static final _byteStream = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.io.InputStream byteStream()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject byteStream() {
-    return _byteStream(reference.pointer, _id_byteStream as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_source = _class.instanceMethodId(
-    r'source',
-    r'()Lokio/BufferedSource;',
-  );
-
-  static final _source = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract okio.BufferedSource source()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject source() {
-    return _source(reference.pointer, _id_source as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_bytes = _class.instanceMethodId(
-    r'bytes',
-    r'()[B',
-  );
-
-  static final _bytes = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final byte[] bytes()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JByteArray bytes() {
-    return _bytes(reference.pointer, _id_bytes as jni$_.JMethodIDPtr)
-        .object<jni$_.JByteArray>(const jni$_.JByteArrayType());
-  }
-
-  static final _id_byteString = _class.instanceMethodId(
-    r'byteString',
-    r'()Lokio/ByteString;',
-  );
-
-  static final _byteString = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okio.ByteString byteString()`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString byteString() {
-    return _byteString(reference.pointer, _id_byteString as jni$_.JMethodIDPtr)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_charStream = _class.instanceMethodId(
-    r'charStream',
-    r'()Ljava/io/Reader;',
-  );
-
-  static final _charStream = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.io.Reader charStream()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject charStream() {
-    return _charStream(reference.pointer, _id_charStream as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_string = _class.instanceMethodId(
-    r'string',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _string = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.lang.String string()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString string() {
-    return _string(reference.pointer, _id_string as jni$_.JMethodIDPtr)
-        .object<jni$_.JString>(const jni$_.JStringType());
-  }
-
-  static final _id_close = _class.instanceMethodId(
-    r'close',
-    r'()V',
-  );
-
-  static final _close = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public void close()`
-  void close() {
-    _close(reference.pointer, _id_close as jni$_.JMethodIDPtr).check();
-  }
+      _id_Companion.get(_class, ResponseBody$Companion.type)
+          as ResponseBody$Companion;
 
   static final _id_create = _class.staticMethodId(
     r'create',
@@ -4713,9 +3819,9 @@
   ) {
     final _$string = string.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create(_class.reference.pointer, _id_create as jni$_.JMethodIDPtr,
+    return _create(_class.reference.pointer, _id_create.pointer,
             _$string.pointer, _$mediaType.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
+        .object<ResponseBody>();
   }
 
   static final _id_create$1 = _class.staticMethodId(
@@ -4748,12 +3854,9 @@
   ) {
     final _$bs = bs.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$1(
-            _class.reference.pointer,
-            _id_create$1 as jni$_.JMethodIDPtr,
-            _$bs.pointer,
-            _$mediaType.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
+    return _create$1(_class.reference.pointer, _id_create$1.pointer,
+            _$bs.pointer, _$mediaType.pointer)
+        .object<ResponseBody>();
   }
 
   static final _id_create$2 = _class.staticMethodId(
@@ -4786,12 +3889,9 @@
   ) {
     final _$byteString = byteString.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$2(
-            _class.reference.pointer,
-            _id_create$2 as jni$_.JMethodIDPtr,
-            _$byteString.pointer,
-            _$mediaType.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
+    return _create$2(_class.reference.pointer, _id_create$2.pointer,
+            _$byteString.pointer, _$mediaType.pointer)
+        .object<ResponseBody>();
   }
 
   static final _id_create$3 = _class.staticMethodId(
@@ -4816,24 +3916,20 @@
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int)>();
+              core$_.int)>();
 
   /// from: `static public final okhttp3.ResponseBody create(okio.BufferedSource bufferedSource, okhttp3.MediaType mediaType, long j)`
   /// The returned object must be released after use, by calling the [release] method.
   static ResponseBody create$3(
     jni$_.JObject bufferedSource,
     jni$_.JObject? mediaType,
-    int j,
+    core$_.int j,
   ) {
     final _$bufferedSource = bufferedSource.reference;
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
-    return _create$3(
-            _class.reference.pointer,
-            _id_create$3 as jni$_.JMethodIDPtr,
-            _$bufferedSource.pointer,
-            _$mediaType.pointer,
-            j)
-        .object<ResponseBody>(const $ResponseBody$Type());
+    return _create$3(_class.reference.pointer, _id_create$3.pointer,
+            _$bufferedSource.pointer, _$mediaType.pointer, j)
+        .object<ResponseBody>();
   }
 
   static final _id_create$4 = _class.staticMethodId(
@@ -4866,12 +3962,9 @@
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$string = string.reference;
-    return _create$4(
-            _class.reference.pointer,
-            _id_create$4 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer,
-            _$string.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
+    return _create$4(_class.reference.pointer, _id_create$4.pointer,
+            _$mediaType.pointer, _$string.pointer)
+        .object<ResponseBody>();
   }
 
   static final _id_create$5 = _class.staticMethodId(
@@ -4904,12 +3997,9 @@
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$bs = bs.reference;
-    return _create$5(
-            _class.reference.pointer,
-            _id_create$5 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer,
-            _$bs.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
+    return _create$5(_class.reference.pointer, _id_create$5.pointer,
+            _$mediaType.pointer, _$bs.pointer)
+        .object<ResponseBody>();
   }
 
   static final _id_create$6 = _class.staticMethodId(
@@ -4942,12 +4032,9 @@
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$byteString = byteString.reference;
-    return _create$6(
-            _class.reference.pointer,
-            _id_create$6 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer,
-            _$byteString.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
+    return _create$6(_class.reference.pointer, _id_create$6.pointer,
+            _$mediaType.pointer, _$byteString.pointer)
+        .object<ResponseBody>();
   }
 
   static final _id_create$7 = _class.staticMethodId(
@@ -4971,119 +4058,255 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>)>();
 
   /// from: `static public final okhttp3.ResponseBody create(okhttp3.MediaType mediaType, long j, okio.BufferedSource bufferedSource)`
   /// The returned object must be released after use, by calling the [release] method.
   static ResponseBody create$7(
     jni$_.JObject? mediaType,
-    int j,
+    core$_.int j,
     jni$_.JObject bufferedSource,
   ) {
     final _$mediaType = mediaType?.reference ?? jni$_.jNullReference;
     final _$bufferedSource = bufferedSource.reference;
-    return _create$7(
-            _class.reference.pointer,
-            _id_create$7 as jni$_.JMethodIDPtr,
-            _$mediaType.pointer,
-            j,
-            _$bufferedSource.pointer)
-        .object<ResponseBody>(const $ResponseBody$Type());
+    return _create$7(_class.reference.pointer, _id_create$7.pointer,
+            _$mediaType.pointer, j, _$bufferedSource.pointer)
+        .object<ResponseBody>();
   }
 }
 
-final class $ResponseBody$NullableType extends jni$_.JObjType<ResponseBody?> {
+extension ResponseBody$$Methods on ResponseBody {
+  static final _id_contentType = ResponseBody._class.instanceMethodId(
+    r'contentType',
+    r'()Lokhttp3/MediaType;',
+  );
+
+  static final _contentType = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun contentType(): okhttp3.MediaType?`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? contentType() {
+    return _contentType(reference.pointer, _id_contentType.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_contentLength = ResponseBody._class.instanceMethodId(
+    r'contentLength',
+    r'()J',
+  );
+
+  static final _contentLength = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun contentLength(): kotlin.Long`
+  core$_.int contentLength() {
+    return _contentLength(reference.pointer, _id_contentLength.pointer).long;
+  }
+
+  static final _id_byteStream = ResponseBody._class.instanceMethodId(
+    r'byteStream',
+    r'()Ljava/io/InputStream;',
+  );
+
+  static final _byteStream = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun byteStream(): java.io.InputStream`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject byteStream() {
+    return _byteStream(reference.pointer, _id_byteStream.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_source = ResponseBody._class.instanceMethodId(
+    r'source',
+    r'()Lokio/BufferedSource;',
+  );
+
+  static final _source = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun source(): okio.BufferedSource`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject source() {
+    return _source(reference.pointer, _id_source.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_bytes = ResponseBody._class.instanceMethodId(
+    r'bytes',
+    r'()[B',
+  );
+
+  static final _bytes = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun bytes(): kotlin.ByteArray`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JByteArray bytes() {
+    return _bytes(reference.pointer, _id_bytes.pointer)
+        .object<jni$_.JByteArray>();
+  }
+
+  static final _id_byteString = ResponseBody._class.instanceMethodId(
+    r'byteString',
+    r'()Lokio/ByteString;',
+  );
+
+  static final _byteString = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun byteString(): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString byteString() {
+    return _byteString(reference.pointer, _id_byteString.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_charStream = ResponseBody._class.instanceMethodId(
+    r'charStream',
+    r'()Ljava/io/Reader;',
+  );
+
+  static final _charStream = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun charStream(): java.io.Reader`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject charStream() {
+    return _charStream(reference.pointer, _id_charStream.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_string = ResponseBody._class.instanceMethodId(
+    r'string',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _string = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun string(): kotlin.String`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString string() {
+    return _string(reference.pointer, _id_string.pointer)
+        .object<jni$_.JString>();
+  }
+
+  static final _id_close = ResponseBody._class.instanceMethodId(
+    r'close',
+    r'()V',
+  );
+
+  static final _close = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun close(): kotlin.Unit`
+  void close() {
+    _close(reference.pointer, _id_close.pointer).check();
+  }
+}
+
+final class $ResponseBody$Type$ extends jni$_.JType<ResponseBody> {
   @jni$_.internal
-  const $ResponseBody$NullableType();
+  const $ResponseBody$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/ResponseBody;';
-
-  @jni$_.internal
-  @core$_.override
-  ResponseBody? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : ResponseBody.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ResponseBody?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ResponseBody$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ResponseBody$NullableType) &&
-        other is $ResponseBody$NullableType;
-  }
-}
-
-final class $ResponseBody$Type extends jni$_.JObjType<ResponseBody> {
-  @jni$_.internal
-  const $ResponseBody$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/ResponseBody;';
-
-  @jni$_.internal
-  @core$_.override
-  ResponseBody fromReference(jni$_.JReference reference) =>
-      ResponseBody.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ResponseBody?> get nullableType =>
-      const $ResponseBody$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ResponseBody$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ResponseBody$Type) &&
-        other is $ResponseBody$Type;
-  }
 }
 
 /// from: `okhttp3.OkHttpClient$Builder`
-class OkHttpClient$Builder extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<OkHttpClient$Builder> $type;
-
-  @jni$_.internal
-  OkHttpClient$Builder.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type OkHttpClient$Builder._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/OkHttpClient$Builder');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $OkHttpClient$Builder$NullableType();
-  static const type = $OkHttpClient$Builder$Type();
+  static const jni$_.JType<OkHttpClient$Builder> type =
+      $OkHttpClient$Builder$Type$();
   static final _id_new$ = _class.constructorId(
     r'()V',
   );
@@ -5103,9 +4326,8 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory OkHttpClient$Builder() {
-    return OkHttpClient$Builder.fromReference(
-        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
-            .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -5129,12 +4351,14 @@
     OkHttpClient okHttpClient,
   ) {
     final _$okHttpClient = okHttpClient.reference;
-    return OkHttpClient$Builder.fromReference(_new$1(_class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr, _$okHttpClient.pointer)
-        .reference);
+    return _new$1(
+            _class.reference.pointer, _id_new$1.pointer, _$okHttpClient.pointer)
+        .object<OkHttpClient$Builder>();
   }
+}
 
-  static final _id_dispatcher = _class.instanceMethodId(
+extension OkHttpClient$Builder$$Methods on OkHttpClient$Builder {
+  static final _id_dispatcher = OkHttpClient$Builder._class.instanceMethodId(
     r'dispatcher',
     r'(Lokhttp3/Dispatcher;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5150,18 +4374,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder dispatcher(okhttp3.Dispatcher dispatcher)`
+  /// from: `public fun dispatcher(dispatcher: okhttp3.Dispatcher): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder dispatcher(
     Dispatcher dispatcher,
   ) {
     final _$dispatcher = dispatcher.reference;
-    return _dispatcher(reference.pointer, _id_dispatcher as jni$_.JMethodIDPtr,
-            _$dispatcher.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _dispatcher(
+            reference.pointer, _id_dispatcher.pointer, _$dispatcher.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_connectionPool = _class.instanceMethodId(
+  static final _id_connectionPool =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'connectionPool',
     r'(Lokhttp3/ConnectionPool;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5177,18 +4402,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder connectionPool(okhttp3.ConnectionPool connectionPool)`
+  /// from: `public fun connectionPool(connectionPool: okhttp3.ConnectionPool): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder connectionPool(
     ConnectionPool connectionPool,
   ) {
     final _$connectionPool = connectionPool.reference;
-    return _connectionPool(reference.pointer,
-            _id_connectionPool as jni$_.JMethodIDPtr, _$connectionPool.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _connectionPool(reference.pointer, _id_connectionPool.pointer,
+            _$connectionPool.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_interceptors = _class.instanceMethodId(
+  static final _id_interceptors = OkHttpClient$Builder._class.instanceMethodId(
     r'interceptors',
     r'()Ljava/util/List;',
   );
@@ -5205,16 +4430,15 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final java.util.List interceptors()`
+  /// from: `public fun interceptors(): kotlin.collections.MutableList<okhttp3.Interceptor>`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JList<jni$_.JObject> interceptors() {
-    return _interceptors(
-            reference.pointer, _id_interceptors as jni$_.JMethodIDPtr)
-        .object<jni$_.JList<jni$_.JObject>>(
-            const jni$_.JListType<jni$_.JObject>(jni$_.JObjectType()));
+    return _interceptors(reference.pointer, _id_interceptors.pointer)
+        .object<jni$_.JList<jni$_.JObject>>();
   }
 
-  static final _id_addInterceptor = _class.instanceMethodId(
+  static final _id_addInterceptor =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'addInterceptor',
     r'(Lokhttp3/Interceptor;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5230,18 +4454,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder addInterceptor(okhttp3.Interceptor interceptor)`
+  /// from: `public fun addInterceptor(interceptor: okhttp3.Interceptor): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder addInterceptor(
     jni$_.JObject interceptor,
   ) {
     final _$interceptor = interceptor.reference;
-    return _addInterceptor(reference.pointer,
-            _id_addInterceptor as jni$_.JMethodIDPtr, _$interceptor.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _addInterceptor(reference.pointer, _id_addInterceptor.pointer,
+            _$interceptor.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_networkInterceptors = _class.instanceMethodId(
+  static final _id_networkInterceptors =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'networkInterceptors',
     r'()Ljava/util/List;',
   );
@@ -5258,16 +4483,16 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final java.util.List networkInterceptors()`
+  /// from: `public fun networkInterceptors(): kotlin.collections.MutableList<okhttp3.Interceptor>`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JList<jni$_.JObject> networkInterceptors() {
     return _networkInterceptors(
-            reference.pointer, _id_networkInterceptors as jni$_.JMethodIDPtr)
-        .object<jni$_.JList<jni$_.JObject>>(
-            const jni$_.JListType<jni$_.JObject>(jni$_.JObjectType()));
+            reference.pointer, _id_networkInterceptors.pointer)
+        .object<jni$_.JList<jni$_.JObject>>();
   }
 
-  static final _id_addNetworkInterceptor = _class.instanceMethodId(
+  static final _id_addNetworkInterceptor =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'addNetworkInterceptor',
     r'(Lokhttp3/Interceptor;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5283,20 +4508,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder addNetworkInterceptor(okhttp3.Interceptor interceptor)`
+  /// from: `public fun addNetworkInterceptor(interceptor: okhttp3.Interceptor): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder addNetworkInterceptor(
     jni$_.JObject interceptor,
   ) {
     final _$interceptor = interceptor.reference;
-    return _addNetworkInterceptor(
-            reference.pointer,
-            _id_addNetworkInterceptor as jni$_.JMethodIDPtr,
-            _$interceptor.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _addNetworkInterceptor(reference.pointer,
+            _id_addNetworkInterceptor.pointer, _$interceptor.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_eventListener = _class.instanceMethodId(
+  static final _id_eventListener = OkHttpClient$Builder._class.instanceMethodId(
     r'eventListener',
     r'(Lokhttp3/EventListener;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5312,18 +4535,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder eventListener(okhttp3.EventListener eventListener)`
+  /// from: `public fun eventListener(eventListener: okhttp3.EventListener): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder eventListener(
     jni$_.JObject eventListener,
   ) {
     final _$eventListener = eventListener.reference;
-    return _eventListener(reference.pointer,
-            _id_eventListener as jni$_.JMethodIDPtr, _$eventListener.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _eventListener(reference.pointer, _id_eventListener.pointer,
+            _$eventListener.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_eventListenerFactory = _class.instanceMethodId(
+  static final _id_eventListenerFactory =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'eventListenerFactory',
     r'(Lokhttp3/EventListener$Factory;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5339,18 +4563,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder eventListenerFactory(okhttp3.EventListener$Factory factory)`
+  /// from: `public fun eventListenerFactory(eventListenerFactory: okhttp3.EventListener.Factory): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder eventListenerFactory(
     jni$_.JObject factory,
   ) {
     final _$factory = factory.reference;
     return _eventListenerFactory(reference.pointer,
-            _id_eventListenerFactory as jni$_.JMethodIDPtr, _$factory.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+            _id_eventListenerFactory.pointer, _$factory.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_retryOnConnectionFailure = _class.instanceMethodId(
+  static final _id_retryOnConnectionFailure =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'retryOnConnectionFailure',
     r'(Z)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5363,19 +4588,19 @@
                   jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder retryOnConnectionFailure(boolean z)`
+  /// from: `public fun retryOnConnectionFailure(retryOnConnectionFailure: kotlin.Boolean): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder retryOnConnectionFailure(
-    bool z,
+    core$_.bool z,
   ) {
-    return _retryOnConnectionFailure(reference.pointer,
-            _id_retryOnConnectionFailure as jni$_.JMethodIDPtr, z ? 1 : 0)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _retryOnConnectionFailure(
+            reference.pointer, _id_retryOnConnectionFailure.pointer, z ? 1 : 0)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_authenticator = _class.instanceMethodId(
+  static final _id_authenticator = OkHttpClient$Builder._class.instanceMethodId(
     r'authenticator',
     r'(Lokhttp3/Authenticator;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5391,18 +4616,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder authenticator(okhttp3.Authenticator authenticator)`
+  /// from: `public fun authenticator(authenticator: okhttp3.Authenticator): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder authenticator(
     jni$_.JObject authenticator,
   ) {
     final _$authenticator = authenticator.reference;
-    return _authenticator(reference.pointer,
-            _id_authenticator as jni$_.JMethodIDPtr, _$authenticator.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _authenticator(reference.pointer, _id_authenticator.pointer,
+            _$authenticator.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_followRedirects = _class.instanceMethodId(
+  static final _id_followRedirects =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'followRedirects',
     r'(Z)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5415,19 +4641,20 @@
                   jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder followRedirects(boolean z)`
+  /// from: `public fun followRedirects(followRedirects: kotlin.Boolean): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder followRedirects(
-    bool z,
+    core$_.bool z,
   ) {
-    return _followRedirects(reference.pointer,
-            _id_followRedirects as jni$_.JMethodIDPtr, z ? 1 : 0)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _followRedirects(
+            reference.pointer, _id_followRedirects.pointer, z ? 1 : 0)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_followSslRedirects = _class.instanceMethodId(
+  static final _id_followSslRedirects =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'followSslRedirects',
     r'(Z)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5440,19 +4667,19 @@
                   jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder followSslRedirects(boolean z)`
+  /// from: `public fun followSslRedirects(followProtocolRedirects: kotlin.Boolean): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder followSslRedirects(
-    bool z,
+    core$_.bool z,
   ) {
-    return _followSslRedirects(reference.pointer,
-            _id_followSslRedirects as jni$_.JMethodIDPtr, z ? 1 : 0)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _followSslRedirects(
+            reference.pointer, _id_followSslRedirects.pointer, z ? 1 : 0)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_cookieJar = _class.instanceMethodId(
+  static final _id_cookieJar = OkHttpClient$Builder._class.instanceMethodId(
     r'cookieJar',
     r'(Lokhttp3/CookieJar;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5468,18 +4695,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder cookieJar(okhttp3.CookieJar cookieJar)`
+  /// from: `public fun cookieJar(cookieJar: okhttp3.CookieJar): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder cookieJar(
     jni$_.JObject cookieJar,
   ) {
     final _$cookieJar = cookieJar.reference;
-    return _cookieJar(reference.pointer, _id_cookieJar as jni$_.JMethodIDPtr,
-            _$cookieJar.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _cookieJar(
+            reference.pointer, _id_cookieJar.pointer, _$cookieJar.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_cache = _class.instanceMethodId(
+  static final _id_cache = OkHttpClient$Builder._class.instanceMethodId(
     r'cache',
     r'(Lokhttp3/Cache;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5495,18 +4722,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder cache(okhttp3.Cache cache)`
+  /// from: `public fun cache(cache: okhttp3.Cache?): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder cache(
     Cache? cache,
   ) {
     final _$cache = cache?.reference ?? jni$_.jNullReference;
-    return _cache(
-            reference.pointer, _id_cache as jni$_.JMethodIDPtr, _$cache.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _cache(reference.pointer, _id_cache.pointer, _$cache.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_dns = _class.instanceMethodId(
+  static final _id_dns = OkHttpClient$Builder._class.instanceMethodId(
     r'dns',
     r'(Lokhttp3/Dns;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5522,17 +4748,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder dns(okhttp3.Dns dns)`
+  /// from: `public fun dns(dns: okhttp3.Dns): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder dns(
     jni$_.JObject dns,
   ) {
     final _$dns = dns.reference;
-    return _dns(reference.pointer, _id_dns as jni$_.JMethodIDPtr, _$dns.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _dns(reference.pointer, _id_dns.pointer, _$dns.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_proxy = _class.instanceMethodId(
+  static final _id_proxy = OkHttpClient$Builder._class.instanceMethodId(
     r'proxy',
     r'(Ljava/net/Proxy;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5548,18 +4774,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder proxy(java.net.Proxy proxy)`
+  /// from: `public fun proxy(proxy: java.net.Proxy?): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder proxy(
     jni$_.JObject? proxy,
   ) {
     final _$proxy = proxy?.reference ?? jni$_.jNullReference;
-    return _proxy(
-            reference.pointer, _id_proxy as jni$_.JMethodIDPtr, _$proxy.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _proxy(reference.pointer, _id_proxy.pointer, _$proxy.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_proxySelector = _class.instanceMethodId(
+  static final _id_proxySelector = OkHttpClient$Builder._class.instanceMethodId(
     r'proxySelector',
     r'(Ljava/net/ProxySelector;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5575,18 +4800,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder proxySelector(java.net.ProxySelector proxySelector)`
+  /// from: `public fun proxySelector(proxySelector: java.net.ProxySelector): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder proxySelector(
     jni$_.JObject proxySelector,
   ) {
     final _$proxySelector = proxySelector.reference;
-    return _proxySelector(reference.pointer,
-            _id_proxySelector as jni$_.JMethodIDPtr, _$proxySelector.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _proxySelector(reference.pointer, _id_proxySelector.pointer,
+            _$proxySelector.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_proxyAuthenticator = _class.instanceMethodId(
+  static final _id_proxyAuthenticator =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'proxyAuthenticator',
     r'(Lokhttp3/Authenticator;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5602,20 +4828,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder proxyAuthenticator(okhttp3.Authenticator authenticator)`
+  /// from: `public fun proxyAuthenticator(proxyAuthenticator: okhttp3.Authenticator): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder proxyAuthenticator(
     jni$_.JObject authenticator,
   ) {
     final _$authenticator = authenticator.reference;
-    return _proxyAuthenticator(
-            reference.pointer,
-            _id_proxyAuthenticator as jni$_.JMethodIDPtr,
-            _$authenticator.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _proxyAuthenticator(reference.pointer,
+            _id_proxyAuthenticator.pointer, _$authenticator.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_socketFactory = _class.instanceMethodId(
+  static final _id_socketFactory = OkHttpClient$Builder._class.instanceMethodId(
     r'socketFactory',
     r'(Ljavax/net/SocketFactory;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5631,18 +4855,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder socketFactory(javax.net.SocketFactory socketFactory)`
+  /// from: `public fun socketFactory(socketFactory: javax.net.SocketFactory): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder socketFactory(
     SocketFactory socketFactory,
   ) {
     final _$socketFactory = socketFactory.reference;
-    return _socketFactory(reference.pointer,
-            _id_socketFactory as jni$_.JMethodIDPtr, _$socketFactory.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _socketFactory(reference.pointer, _id_socketFactory.pointer,
+            _$socketFactory.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_sslSocketFactory = _class.instanceMethodId(
+  static final _id_sslSocketFactory =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'sslSocketFactory',
     r'(Ljavax/net/ssl/SSLSocketFactory;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5658,20 +4883,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder sslSocketFactory(javax.net.ssl.SSLSocketFactory sSLSocketFactory)`
+  /// from: `public fun sslSocketFactory(sslSocketFactory: javax.net.ssl.SSLSocketFactory): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder sslSocketFactory(
     SSLSocketFactory sSLSocketFactory,
   ) {
     final _$sSLSocketFactory = sSLSocketFactory.reference;
-    return _sslSocketFactory(
-            reference.pointer,
-            _id_sslSocketFactory as jni$_.JMethodIDPtr,
+    return _sslSocketFactory(reference.pointer, _id_sslSocketFactory.pointer,
             _$sSLSocketFactory.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_sslSocketFactory$1 = _class.instanceMethodId(
+  static final _id_sslSocketFactory$1 =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'sslSocketFactory',
     r'(Ljavax/net/ssl/SSLSocketFactory;Ljavax/net/ssl/X509TrustManager;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5693,7 +4917,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder sslSocketFactory(javax.net.ssl.SSLSocketFactory sSLSocketFactory, javax.net.ssl.X509TrustManager x509TrustManager)`
+  /// from: `public fun sslSocketFactory(sslSocketFactory: javax.net.ssl.SSLSocketFactory, trustManager: javax.net.ssl.X509TrustManager): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder sslSocketFactory$1(
     SSLSocketFactory sSLSocketFactory,
@@ -5703,13 +4927,14 @@
     final _$x509TrustManager = x509TrustManager.reference;
     return _sslSocketFactory$1(
             reference.pointer,
-            _id_sslSocketFactory$1 as jni$_.JMethodIDPtr,
+            _id_sslSocketFactory$1.pointer,
             _$sSLSocketFactory.pointer,
             _$x509TrustManager.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_connectionSpecs = _class.instanceMethodId(
+  static final _id_connectionSpecs =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'connectionSpecs',
     r'(Ljava/util/List;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5725,18 +4950,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder connectionSpecs(java.util.List list)`
+  /// from: `public fun connectionSpecs(connectionSpecs: kotlin.collections.List<okhttp3.ConnectionSpec>): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder connectionSpecs(
     jni$_.JList<jni$_.JObject> list,
   ) {
     final _$list = list.reference;
-    return _connectionSpecs(reference.pointer,
-            _id_connectionSpecs as jni$_.JMethodIDPtr, _$list.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _connectionSpecs(
+            reference.pointer, _id_connectionSpecs.pointer, _$list.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_protocols = _class.instanceMethodId(
+  static final _id_protocols = OkHttpClient$Builder._class.instanceMethodId(
     r'protocols',
     r'(Ljava/util/List;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5752,18 +4977,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder protocols(java.util.List list)`
+  /// from: `public fun protocols(protocols: kotlin.collections.List<okhttp3.Protocol>): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder protocols(
     jni$_.JList<jni$_.JObject> list,
   ) {
     final _$list = list.reference;
-    return _protocols(reference.pointer, _id_protocols as jni$_.JMethodIDPtr,
-            _$list.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _protocols(reference.pointer, _id_protocols.pointer, _$list.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_hostnameVerifier = _class.instanceMethodId(
+  static final _id_hostnameVerifier =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'hostnameVerifier',
     r'(Ljavax/net/ssl/HostnameVerifier;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5779,20 +5004,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder hostnameVerifier(javax.net.ssl.HostnameVerifier hostnameVerifier)`
+  /// from: `public fun hostnameVerifier(hostnameVerifier: javax.net.ssl.HostnameVerifier): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder hostnameVerifier(
     HostnameVerifier hostnameVerifier,
   ) {
     final _$hostnameVerifier = hostnameVerifier.reference;
-    return _hostnameVerifier(
-            reference.pointer,
-            _id_hostnameVerifier as jni$_.JMethodIDPtr,
+    return _hostnameVerifier(reference.pointer, _id_hostnameVerifier.pointer,
             _$hostnameVerifier.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_certificatePinner = _class.instanceMethodId(
+  static final _id_certificatePinner =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'certificatePinner',
     r'(Lokhttp3/CertificatePinner;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5808,20 +5032,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder certificatePinner(okhttp3.CertificatePinner certificatePinner)`
+  /// from: `public fun certificatePinner(certificatePinner: okhttp3.CertificatePinner): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder certificatePinner(
     jni$_.JObject certificatePinner,
   ) {
     final _$certificatePinner = certificatePinner.reference;
-    return _certificatePinner(
-            reference.pointer,
-            _id_certificatePinner as jni$_.JMethodIDPtr,
+    return _certificatePinner(reference.pointer, _id_certificatePinner.pointer,
             _$certificatePinner.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_callTimeout = _class.instanceMethodId(
+  static final _id_callTimeout = OkHttpClient$Builder._class.instanceMethodId(
     r'callTimeout',
     r'(JLjava/util/concurrent/TimeUnit;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5836,21 +5058,21 @@
           'globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>)>();
+              jni$_.JMethodIDPtr, core$_.int, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder callTimeout(long j, java.util.concurrent.TimeUnit timeUnit)`
+  /// from: `public fun callTimeout(timeout: kotlin.Long, unit: java.util.concurrent.TimeUnit): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder callTimeout(
-    int j,
+    core$_.int j,
     TimeUnit timeUnit,
   ) {
     final _$timeUnit = timeUnit.reference;
-    return _callTimeout(reference.pointer,
-            _id_callTimeout as jni$_.JMethodIDPtr, j, _$timeUnit.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _callTimeout(
+            reference.pointer, _id_callTimeout.pointer, j, _$timeUnit.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_callTimeout$1 = _class.instanceMethodId(
+  static final _id_callTimeout$1 = OkHttpClient$Builder._class.instanceMethodId(
     r'callTimeout',
     r'(Ljava/time/Duration;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5866,18 +5088,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder callTimeout(java.time.Duration duration)`
+  /// from: `public fun callTimeout(duration: java.time.Duration): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder callTimeout$1(
     jni$_.JObject duration,
   ) {
     final _$duration = duration.reference;
-    return _callTimeout$1(reference.pointer,
-            _id_callTimeout$1 as jni$_.JMethodIDPtr, _$duration.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _callTimeout$1(
+            reference.pointer, _id_callTimeout$1.pointer, _$duration.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_connectTimeout = _class.instanceMethodId(
+  static final _id_connectTimeout =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'connectTimeout',
     r'(JLjava/util/concurrent/TimeUnit;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5892,21 +5115,22 @@
           'globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>)>();
+              jni$_.JMethodIDPtr, core$_.int, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder connectTimeout(long j, java.util.concurrent.TimeUnit timeUnit)`
+  /// from: `public fun connectTimeout(timeout: kotlin.Long, unit: java.util.concurrent.TimeUnit): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder connectTimeout(
-    int j,
+    core$_.int j,
     TimeUnit timeUnit,
   ) {
     final _$timeUnit = timeUnit.reference;
-    return _connectTimeout(reference.pointer,
-            _id_connectTimeout as jni$_.JMethodIDPtr, j, _$timeUnit.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _connectTimeout(reference.pointer, _id_connectTimeout.pointer, j,
+            _$timeUnit.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_connectTimeout$1 = _class.instanceMethodId(
+  static final _id_connectTimeout$1 =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'connectTimeout',
     r'(Ljava/time/Duration;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5922,18 +5146,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder connectTimeout(java.time.Duration duration)`
+  /// from: `public fun connectTimeout(duration: java.time.Duration): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder connectTimeout$1(
     jni$_.JObject duration,
   ) {
     final _$duration = duration.reference;
-    return _connectTimeout$1(reference.pointer,
-            _id_connectTimeout$1 as jni$_.JMethodIDPtr, _$duration.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _connectTimeout$1(
+            reference.pointer, _id_connectTimeout$1.pointer, _$duration.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_readTimeout = _class.instanceMethodId(
+  static final _id_readTimeout = OkHttpClient$Builder._class.instanceMethodId(
     r'readTimeout',
     r'(JLjava/util/concurrent/TimeUnit;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5948,21 +5172,21 @@
           'globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>)>();
+              jni$_.JMethodIDPtr, core$_.int, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder readTimeout(long j, java.util.concurrent.TimeUnit timeUnit)`
+  /// from: `public fun readTimeout(timeout: kotlin.Long, unit: java.util.concurrent.TimeUnit): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder readTimeout(
-    int j,
+    core$_.int j,
     TimeUnit timeUnit,
   ) {
     final _$timeUnit = timeUnit.reference;
-    return _readTimeout(reference.pointer,
-            _id_readTimeout as jni$_.JMethodIDPtr, j, _$timeUnit.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _readTimeout(
+            reference.pointer, _id_readTimeout.pointer, j, _$timeUnit.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_readTimeout$1 = _class.instanceMethodId(
+  static final _id_readTimeout$1 = OkHttpClient$Builder._class.instanceMethodId(
     r'readTimeout',
     r'(Ljava/time/Duration;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -5978,18 +5202,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder readTimeout(java.time.Duration duration)`
+  /// from: `public fun readTimeout(duration: java.time.Duration): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder readTimeout$1(
     jni$_.JObject duration,
   ) {
     final _$duration = duration.reference;
-    return _readTimeout$1(reference.pointer,
-            _id_readTimeout$1 as jni$_.JMethodIDPtr, _$duration.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _readTimeout$1(
+            reference.pointer, _id_readTimeout$1.pointer, _$duration.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_writeTimeout = _class.instanceMethodId(
+  static final _id_writeTimeout = OkHttpClient$Builder._class.instanceMethodId(
     r'writeTimeout',
     r'(JLjava/util/concurrent/TimeUnit;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -6004,21 +5228,22 @@
           'globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>)>();
+              jni$_.JMethodIDPtr, core$_.int, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder writeTimeout(long j, java.util.concurrent.TimeUnit timeUnit)`
+  /// from: `public fun writeTimeout(timeout: kotlin.Long, unit: java.util.concurrent.TimeUnit): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder writeTimeout(
-    int j,
+    core$_.int j,
     TimeUnit timeUnit,
   ) {
     final _$timeUnit = timeUnit.reference;
-    return _writeTimeout(reference.pointer,
-            _id_writeTimeout as jni$_.JMethodIDPtr, j, _$timeUnit.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _writeTimeout(
+            reference.pointer, _id_writeTimeout.pointer, j, _$timeUnit.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_writeTimeout$1 = _class.instanceMethodId(
+  static final _id_writeTimeout$1 =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'writeTimeout',
     r'(Ljava/time/Duration;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -6034,18 +5259,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder writeTimeout(java.time.Duration duration)`
+  /// from: `public fun writeTimeout(duration: java.time.Duration): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder writeTimeout$1(
     jni$_.JObject duration,
   ) {
     final _$duration = duration.reference;
-    return _writeTimeout$1(reference.pointer,
-            _id_writeTimeout$1 as jni$_.JMethodIDPtr, _$duration.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _writeTimeout$1(
+            reference.pointer, _id_writeTimeout$1.pointer, _$duration.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_pingInterval = _class.instanceMethodId(
+  static final _id_pingInterval = OkHttpClient$Builder._class.instanceMethodId(
     r'pingInterval',
     r'(JLjava/util/concurrent/TimeUnit;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -6060,21 +5285,22 @@
           'globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>)>();
+              jni$_.JMethodIDPtr, core$_.int, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder pingInterval(long j, java.util.concurrent.TimeUnit timeUnit)`
+  /// from: `public fun pingInterval(interval: kotlin.Long, unit: java.util.concurrent.TimeUnit): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder pingInterval(
-    int j,
+    core$_.int j,
     TimeUnit timeUnit,
   ) {
     final _$timeUnit = timeUnit.reference;
-    return _pingInterval(reference.pointer,
-            _id_pingInterval as jni$_.JMethodIDPtr, j, _$timeUnit.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _pingInterval(
+            reference.pointer, _id_pingInterval.pointer, j, _$timeUnit.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_pingInterval$1 = _class.instanceMethodId(
+  static final _id_pingInterval$1 =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'pingInterval',
     r'(Ljava/time/Duration;)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -6090,18 +5316,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder pingInterval(java.time.Duration duration)`
+  /// from: `public fun pingInterval(duration: java.time.Duration): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder pingInterval$1(
     jni$_.JObject duration,
   ) {
     final _$duration = duration.reference;
-    return _pingInterval$1(reference.pointer,
-            _id_pingInterval$1 as jni$_.JMethodIDPtr, _$duration.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _pingInterval$1(
+            reference.pointer, _id_pingInterval$1.pointer, _$duration.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_minWebSocketMessageToCompress = _class.instanceMethodId(
+  static final _id_minWebSocketMessageToCompress =
+      OkHttpClient$Builder._class.instanceMethodId(
     r'minWebSocketMessageToCompress',
     r'(J)Lokhttp3/OkHttpClient$Builder;',
   );
@@ -6114,19 +5341,19 @@
               'globalEnv_CallObjectMethod')
           .asFunction<
               jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
+                  jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder minWebSocketMessageToCompress(long j)`
+  /// from: `public fun minWebSocketMessageToCompress(bytes: kotlin.Long): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder minWebSocketMessageToCompress(
-    int j,
+    core$_.int j,
   ) {
-    return _minWebSocketMessageToCompress(reference.pointer,
-            _id_minWebSocketMessageToCompress as jni$_.JMethodIDPtr, j)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _minWebSocketMessageToCompress(
+            reference.pointer, _id_minWebSocketMessageToCompress.pointer, j)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_build = _class.instanceMethodId(
+  static final _id_build = OkHttpClient$Builder._class.instanceMethodId(
     r'build',
     r'()Lokhttp3/OkHttpClient;',
   );
@@ -6143,108 +5370,31 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final okhttp3.OkHttpClient build()`
+  /// from: `public fun build(): okhttp3.OkHttpClient`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient build() {
-    return _build(reference.pointer, _id_build as jni$_.JMethodIDPtr)
-        .object<OkHttpClient>(const $OkHttpClient$Type());
+    return _build(reference.pointer, _id_build.pointer).object<OkHttpClient>();
   }
 }
 
-final class $OkHttpClient$Builder$NullableType
-    extends jni$_.JObjType<OkHttpClient$Builder?> {
+final class $OkHttpClient$Builder$Type$
+    extends jni$_.JType<OkHttpClient$Builder> {
   @jni$_.internal
-  const $OkHttpClient$Builder$NullableType();
+  const $OkHttpClient$Builder$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/OkHttpClient$Builder;';
-
-  @jni$_.internal
-  @core$_.override
-  OkHttpClient$Builder? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : OkHttpClient$Builder.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<OkHttpClient$Builder?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($OkHttpClient$Builder$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($OkHttpClient$Builder$NullableType) &&
-        other is $OkHttpClient$Builder$NullableType;
-  }
-}
-
-final class $OkHttpClient$Builder$Type
-    extends jni$_.JObjType<OkHttpClient$Builder> {
-  @jni$_.internal
-  const $OkHttpClient$Builder$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/OkHttpClient$Builder;';
-
-  @jni$_.internal
-  @core$_.override
-  OkHttpClient$Builder fromReference(jni$_.JReference reference) =>
-      OkHttpClient$Builder.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<OkHttpClient$Builder?> get nullableType =>
-      const $OkHttpClient$Builder$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($OkHttpClient$Builder$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($OkHttpClient$Builder$Type) &&
-        other is $OkHttpClient$Builder$Type;
-  }
 }
 
 /// from: `okhttp3.OkHttpClient$Companion`
-class OkHttpClient$Companion extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<OkHttpClient$Companion> $type;
-
-  @jni$_.internal
-  OkHttpClient$Companion.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type OkHttpClient$Companion._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/OkHttpClient$Companion');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $OkHttpClient$Companion$NullableType();
-  static const type = $OkHttpClient$Companion$Type();
+  static const jni$_.JType<OkHttpClient$Companion> type =
+      $OkHttpClient$Companion$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Lkotlin/jvm/internal/DefaultConstructorMarker;)V',
   );
@@ -6267,106 +5417,29 @@
   ) {
     final _$defaultConstructorMarker =
         defaultConstructorMarker?.reference ?? jni$_.jNullReference;
-    return OkHttpClient$Companion.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$defaultConstructorMarker.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$defaultConstructorMarker.pointer)
+        .object<OkHttpClient$Companion>();
   }
 }
 
-final class $OkHttpClient$Companion$NullableType
-    extends jni$_.JObjType<OkHttpClient$Companion?> {
+final class $OkHttpClient$Companion$Type$
+    extends jni$_.JType<OkHttpClient$Companion> {
   @jni$_.internal
-  const $OkHttpClient$Companion$NullableType();
+  const $OkHttpClient$Companion$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/OkHttpClient$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  OkHttpClient$Companion? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : OkHttpClient$Companion.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<OkHttpClient$Companion?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($OkHttpClient$Companion$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($OkHttpClient$Companion$NullableType) &&
-        other is $OkHttpClient$Companion$NullableType;
-  }
-}
-
-final class $OkHttpClient$Companion$Type
-    extends jni$_.JObjType<OkHttpClient$Companion> {
-  @jni$_.internal
-  const $OkHttpClient$Companion$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/OkHttpClient$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  OkHttpClient$Companion fromReference(jni$_.JReference reference) =>
-      OkHttpClient$Companion.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<OkHttpClient$Companion?> get nullableType =>
-      const $OkHttpClient$Companion$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($OkHttpClient$Companion$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($OkHttpClient$Companion$Type) &&
-        other is $OkHttpClient$Companion$Type;
-  }
 }
 
 /// from: `okhttp3.OkHttpClient`
-class OkHttpClient extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<OkHttpClient> $type;
-
-  @jni$_.internal
-  OkHttpClient.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type OkHttpClient._(jni$_.JObject _$this)
+    implements jni$_.JObject, Call$Factory, WebSocket$Factory {
   static final _class = jni$_.JClass.forName(r'okhttp3/OkHttpClient');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $OkHttpClient$NullableType();
-  static const type = $OkHttpClient$Type();
+  static const jni$_.JType<OkHttpClient> type = $OkHttpClient$Type$();
   static final _id_Companion = _class.staticFieldId(
     r'Companion',
     r'Lokhttp3/OkHttpClient$Companion;',
@@ -6375,7 +5448,8 @@
   /// from: `static public final okhttp3.OkHttpClient$Companion Companion`
   /// The returned object must be released after use, by calling the [release] method.
   static OkHttpClient$Companion get Companion =>
-      _id_Companion.get(_class, const $OkHttpClient$Companion$Type());
+      _id_Companion.get(_class, OkHttpClient$Companion.type)
+          as OkHttpClient$Companion;
 
   static final _id_new$ = _class.constructorId(
     r'(Lokhttp3/OkHttpClient$Builder;)V',
@@ -6398,749 +5472,8 @@
     OkHttpClient$Builder builder,
   ) {
     final _$builder = builder.reference;
-    return OkHttpClient.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$builder.pointer)
-        .reference);
-  }
-
-  static final _id_dispatcher = _class.instanceMethodId(
-    r'dispatcher',
-    r'()Lokhttp3/Dispatcher;',
-  );
-
-  static final _dispatcher = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.Dispatcher dispatcher()`
-  /// The returned object must be released after use, by calling the [release] method.
-  Dispatcher dispatcher() {
-    return _dispatcher(reference.pointer, _id_dispatcher as jni$_.JMethodIDPtr)
-        .object<Dispatcher>(const $Dispatcher$Type());
-  }
-
-  static final _id_connectionPool = _class.instanceMethodId(
-    r'connectionPool',
-    r'()Lokhttp3/ConnectionPool;',
-  );
-
-  static final _connectionPool = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.ConnectionPool connectionPool()`
-  /// The returned object must be released after use, by calling the [release] method.
-  ConnectionPool connectionPool() {
-    return _connectionPool(
-            reference.pointer, _id_connectionPool as jni$_.JMethodIDPtr)
-        .object<ConnectionPool>(const $ConnectionPool$Type());
-  }
-
-  static final _id_interceptors = _class.instanceMethodId(
-    r'interceptors',
-    r'()Ljava/util/List;',
-  );
-
-  static final _interceptors = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.util.List interceptors()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JList<jni$_.JObject> interceptors() {
-    return _interceptors(
-            reference.pointer, _id_interceptors as jni$_.JMethodIDPtr)
-        .object<jni$_.JList<jni$_.JObject>>(
-            const jni$_.JListType<jni$_.JObject>(jni$_.JObjectType()));
-  }
-
-  static final _id_networkInterceptors = _class.instanceMethodId(
-    r'networkInterceptors',
-    r'()Ljava/util/List;',
-  );
-
-  static final _networkInterceptors = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.util.List networkInterceptors()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JList<jni$_.JObject> networkInterceptors() {
-    return _networkInterceptors(
-            reference.pointer, _id_networkInterceptors as jni$_.JMethodIDPtr)
-        .object<jni$_.JList<jni$_.JObject>>(
-            const jni$_.JListType<jni$_.JObject>(jni$_.JObjectType()));
-  }
-
-  static final _id_eventListenerFactory = _class.instanceMethodId(
-    r'eventListenerFactory',
-    r'()Lokhttp3/EventListener$Factory;',
-  );
-
-  static final _eventListenerFactory = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.EventListener$Factory eventListenerFactory()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject eventListenerFactory() {
-    return _eventListenerFactory(
-            reference.pointer, _id_eventListenerFactory as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_retryOnConnectionFailure = _class.instanceMethodId(
-    r'retryOnConnectionFailure',
-    r'()Z',
-  );
-
-  static final _retryOnConnectionFailure = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final boolean retryOnConnectionFailure()`
-  bool retryOnConnectionFailure() {
-    return _retryOnConnectionFailure(reference.pointer,
-            _id_retryOnConnectionFailure as jni$_.JMethodIDPtr)
-        .boolean;
-  }
-
-  static final _id_authenticator = _class.instanceMethodId(
-    r'authenticator',
-    r'()Lokhttp3/Authenticator;',
-  );
-
-  static final _authenticator = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.Authenticator authenticator()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject authenticator() {
-    return _authenticator(
-            reference.pointer, _id_authenticator as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_followRedirects = _class.instanceMethodId(
-    r'followRedirects',
-    r'()Z',
-  );
-
-  static final _followRedirects = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final boolean followRedirects()`
-  bool followRedirects() {
-    return _followRedirects(
-            reference.pointer, _id_followRedirects as jni$_.JMethodIDPtr)
-        .boolean;
-  }
-
-  static final _id_followSslRedirects = _class.instanceMethodId(
-    r'followSslRedirects',
-    r'()Z',
-  );
-
-  static final _followSslRedirects = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final boolean followSslRedirects()`
-  bool followSslRedirects() {
-    return _followSslRedirects(
-            reference.pointer, _id_followSslRedirects as jni$_.JMethodIDPtr)
-        .boolean;
-  }
-
-  static final _id_cookieJar = _class.instanceMethodId(
-    r'cookieJar',
-    r'()Lokhttp3/CookieJar;',
-  );
-
-  static final _cookieJar = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.CookieJar cookieJar()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject cookieJar() {
-    return _cookieJar(reference.pointer, _id_cookieJar as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_cache = _class.instanceMethodId(
-    r'cache',
-    r'()Lokhttp3/Cache;',
-  );
-
-  static final _cache = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.Cache cache()`
-  /// The returned object must be released after use, by calling the [release] method.
-  Cache? cache() {
-    return _cache(reference.pointer, _id_cache as jni$_.JMethodIDPtr)
-        .object<Cache?>(const $Cache$NullableType());
-  }
-
-  static final _id_dns = _class.instanceMethodId(
-    r'dns',
-    r'()Lokhttp3/Dns;',
-  );
-
-  static final _dns = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.Dns dns()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject dns() {
-    return _dns(reference.pointer, _id_dns as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_proxy = _class.instanceMethodId(
-    r'proxy',
-    r'()Ljava/net/Proxy;',
-  );
-
-  static final _proxy = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.net.Proxy proxy()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? proxy() {
-    return _proxy(reference.pointer, _id_proxy as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_proxySelector = _class.instanceMethodId(
-    r'proxySelector',
-    r'()Ljava/net/ProxySelector;',
-  );
-
-  static final _proxySelector = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.net.ProxySelector proxySelector()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject proxySelector() {
-    return _proxySelector(
-            reference.pointer, _id_proxySelector as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_proxyAuthenticator = _class.instanceMethodId(
-    r'proxyAuthenticator',
-    r'()Lokhttp3/Authenticator;',
-  );
-
-  static final _proxyAuthenticator = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.Authenticator proxyAuthenticator()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject proxyAuthenticator() {
-    return _proxyAuthenticator(
-            reference.pointer, _id_proxyAuthenticator as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_socketFactory = _class.instanceMethodId(
-    r'socketFactory',
-    r'()Ljavax/net/SocketFactory;',
-  );
-
-  static final _socketFactory = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.SocketFactory socketFactory()`
-  /// The returned object must be released after use, by calling the [release] method.
-  SocketFactory socketFactory() {
-    return _socketFactory(
-            reference.pointer, _id_socketFactory as jni$_.JMethodIDPtr)
-        .object<SocketFactory>(const $SocketFactory$Type());
-  }
-
-  static final _id_sslSocketFactory = _class.instanceMethodId(
-    r'sslSocketFactory',
-    r'()Ljavax/net/ssl/SSLSocketFactory;',
-  );
-
-  static final _sslSocketFactory = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.SSLSocketFactory sslSocketFactory()`
-  /// The returned object must be released after use, by calling the [release] method.
-  SSLSocketFactory sslSocketFactory() {
-    return _sslSocketFactory(
-            reference.pointer, _id_sslSocketFactory as jni$_.JMethodIDPtr)
-        .object<SSLSocketFactory>(const $SSLSocketFactory$Type());
-  }
-
-  static final _id_x509TrustManager = _class.instanceMethodId(
-    r'x509TrustManager',
-    r'()Ljavax/net/ssl/X509TrustManager;',
-  );
-
-  static final _x509TrustManager = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.X509TrustManager x509TrustManager()`
-  /// The returned object must be released after use, by calling the [release] method.
-  X509TrustManager? x509TrustManager() {
-    return _x509TrustManager(
-            reference.pointer, _id_x509TrustManager as jni$_.JMethodIDPtr)
-        .object<X509TrustManager?>(const $X509TrustManager$NullableType());
-  }
-
-  static final _id_connectionSpecs = _class.instanceMethodId(
-    r'connectionSpecs',
-    r'()Ljava/util/List;',
-  );
-
-  static final _connectionSpecs = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.util.List connectionSpecs()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JList<jni$_.JObject> connectionSpecs() {
-    return _connectionSpecs(
-            reference.pointer, _id_connectionSpecs as jni$_.JMethodIDPtr)
-        .object<jni$_.JList<jni$_.JObject>>(
-            const jni$_.JListType<jni$_.JObject>(jni$_.JObjectType()));
-  }
-
-  static final _id_protocols = _class.instanceMethodId(
-    r'protocols',
-    r'()Ljava/util/List;',
-  );
-
-  static final _protocols = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.util.List protocols()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JList<jni$_.JObject> protocols() {
-    return _protocols(reference.pointer, _id_protocols as jni$_.JMethodIDPtr)
-        .object<jni$_.JList<jni$_.JObject>>(
-            const jni$_.JListType<jni$_.JObject>(jni$_.JObjectType()));
-  }
-
-  static final _id_hostnameVerifier = _class.instanceMethodId(
-    r'hostnameVerifier',
-    r'()Ljavax/net/ssl/HostnameVerifier;',
-  );
-
-  static final _hostnameVerifier = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.HostnameVerifier hostnameVerifier()`
-  /// The returned object must be released after use, by calling the [release] method.
-  HostnameVerifier hostnameVerifier() {
-    return _hostnameVerifier(
-            reference.pointer, _id_hostnameVerifier as jni$_.JMethodIDPtr)
-        .object<HostnameVerifier>(const $HostnameVerifier$Type());
-  }
-
-  static final _id_certificatePinner = _class.instanceMethodId(
-    r'certificatePinner',
-    r'()Lokhttp3/CertificatePinner;',
-  );
-
-  static final _certificatePinner = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.CertificatePinner certificatePinner()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject certificatePinner() {
-    return _certificatePinner(
-            reference.pointer, _id_certificatePinner as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_certificateChainCleaner = _class.instanceMethodId(
-    r'certificateChainCleaner',
-    r'()Lokhttp3/internal/tls/CertificateChainCleaner;',
-  );
-
-  static final _certificateChainCleaner = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.internal.tls.CertificateChainCleaner certificateChainCleaner()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? certificateChainCleaner() {
-    return _certificateChainCleaner(reference.pointer,
-            _id_certificateChainCleaner as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_callTimeoutMillis = _class.instanceMethodId(
-    r'callTimeoutMillis',
-    r'()I',
-  );
-
-  static final _callTimeoutMillis = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int callTimeoutMillis()`
-  int callTimeoutMillis() {
-    return _callTimeoutMillis(
-            reference.pointer, _id_callTimeoutMillis as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_connectTimeoutMillis = _class.instanceMethodId(
-    r'connectTimeoutMillis',
-    r'()I',
-  );
-
-  static final _connectTimeoutMillis = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int connectTimeoutMillis()`
-  int connectTimeoutMillis() {
-    return _connectTimeoutMillis(
-            reference.pointer, _id_connectTimeoutMillis as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_readTimeoutMillis = _class.instanceMethodId(
-    r'readTimeoutMillis',
-    r'()I',
-  );
-
-  static final _readTimeoutMillis = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int readTimeoutMillis()`
-  int readTimeoutMillis() {
-    return _readTimeoutMillis(
-            reference.pointer, _id_readTimeoutMillis as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_writeTimeoutMillis = _class.instanceMethodId(
-    r'writeTimeoutMillis',
-    r'()I',
-  );
-
-  static final _writeTimeoutMillis = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int writeTimeoutMillis()`
-  int writeTimeoutMillis() {
-    return _writeTimeoutMillis(
-            reference.pointer, _id_writeTimeoutMillis as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_pingIntervalMillis = _class.instanceMethodId(
-    r'pingIntervalMillis',
-    r'()I',
-  );
-
-  static final _pingIntervalMillis = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int pingIntervalMillis()`
-  int pingIntervalMillis() {
-    return _pingIntervalMillis(
-            reference.pointer, _id_pingIntervalMillis as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_minWebSocketMessageToCompress = _class.instanceMethodId(
-    r'minWebSocketMessageToCompress',
-    r'()J',
-  );
-
-  static final _minWebSocketMessageToCompress =
-      jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                    jni$_.Pointer<jni$_.Void>,
-                    jni$_.JMethodIDPtr,
-                  )>>('globalEnv_CallLongMethod')
-          .asFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>();
-
-  /// from: `public final long minWebSocketMessageToCompress()`
-  int minWebSocketMessageToCompress() {
-    return _minWebSocketMessageToCompress(reference.pointer,
-            _id_minWebSocketMessageToCompress as jni$_.JMethodIDPtr)
-        .long;
-  }
-
-  static final _id_getRouteDatabase = _class.instanceMethodId(
-    r'getRouteDatabase',
-    r'()Lokhttp3/internal/connection/RouteDatabase;',
-  );
-
-  static final _getRouteDatabase = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.internal.connection.RouteDatabase getRouteDatabase()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject getRouteDatabase() {
-    return _getRouteDatabase(
-            reference.pointer, _id_getRouteDatabase as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
+    return _new$(_class.reference.pointer, _id_new$.pointer, _$builder.pointer)
+        .object<OkHttpClient>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -7162,12 +5495,736 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory OkHttpClient.new$1() {
-    return OkHttpClient.fromReference(
-        _new$1(_class.reference.pointer, _id_new$1 as jni$_.JMethodIDPtr)
-            .reference);
+    return _new$1(_class.reference.pointer, _id_new$1.pointer)
+        .object<OkHttpClient>();
+  }
+}
+
+extension OkHttpClient$$Methods on OkHttpClient {
+  static final _id_dispatcher = OkHttpClient._class.instanceMethodId(
+    r'dispatcher',
+    r'()Lokhttp3/Dispatcher;',
+  );
+
+  static final _dispatcher = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okhttp3.Dispatcher dispatcher()`
+  /// The returned object must be released after use, by calling the [release] method.
+  Dispatcher dispatcher() {
+    return _dispatcher(reference.pointer, _id_dispatcher.pointer)
+        .object<Dispatcher>();
   }
 
-  static final _id_newCall = _class.instanceMethodId(
+  static final _id_connectionPool = OkHttpClient._class.instanceMethodId(
+    r'connectionPool',
+    r'()Lokhttp3/ConnectionPool;',
+  );
+
+  static final _connectionPool = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okhttp3.ConnectionPool connectionPool()`
+  /// The returned object must be released after use, by calling the [release] method.
+  ConnectionPool connectionPool() {
+    return _connectionPool(reference.pointer, _id_connectionPool.pointer)
+        .object<ConnectionPool>();
+  }
+
+  static final _id_interceptors = OkHttpClient._class.instanceMethodId(
+    r'interceptors',
+    r'()Ljava/util/List;',
+  );
+
+  static final _interceptors = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.util.List<okhttp3.Interceptor> interceptors()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JList<jni$_.JObject> interceptors() {
+    return _interceptors(reference.pointer, _id_interceptors.pointer)
+        .object<jni$_.JList<jni$_.JObject>>();
+  }
+
+  static final _id_networkInterceptors = OkHttpClient._class.instanceMethodId(
+    r'networkInterceptors',
+    r'()Ljava/util/List;',
+  );
+
+  static final _networkInterceptors = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.util.List<okhttp3.Interceptor> networkInterceptors()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JList<jni$_.JObject> networkInterceptors() {
+    return _networkInterceptors(
+            reference.pointer, _id_networkInterceptors.pointer)
+        .object<jni$_.JList<jni$_.JObject>>();
+  }
+
+  static final _id_eventListenerFactory = OkHttpClient._class.instanceMethodId(
+    r'eventListenerFactory',
+    r'()Lokhttp3/EventListener$Factory;',
+  );
+
+  static final _eventListenerFactory = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okhttp3.EventListener$Factory eventListenerFactory()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject eventListenerFactory() {
+    return _eventListenerFactory(
+            reference.pointer, _id_eventListenerFactory.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_retryOnConnectionFailure =
+      OkHttpClient._class.instanceMethodId(
+    r'retryOnConnectionFailure',
+    r'()Z',
+  );
+
+  static final _retryOnConnectionFailure = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final boolean retryOnConnectionFailure()`
+  core$_.bool retryOnConnectionFailure() {
+    return _retryOnConnectionFailure(
+            reference.pointer, _id_retryOnConnectionFailure.pointer)
+        .boolean;
+  }
+
+  static final _id_authenticator = OkHttpClient._class.instanceMethodId(
+    r'authenticator',
+    r'()Lokhttp3/Authenticator;',
+  );
+
+  static final _authenticator = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okhttp3.Authenticator authenticator()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject authenticator() {
+    return _authenticator(reference.pointer, _id_authenticator.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_followRedirects = OkHttpClient._class.instanceMethodId(
+    r'followRedirects',
+    r'()Z',
+  );
+
+  static final _followRedirects = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final boolean followRedirects()`
+  core$_.bool followRedirects() {
+    return _followRedirects(reference.pointer, _id_followRedirects.pointer)
+        .boolean;
+  }
+
+  static final _id_followSslRedirects = OkHttpClient._class.instanceMethodId(
+    r'followSslRedirects',
+    r'()Z',
+  );
+
+  static final _followSslRedirects = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final boolean followSslRedirects()`
+  core$_.bool followSslRedirects() {
+    return _followSslRedirects(
+            reference.pointer, _id_followSslRedirects.pointer)
+        .boolean;
+  }
+
+  static final _id_cookieJar = OkHttpClient._class.instanceMethodId(
+    r'cookieJar',
+    r'()Lokhttp3/CookieJar;',
+  );
+
+  static final _cookieJar = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okhttp3.CookieJar cookieJar()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject cookieJar() {
+    return _cookieJar(reference.pointer, _id_cookieJar.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_cache = OkHttpClient._class.instanceMethodId(
+    r'cache',
+    r'()Lokhttp3/Cache;',
+  );
+
+  static final _cache = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okhttp3.Cache cache()`
+  /// The returned object must be released after use, by calling the [release] method.
+  Cache? cache() {
+    return _cache(reference.pointer, _id_cache.pointer).object<Cache?>();
+  }
+
+  static final _id_dns = OkHttpClient._class.instanceMethodId(
+    r'dns',
+    r'()Lokhttp3/Dns;',
+  );
+
+  static final _dns = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okhttp3.Dns dns()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject dns() {
+    return _dns(reference.pointer, _id_dns.pointer).object<jni$_.JObject>();
+  }
+
+  static final _id_proxy = OkHttpClient._class.instanceMethodId(
+    r'proxy',
+    r'()Ljava/net/Proxy;',
+  );
+
+  static final _proxy = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.net.Proxy proxy()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? proxy() {
+    return _proxy(reference.pointer, _id_proxy.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_proxySelector = OkHttpClient._class.instanceMethodId(
+    r'proxySelector',
+    r'()Ljava/net/ProxySelector;',
+  );
+
+  static final _proxySelector = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.net.ProxySelector proxySelector()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject proxySelector() {
+    return _proxySelector(reference.pointer, _id_proxySelector.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_proxyAuthenticator = OkHttpClient._class.instanceMethodId(
+    r'proxyAuthenticator',
+    r'()Lokhttp3/Authenticator;',
+  );
+
+  static final _proxyAuthenticator = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okhttp3.Authenticator proxyAuthenticator()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject proxyAuthenticator() {
+    return _proxyAuthenticator(
+            reference.pointer, _id_proxyAuthenticator.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_socketFactory = OkHttpClient._class.instanceMethodId(
+    r'socketFactory',
+    r'()Ljavax/net/SocketFactory;',
+  );
+
+  static final _socketFactory = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.SocketFactory socketFactory()`
+  /// The returned object must be released after use, by calling the [release] method.
+  SocketFactory socketFactory() {
+    return _socketFactory(reference.pointer, _id_socketFactory.pointer)
+        .object<SocketFactory>();
+  }
+
+  static final _id_sslSocketFactory = OkHttpClient._class.instanceMethodId(
+    r'sslSocketFactory',
+    r'()Ljavax/net/ssl/SSLSocketFactory;',
+  );
+
+  static final _sslSocketFactory = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.ssl.SSLSocketFactory sslSocketFactory()`
+  /// The returned object must be released after use, by calling the [release] method.
+  SSLSocketFactory sslSocketFactory() {
+    return _sslSocketFactory(reference.pointer, _id_sslSocketFactory.pointer)
+        .object<SSLSocketFactory>();
+  }
+
+  static final _id_x509TrustManager = OkHttpClient._class.instanceMethodId(
+    r'x509TrustManager',
+    r'()Ljavax/net/ssl/X509TrustManager;',
+  );
+
+  static final _x509TrustManager = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.ssl.X509TrustManager x509TrustManager()`
+  /// The returned object must be released after use, by calling the [release] method.
+  X509TrustManager? x509TrustManager() {
+    return _x509TrustManager(reference.pointer, _id_x509TrustManager.pointer)
+        .object<X509TrustManager?>();
+  }
+
+  static final _id_connectionSpecs = OkHttpClient._class.instanceMethodId(
+    r'connectionSpecs',
+    r'()Ljava/util/List;',
+  );
+
+  static final _connectionSpecs = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.util.List<okhttp3.ConnectionSpec> connectionSpecs()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JList<jni$_.JObject> connectionSpecs() {
+    return _connectionSpecs(reference.pointer, _id_connectionSpecs.pointer)
+        .object<jni$_.JList<jni$_.JObject>>();
+  }
+
+  static final _id_protocols = OkHttpClient._class.instanceMethodId(
+    r'protocols',
+    r'()Ljava/util/List;',
+  );
+
+  static final _protocols = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.util.List<okhttp3.Protocol> protocols()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JList<jni$_.JObject> protocols() {
+    return _protocols(reference.pointer, _id_protocols.pointer)
+        .object<jni$_.JList<jni$_.JObject>>();
+  }
+
+  static final _id_hostnameVerifier = OkHttpClient._class.instanceMethodId(
+    r'hostnameVerifier',
+    r'()Ljavax/net/ssl/HostnameVerifier;',
+  );
+
+  static final _hostnameVerifier = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.ssl.HostnameVerifier hostnameVerifier()`
+  /// The returned object must be released after use, by calling the [release] method.
+  HostnameVerifier hostnameVerifier() {
+    return _hostnameVerifier(reference.pointer, _id_hostnameVerifier.pointer)
+        .object<HostnameVerifier>();
+  }
+
+  static final _id_certificatePinner = OkHttpClient._class.instanceMethodId(
+    r'certificatePinner',
+    r'()Lokhttp3/CertificatePinner;',
+  );
+
+  static final _certificatePinner = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okhttp3.CertificatePinner certificatePinner()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject certificatePinner() {
+    return _certificatePinner(reference.pointer, _id_certificatePinner.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_certificateChainCleaner =
+      OkHttpClient._class.instanceMethodId(
+    r'certificateChainCleaner',
+    r'()Lokhttp3/internal/tls/CertificateChainCleaner;',
+  );
+
+  static final _certificateChainCleaner = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okhttp3.internal.tls.CertificateChainCleaner certificateChainCleaner()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? certificateChainCleaner() {
+    return _certificateChainCleaner(
+            reference.pointer, _id_certificateChainCleaner.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_callTimeoutMillis = OkHttpClient._class.instanceMethodId(
+    r'callTimeoutMillis',
+    r'()I',
+  );
+
+  static final _callTimeoutMillis = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final int callTimeoutMillis()`
+  core$_.int callTimeoutMillis() {
+    return _callTimeoutMillis(reference.pointer, _id_callTimeoutMillis.pointer)
+        .integer;
+  }
+
+  static final _id_connectTimeoutMillis = OkHttpClient._class.instanceMethodId(
+    r'connectTimeoutMillis',
+    r'()I',
+  );
+
+  static final _connectTimeoutMillis = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final int connectTimeoutMillis()`
+  core$_.int connectTimeoutMillis() {
+    return _connectTimeoutMillis(
+            reference.pointer, _id_connectTimeoutMillis.pointer)
+        .integer;
+  }
+
+  static final _id_readTimeoutMillis = OkHttpClient._class.instanceMethodId(
+    r'readTimeoutMillis',
+    r'()I',
+  );
+
+  static final _readTimeoutMillis = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final int readTimeoutMillis()`
+  core$_.int readTimeoutMillis() {
+    return _readTimeoutMillis(reference.pointer, _id_readTimeoutMillis.pointer)
+        .integer;
+  }
+
+  static final _id_writeTimeoutMillis = OkHttpClient._class.instanceMethodId(
+    r'writeTimeoutMillis',
+    r'()I',
+  );
+
+  static final _writeTimeoutMillis = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final int writeTimeoutMillis()`
+  core$_.int writeTimeoutMillis() {
+    return _writeTimeoutMillis(
+            reference.pointer, _id_writeTimeoutMillis.pointer)
+        .integer;
+  }
+
+  static final _id_pingIntervalMillis = OkHttpClient._class.instanceMethodId(
+    r'pingIntervalMillis',
+    r'()I',
+  );
+
+  static final _pingIntervalMillis = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final int pingIntervalMillis()`
+  core$_.int pingIntervalMillis() {
+    return _pingIntervalMillis(
+            reference.pointer, _id_pingIntervalMillis.pointer)
+        .integer;
+  }
+
+  static final _id_minWebSocketMessageToCompress =
+      OkHttpClient._class.instanceMethodId(
+    r'minWebSocketMessageToCompress',
+    r'()J',
+  );
+
+  static final _minWebSocketMessageToCompress =
+      jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                    jni$_.Pointer<jni$_.Void>,
+                    jni$_.JMethodIDPtr,
+                  )>>('globalEnv_CallLongMethod')
+          .asFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>();
+
+  /// from: `public final long minWebSocketMessageToCompress()`
+  core$_.int minWebSocketMessageToCompress() {
+    return _minWebSocketMessageToCompress(
+            reference.pointer, _id_minWebSocketMessageToCompress.pointer)
+        .long;
+  }
+
+  static final _id_get$routeDatabase = OkHttpClient._class.instanceMethodId(
+    r'getRouteDatabase',
+    r'()Lokhttp3/internal/connection/RouteDatabase;',
+  );
+
+  static final _get$routeDatabase = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okhttp3.internal.connection.RouteDatabase getRouteDatabase()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject get routeDatabase {
+    return _get$routeDatabase(reference.pointer, _id_get$routeDatabase.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_newCall = OkHttpClient._class.instanceMethodId(
     r'newCall',
     r'(Lokhttp3/Request;)Lokhttp3/Call;',
   );
@@ -7183,18 +6240,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.Call newCall(okhttp3.Request request)`
+  /// from: `public fun newCall(request: okhttp3.Request): okhttp3.Call`
   /// The returned object must be released after use, by calling the [release] method.
   Call newCall(
     Request request,
   ) {
     final _$request = request.reference;
-    return _newCall(reference.pointer, _id_newCall as jni$_.JMethodIDPtr,
-            _$request.pointer)
-        .object<Call>(const $Call$Type());
+    return _newCall(reference.pointer, _id_newCall.pointer, _$request.pointer)
+        .object<Call>();
   }
 
-  static final _id_newWebSocket = _class.instanceMethodId(
+  static final _id_newWebSocket = OkHttpClient._class.instanceMethodId(
     r'newWebSocket',
     r'(Lokhttp3/Request;Lokhttp3/WebSocketListener;)Lokhttp3/WebSocket;',
   );
@@ -7216,7 +6272,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public okhttp3.WebSocket newWebSocket(okhttp3.Request request, okhttp3.WebSocketListener webSocketListener)`
+  /// from: `public fun newWebSocket(request: okhttp3.Request, listener: okhttp3.WebSocketListener): okhttp3.WebSocket`
   /// The returned object must be released after use, by calling the [release] method.
   WebSocket newWebSocket(
     Request request,
@@ -7224,15 +6280,12 @@
   ) {
     final _$request = request.reference;
     final _$webSocketListener = webSocketListener.reference;
-    return _newWebSocket(
-            reference.pointer,
-            _id_newWebSocket as jni$_.JMethodIDPtr,
-            _$request.pointer,
-            _$webSocketListener.pointer)
-        .object<WebSocket>(const $WebSocket$Type());
+    return _newWebSocket(reference.pointer, _id_newWebSocket.pointer,
+            _$request.pointer, _$webSocketListener.pointer)
+        .object<WebSocket>();
   }
 
-  static final _id_newBuilder = _class.instanceMethodId(
+  static final _id_newBuilder = OkHttpClient._class.instanceMethodId(
     r'newBuilder',
     r'()Lokhttp3/OkHttpClient$Builder;',
   );
@@ -7249,14 +6302,14 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public okhttp3.OkHttpClient$Builder newBuilder()`
+  /// from: `public fun newBuilder(): okhttp3.OkHttpClient.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   OkHttpClient$Builder newBuilder() {
-    return _newBuilder(reference.pointer, _id_newBuilder as jni$_.JMethodIDPtr)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    return _newBuilder(reference.pointer, _id_newBuilder.pointer)
+        .object<OkHttpClient$Builder>();
   }
 
-  static final _id_clone = _class.instanceMethodId(
+  static final _id_clone = OkHttpClient._class.instanceMethodId(
     r'clone',
     r'()Ljava/lang/Object;',
   );
@@ -7276,133 +6329,30 @@
   /// from: `public java.lang.Object clone()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject clone() {
-    return _clone(reference.pointer, _id_clone as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
+    return _clone(reference.pointer, _id_clone.pointer).object<jni$_.JObject>();
   }
 }
 
-final class $OkHttpClient$NullableType extends jni$_.JObjType<OkHttpClient?> {
+final class $OkHttpClient$Type$ extends jni$_.JType<OkHttpClient> {
   @jni$_.internal
-  const $OkHttpClient$NullableType();
+  const $OkHttpClient$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/OkHttpClient;';
-
-  @jni$_.internal
-  @core$_.override
-  OkHttpClient? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : OkHttpClient.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<OkHttpClient?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($OkHttpClient$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($OkHttpClient$NullableType) &&
-        other is $OkHttpClient$NullableType;
-  }
-}
-
-final class $OkHttpClient$Type extends jni$_.JObjType<OkHttpClient> {
-  @jni$_.internal
-  const $OkHttpClient$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/OkHttpClient;';
-
-  @jni$_.internal
-  @core$_.override
-  OkHttpClient fromReference(jni$_.JReference reference) =>
-      OkHttpClient.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<OkHttpClient?> get nullableType =>
-      const $OkHttpClient$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($OkHttpClient$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($OkHttpClient$Type) &&
-        other is $OkHttpClient$Type;
-  }
 }
 
 /// from: `okhttp3.Call$Factory`
-class Call$Factory extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Call$Factory> $type;
-
-  @jni$_.internal
-  Call$Factory.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Call$Factory._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Call$Factory');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Call$Factory$NullableType();
-  static const type = $Call$Factory$Type();
-  static final _id_newCall = _class.instanceMethodId(
-    r'newCall',
-    r'(Lokhttp3/Request;)Lokhttp3/Call;',
-  );
-
-  static final _newCall = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract okhttp3.Call newCall(okhttp3.Request request)`
-  /// The returned object must be released after use, by calling the [release] method.
-  Call newCall(
-    Request request,
-  ) {
-    final _$request = request.reference;
-    return _newCall(reference.pointer, _id_newCall as jni$_.JMethodIDPtr,
-            _$request.pointer)
-        .object<Call>(const $Call$Type());
-  }
+  static const jni$_.JType<Call$Factory> type = $Call$Factory$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $Call$Factory> _$impls = {};
+  static final core$_.Map<core$_.int, $Call$Factory> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -7423,7 +6373,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -7431,10 +6381,10 @@
       final $a = $i.args;
       if ($d == r'newCall(Lokhttp3/Request;)Lokhttp3/Call;') {
         final $r = _$impls[$p]!.newCall(
-          $a![0]!.as(const $Request$Type(), releaseOriginal: true),
+          ($a![0] as Request),
         );
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -7475,9 +6425,35 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return Call$Factory.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<Call$Factory>();
+  }
+}
+
+extension Call$Factory$$Methods on Call$Factory {
+  static final _id_newCall = Call$Factory._class.instanceMethodId(
+    r'newCall',
+    r'(Lokhttp3/Request;)Lokhttp3/Call;',
+  );
+
+  static final _newCall = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun newCall(request: okhttp3.Request): okhttp3.Call`
+  /// The returned object must be released after use, by calling the [release] method.
+  Call newCall(
+    Request request,
+  ) {
+    final _$request = request.reference;
+    return _newCall(reference.pointer, _id_newCall.pointer, _$request.pointer)
+        .object<Call>();
   }
 }
 
@@ -7501,291 +6477,26 @@
   }
 }
 
-final class $Call$Factory$NullableType extends jni$_.JObjType<Call$Factory?> {
+final class $Call$Factory$Type$ extends jni$_.JType<Call$Factory> {
   @jni$_.internal
-  const $Call$Factory$NullableType();
+  const $Call$Factory$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Call$Factory;';
-
-  @jni$_.internal
-  @core$_.override
-  Call$Factory? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Call$Factory.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Call$Factory?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Call$Factory$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Call$Factory$NullableType) &&
-        other is $Call$Factory$NullableType;
-  }
-}
-
-final class $Call$Factory$Type extends jni$_.JObjType<Call$Factory> {
-  @jni$_.internal
-  const $Call$Factory$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Call$Factory;';
-
-  @jni$_.internal
-  @core$_.override
-  Call$Factory fromReference(jni$_.JReference reference) =>
-      Call$Factory.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Call$Factory?> get nullableType =>
-      const $Call$Factory$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Call$Factory$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Call$Factory$Type) &&
-        other is $Call$Factory$Type;
-  }
 }
 
 /// from: `okhttp3.Call`
-class Call extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Call> $type;
-
-  @jni$_.internal
-  Call.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Call._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Call');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Call$NullableType();
-  static const type = $Call$Type();
-  static final _id_request = _class.instanceMethodId(
-    r'request',
-    r'()Lokhttp3/Request;',
-  );
-
-  static final _request = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract okhttp3.Request request()`
-  /// The returned object must be released after use, by calling the [release] method.
-  Request request() {
-    return _request(reference.pointer, _id_request as jni$_.JMethodIDPtr)
-        .object<Request>(const $Request$Type());
-  }
-
-  static final _id_execute = _class.instanceMethodId(
-    r'execute',
-    r'()Lokhttp3/Response;',
-  );
-
-  static final _execute = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract okhttp3.Response execute()`
-  /// The returned object must be released after use, by calling the [release] method.
-  Response execute() {
-    return _execute(reference.pointer, _id_execute as jni$_.JMethodIDPtr)
-        .object<Response>(const $Response$Type());
-  }
-
-  static final _id_enqueue = _class.instanceMethodId(
-    r'enqueue',
-    r'(Lokhttp3/Callback;)V',
-  );
-
-  static final _enqueue = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void enqueue(okhttp3.Callback callback)`
-  void enqueue(
-    Callback callback,
-  ) {
-    final _$callback = callback.reference;
-    _enqueue(reference.pointer, _id_enqueue as jni$_.JMethodIDPtr,
-            _$callback.pointer)
-        .check();
-  }
-
-  static final _id_cancel = _class.instanceMethodId(
-    r'cancel',
-    r'()V',
-  );
-
-  static final _cancel = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract void cancel()`
-  void cancel() {
-    _cancel(reference.pointer, _id_cancel as jni$_.JMethodIDPtr).check();
-  }
-
-  static final _id_isExecuted = _class.instanceMethodId(
-    r'isExecuted',
-    r'()Z',
-  );
-
-  static final _isExecuted = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract boolean isExecuted()`
-  bool isExecuted() {
-    return _isExecuted(reference.pointer, _id_isExecuted as jni$_.JMethodIDPtr)
-        .boolean;
-  }
-
-  static final _id_isCanceled = _class.instanceMethodId(
-    r'isCanceled',
-    r'()Z',
-  );
-
-  static final _isCanceled = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract boolean isCanceled()`
-  bool isCanceled() {
-    return _isCanceled(reference.pointer, _id_isCanceled as jni$_.JMethodIDPtr)
-        .boolean;
-  }
-
-  static final _id_timeout = _class.instanceMethodId(
-    r'timeout',
-    r'()Lokio/Timeout;',
-  );
-
-  static final _timeout = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract okio.Timeout timeout()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject timeout() {
-    return _timeout(reference.pointer, _id_timeout as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_clone = _class.instanceMethodId(
-    r'clone',
-    r'()Lokhttp3/Call;',
-  );
-
-  static final _clone = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract okhttp3.Call clone()`
-  /// The returned object must be released after use, by calling the [release] method.
-  Call clone() {
-    return _clone(reference.pointer, _id_clone as jni$_.JMethodIDPtr)
-        .object<Call>(const $Call$Type());
-  }
+  static const jni$_.JType<Call> type = $Call$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $Call> _$impls = {};
+  static final core$_.Map<core$_.int, $Call> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -7806,7 +6517,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -7815,7 +6526,7 @@
       if ($d == r'request()Lokhttp3/Request;') {
         final $r = _$impls[$p]!.request();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -7823,14 +6534,14 @@
       if ($d == r'execute()Lokhttp3/Response;') {
         final $r = _$impls[$p]!.execute();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
       }
       if ($d == r'enqueue(Lokhttp3/Callback;)V') {
         _$impls[$p]!.enqueue(
-          $a![0]!.as(const $Callback$Type(), releaseOriginal: true),
+          ($a![0] as Callback),
         );
         return jni$_.nullptr;
       }
@@ -7840,16 +6551,16 @@
       }
       if ($d == r'isExecuted()Z') {
         final $r = _$impls[$p]!.isExecuted();
-        return jni$_.JBoolean($r).reference.toPointer();
+        return $r.toJBoolean().reference.toPointer();
       }
       if ($d == r'isCanceled()Z') {
         final $r = _$impls[$p]!.isCanceled();
-        return jni$_.JBoolean($r).reference.toPointer();
+        return $r.toJBoolean().reference.toPointer();
       }
       if ($d == r'timeout()Lokio/Timeout;') {
         final $r = _$impls[$p]!.timeout();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -7857,7 +6568,7 @@
       if ($d == r'clone()Lokhttp3/Call;') {
         final $r = _$impls[$p]!.clone();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -7901,9 +6612,193 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return Call.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<Call>();
+  }
+}
+
+extension Call$$Methods on Call {
+  static final _id_request = Call._class.instanceMethodId(
+    r'request',
+    r'()Lokhttp3/Request;',
+  );
+
+  static final _request = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun request(): okhttp3.Request`
+  /// The returned object must be released after use, by calling the [release] method.
+  Request request() {
+    return _request(reference.pointer, _id_request.pointer).object<Request>();
+  }
+
+  static final _id_execute = Call._class.instanceMethodId(
+    r'execute',
+    r'()Lokhttp3/Response;',
+  );
+
+  static final _execute = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun execute(): okhttp3.Response`
+  /// The returned object must be released after use, by calling the [release] method.
+  Response execute() {
+    return _execute(reference.pointer, _id_execute.pointer).object<Response>();
+  }
+
+  static final _id_enqueue = Call._class.instanceMethodId(
+    r'enqueue',
+    r'(Lokhttp3/Callback;)V',
+  );
+
+  static final _enqueue = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun enqueue(responseCallback: okhttp3.Callback): kotlin.Unit`
+  void enqueue(
+    Callback callback,
+  ) {
+    final _$callback = callback.reference;
+    _enqueue(reference.pointer, _id_enqueue.pointer, _$callback.pointer)
+        .check();
+  }
+
+  static final _id_cancel = Call._class.instanceMethodId(
+    r'cancel',
+    r'()V',
+  );
+
+  static final _cancel = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun cancel(): kotlin.Unit`
+  void cancel() {
+    _cancel(reference.pointer, _id_cancel.pointer).check();
+  }
+
+  static final _id_isExecuted = Call._class.instanceMethodId(
+    r'isExecuted',
+    r'()Z',
+  );
+
+  static final _isExecuted = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun isExecuted(): kotlin.Boolean`
+  core$_.bool isExecuted() {
+    return _isExecuted(reference.pointer, _id_isExecuted.pointer).boolean;
+  }
+
+  static final _id_isCanceled = Call._class.instanceMethodId(
+    r'isCanceled',
+    r'()Z',
+  );
+
+  static final _isCanceled = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun isCanceled(): kotlin.Boolean`
+  core$_.bool isCanceled() {
+    return _isCanceled(reference.pointer, _id_isCanceled.pointer).boolean;
+  }
+
+  static final _id_timeout = Call._class.instanceMethodId(
+    r'timeout',
+    r'()Lokio/Timeout;',
+  );
+
+  static final _timeout = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun timeout(): okio.Timeout`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject timeout() {
+    return _timeout(reference.pointer, _id_timeout.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_clone = Call._class.instanceMethodId(
+    r'clone',
+    r'()Lokhttp3/Call;',
+  );
+
+  static final _clone = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun clone(): okhttp3.Call`
+  /// The returned object must be released after use, by calling the [release] method.
+  Call clone() {
+    return _clone(reference.pointer, _id_clone.pointer).object<Call>();
   }
 }
 
@@ -7912,11 +6807,11 @@
     required Request Function() request,
     required Response Function() execute,
     required void Function(Callback callback) enqueue,
-    bool enqueue$async,
+    core$_.bool enqueue$async,
     required void Function() cancel,
-    bool cancel$async,
-    required bool Function() isExecuted,
-    required bool Function() isCanceled,
+    core$_.bool cancel$async,
+    required core$_.bool Function() isExecuted,
+    required core$_.bool Function() isCanceled,
     required jni$_.JObject Function() timeout,
     required Call Function() clone,
   }) = _$Call;
@@ -7924,11 +6819,11 @@
   Request request();
   Response execute();
   void enqueue(Callback callback);
-  bool get enqueue$async => false;
+  core$_.bool get enqueue$async => false;
   void cancel();
-  bool get cancel$async => false;
-  bool isExecuted();
-  bool isCanceled();
+  core$_.bool get cancel$async => false;
+  core$_.bool isExecuted();
+  core$_.bool isCanceled();
   jni$_.JObject timeout();
   Call clone();
 }
@@ -7941,8 +6836,8 @@
     this.enqueue$async = false,
     required void Function() cancel,
     this.cancel$async = false,
-    required bool Function() isExecuted,
-    required bool Function() isCanceled,
+    required core$_.bool Function() isExecuted,
+    required core$_.bool Function() isCanceled,
     required jni$_.JObject Function() timeout,
     required Call Function() clone,
   })  : _request = request,
@@ -7957,11 +6852,11 @@
   final Request Function() _request;
   final Response Function() _execute;
   final void Function(Callback callback) _enqueue;
-  final bool enqueue$async;
+  final core$_.bool enqueue$async;
   final void Function() _cancel;
-  final bool cancel$async;
-  final bool Function() _isExecuted;
-  final bool Function() _isCanceled;
+  final core$_.bool cancel$async;
+  final core$_.bool Function() _isExecuted;
+  final core$_.bool Function() _isCanceled;
   final jni$_.JObject Function() _timeout;
   final Call Function() _clone;
 
@@ -7981,11 +6876,11 @@
     return _cancel();
   }
 
-  bool isExecuted() {
+  core$_.bool isExecuted() {
     return _isExecuted();
   }
 
-  bool isCanceled() {
+  core$_.bool isCanceled() {
     return _isCanceled();
   }
 
@@ -7998,94 +6893,22 @@
   }
 }
 
-final class $Call$NullableType extends jni$_.JObjType<Call?> {
+final class $Call$Type$ extends jni$_.JType<Call> {
   @jni$_.internal
-  const $Call$NullableType();
+  const $Call$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Call;';
-
-  @jni$_.internal
-  @core$_.override
-  Call? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Call.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Call?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Call$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Call$NullableType) &&
-        other is $Call$NullableType;
-  }
-}
-
-final class $Call$Type extends jni$_.JObjType<Call> {
-  @jni$_.internal
-  const $Call$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Call;';
-
-  @jni$_.internal
-  @core$_.override
-  Call fromReference(jni$_.JReference reference) => Call.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Call?> get nullableType => const $Call$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Call$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Call$Type) && other is $Call$Type;
-  }
 }
 
 /// from: `okhttp3.Headers$Builder`
-class Headers$Builder extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Headers$Builder> $type;
-
-  @jni$_.internal
-  Headers$Builder.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Headers$Builder._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Headers$Builder');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Headers$Builder$NullableType();
-  static const type = $Headers$Builder$Type();
+  static const jni$_.JType<Headers$Builder> type = $Headers$Builder$Type$();
   static final _id_new$ = _class.constructorId(
     r'()V',
   );
@@ -8105,12 +6928,13 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory Headers$Builder() {
-    return Headers$Builder.fromReference(
-        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
-            .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer)
+        .object<Headers$Builder>();
   }
+}
 
-  static final _id_add = _class.instanceMethodId(
+extension Headers$Builder$$Methods on Headers$Builder {
+  static final _id_add = Headers$Builder._class.instanceMethodId(
     r'add',
     r'(Ljava/lang/String;)Lokhttp3/Headers$Builder;',
   );
@@ -8126,18 +6950,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.Headers$Builder add(java.lang.String string)`
+  /// from: `public fun add(line: kotlin.String): okhttp3.Headers.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Headers$Builder add(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _add(
-            reference.pointer, _id_add as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<Headers$Builder>(const $Headers$Builder$Type());
+    return _add(reference.pointer, _id_add.pointer, _$string.pointer)
+        .object<Headers$Builder>();
   }
 
-  static final _id_add$1 = _class.instanceMethodId(
+  static final _id_add$1 = Headers$Builder._class.instanceMethodId(
     r'add',
     r'(Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Headers$Builder;',
   );
@@ -8159,7 +6982,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.Headers$Builder add(java.lang.String string, java.lang.String string1)`
+  /// from: `public fun add(name: kotlin.String, value: kotlin.String): okhttp3.Headers.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Headers$Builder add$1(
     jni$_.JString string,
@@ -8167,12 +6990,12 @@
   ) {
     final _$string = string.reference;
     final _$string1 = string1.reference;
-    return _add$1(reference.pointer, _id_add$1 as jni$_.JMethodIDPtr,
-            _$string.pointer, _$string1.pointer)
-        .object<Headers$Builder>(const $Headers$Builder$Type());
+    return _add$1(reference.pointer, _id_add$1.pointer, _$string.pointer,
+            _$string1.pointer)
+        .object<Headers$Builder>();
   }
 
-  static final _id_addUnsafeNonAscii = _class.instanceMethodId(
+  static final _id_addUnsafeNonAscii = Headers$Builder._class.instanceMethodId(
     r'addUnsafeNonAscii',
     r'(Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Headers$Builder;',
   );
@@ -8194,7 +7017,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.Headers$Builder addUnsafeNonAscii(java.lang.String string, java.lang.String string1)`
+  /// from: `public fun addUnsafeNonAscii(name: kotlin.String, value: kotlin.String): okhttp3.Headers.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Headers$Builder addUnsafeNonAscii(
     jni$_.JString string,
@@ -8202,15 +7025,12 @@
   ) {
     final _$string = string.reference;
     final _$string1 = string1.reference;
-    return _addUnsafeNonAscii(
-            reference.pointer,
-            _id_addUnsafeNonAscii as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$string1.pointer)
-        .object<Headers$Builder>(const $Headers$Builder$Type());
+    return _addUnsafeNonAscii(reference.pointer, _id_addUnsafeNonAscii.pointer,
+            _$string.pointer, _$string1.pointer)
+        .object<Headers$Builder>();
   }
 
-  static final _id_addAll = _class.instanceMethodId(
+  static final _id_addAll = Headers$Builder._class.instanceMethodId(
     r'addAll',
     r'(Lokhttp3/Headers;)Lokhttp3/Headers$Builder;',
   );
@@ -8226,18 +7046,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.Headers$Builder addAll(okhttp3.Headers headers)`
+  /// from: `public fun addAll(headers: okhttp3.Headers): okhttp3.Headers.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Headers$Builder addAll(
     Headers headers,
   ) {
     final _$headers = headers.reference;
-    return _addAll(reference.pointer, _id_addAll as jni$_.JMethodIDPtr,
-            _$headers.pointer)
-        .object<Headers$Builder>(const $Headers$Builder$Type());
+    return _addAll(reference.pointer, _id_addAll.pointer, _$headers.pointer)
+        .object<Headers$Builder>();
   }
 
-  static final _id_add$2 = _class.instanceMethodId(
+  static final _id_add$2 = Headers$Builder._class.instanceMethodId(
     r'add',
     r'(Ljava/lang/String;Ljava/util/Date;)Lokhttp3/Headers$Builder;',
   );
@@ -8259,7 +7078,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.Headers$Builder add(java.lang.String string, java.util.Date date)`
+  /// from: `public fun add(name: kotlin.String, value: java.util.Date): okhttp3.Headers.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Headers$Builder add$2(
     jni$_.JString string,
@@ -8267,12 +7086,12 @@
   ) {
     final _$string = string.reference;
     final _$date = date.reference;
-    return _add$2(reference.pointer, _id_add$2 as jni$_.JMethodIDPtr,
-            _$string.pointer, _$date.pointer)
-        .object<Headers$Builder>(const $Headers$Builder$Type());
+    return _add$2(reference.pointer, _id_add$2.pointer, _$string.pointer,
+            _$date.pointer)
+        .object<Headers$Builder>();
   }
 
-  static final _id_add$3 = _class.instanceMethodId(
+  static final _id_add$3 = Headers$Builder._class.instanceMethodId(
     r'add',
     r'(Ljava/lang/String;Ljava/time/Instant;)Lokhttp3/Headers$Builder;',
   );
@@ -8294,7 +7113,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.Headers$Builder add(java.lang.String string, java.time.Instant instant)`
+  /// from: `public fun add(name: kotlin.String, value: java.time.Instant): okhttp3.Headers.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Headers$Builder add$3(
     jni$_.JString string,
@@ -8302,12 +7121,12 @@
   ) {
     final _$string = string.reference;
     final _$instant = instant.reference;
-    return _add$3(reference.pointer, _id_add$3 as jni$_.JMethodIDPtr,
-            _$string.pointer, _$instant.pointer)
-        .object<Headers$Builder>(const $Headers$Builder$Type());
+    return _add$3(reference.pointer, _id_add$3.pointer, _$string.pointer,
+            _$instant.pointer)
+        .object<Headers$Builder>();
   }
 
-  static final _id_set = _class.instanceMethodId(
+  static final _id_set = Headers$Builder._class.instanceMethodId(
     r'set',
     r'(Ljava/lang/String;Ljava/util/Date;)Lokhttp3/Headers$Builder;',
   );
@@ -8329,7 +7148,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.Headers$Builder set(java.lang.String string, java.util.Date date)`
+  /// from: `public operator fun set(name: kotlin.String, value: java.util.Date): okhttp3.Headers.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Headers$Builder set(
     jni$_.JString string,
@@ -8337,12 +7156,12 @@
   ) {
     final _$string = string.reference;
     final _$date = date.reference;
-    return _set(reference.pointer, _id_set as jni$_.JMethodIDPtr,
-            _$string.pointer, _$date.pointer)
-        .object<Headers$Builder>(const $Headers$Builder$Type());
+    return _set(reference.pointer, _id_set.pointer, _$string.pointer,
+            _$date.pointer)
+        .object<Headers$Builder>();
   }
 
-  static final _id_set$1 = _class.instanceMethodId(
+  static final _id_set$1 = Headers$Builder._class.instanceMethodId(
     r'set',
     r'(Ljava/lang/String;Ljava/time/Instant;)Lokhttp3/Headers$Builder;',
   );
@@ -8364,7 +7183,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.Headers$Builder set(java.lang.String string, java.time.Instant instant)`
+  /// from: `public operator fun set(name: kotlin.String, value: java.time.Instant): okhttp3.Headers.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Headers$Builder set$1(
     jni$_.JString string,
@@ -8372,12 +7191,12 @@
   ) {
     final _$string = string.reference;
     final _$instant = instant.reference;
-    return _set$1(reference.pointer, _id_set$1 as jni$_.JMethodIDPtr,
-            _$string.pointer, _$instant.pointer)
-        .object<Headers$Builder>(const $Headers$Builder$Type());
+    return _set$1(reference.pointer, _id_set$1.pointer, _$string.pointer,
+            _$instant.pointer)
+        .object<Headers$Builder>();
   }
 
-  static final _id_removeAll = _class.instanceMethodId(
+  static final _id_removeAll = Headers$Builder._class.instanceMethodId(
     r'removeAll',
     r'(Ljava/lang/String;)Lokhttp3/Headers$Builder;',
   );
@@ -8393,18 +7212,18 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.Headers$Builder removeAll(java.lang.String string)`
+  /// from: `public fun removeAll(name: kotlin.String): okhttp3.Headers.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Headers$Builder removeAll(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _removeAll(reference.pointer, _id_removeAll as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<Headers$Builder>(const $Headers$Builder$Type());
+    return _removeAll(
+            reference.pointer, _id_removeAll.pointer, _$string.pointer)
+        .object<Headers$Builder>();
   }
 
-  static final _id_set$2 = _class.instanceMethodId(
+  static final _id_set$2 = Headers$Builder._class.instanceMethodId(
     r'set',
     r'(Ljava/lang/String;Ljava/lang/String;)Lokhttp3/Headers$Builder;',
   );
@@ -8426,7 +7245,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.Headers$Builder set(java.lang.String string, java.lang.String string1)`
+  /// from: `public operator fun set(name: kotlin.String, value: kotlin.String): okhttp3.Headers.Builder`
   /// The returned object must be released after use, by calling the [release] method.
   Headers$Builder set$2(
     jni$_.JString string,
@@ -8434,12 +7253,12 @@
   ) {
     final _$string = string.reference;
     final _$string1 = string1.reference;
-    return _set$2(reference.pointer, _id_set$2 as jni$_.JMethodIDPtr,
-            _$string.pointer, _$string1.pointer)
-        .object<Headers$Builder>(const $Headers$Builder$Type());
+    return _set$2(reference.pointer, _id_set$2.pointer, _$string.pointer,
+            _$string1.pointer)
+        .object<Headers$Builder>();
   }
 
-  static final _id_get = _class.instanceMethodId(
+  static final _id_get = Headers$Builder._class.instanceMethodId(
     r'get',
     r'(Ljava/lang/String;)Ljava/lang/String;',
   );
@@ -8455,18 +7274,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final java.lang.String get(java.lang.String string)`
+  /// from: `public operator fun get(name: kotlin.String): kotlin.String?`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString? get(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _get(
-            reference.pointer, _id_get as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+    return _get(reference.pointer, _id_get.pointer, _$string.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_build = _class.instanceMethodId(
+  static final _id_build = Headers$Builder._class.instanceMethodId(
     r'build',
     r'()Lokhttp3/Headers;',
   );
@@ -8483,160 +7301,37 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final okhttp3.Headers build()`
+  /// from: `public fun build(): okhttp3.Headers`
   /// The returned object must be released after use, by calling the [release] method.
   Headers build() {
-    return _build(reference.pointer, _id_build as jni$_.JMethodIDPtr)
-        .object<Headers>(const $Headers$Type());
+    return _build(reference.pointer, _id_build.pointer).object<Headers>();
+  }
+
+  void operator []=(jni$_.JString string, jni$_.JObject date) {
+    set(string, date);
+  }
+
+  jni$_.JString? operator [](jni$_.JString string) {
+    return get(string);
   }
 }
 
-final class $Headers$Builder$NullableType
-    extends jni$_.JObjType<Headers$Builder?> {
+final class $Headers$Builder$Type$ extends jni$_.JType<Headers$Builder> {
   @jni$_.internal
-  const $Headers$Builder$NullableType();
+  const $Headers$Builder$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Headers$Builder;';
-
-  @jni$_.internal
-  @core$_.override
-  Headers$Builder? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Headers$Builder.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Headers$Builder?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Headers$Builder$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Headers$Builder$NullableType) &&
-        other is $Headers$Builder$NullableType;
-  }
-}
-
-final class $Headers$Builder$Type extends jni$_.JObjType<Headers$Builder> {
-  @jni$_.internal
-  const $Headers$Builder$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Headers$Builder;';
-
-  @jni$_.internal
-  @core$_.override
-  Headers$Builder fromReference(jni$_.JReference reference) =>
-      Headers$Builder.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Headers$Builder?> get nullableType =>
-      const $Headers$Builder$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Headers$Builder$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Headers$Builder$Type) &&
-        other is $Headers$Builder$Type;
-  }
 }
 
 /// from: `okhttp3.Headers$Companion`
-class Headers$Companion extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Headers$Companion> $type;
-
-  @jni$_.internal
-  Headers$Companion.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Headers$Companion._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Headers$Companion');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Headers$Companion$NullableType();
-  static const type = $Headers$Companion$Type();
-  static final _id_of = _class.instanceMethodId(
-    r'of',
-    r'([Ljava/lang/String;)Lokhttp3/Headers;',
-  );
-
-  static final _of = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okhttp3.Headers of(java.lang.String[] strings)`
-  /// The returned object must be released after use, by calling the [release] method.
-  Headers of(
-    jni$_.JArray<jni$_.JString> strings,
-  ) {
-    final _$strings = strings.reference;
-    return _of(
-            reference.pointer, _id_of as jni$_.JMethodIDPtr, _$strings.pointer)
-        .object<Headers>(const $Headers$Type());
-  }
-
-  static final _id_of$1 = _class.instanceMethodId(
-    r'of',
-    r'(Ljava/util/Map;)Lokhttp3/Headers;',
-  );
-
-  static final _of$1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okhttp3.Headers of(java.util.Map map)`
-  /// The returned object must be released after use, by calling the [release] method.
-  Headers of$1(
-    jni$_.JMap<jni$_.JString?, jni$_.JString?> map,
-  ) {
-    final _$map = map.reference;
-    return _of$1(
-            reference.pointer, _id_of$1 as jni$_.JMethodIDPtr, _$map.pointer)
-        .object<Headers>(const $Headers$Type());
-  }
-
+  static const jni$_.JType<Headers$Companion> type = $Headers$Companion$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Lkotlin/jvm/internal/DefaultConstructorMarker;)V',
   );
@@ -8659,105 +7354,81 @@
   ) {
     final _$defaultConstructorMarker =
         defaultConstructorMarker?.reference ?? jni$_.jNullReference;
-    return Headers$Companion.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$defaultConstructorMarker.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$defaultConstructorMarker.pointer)
+        .object<Headers$Companion>();
   }
 }
 
-final class $Headers$Companion$NullableType
-    extends jni$_.JObjType<Headers$Companion?> {
+extension Headers$Companion$$Methods on Headers$Companion {
+  static final _id_of = Headers$Companion._class.instanceMethodId(
+    r'of',
+    r'([Ljava/lang/String;)Lokhttp3/Headers;',
+  );
+
+  static final _of = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun headersOf(vararg namesAndValues: kotlin.String): okhttp3.Headers`
+  /// The returned object must be released after use, by calling the [release] method.
+  Headers of(
+    jni$_.JArray<jni$_.JString> strings,
+  ) {
+    final _$strings = strings.reference;
+    return _of(reference.pointer, _id_of.pointer, _$strings.pointer)
+        .object<Headers>();
+  }
+
+  static final _id_of$1 = Headers$Companion._class.instanceMethodId(
+    r'of',
+    r'(Ljava/util/Map;)Lokhttp3/Headers;',
+  );
+
+  static final _of$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun toHeaders(): okhttp3.Headers`
+  /// The returned object must be released after use, by calling the [release] method.
+  Headers of$1(
+    jni$_.JMap<jni$_.JString?, jni$_.JString?> map,
+  ) {
+    final _$map = map.reference;
+    return _of$1(reference.pointer, _id_of$1.pointer, _$map.pointer)
+        .object<Headers>();
+  }
+}
+
+final class $Headers$Companion$Type$ extends jni$_.JType<Headers$Companion> {
   @jni$_.internal
-  const $Headers$Companion$NullableType();
+  const $Headers$Companion$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Headers$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  Headers$Companion? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : Headers$Companion.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Headers$Companion?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Headers$Companion$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Headers$Companion$NullableType) &&
-        other is $Headers$Companion$NullableType;
-  }
-}
-
-final class $Headers$Companion$Type extends jni$_.JObjType<Headers$Companion> {
-  @jni$_.internal
-  const $Headers$Companion$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Headers$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  Headers$Companion fromReference(jni$_.JReference reference) =>
-      Headers$Companion.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Headers$Companion?> get nullableType =>
-      const $Headers$Companion$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Headers$Companion$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Headers$Companion$Type) &&
-        other is $Headers$Companion$Type;
-  }
 }
 
 /// from: `okhttp3.Headers`
-class Headers extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Headers> $type;
-
-  @jni$_.internal
-  Headers.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Headers._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Headers');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Headers$NullableType();
-  static const type = $Headers$Type();
+  static const jni$_.JType<Headers> type = $Headers$Type$();
   static final _id_Companion = _class.staticFieldId(
     r'Companion',
     r'Lokhttp3/Headers$Companion;',
@@ -8766,383 +7437,7 @@
   /// from: `static public final okhttp3.Headers$Companion Companion`
   /// The returned object must be released after use, by calling the [release] method.
   static Headers$Companion get Companion =>
-      _id_Companion.get(_class, const $Headers$Companion$Type());
-
-  static final _id_get = _class.instanceMethodId(
-    r'get',
-    r'(Ljava/lang/String;)Ljava/lang/String;',
-  );
-
-  static final _get = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final java.lang.String get(java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? get(
-    jni$_.JString string,
-  ) {
-    final _$string = string.reference;
-    return _get(
-            reference.pointer, _id_get as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getDate = _class.instanceMethodId(
-    r'getDate',
-    r'(Ljava/lang/String;)Ljava/util/Date;',
-  );
-
-  static final _getDate = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final java.util.Date getDate(java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getDate(
-    jni$_.JString string,
-  ) {
-    final _$string = string.reference;
-    return _getDate(reference.pointer, _id_getDate as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_getInstant = _class.instanceMethodId(
-    r'getInstant',
-    r'(Ljava/lang/String;)Ljava/time/Instant;',
-  );
-
-  static final _getInstant = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final java.time.Instant getInstant(java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getInstant(
-    jni$_.JString string,
-  ) {
-    final _$string = string.reference;
-    return _getInstant(reference.pointer, _id_getInstant as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_size = _class.instanceMethodId(
-    r'size',
-    r'()I',
-  );
-
-  static final _size = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int size()`
-  int size() {
-    return _size(reference.pointer, _id_size as jni$_.JMethodIDPtr).integer;
-  }
-
-  static final _id_name = _class.instanceMethodId(
-    r'name',
-    r'(I)Ljava/lang/String;',
-  );
-
-  static final _name = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public final java.lang.String name(int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString name(
-    int i,
-  ) {
-    return _name(reference.pointer, _id_name as jni$_.JMethodIDPtr, i)
-        .object<jni$_.JString>(const jni$_.JStringType());
-  }
-
-  static final _id_value = _class.instanceMethodId(
-    r'value',
-    r'(I)Ljava/lang/String;',
-  );
-
-  static final _value = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public final java.lang.String value(int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString value(
-    int i,
-  ) {
-    return _value(reference.pointer, _id_value as jni$_.JMethodIDPtr, i)
-        .object<jni$_.JString>(const jni$_.JStringType());
-  }
-
-  static final _id_names = _class.instanceMethodId(
-    r'names',
-    r'()Ljava/util/Set;',
-  );
-
-  static final _names = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.util.Set names()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JSet<jni$_.JString> names() {
-    return _names(reference.pointer, _id_names as jni$_.JMethodIDPtr)
-        .object<jni$_.JSet<jni$_.JString>>(
-            const jni$_.JSetType<jni$_.JString>(jni$_.JStringType()));
-  }
-
-  static final _id_values = _class.instanceMethodId(
-    r'values',
-    r'(Ljava/lang/String;)Ljava/util/List;',
-  );
-
-  static final _values = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final java.util.List values(java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JList<jni$_.JString> values(
-    jni$_.JString string,
-  ) {
-    final _$string = string.reference;
-    return _values(reference.pointer, _id_values as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<jni$_.JList<jni$_.JString>>(
-            const jni$_.JListType<jni$_.JString>(jni$_.JStringType()));
-  }
-
-  static final _id_byteCount = _class.instanceMethodId(
-    r'byteCount',
-    r'()J',
-  );
-
-  static final _byteCount = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final long byteCount()`
-  int byteCount() {
-    return _byteCount(reference.pointer, _id_byteCount as jni$_.JMethodIDPtr)
-        .long;
-  }
-
-  static final _id_iterator = _class.instanceMethodId(
-    r'iterator',
-    r'()Ljava/util/Iterator;',
-  );
-
-  static final _iterator = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.util.Iterator iterator()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JIterator<jni$_.JObject> iterator() {
-    return _iterator(reference.pointer, _id_iterator as jni$_.JMethodIDPtr)
-        .object<jni$_.JIterator<jni$_.JObject>>(
-            const jni$_.JIteratorType<jni$_.JObject>(jni$_.JObjectType()));
-  }
-
-  static final _id_newBuilder = _class.instanceMethodId(
-    r'newBuilder',
-    r'()Lokhttp3/Headers$Builder;',
-  );
-
-  static final _newBuilder = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okhttp3.Headers$Builder newBuilder()`
-  /// The returned object must be released after use, by calling the [release] method.
-  Headers$Builder newBuilder() {
-    return _newBuilder(reference.pointer, _id_newBuilder as jni$_.JMethodIDPtr)
-        .object<Headers$Builder>(const $Headers$Builder$Type());
-  }
-
-  static final _id_equals = _class.instanceMethodId(
-    r'equals',
-    r'(Ljava/lang/Object;)Z',
-  );
-
-  static final _equals = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public boolean equals(java.lang.Object object)`
-  bool equals(
-    jni$_.JObject? object,
-  ) {
-    final _$object = object?.reference ?? jni$_.jNullReference;
-    return _equals(reference.pointer, _id_equals as jni$_.JMethodIDPtr,
-            _$object.pointer)
-        .boolean;
-  }
-
-  static final _id_hashCode$1 = _class.instanceMethodId(
-    r'hashCode',
-    r'()I',
-  );
-
-  static final _hashCode$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public int hashCode()`
-  int hashCode$1() {
-    return _hashCode$1(reference.pointer, _id_hashCode$1 as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_toString$1 = _class.instanceMethodId(
-    r'toString',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _toString$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.lang.String toString()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString toString$1() {
-    return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr)
-        .object<jni$_.JString>(const jni$_.JStringType());
-  }
-
-  static final _id_toMultimap = _class.instanceMethodId(
-    r'toMultimap',
-    r'()Ljava/util/Map;',
-  );
-
-  static final _toMultimap = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.util.Map toMultimap()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JMap<jni$_.JString, jni$_.JList<jni$_.JString>> toMultimap() {
-    return _toMultimap(reference.pointer, _id_toMultimap as jni$_.JMethodIDPtr)
-        .object<jni$_.JMap<jni$_.JString, jni$_.JList<jni$_.JString>>>(
-            const jni$_.JMapType<jni$_.JString, jni$_.JList<jni$_.JString>>(
-                jni$_.JStringType(),
-                jni$_.JListType<jni$_.JString>(jni$_.JStringType())));
-  }
+      _id_Companion.get(_class, Headers$Companion.type) as Headers$Companion;
 
   static final _id_of = _class.staticMethodId(
     r'of',
@@ -9166,9 +7461,8 @@
     jni$_.JArray<jni$_.JString?> strings,
   ) {
     final _$strings = strings.reference;
-    return _of(_class.reference.pointer, _id_of as jni$_.JMethodIDPtr,
-            _$strings.pointer)
-        .object<Headers>(const $Headers$Type());
+    return _of(_class.reference.pointer, _id_of.pointer, _$strings.pointer)
+        .object<Headers>();
   }
 
   static final _id_of$1 = _class.staticMethodId(
@@ -9187,15 +7481,14 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public final okhttp3.Headers of(java.util.Map map)`
+  /// from: `static public final okhttp3.Headers of(java.util.Map<java.lang.String, java.lang.String> map)`
   /// The returned object must be released after use, by calling the [release] method.
   static Headers of$1(
     jni$_.JMap<jni$_.JString?, jni$_.JString?> map,
   ) {
     final _$map = map.reference;
-    return _of$1(_class.reference.pointer, _id_of$1 as jni$_.JMethodIDPtr,
-            _$map.pointer)
-        .object<Headers>(const $Headers$Type());
+    return _of$1(_class.reference.pointer, _id_of$1.pointer, _$map.pointer)
+        .object<Headers>();
   }
 
   static final _id_new$ = _class.constructorId(
@@ -9228,175 +7521,402 @@
     final _$strings = strings?.reference ?? jni$_.jNullReference;
     final _$defaultConstructorMarker =
         defaultConstructorMarker?.reference ?? jni$_.jNullReference;
-    return Headers.fromReference(_new$(
-            _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
-            _$strings.pointer,
+    return _new$(_class.reference.pointer, _id_new$.pointer, _$strings.pointer,
             _$defaultConstructorMarker.pointer)
-        .reference);
+        .object<Headers>();
   }
 }
 
-final class $Headers$NullableType extends jni$_.JObjType<Headers?> {
+extension Headers$$Methods on Headers {
+  static final _id_get = Headers._class.instanceMethodId(
+    r'get',
+    r'(Ljava/lang/String;)Ljava/lang/String;',
+  );
+
+  static final _get = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public operator fun get(name: kotlin.String): kotlin.String?`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? get(
+    jni$_.JString string,
+  ) {
+    final _$string = string.reference;
+    return _get(reference.pointer, _id_get.pointer, _$string.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_getDate = Headers._class.instanceMethodId(
+    r'getDate',
+    r'(Ljava/lang/String;)Ljava/util/Date;',
+  );
+
+  static final _getDate = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun getDate(name: kotlin.String): java.util.Date?`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? getDate(
+    jni$_.JString string,
+  ) {
+    final _$string = string.reference;
+    return _getDate(reference.pointer, _id_getDate.pointer, _$string.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_getInstant = Headers._class.instanceMethodId(
+    r'getInstant',
+    r'(Ljava/lang/String;)Ljava/time/Instant;',
+  );
+
+  static final _getInstant = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun getInstant(name: kotlin.String): java.time.Instant?`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? getInstant(
+    jni$_.JString string,
+  ) {
+    final _$string = string.reference;
+    return _getInstant(
+            reference.pointer, _id_getInstant.pointer, _$string.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_size = Headers._class.instanceMethodId(
+    r'size',
+    r'()I',
+  );
+
+  static final _size = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final int size()`
+  core$_.int size() {
+    return _size(reference.pointer, _id_size.pointer).integer;
+  }
+
+  static final _id_name = Headers._class.instanceMethodId(
+    r'name',
+    r'(I)Ljava/lang/String;',
+  );
+
+  static final _name = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public fun name(index: kotlin.Int): kotlin.String`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString name(
+    core$_.int i,
+  ) {
+    return _name(reference.pointer, _id_name.pointer, i)
+        .object<jni$_.JString>();
+  }
+
+  static final _id_value = Headers._class.instanceMethodId(
+    r'value',
+    r'(I)Ljava/lang/String;',
+  );
+
+  static final _value = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public fun value(index: kotlin.Int): kotlin.String`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString value(
+    core$_.int i,
+  ) {
+    return _value(reference.pointer, _id_value.pointer, i)
+        .object<jni$_.JString>();
+  }
+
+  static final _id_names = Headers._class.instanceMethodId(
+    r'names',
+    r'()Ljava/util/Set;',
+  );
+
+  static final _names = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun names(): kotlin.collections.Set<kotlin.String>`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JSet<jni$_.JString> names() {
+    return _names(reference.pointer, _id_names.pointer)
+        .object<jni$_.JSet<jni$_.JString>>();
+  }
+
+  static final _id_values = Headers._class.instanceMethodId(
+    r'values',
+    r'(Ljava/lang/String;)Ljava/util/List;',
+  );
+
+  static final _values = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun values(name: kotlin.String): kotlin.collections.List<kotlin.String>`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JList<jni$_.JString> values(
+    jni$_.JString string,
+  ) {
+    final _$string = string.reference;
+    return _values(reference.pointer, _id_values.pointer, _$string.pointer)
+        .object<jni$_.JList<jni$_.JString>>();
+  }
+
+  static final _id_byteCount = Headers._class.instanceMethodId(
+    r'byteCount',
+    r'()J',
+  );
+
+  static final _byteCount = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun byteCount(): kotlin.Long`
+  core$_.int byteCount() {
+    return _byteCount(reference.pointer, _id_byteCount.pointer).long;
+  }
+
+  static final _id_iterator = Headers._class.instanceMethodId(
+    r'iterator',
+    r'()Ljava/util/Iterator;',
+  );
+
+  static final _iterator = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public operator fun iterator(): kotlin.collections.Iterator<kotlin.Pair<kotlin.String, kotlin.String>>`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JIterator<jni$_.JObject> iterator() {
+    return _iterator(reference.pointer, _id_iterator.pointer)
+        .object<jni$_.JIterator<jni$_.JObject>>();
+  }
+
+  static final _id_newBuilder = Headers._class.instanceMethodId(
+    r'newBuilder',
+    r'()Lokhttp3/Headers$Builder;',
+  );
+
+  static final _newBuilder = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun newBuilder(): okhttp3.Headers.Builder`
+  /// The returned object must be released after use, by calling the [release] method.
+  Headers$Builder newBuilder() {
+    return _newBuilder(reference.pointer, _id_newBuilder.pointer)
+        .object<Headers$Builder>();
+  }
+
+  static final _id_equals = Headers._class.instanceMethodId(
+    r'equals',
+    r'(Ljava/lang/Object;)Z',
+  );
+
+  static final _equals = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public operator fun equals(other: kotlin.Any?): kotlin.Boolean`
+  core$_.bool equals(
+    jni$_.JObject? object,
+  ) {
+    final _$object = object?.reference ?? jni$_.jNullReference;
+    return _equals(reference.pointer, _id_equals.pointer, _$object.pointer)
+        .boolean;
+  }
+
+  static final _id_hashCode$1 = Headers._class.instanceMethodId(
+    r'hashCode',
+    r'()I',
+  );
+
+  static final _hashCode$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun hashCode(): kotlin.Int`
+  core$_.int hashCode$1() {
+    return _hashCode$1(reference.pointer, _id_hashCode$1.pointer).integer;
+  }
+
+  static final _id_toString$1 = Headers._class.instanceMethodId(
+    r'toString',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _toString$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun toString(): kotlin.String`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString toString$1() {
+    return _toString$1(reference.pointer, _id_toString$1.pointer)
+        .object<jni$_.JString>();
+  }
+
+  static final _id_toMultimap = Headers._class.instanceMethodId(
+    r'toMultimap',
+    r'()Ljava/util/Map;',
+  );
+
+  static final _toMultimap = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun toMultimap(): kotlin.collections.Map<kotlin.String, kotlin.collections.List<kotlin.String>>`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JMap<jni$_.JString, jni$_.JList<jni$_.JString>> toMultimap() {
+    return _toMultimap(reference.pointer, _id_toMultimap.pointer)
+        .object<jni$_.JMap<jni$_.JString, jni$_.JList<jni$_.JString>>>();
+  }
+
+  jni$_.JString? operator [](jni$_.JString string) {
+    return get(string);
+  }
+}
+
+final class $Headers$Type$ extends jni$_.JType<Headers> {
   @jni$_.internal
-  const $Headers$NullableType();
+  const $Headers$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Headers;';
-
-  @jni$_.internal
-  @core$_.override
-  Headers? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Headers.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Headers?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Headers$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Headers$NullableType) &&
-        other is $Headers$NullableType;
-  }
-}
-
-final class $Headers$Type extends jni$_.JObjType<Headers> {
-  @jni$_.internal
-  const $Headers$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Headers;';
-
-  @jni$_.internal
-  @core$_.override
-  Headers fromReference(jni$_.JReference reference) => Headers.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Headers?> get nullableType => const $Headers$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Headers$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Headers$Type) && other is $Headers$Type;
-  }
 }
 
 /// from: `okhttp3.Callback`
-class Callback extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Callback> $type;
-
-  @jni$_.internal
-  Callback.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Callback._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Callback');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Callback$NullableType();
-  static const type = $Callback$Type();
-  static final _id_onFailure = _class.instanceMethodId(
-    r'onFailure',
-    r'(Lokhttp3/Call;Ljava/io/IOException;)V',
-  );
-
-  static final _onFailure = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void onFailure(okhttp3.Call call, java.io.IOException iOException)`
-  void onFailure(
-    Call call,
-    jni$_.JObject iOException,
-  ) {
-    final _$call = call.reference;
-    final _$iOException = iOException.reference;
-    _onFailure(reference.pointer, _id_onFailure as jni$_.JMethodIDPtr,
-            _$call.pointer, _$iOException.pointer)
-        .check();
-  }
-
-  static final _id_onResponse = _class.instanceMethodId(
-    r'onResponse',
-    r'(Lokhttp3/Call;Lokhttp3/Response;)V',
-  );
-
-  static final _onResponse = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void onResponse(okhttp3.Call call, okhttp3.Response response)`
-  void onResponse(
-    Call call,
-    Response response,
-  ) {
-    final _$call = call.reference;
-    final _$response = response.reference;
-    _onResponse(reference.pointer, _id_onResponse as jni$_.JMethodIDPtr,
-            _$call.pointer, _$response.pointer)
-        .check();
-  }
+  static const jni$_.JType<Callback> type = $Callback$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $Callback> _$impls = {};
+  static final core$_.Map<core$_.int, $Callback> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -9417,7 +7937,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -9425,15 +7945,15 @@
       final $a = $i.args;
       if ($d == r'onFailure(Lokhttp3/Call;Ljava/io/IOException;)V') {
         _$impls[$p]!.onFailure(
-          $a![0]!.as(const $Call$Type(), releaseOriginal: true),
-          $a![1]!.as(const jni$_.JObjectType(), releaseOriginal: true),
+          ($a![0] as Call),
+          ($a![1] as jni$_.JObject),
         );
         return jni$_.nullptr;
       }
       if ($d == r'onResponse(Lokhttp3/Call;Lokhttp3/Response;)V') {
         _$impls[$p]!.onResponse(
-          $a![0]!.as(const $Call$Type(), releaseOriginal: true),
-          $a![1]!.as(const $Response$Type(), releaseOriginal: true),
+          ($a![0] as Call),
+          ($a![1] as Response),
         );
         return jni$_.nullptr;
       }
@@ -9478,24 +7998,92 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return Callback.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<Callback>();
+  }
+}
+
+extension Callback$$Methods on Callback {
+  static final _id_onFailure = Callback._class.instanceMethodId(
+    r'onFailure',
+    r'(Lokhttp3/Call;Ljava/io/IOException;)V',
+  );
+
+  static final _onFailure = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun onFailure(call: okhttp3.Call, e: java.io.IOException): kotlin.Unit`
+  void onFailure(
+    Call call,
+    jni$_.JObject iOException,
+  ) {
+    final _$call = call.reference;
+    final _$iOException = iOException.reference;
+    _onFailure(reference.pointer, _id_onFailure.pointer, _$call.pointer,
+            _$iOException.pointer)
+        .check();
+  }
+
+  static final _id_onResponse = Callback._class.instanceMethodId(
+    r'onResponse',
+    r'(Lokhttp3/Call;Lokhttp3/Response;)V',
+  );
+
+  static final _onResponse = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun onResponse(call: okhttp3.Call, response: okhttp3.Response): kotlin.Unit`
+  void onResponse(
+    Call call,
+    Response response,
+  ) {
+    final _$call = call.reference;
+    final _$response = response.reference;
+    _onResponse(reference.pointer, _id_onResponse.pointer, _$call.pointer,
+            _$response.pointer)
+        .check();
   }
 }
 
 abstract base mixin class $Callback {
   factory $Callback({
     required void Function(Call call, jni$_.JObject iOException) onFailure,
-    bool onFailure$async,
+    core$_.bool onFailure$async,
     required void Function(Call call, Response response) onResponse,
-    bool onResponse$async,
+    core$_.bool onResponse$async,
   }) = _$Callback;
 
   void onFailure(Call call, jni$_.JObject iOException);
-  bool get onFailure$async => false;
+  core$_.bool get onFailure$async => false;
   void onResponse(Call call, Response response);
-  bool get onResponse$async => false;
+  core$_.bool get onResponse$async => false;
 }
 
 final class _$Callback with $Callback {
@@ -9508,9 +8096,9 @@
         _onResponse = onResponse;
 
   final void Function(Call call, jni$_.JObject iOException) _onFailure;
-  final bool onFailure$async;
+  final core$_.bool onFailure$async;
   final void Function(Call call, Response response) _onResponse;
-  final bool onResponse$async;
+  final core$_.bool onResponse$async;
 
   void onFailure(Call call, jni$_.JObject iOException) {
     return _onFailure(call, iOException);
@@ -9521,94 +8109,21 @@
   }
 }
 
-final class $Callback$NullableType extends jni$_.JObjType<Callback?> {
+final class $Callback$Type$ extends jni$_.JType<Callback> {
   @jni$_.internal
-  const $Callback$NullableType();
+  const $Callback$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Callback;';
-
-  @jni$_.internal
-  @core$_.override
-  Callback? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Callback.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Callback?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Callback$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Callback$NullableType) &&
-        other is $Callback$NullableType;
-  }
-}
-
-final class $Callback$Type extends jni$_.JObjType<Callback> {
-  @jni$_.internal
-  const $Callback$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Callback;';
-
-  @jni$_.internal
-  @core$_.override
-  Callback fromReference(jni$_.JReference reference) => Callback.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Callback?> get nullableType => const $Callback$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Callback$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Callback$Type) && other is $Callback$Type;
-  }
 }
 
 /// from: `okhttp3.ConnectionPool`
-class ConnectionPool extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<ConnectionPool> $type;
-
-  @jni$_.internal
-  ConnectionPool.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type ConnectionPool._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/ConnectionPool');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $ConnectionPool$NullableType();
-  static const type = $ConnectionPool$Type();
+  static const jni$_.JType<ConnectionPool> type = $ConnectionPool$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Lokhttp3/internal/connection/RealConnectionPool;)V',
   );
@@ -9630,9 +8145,9 @@
     jni$_.JObject realConnectionPool,
   ) {
     final _$realConnectionPool = realConnectionPool.reference;
-    return ConnectionPool.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$realConnectionPool.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$realConnectionPool.pointer)
+        .object<ConnectionPool>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -9651,20 +8166,24 @@
                         jni$_.Pointer<jni$_.Void>
                       )>)>>('globalEnv_NewObject')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, int, jni$_.Pointer<jni$_.Void>)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
 
   /// from: `public void <init>(int i, long j, java.util.concurrent.TimeUnit timeUnit)`
   /// The returned object must be released after use, by calling the [release] method.
   factory ConnectionPool.new$1(
-    int i,
-    int j,
+    core$_.int i,
+    core$_.int j,
     TimeUnit timeUnit,
   ) {
     final _$timeUnit = timeUnit.reference;
-    return ConnectionPool.fromReference(_new$1(_class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr, i, j, _$timeUnit.pointer)
-        .reference);
+    return _new$1(_class.reference.pointer, _id_new$1.pointer, i, j,
+            _$timeUnit.pointer)
+        .object<ConnectionPool>();
   }
 
   static final _id_new$2 = _class.constructorId(
@@ -9686,12 +8205,13 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory ConnectionPool.new$2() {
-    return ConnectionPool.fromReference(
-        _new$2(_class.reference.pointer, _id_new$2 as jni$_.JMethodIDPtr)
-            .reference);
+    return _new$2(_class.reference.pointer, _id_new$2.pointer)
+        .object<ConnectionPool>();
   }
+}
 
-  static final _id_idleConnectionCount = _class.instanceMethodId(
+extension ConnectionPool$$Methods on ConnectionPool {
+  static final _id_idleConnectionCount = ConnectionPool._class.instanceMethodId(
     r'idleConnectionCount',
     r'()I',
   );
@@ -9708,14 +8228,14 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final int idleConnectionCount()`
-  int idleConnectionCount() {
+  /// from: `public fun idleConnectionCount(): kotlin.Int`
+  core$_.int idleConnectionCount() {
     return _idleConnectionCount(
-            reference.pointer, _id_idleConnectionCount as jni$_.JMethodIDPtr)
+            reference.pointer, _id_idleConnectionCount.pointer)
         .integer;
   }
 
-  static final _id_connectionCount = _class.instanceMethodId(
+  static final _id_connectionCount = ConnectionPool._class.instanceMethodId(
     r'connectionCount',
     r'()I',
   );
@@ -9732,14 +8252,13 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final int connectionCount()`
-  int connectionCount() {
-    return _connectionCount(
-            reference.pointer, _id_connectionCount as jni$_.JMethodIDPtr)
+  /// from: `public fun connectionCount(): kotlin.Int`
+  core$_.int connectionCount() {
+    return _connectionCount(reference.pointer, _id_connectionCount.pointer)
         .integer;
   }
 
-  static final _id_evictAll = _class.instanceMethodId(
+  static final _id_evictAll = ConnectionPool._class.instanceMethodId(
     r'evictAll',
     r'()V',
   );
@@ -9756,104 +8275,27 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final void evictAll()`
+  /// from: `public fun evictAll(): kotlin.Unit`
   void evictAll() {
-    _evictAll(reference.pointer, _id_evictAll as jni$_.JMethodIDPtr).check();
+    _evictAll(reference.pointer, _id_evictAll.pointer).check();
   }
 }
 
-final class $ConnectionPool$NullableType
-    extends jni$_.JObjType<ConnectionPool?> {
+final class $ConnectionPool$Type$ extends jni$_.JType<ConnectionPool> {
   @jni$_.internal
-  const $ConnectionPool$NullableType();
+  const $ConnectionPool$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/ConnectionPool;';
-
-  @jni$_.internal
-  @core$_.override
-  ConnectionPool? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : ConnectionPool.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ConnectionPool?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ConnectionPool$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ConnectionPool$NullableType) &&
-        other is $ConnectionPool$NullableType;
-  }
-}
-
-final class $ConnectionPool$Type extends jni$_.JObjType<ConnectionPool> {
-  @jni$_.internal
-  const $ConnectionPool$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/ConnectionPool;';
-
-  @jni$_.internal
-  @core$_.override
-  ConnectionPool fromReference(jni$_.JReference reference) =>
-      ConnectionPool.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ConnectionPool?> get nullableType =>
-      const $ConnectionPool$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ConnectionPool$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ConnectionPool$Type) &&
-        other is $ConnectionPool$Type;
-  }
 }
 
 /// from: `okhttp3.Dispatcher`
-class Dispatcher extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Dispatcher> $type;
-
-  @jni$_.internal
-  Dispatcher.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Dispatcher._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Dispatcher');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Dispatcher$NullableType();
-  static const type = $Dispatcher$Type();
+  static const jni$_.JType<Dispatcher> type = $Dispatcher$Type$();
   static final _id_new$ = _class.constructorId(
     r'()V',
   );
@@ -9873,181 +8315,8 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory Dispatcher() {
-    return Dispatcher.fromReference(
-        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
-            .reference);
-  }
-
-  static final _id_getMaxRequests = _class.instanceMethodId(
-    r'getMaxRequests',
-    r'()I',
-  );
-
-  static final _getMaxRequests = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int getMaxRequests()`
-  int getMaxRequests() {
-    return _getMaxRequests(
-            reference.pointer, _id_getMaxRequests as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_setMaxRequests = _class.instanceMethodId(
-    r'setMaxRequests',
-    r'(I)V',
-  );
-
-  static final _setMaxRequests = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public final void setMaxRequests(int i)`
-  void setMaxRequests(
-    int i,
-  ) {
-    _setMaxRequests(
-            reference.pointer, _id_setMaxRequests as jni$_.JMethodIDPtr, i)
-        .check();
-  }
-
-  static final _id_getMaxRequestsPerHost = _class.instanceMethodId(
-    r'getMaxRequestsPerHost',
-    r'()I',
-  );
-
-  static final _getMaxRequestsPerHost = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int getMaxRequestsPerHost()`
-  int getMaxRequestsPerHost() {
-    return _getMaxRequestsPerHost(
-            reference.pointer, _id_getMaxRequestsPerHost as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_setMaxRequestsPerHost = _class.instanceMethodId(
-    r'setMaxRequestsPerHost',
-    r'(I)V',
-  );
-
-  static final _setMaxRequestsPerHost = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public final void setMaxRequestsPerHost(int i)`
-  void setMaxRequestsPerHost(
-    int i,
-  ) {
-    _setMaxRequestsPerHost(reference.pointer,
-            _id_setMaxRequestsPerHost as jni$_.JMethodIDPtr, i)
-        .check();
-  }
-
-  static final _id_getIdleCallback = _class.instanceMethodId(
-    r'getIdleCallback',
-    r'()Ljava/lang/Runnable;',
-  );
-
-  static final _getIdleCallback = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.lang.Runnable getIdleCallback()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getIdleCallback() {
-    return _getIdleCallback(
-            reference.pointer, _id_getIdleCallback as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_setIdleCallback = _class.instanceMethodId(
-    r'setIdleCallback',
-    r'(Ljava/lang/Runnable;)V',
-  );
-
-  static final _setIdleCallback = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final void setIdleCallback(java.lang.Runnable runnable)`
-  void setIdleCallback(
-    jni$_.JObject? runnable,
-  ) {
-    final _$runnable = runnable?.reference ?? jni$_.jNullReference;
-    _setIdleCallback(reference.pointer,
-            _id_setIdleCallback as jni$_.JMethodIDPtr, _$runnable.pointer)
-        .check();
-  }
-
-  static final _id_executorService = _class.instanceMethodId(
-    r'executorService',
-    r'()Ljava/util/concurrent/ExecutorService;',
-  );
-
-  static final _executorService = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.util.concurrent.ExecutorService executorService()`
-  /// The returned object must be released after use, by calling the [release] method.
-  ExecutorService executorService() {
-    return _executorService(
-            reference.pointer, _id_executorService as jni$_.JMethodIDPtr)
-        .object<ExecutorService>(const $ExecutorService$Type());
+    return _new$(_class.reference.pointer, _id_new$.pointer)
+        .object<Dispatcher>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -10071,12 +8340,175 @@
     ExecutorService executorService,
   ) {
     final _$executorService = executorService.reference;
-    return Dispatcher.fromReference(_new$1(_class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr, _$executorService.pointer)
-        .reference);
+    return _new$1(_class.reference.pointer, _id_new$1.pointer,
+            _$executorService.pointer)
+        .object<Dispatcher>();
+  }
+}
+
+extension Dispatcher$$Methods on Dispatcher {
+  static final _id_get$maxRequests = Dispatcher._class.instanceMethodId(
+    r'getMaxRequests',
+    r'()I',
+  );
+
+  static final _get$maxRequests = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final int getMaxRequests()`
+  core$_.int get maxRequests {
+    return _get$maxRequests(reference.pointer, _id_get$maxRequests.pointer)
+        .integer;
   }
 
-  static final _id_cancelAll = _class.instanceMethodId(
+  static final _id_set$maxRequests = Dispatcher._class.instanceMethodId(
+    r'setMaxRequests',
+    r'(I)V',
+  );
+
+  static final _set$maxRequests = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public final void setMaxRequests(int i)`
+  set maxRequests(core$_.int i) {
+    _set$maxRequests(reference.pointer, _id_set$maxRequests.pointer, i).check();
+  }
+
+  static final _id_get$maxRequestsPerHost = Dispatcher._class.instanceMethodId(
+    r'getMaxRequestsPerHost',
+    r'()I',
+  );
+
+  static final _get$maxRequestsPerHost = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final int getMaxRequestsPerHost()`
+  core$_.int get maxRequestsPerHost {
+    return _get$maxRequestsPerHost(
+            reference.pointer, _id_get$maxRequestsPerHost.pointer)
+        .integer;
+  }
+
+  static final _id_set$maxRequestsPerHost = Dispatcher._class.instanceMethodId(
+    r'setMaxRequestsPerHost',
+    r'(I)V',
+  );
+
+  static final _set$maxRequestsPerHost = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public final void setMaxRequestsPerHost(int i)`
+  set maxRequestsPerHost(core$_.int i) {
+    _set$maxRequestsPerHost(
+            reference.pointer, _id_set$maxRequestsPerHost.pointer, i)
+        .check();
+  }
+
+  static final _id_get$idleCallback = Dispatcher._class.instanceMethodId(
+    r'getIdleCallback',
+    r'()Ljava/lang/Runnable;',
+  );
+
+  static final _get$idleCallback = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.lang.Runnable getIdleCallback()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get idleCallback {
+    return _get$idleCallback(reference.pointer, _id_get$idleCallback.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_set$idleCallback = Dispatcher._class.instanceMethodId(
+    r'setIdleCallback',
+    r'(Ljava/lang/Runnable;)V',
+  );
+
+  static final _set$idleCallback = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final void setIdleCallback(java.lang.Runnable runnable)`
+  set idleCallback(jni$_.JObject? runnable) {
+    final _$runnable = runnable?.reference ?? jni$_.jNullReference;
+    _set$idleCallback(
+            reference.pointer, _id_set$idleCallback.pointer, _$runnable.pointer)
+        .check();
+  }
+
+  static final _id_executorService = Dispatcher._class.instanceMethodId(
+    r'executorService',
+    r'()Ljava/util/concurrent/ExecutorService;',
+  );
+
+  static final _executorService = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.util.concurrent.ExecutorService executorService()`
+  /// The returned object must be released after use, by calling the [release] method.
+  ExecutorService executorService() {
+    return _executorService(reference.pointer, _id_executorService.pointer)
+        .object<ExecutorService>();
+  }
+
+  static final _id_cancelAll = Dispatcher._class.instanceMethodId(
     r'cancelAll',
     r'()V',
   );
@@ -10093,12 +8525,12 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final void cancelAll()`
+  /// from: `public fun cancelAll(): kotlin.Unit`
   void cancelAll() {
-    _cancelAll(reference.pointer, _id_cancelAll as jni$_.JMethodIDPtr).check();
+    _cancelAll(reference.pointer, _id_cancelAll.pointer).check();
   }
 
-  static final _id_queuedCalls = _class.instanceMethodId(
+  static final _id_queuedCalls = Dispatcher._class.instanceMethodId(
     r'queuedCalls',
     r'()Ljava/util/List;',
   );
@@ -10115,15 +8547,14 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final java.util.List queuedCalls()`
+  /// from: `public fun queuedCalls(): kotlin.collections.List<okhttp3.Call>`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JList<Call> queuedCalls() {
-    return _queuedCalls(
-            reference.pointer, _id_queuedCalls as jni$_.JMethodIDPtr)
-        .object<jni$_.JList<Call>>(const jni$_.JListType<Call>($Call$Type()));
+    return _queuedCalls(reference.pointer, _id_queuedCalls.pointer)
+        .object<jni$_.JList<Call>>();
   }
 
-  static final _id_runningCalls = _class.instanceMethodId(
+  static final _id_runningCalls = Dispatcher._class.instanceMethodId(
     r'runningCalls',
     r'()Ljava/util/List;',
   );
@@ -10140,15 +8571,14 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final java.util.List runningCalls()`
+  /// from: `public fun runningCalls(): kotlin.collections.List<okhttp3.Call>`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JList<Call> runningCalls() {
-    return _runningCalls(
-            reference.pointer, _id_runningCalls as jni$_.JMethodIDPtr)
-        .object<jni$_.JList<Call>>(const jni$_.JListType<Call>($Call$Type()));
+    return _runningCalls(reference.pointer, _id_runningCalls.pointer)
+        .object<jni$_.JList<Call>>();
   }
 
-  static final _id_queuedCallsCount = _class.instanceMethodId(
+  static final _id_queuedCallsCount = Dispatcher._class.instanceMethodId(
     r'queuedCallsCount',
     r'()I',
   );
@@ -10165,14 +8595,13 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final int queuedCallsCount()`
-  int queuedCallsCount() {
-    return _queuedCallsCount(
-            reference.pointer, _id_queuedCallsCount as jni$_.JMethodIDPtr)
+  /// from: `public fun queuedCallsCount(): kotlin.Int`
+  core$_.int queuedCallsCount() {
+    return _queuedCallsCount(reference.pointer, _id_queuedCallsCount.pointer)
         .integer;
   }
 
-  static final _id_runningCallsCount = _class.instanceMethodId(
+  static final _id_runningCallsCount = Dispatcher._class.instanceMethodId(
     r'runningCallsCount',
     r'()I',
   );
@@ -10189,470 +8618,35 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final int runningCallsCount()`
-  int runningCallsCount() {
-    return _runningCallsCount(
-            reference.pointer, _id_runningCallsCount as jni$_.JMethodIDPtr)
+  /// from: `public fun runningCallsCount(): kotlin.Int`
+  core$_.int runningCallsCount() {
+    return _runningCallsCount(reference.pointer, _id_runningCallsCount.pointer)
         .integer;
   }
 }
 
-final class $Dispatcher$NullableType extends jni$_.JObjType<Dispatcher?> {
+final class $Dispatcher$Type$ extends jni$_.JType<Dispatcher> {
   @jni$_.internal
-  const $Dispatcher$NullableType();
+  const $Dispatcher$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Dispatcher;';
-
-  @jni$_.internal
-  @core$_.override
-  Dispatcher? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Dispatcher.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Dispatcher?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Dispatcher$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Dispatcher$NullableType) &&
-        other is $Dispatcher$NullableType;
-  }
-}
-
-final class $Dispatcher$Type extends jni$_.JObjType<Dispatcher> {
-  @jni$_.internal
-  const $Dispatcher$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Dispatcher;';
-
-  @jni$_.internal
-  @core$_.override
-  Dispatcher fromReference(jni$_.JReference reference) =>
-      Dispatcher.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Dispatcher?> get nullableType =>
-      const $Dispatcher$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Dispatcher$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Dispatcher$Type) && other is $Dispatcher$Type;
-  }
 }
 
 /// from: `java.util.concurrent.ExecutorService`
-class ExecutorService extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<ExecutorService> $type;
-
-  @jni$_.internal
-  ExecutorService.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type ExecutorService._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'java/util/concurrent/ExecutorService');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $ExecutorService$NullableType();
-  static const type = $ExecutorService$Type();
-  static final _id_shutdown = _class.instanceMethodId(
-    r'shutdown',
-    r'()V',
-  );
-
-  static final _shutdown = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract void shutdown()`
-  void shutdown() {
-    _shutdown(reference.pointer, _id_shutdown as jni$_.JMethodIDPtr).check();
-  }
-
-  static final _id_shutdownNow = _class.instanceMethodId(
-    r'shutdownNow',
-    r'()Ljava/util/List;',
-  );
-
-  static final _shutdownNow = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.util.List shutdownNow()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JList<jni$_.JObject?>? shutdownNow() {
-    return _shutdownNow(
-            reference.pointer, _id_shutdownNow as jni$_.JMethodIDPtr)
-        .object<jni$_.JList<jni$_.JObject?>?>(
-            const jni$_.JListNullableType<jni$_.JObject?>(
-                jni$_.JObjectNullableType()));
-  }
-
-  static final _id_isShutdown = _class.instanceMethodId(
-    r'isShutdown',
-    r'()Z',
-  );
-
-  static final _isShutdown = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract boolean isShutdown()`
-  bool isShutdown() {
-    return _isShutdown(reference.pointer, _id_isShutdown as jni$_.JMethodIDPtr)
-        .boolean;
-  }
-
-  static final _id_isTerminated = _class.instanceMethodId(
-    r'isTerminated',
-    r'()Z',
-  );
-
-  static final _isTerminated = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract boolean isTerminated()`
-  bool isTerminated() {
-    return _isTerminated(
-            reference.pointer, _id_isTerminated as jni$_.JMethodIDPtr)
-        .boolean;
-  }
-
-  static final _id_awaitTermination = _class.instanceMethodId(
-    r'awaitTermination',
-    r'(JLjava/util/concurrent/TimeUnit;)Z',
-  );
-
-  static final _awaitTermination = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Int64, jni$_.Pointer<jni$_.Void>)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract boolean awaitTermination(long j, java.util.concurrent.TimeUnit timeUnit)`
-  bool awaitTermination(
-    int j,
-    TimeUnit? timeUnit,
-  ) {
-    final _$timeUnit = timeUnit?.reference ?? jni$_.jNullReference;
-    return _awaitTermination(reference.pointer,
-            _id_awaitTermination as jni$_.JMethodIDPtr, j, _$timeUnit.pointer)
-        .boolean;
-  }
-
-  static final _id_submit = _class.instanceMethodId(
-    r'submit',
-    r'(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;',
-  );
-
-  static final _submit = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.util.concurrent.Future submit(java.util.concurrent.Callable callable)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? submit<$T extends jni$_.JObject?>(
-    jni$_.JObject? callable, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$callable = callable?.reference ?? jni$_.jNullReference;
-    return _submit(reference.pointer, _id_submit as jni$_.JMethodIDPtr,
-            _$callable.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_submit$1 = _class.instanceMethodId(
-    r'submit',
-    r'(Ljava/lang/Runnable;Ljava/lang/Object;)Ljava/util/concurrent/Future;',
-  );
-
-  static final _submit$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.util.concurrent.Future submit(java.lang.Runnable runnable, T object)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? submit$1<$T extends jni$_.JObject?>(
-    jni$_.JObject? runnable,
-    $T? object, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$runnable = runnable?.reference ?? jni$_.jNullReference;
-    final _$object = object?.reference ?? jni$_.jNullReference;
-    return _submit$1(reference.pointer, _id_submit$1 as jni$_.JMethodIDPtr,
-            _$runnable.pointer, _$object.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_submit$2 = _class.instanceMethodId(
-    r'submit',
-    r'(Ljava/lang/Runnable;)Ljava/util/concurrent/Future;',
-  );
-
-  static final _submit$2 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.util.concurrent.Future submit(java.lang.Runnable runnable)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? submit$2(
-    jni$_.JObject? runnable,
-  ) {
-    final _$runnable = runnable?.reference ?? jni$_.jNullReference;
-    return _submit$2(reference.pointer, _id_submit$2 as jni$_.JMethodIDPtr,
-            _$runnable.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_invokeAll = _class.instanceMethodId(
-    r'invokeAll',
-    r'(Ljava/util/Collection;)Ljava/util/List;',
-  );
-
-  static final _invokeAll = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.util.List invokeAll(java.util.Collection collection)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JList<jni$_.JObject?>? invokeAll<$T extends jni$_.JObject?>(
-    jni$_.JObject? collection, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$collection = collection?.reference ?? jni$_.jNullReference;
-    return _invokeAll(reference.pointer, _id_invokeAll as jni$_.JMethodIDPtr,
-            _$collection.pointer)
-        .object<jni$_.JList<jni$_.JObject?>?>(
-            const jni$_.JListNullableType<jni$_.JObject?>(
-                jni$_.JObjectNullableType()));
-  }
-
-  static final _id_invokeAll$1 = _class.instanceMethodId(
-    r'invokeAll',
-    r'(Ljava/util/Collection;JLjava/util/concurrent/TimeUnit;)Ljava/util/List;',
-  );
-
-  static final _invokeAll$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int64,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.util.List invokeAll(java.util.Collection collection, long j, java.util.concurrent.TimeUnit timeUnit)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JList<jni$_.JObject?>? invokeAll$1<$T extends jni$_.JObject?>(
-    jni$_.JObject? collection,
-    int j,
-    TimeUnit? timeUnit, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$collection = collection?.reference ?? jni$_.jNullReference;
-    final _$timeUnit = timeUnit?.reference ?? jni$_.jNullReference;
-    return _invokeAll$1(
-            reference.pointer,
-            _id_invokeAll$1 as jni$_.JMethodIDPtr,
-            _$collection.pointer,
-            j,
-            _$timeUnit.pointer)
-        .object<jni$_.JList<jni$_.JObject?>?>(
-            const jni$_.JListNullableType<jni$_.JObject?>(
-                jni$_.JObjectNullableType()));
-  }
-
-  static final _id_invokeAny = _class.instanceMethodId(
-    r'invokeAny',
-    r'(Ljava/util/Collection;)Ljava/lang/Object;',
-  );
-
-  static final _invokeAny = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract T invokeAny(java.util.Collection collection)`
-  /// The returned object must be released after use, by calling the [release] method.
-  $T? invokeAny<$T extends jni$_.JObject?>(
-    jni$_.JObject? collection, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$collection = collection?.reference ?? jni$_.jNullReference;
-    return _invokeAny(reference.pointer, _id_invokeAny as jni$_.JMethodIDPtr,
-            _$collection.pointer)
-        .object<$T?>(T.nullableType);
-  }
-
-  static final _id_invokeAny$1 = _class.instanceMethodId(
-    r'invokeAny',
-    r'(Ljava/util/Collection;JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object;',
-  );
-
-  static final _invokeAny$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int64,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract T invokeAny(java.util.Collection collection, long j, java.util.concurrent.TimeUnit timeUnit)`
-  /// The returned object must be released after use, by calling the [release] method.
-  $T? invokeAny$1<$T extends jni$_.JObject?>(
-    jni$_.JObject? collection,
-    int j,
-    TimeUnit? timeUnit, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$collection = collection?.reference ?? jni$_.jNullReference;
-    final _$timeUnit = timeUnit?.reference ?? jni$_.jNullReference;
-    return _invokeAny$1(
-            reference.pointer,
-            _id_invokeAny$1 as jni$_.JMethodIDPtr,
-            _$collection.pointer,
-            j,
-            _$timeUnit.pointer)
-        .object<$T?>(T.nullableType);
-  }
+  static const jni$_.JType<ExecutorService> type = $ExecutorService$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $ExecutorService> _$impls = {};
+  static final core$_.Map<core$_.int, $ExecutorService> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -10673,80 +8667,29 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
       final $d = $i.methodDescriptor.toDartString(releaseOriginal: true);
       final $a = $i.args;
-      if ($d == r'shutdown()V') {
-        _$impls[$p]!.shutdown();
-        return jni$_.nullptr;
-      }
-      if ($d == r'shutdownNow()Ljava/util/List;') {
-        final $r = _$impls[$p]!.shutdownNow();
-        return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
-                .reference
-                .toPointer() ??
-            jni$_.nullptr;
-      }
-      if ($d == r'isShutdown()Z') {
-        final $r = _$impls[$p]!.isShutdown();
-        return jni$_.JBoolean($r).reference.toPointer();
-      }
-      if ($d == r'isTerminated()Z') {
-        final $r = _$impls[$p]!.isTerminated();
-        return jni$_.JBoolean($r).reference.toPointer();
-      }
       if ($d == r'awaitTermination(JLjava/util/concurrent/TimeUnit;)Z') {
         final $r = _$impls[$p]!.awaitTermination(
-          $a![0]!
-              .as(const jni$_.JLongType(), releaseOriginal: true)
-              .longValue(releaseOriginal: true),
-          $a![1]?.as(const $TimeUnit$Type(), releaseOriginal: true),
+          ($a![0] as jni$_.JLong).toDartInt(releaseOriginal: true),
+          ($a![1] as TimeUnit?),
         );
-        return jni$_.JBoolean($r).reference.toPointer();
+        return $r.toJBoolean().reference.toPointer();
       }
-      if ($d ==
-          r'submit(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;') {
-        final $r = _$impls[$p]!.submit(
-          $a![0]?.as(const jni$_.JObjectType(), releaseOriginal: true),
-        );
-        return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
-                .reference
-                .toPointer() ??
-            jni$_.nullptr;
-      }
-      if ($d ==
-          r'submit(Ljava/lang/Runnable;Ljava/lang/Object;)Ljava/util/concurrent/Future;') {
-        final $r = _$impls[$p]!.submit$1(
-          $a![0]?.as(const jni$_.JObjectType(), releaseOriginal: true),
-          $a![1]?.as(const jni$_.JObjectType(), releaseOriginal: true),
-        );
-        return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
-                .reference
-                .toPointer() ??
-            jni$_.nullptr;
-      }
-      if ($d == r'submit(Ljava/lang/Runnable;)Ljava/util/concurrent/Future;') {
-        final $r = _$impls[$p]!.submit$2(
-          $a![0]?.as(const jni$_.JObjectType(), releaseOriginal: true),
-        );
-        return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
-                .reference
-                .toPointer() ??
-            jni$_.nullptr;
+      if ($d == r'close()V') {
+        _$impls[$p]!.close();
+        return jni$_.nullptr;
       }
       if ($d == r'invokeAll(Ljava/util/Collection;)Ljava/util/List;') {
         final $r = _$impls[$p]!.invokeAll(
-          $a![0]?.as(const jni$_.JObjectType(), releaseOriginal: true),
+          ($a![0] as jni$_.JObject?),
         );
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -10754,24 +8697,22 @@
       if ($d ==
           r'invokeAll(Ljava/util/Collection;JLjava/util/concurrent/TimeUnit;)Ljava/util/List;') {
         final $r = _$impls[$p]!.invokeAll$1(
-          $a![0]?.as(const jni$_.JObjectType(), releaseOriginal: true),
-          $a![1]!
-              .as(const jni$_.JLongType(), releaseOriginal: true)
-              .longValue(releaseOriginal: true),
-          $a![2]?.as(const $TimeUnit$Type(), releaseOriginal: true),
+          ($a![0] as jni$_.JObject?),
+          ($a![1] as jni$_.JLong).toDartInt(releaseOriginal: true),
+          ($a![2] as TimeUnit?),
         );
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
       }
       if ($d == r'invokeAny(Ljava/util/Collection;)Ljava/lang/Object;') {
         final $r = _$impls[$p]!.invokeAny(
-          $a![0]?.as(const jni$_.JObjectType(), releaseOriginal: true),
+          ($a![0] as jni$_.JObject?),
         );
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -10779,14 +8720,65 @@
       if ($d ==
           r'invokeAny(Ljava/util/Collection;JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object;') {
         final $r = _$impls[$p]!.invokeAny$1(
-          $a![0]?.as(const jni$_.JObjectType(), releaseOriginal: true),
-          $a![1]!
-              .as(const jni$_.JLongType(), releaseOriginal: true)
-              .longValue(releaseOriginal: true),
-          $a![2]?.as(const $TimeUnit$Type(), releaseOriginal: true),
+          ($a![0] as jni$_.JObject?),
+          ($a![1] as jni$_.JLong).toDartInt(releaseOriginal: true),
+          ($a![2] as TimeUnit?),
         );
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
+      if ($d == r'isShutdown()Z') {
+        final $r = _$impls[$p]!.isShutdown();
+        return $r.toJBoolean().reference.toPointer();
+      }
+      if ($d == r'isTerminated()Z') {
+        final $r = _$impls[$p]!.isTerminated();
+        return $r.toJBoolean().reference.toPointer();
+      }
+      if ($d == r'shutdown()V') {
+        _$impls[$p]!.shutdown();
+        return jni$_.nullptr;
+      }
+      if ($d == r'shutdownNow()Ljava/util/List;') {
+        final $r = _$impls[$p]!.shutdownNow();
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
+      if ($d == r'submit(Ljava/lang/Runnable;)Ljava/util/concurrent/Future;') {
+        final $r = _$impls[$p]!.submit(
+          ($a![0] as jni$_.JObject?),
+        );
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
+      if ($d ==
+          r'submit(Ljava/lang/Runnable;Ljava/lang/Object;)Ljava/util/concurrent/Future;') {
+        final $r = _$impls[$p]!.submit$1(
+          ($a![0] as jni$_.JObject?),
+          ($a![1] as jni$_.JObject?),
+        );
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
+      if ($d ==
+          r'submit(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;') {
+        final $r = _$impls[$p]!.submit$2(
+          ($a![0] as jni$_.JObject?),
+        );
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -10817,6 +8809,7 @@
       $p,
       _$invokePointer,
       [
+        if ($impl.close$async) r'close()V',
         if ($impl.shutdown$async) r'shutdown()V',
       ],
     );
@@ -10829,105 +8822,509 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return ExecutorService.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<ExecutorService>();
+  }
+}
+
+extension ExecutorService$$Methods on ExecutorService {
+  static final _id_awaitTermination = ExecutorService._class.instanceMethodId(
+    r'awaitTermination',
+    r'(JLjava/util/concurrent/TimeUnit;)Z',
+  );
+
+  static final _awaitTermination = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Int64, jni$_.Pointer<jni$_.Void>)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, core$_.int, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract boolean awaitTermination(long j, java.util.concurrent.TimeUnit timeUnit)`
+  core$_.bool awaitTermination(
+    core$_.int j,
+    TimeUnit? timeUnit,
+  ) {
+    final _$timeUnit = timeUnit?.reference ?? jni$_.jNullReference;
+    return _awaitTermination(reference.pointer, _id_awaitTermination.pointer, j,
+            _$timeUnit.pointer)
+        .boolean;
+  }
+
+  static final _id_close = ExecutorService._class.instanceMethodId(
+    r'close',
+    r'()V',
+  );
+
+  static final _close = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public void close()`
+  void close() {
+    _close(reference.pointer, _id_close.pointer).check();
+  }
+
+  static final _id_invokeAll = ExecutorService._class.instanceMethodId(
+    r'invokeAll',
+    r'(Ljava/util/Collection;)Ljava/util/List;',
+  );
+
+  static final _invokeAll = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable> collection)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JList<jni$_.JObject?>? invokeAll<$T extends jni$_.JObject?>(
+    jni$_.JObject? collection,
+  ) {
+    final _$collection = collection?.reference ?? jni$_.jNullReference;
+    return _invokeAll(
+            reference.pointer, _id_invokeAll.pointer, _$collection.pointer)
+        .object<jni$_.JList<jni$_.JObject?>?>();
+  }
+
+  static final _id_invokeAll$1 = ExecutorService._class.instanceMethodId(
+    r'invokeAll',
+    r'(Ljava/util/Collection;JLjava/util/concurrent/TimeUnit;)Ljava/util/List;',
+  );
+
+  static final _invokeAll$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int64,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable> collection, long j, java.util.concurrent.TimeUnit timeUnit)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JList<jni$_.JObject?>? invokeAll$1<$T extends jni$_.JObject?>(
+    jni$_.JObject? collection,
+    core$_.int j,
+    TimeUnit? timeUnit,
+  ) {
+    final _$collection = collection?.reference ?? jni$_.jNullReference;
+    final _$timeUnit = timeUnit?.reference ?? jni$_.jNullReference;
+    return _invokeAll$1(reference.pointer, _id_invokeAll$1.pointer,
+            _$collection.pointer, j, _$timeUnit.pointer)
+        .object<jni$_.JList<jni$_.JObject?>?>();
+  }
+
+  static final _id_invokeAny = ExecutorService._class.instanceMethodId(
+    r'invokeAny',
+    r'(Ljava/util/Collection;)Ljava/lang/Object;',
+  );
+
+  static final _invokeAny = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable> collection)`
+  /// The returned object must be released after use, by calling the [release] method.
+  $T? invokeAny<$T extends jni$_.JObject?>(
+    jni$_.JObject? collection,
+  ) {
+    final _$collection = collection?.reference ?? jni$_.jNullReference;
+    return _invokeAny(
+            reference.pointer, _id_invokeAny.pointer, _$collection.pointer)
+        .object<$T?>();
+  }
+
+  static final _id_invokeAny$1 = ExecutorService._class.instanceMethodId(
+    r'invokeAny',
+    r'(Ljava/util/Collection;JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object;',
+  );
+
+  static final _invokeAny$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int64,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable> collection, long j, java.util.concurrent.TimeUnit timeUnit)`
+  /// The returned object must be released after use, by calling the [release] method.
+  $T? invokeAny$1<$T extends jni$_.JObject?>(
+    jni$_.JObject? collection,
+    core$_.int j,
+    TimeUnit? timeUnit,
+  ) {
+    final _$collection = collection?.reference ?? jni$_.jNullReference;
+    final _$timeUnit = timeUnit?.reference ?? jni$_.jNullReference;
+    return _invokeAny$1(reference.pointer, _id_invokeAny$1.pointer,
+            _$collection.pointer, j, _$timeUnit.pointer)
+        .object<$T?>();
+  }
+
+  static final _id_isShutdown = ExecutorService._class.instanceMethodId(
+    r'isShutdown',
+    r'()Z',
+  );
+
+  static final _isShutdown = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract boolean isShutdown()`
+  core$_.bool isShutdown() {
+    return _isShutdown(reference.pointer, _id_isShutdown.pointer).boolean;
+  }
+
+  static final _id_isTerminated = ExecutorService._class.instanceMethodId(
+    r'isTerminated',
+    r'()Z',
+  );
+
+  static final _isTerminated = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract boolean isTerminated()`
+  core$_.bool isTerminated() {
+    return _isTerminated(reference.pointer, _id_isTerminated.pointer).boolean;
+  }
+
+  static final _id_shutdown = ExecutorService._class.instanceMethodId(
+    r'shutdown',
+    r'()V',
+  );
+
+  static final _shutdown = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract void shutdown()`
+  void shutdown() {
+    _shutdown(reference.pointer, _id_shutdown.pointer).check();
+  }
+
+  static final _id_shutdownNow = ExecutorService._class.instanceMethodId(
+    r'shutdownNow',
+    r'()Ljava/util/List;',
+  );
+
+  static final _shutdownNow = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.util.List<java.lang.Runnable> shutdownNow()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JList<jni$_.JObject?>? shutdownNow() {
+    return _shutdownNow(reference.pointer, _id_shutdownNow.pointer)
+        .object<jni$_.JList<jni$_.JObject?>?>();
+  }
+
+  static final _id_submit = ExecutorService._class.instanceMethodId(
+    r'submit',
+    r'(Ljava/lang/Runnable;)Ljava/util/concurrent/Future;',
+  );
+
+  static final _submit = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.util.concurrent.Future<?> submit(java.lang.Runnable runnable)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? submit(
+    jni$_.JObject? runnable,
+  ) {
+    final _$runnable = runnable?.reference ?? jni$_.jNullReference;
+    return _submit(reference.pointer, _id_submit.pointer, _$runnable.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_submit$1 = ExecutorService._class.instanceMethodId(
+    r'submit',
+    r'(Ljava/lang/Runnable;Ljava/lang/Object;)Ljava/util/concurrent/Future;',
+  );
+
+  static final _submit$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.util.concurrent.Future<T> submit(java.lang.Runnable runnable, T object)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? submit$1<$T extends jni$_.JObject?>(
+    jni$_.JObject? runnable,
+    $T? object,
+  ) {
+    final _$runnable = runnable?.reference ?? jni$_.jNullReference;
+    final _$object = object?.reference ?? jni$_.jNullReference;
+    return _submit$1(reference.pointer, _id_submit$1.pointer,
+            _$runnable.pointer, _$object.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_submit$2 = ExecutorService._class.instanceMethodId(
+    r'submit',
+    r'(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;',
+  );
+
+  static final _submit$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.util.concurrent.Future<T> submit(java.util.concurrent.Callable<T> callable)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? submit$2<$T extends jni$_.JObject?>(
+    jni$_.JObject? callable,
+  ) {
+    final _$callable = callable?.reference ?? jni$_.jNullReference;
+    return _submit$2(
+            reference.pointer, _id_submit$2.pointer, _$callable.pointer)
+        .object<jni$_.JObject?>();
   }
 }
 
 abstract base mixin class $ExecutorService {
   factory $ExecutorService({
-    required void Function() shutdown,
-    bool shutdown$async,
-    required jni$_.JList<jni$_.JObject?>? Function() shutdownNow,
-    required bool Function() isShutdown,
-    required bool Function() isTerminated,
-    required bool Function(int j, TimeUnit? timeUnit) awaitTermination,
-    required jni$_.JObject? Function(jni$_.JObject? callable) submit,
-    required jni$_.JObject? Function(
-            jni$_.JObject? runnable, jni$_.JObject? object)
-        submit$1,
-    required jni$_.JObject? Function(jni$_.JObject? runnable) submit$2,
+    required core$_.bool Function(core$_.int j, TimeUnit? timeUnit)
+        awaitTermination,
+    required void Function() close,
+    core$_.bool close$async,
     required jni$_.JList<jni$_.JObject?>? Function(jni$_.JObject? collection)
         invokeAll,
     required jni$_.JList<jni$_.JObject?>? Function(
-            jni$_.JObject? collection, int j, TimeUnit? timeUnit)
+            jni$_.JObject? collection, core$_.int j, TimeUnit? timeUnit)
         invokeAll$1,
     required jni$_.JObject? Function(jni$_.JObject? collection) invokeAny,
     required jni$_.JObject? Function(
-            jni$_.JObject? collection, int j, TimeUnit? timeUnit)
+            jni$_.JObject? collection, core$_.int j, TimeUnit? timeUnit)
         invokeAny$1,
+    required core$_.bool Function() isShutdown,
+    required core$_.bool Function() isTerminated,
+    required void Function() shutdown,
+    core$_.bool shutdown$async,
+    required jni$_.JList<jni$_.JObject?>? Function() shutdownNow,
+    required jni$_.JObject? Function(jni$_.JObject? runnable) submit,
+    required jni$_.JObject? Function(
+            jni$_.JObject? runnable, jni$_.JObject? object)
+        submit$1,
+    required jni$_.JObject? Function(jni$_.JObject? callable) submit$2,
   }) = _$ExecutorService;
 
-  void shutdown();
-  bool get shutdown$async => false;
-  jni$_.JList<jni$_.JObject?>? shutdownNow();
-  bool isShutdown();
-  bool isTerminated();
-  bool awaitTermination(int j, TimeUnit? timeUnit);
-  jni$_.JObject? submit(jni$_.JObject? callable);
-  jni$_.JObject? submit$1(jni$_.JObject? runnable, jni$_.JObject? object);
-  jni$_.JObject? submit$2(jni$_.JObject? runnable);
+  core$_.bool awaitTermination(core$_.int j, TimeUnit? timeUnit);
+  void close();
+  core$_.bool get close$async => false;
   jni$_.JList<jni$_.JObject?>? invokeAll(jni$_.JObject? collection);
   jni$_.JList<jni$_.JObject?>? invokeAll$1(
-      jni$_.JObject? collection, int j, TimeUnit? timeUnit);
+      jni$_.JObject? collection, core$_.int j, TimeUnit? timeUnit);
   jni$_.JObject? invokeAny(jni$_.JObject? collection);
   jni$_.JObject? invokeAny$1(
-      jni$_.JObject? collection, int j, TimeUnit? timeUnit);
+      jni$_.JObject? collection, core$_.int j, TimeUnit? timeUnit);
+  core$_.bool isShutdown();
+  core$_.bool isTerminated();
+  void shutdown();
+  core$_.bool get shutdown$async => false;
+  jni$_.JList<jni$_.JObject?>? shutdownNow();
+  jni$_.JObject? submit(jni$_.JObject? runnable);
+  jni$_.JObject? submit$1(jni$_.JObject? runnable, jni$_.JObject? object);
+  jni$_.JObject? submit$2(jni$_.JObject? callable);
 }
 
 final class _$ExecutorService with $ExecutorService {
   _$ExecutorService({
-    required void Function() shutdown,
-    this.shutdown$async = false,
-    required jni$_.JList<jni$_.JObject?>? Function() shutdownNow,
-    required bool Function() isShutdown,
-    required bool Function() isTerminated,
-    required bool Function(int j, TimeUnit? timeUnit) awaitTermination,
-    required jni$_.JObject? Function(jni$_.JObject? callable) submit,
-    required jni$_.JObject? Function(
-            jni$_.JObject? runnable, jni$_.JObject? object)
-        submit$1,
-    required jni$_.JObject? Function(jni$_.JObject? runnable) submit$2,
+    required core$_.bool Function(core$_.int j, TimeUnit? timeUnit)
+        awaitTermination,
+    required void Function() close,
+    this.close$async = false,
     required jni$_.JList<jni$_.JObject?>? Function(jni$_.JObject? collection)
         invokeAll,
     required jni$_.JList<jni$_.JObject?>? Function(
-            jni$_.JObject? collection, int j, TimeUnit? timeUnit)
+            jni$_.JObject? collection, core$_.int j, TimeUnit? timeUnit)
         invokeAll$1,
     required jni$_.JObject? Function(jni$_.JObject? collection) invokeAny,
     required jni$_.JObject? Function(
-            jni$_.JObject? collection, int j, TimeUnit? timeUnit)
+            jni$_.JObject? collection, core$_.int j, TimeUnit? timeUnit)
         invokeAny$1,
-  })  : _shutdown = shutdown,
-        _shutdownNow = shutdownNow,
-        _isShutdown = isShutdown,
-        _isTerminated = isTerminated,
-        _awaitTermination = awaitTermination,
-        _submit = submit,
-        _submit$1 = submit$1,
-        _submit$2 = submit$2,
+    required core$_.bool Function() isShutdown,
+    required core$_.bool Function() isTerminated,
+    required void Function() shutdown,
+    this.shutdown$async = false,
+    required jni$_.JList<jni$_.JObject?>? Function() shutdownNow,
+    required jni$_.JObject? Function(jni$_.JObject? runnable) submit,
+    required jni$_.JObject? Function(
+            jni$_.JObject? runnable, jni$_.JObject? object)
+        submit$1,
+    required jni$_.JObject? Function(jni$_.JObject? callable) submit$2,
+  })  : _awaitTermination = awaitTermination,
+        _close = close,
         _invokeAll = invokeAll,
         _invokeAll$1 = invokeAll$1,
         _invokeAny = invokeAny,
-        _invokeAny$1 = invokeAny$1;
+        _invokeAny$1 = invokeAny$1,
+        _isShutdown = isShutdown,
+        _isTerminated = isTerminated,
+        _shutdown = shutdown,
+        _shutdownNow = shutdownNow,
+        _submit = submit,
+        _submit$1 = submit$1,
+        _submit$2 = submit$2;
 
-  final void Function() _shutdown;
-  final bool shutdown$async;
-  final jni$_.JList<jni$_.JObject?>? Function() _shutdownNow;
-  final bool Function() _isShutdown;
-  final bool Function() _isTerminated;
-  final bool Function(int j, TimeUnit? timeUnit) _awaitTermination;
-  final jni$_.JObject? Function(jni$_.JObject? callable) _submit;
-  final jni$_.JObject? Function(jni$_.JObject? runnable, jni$_.JObject? object)
-      _submit$1;
-  final jni$_.JObject? Function(jni$_.JObject? runnable) _submit$2;
+  final core$_.bool Function(core$_.int j, TimeUnit? timeUnit)
+      _awaitTermination;
+  final void Function() _close;
+  final core$_.bool close$async;
   final jni$_.JList<jni$_.JObject?>? Function(jni$_.JObject? collection)
       _invokeAll;
   final jni$_.JList<jni$_.JObject?>? Function(
-      jni$_.JObject? collection, int j, TimeUnit? timeUnit) _invokeAll$1;
+      jni$_.JObject? collection, core$_.int j, TimeUnit? timeUnit) _invokeAll$1;
   final jni$_.JObject? Function(jni$_.JObject? collection) _invokeAny;
   final jni$_.JObject? Function(
-      jni$_.JObject? collection, int j, TimeUnit? timeUnit) _invokeAny$1;
+      jni$_.JObject? collection, core$_.int j, TimeUnit? timeUnit) _invokeAny$1;
+  final core$_.bool Function() _isShutdown;
+  final core$_.bool Function() _isTerminated;
+  final void Function() _shutdown;
+  final core$_.bool shutdown$async;
+  final jni$_.JList<jni$_.JObject?>? Function() _shutdownNow;
+  final jni$_.JObject? Function(jni$_.JObject? runnable) _submit;
+  final jni$_.JObject? Function(jni$_.JObject? runnable, jni$_.JObject? object)
+      _submit$1;
+  final jni$_.JObject? Function(jni$_.JObject? callable) _submit$2;
+
+  core$_.bool awaitTermination(core$_.int j, TimeUnit? timeUnit) {
+    return _awaitTermination(j, timeUnit);
+  }
+
+  void close() {
+    return _close();
+  }
+
+  jni$_.JList<jni$_.JObject?>? invokeAll(jni$_.JObject? collection) {
+    return _invokeAll(collection);
+  }
+
+  jni$_.JList<jni$_.JObject?>? invokeAll$1(
+      jni$_.JObject? collection, core$_.int j, TimeUnit? timeUnit) {
+    return _invokeAll$1(collection, j, timeUnit);
+  }
+
+  jni$_.JObject? invokeAny(jni$_.JObject? collection) {
+    return _invokeAny(collection);
+  }
+
+  jni$_.JObject? invokeAny$1(
+      jni$_.JObject? collection, core$_.int j, TimeUnit? timeUnit) {
+    return _invokeAny$1(collection, j, timeUnit);
+  }
+
+  core$_.bool isShutdown() {
+    return _isShutdown();
+  }
+
+  core$_.bool isTerminated() {
+    return _isTerminated();
+  }
 
   void shutdown() {
     return _shutdown();
@@ -10937,142 +9334,65 @@
     return _shutdownNow();
   }
 
-  bool isShutdown() {
-    return _isShutdown();
-  }
-
-  bool isTerminated() {
-    return _isTerminated();
-  }
-
-  bool awaitTermination(int j, TimeUnit? timeUnit) {
-    return _awaitTermination(j, timeUnit);
-  }
-
-  jni$_.JObject? submit(jni$_.JObject? callable) {
-    return _submit(callable);
+  jni$_.JObject? submit(jni$_.JObject? runnable) {
+    return _submit(runnable);
   }
 
   jni$_.JObject? submit$1(jni$_.JObject? runnable, jni$_.JObject? object) {
     return _submit$1(runnable, object);
   }
 
-  jni$_.JObject? submit$2(jni$_.JObject? runnable) {
-    return _submit$2(runnable);
-  }
-
-  jni$_.JList<jni$_.JObject?>? invokeAll(jni$_.JObject? collection) {
-    return _invokeAll(collection);
-  }
-
-  jni$_.JList<jni$_.JObject?>? invokeAll$1(
-      jni$_.JObject? collection, int j, TimeUnit? timeUnit) {
-    return _invokeAll$1(collection, j, timeUnit);
-  }
-
-  jni$_.JObject? invokeAny(jni$_.JObject? collection) {
-    return _invokeAny(collection);
-  }
-
-  jni$_.JObject? invokeAny$1(
-      jni$_.JObject? collection, int j, TimeUnit? timeUnit) {
-    return _invokeAny$1(collection, j, timeUnit);
+  jni$_.JObject? submit$2(jni$_.JObject? callable) {
+    return _submit$2(callable);
   }
 }
 
-final class $ExecutorService$NullableType
-    extends jni$_.JObjType<ExecutorService?> {
+final class $ExecutorService$Type$ extends jni$_.JType<ExecutorService> {
   @jni$_.internal
-  const $ExecutorService$NullableType();
+  const $ExecutorService$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/util/concurrent/ExecutorService;';
-
-  @jni$_.internal
-  @core$_.override
-  ExecutorService? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : ExecutorService.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ExecutorService?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ExecutorService$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ExecutorService$NullableType) &&
-        other is $ExecutorService$NullableType;
-  }
-}
-
-final class $ExecutorService$Type extends jni$_.JObjType<ExecutorService> {
-  @jni$_.internal
-  const $ExecutorService$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/util/concurrent/ExecutorService;';
-
-  @jni$_.internal
-  @core$_.override
-  ExecutorService fromReference(jni$_.JReference reference) =>
-      ExecutorService.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ExecutorService?> get nullableType =>
-      const $ExecutorService$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ExecutorService$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ExecutorService$Type) &&
-        other is $ExecutorService$Type;
-  }
 }
 
 /// from: `okhttp3.Cache$Companion`
-class Cache$Companion extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Cache$Companion> $type;
-
-  @jni$_.internal
-  Cache$Companion.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Cache$Companion._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Cache$Companion');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Cache$Companion$NullableType();
-  static const type = $Cache$Companion$Type();
-  static final _id_key = _class.instanceMethodId(
+  static const jni$_.JType<Cache$Companion> type = $Cache$Companion$Type$();
+  static final _id_new$ = _class.constructorId(
+    r'(Lkotlin/jvm/internal/DefaultConstructorMarker;)V',
+  );
+
+  static final _new$ = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `synthetic public void <init>(kotlin.jvm.internal.DefaultConstructorMarker defaultConstructorMarker)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory Cache$Companion(
+    jni$_.JObject? defaultConstructorMarker,
+  ) {
+    final _$defaultConstructorMarker =
+        defaultConstructorMarker?.reference ?? jni$_.jNullReference;
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$defaultConstructorMarker.pointer)
+        .object<Cache$Companion>();
+  }
+}
+
+extension Cache$Companion$$Methods on Cache$Companion {
+  static final _id_key = Cache$Companion._class.instanceMethodId(
     r'key',
     r'(Lokhttp3/HttpUrl;)Ljava/lang/String;',
   );
@@ -11088,18 +9408,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final java.lang.String key(okhttp3.HttpUrl httpUrl)`
+  /// from: `public fun key(url: okhttp3.HttpUrl): kotlin.String`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString key(
     jni$_.JObject httpUrl,
   ) {
     final _$httpUrl = httpUrl.reference;
-    return _key(
-            reference.pointer, _id_key as jni$_.JMethodIDPtr, _$httpUrl.pointer)
-        .object<jni$_.JString>(const jni$_.JStringType());
+    return _key(reference.pointer, _id_key.pointer, _$httpUrl.pointer)
+        .object<jni$_.JString>();
   }
 
-  static final _id_varyMatches = _class.instanceMethodId(
+  static final _id_varyMatches = Cache$Companion._class.instanceMethodId(
     r'varyMatches',
     r'(Lokhttp3/Response;Lokhttp3/Headers;Lokhttp3/Request;)Z',
   );
@@ -11123,8 +9442,8 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final boolean varyMatches(okhttp3.Response response, okhttp3.Headers headers, okhttp3.Request request)`
-  bool varyMatches(
+  /// from: `public fun varyMatches(cachedResponse: okhttp3.Response, cachedRequest: okhttp3.Headers, newRequest: okhttp3.Request): kotlin.Boolean`
+  core$_.bool varyMatches(
     Response response,
     Headers headers,
     Request request,
@@ -11132,16 +9451,12 @@
     final _$response = response.reference;
     final _$headers = headers.reference;
     final _$request = request.reference;
-    return _varyMatches(
-            reference.pointer,
-            _id_varyMatches as jni$_.JMethodIDPtr,
-            _$response.pointer,
-            _$headers.pointer,
-            _$request.pointer)
+    return _varyMatches(reference.pointer, _id_varyMatches.pointer,
+            _$response.pointer, _$headers.pointer, _$request.pointer)
         .boolean;
   }
 
-  static final _id_hasVaryAll = _class.instanceMethodId(
+  static final _id_hasVaryAll = Cache$Companion._class.instanceMethodId(
     r'hasVaryAll',
     r'(Lokhttp3/Response;)Z',
   );
@@ -11157,17 +9472,17 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final boolean hasVaryAll(okhttp3.Response response)`
-  bool hasVaryAll(
+  /// from: `public fun hasVaryAll(): kotlin.Boolean`
+  core$_.bool hasVaryAll(
     Response response,
   ) {
     final _$response = response.reference;
-    return _hasVaryAll(reference.pointer, _id_hasVaryAll as jni$_.JMethodIDPtr,
-            _$response.pointer)
+    return _hasVaryAll(
+            reference.pointer, _id_hasVaryAll.pointer, _$response.pointer)
         .boolean;
   }
 
-  static final _id_varyHeaders = _class.instanceMethodId(
+  static final _id_varyHeaders = Cache$Companion._class.instanceMethodId(
     r'varyHeaders',
     r'(Lokhttp3/Response;)Lokhttp3/Headers;',
   );
@@ -11183,137 +9498,34 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.Headers varyHeaders(okhttp3.Response response)`
+  /// from: `public fun varyHeaders(): okhttp3.Headers`
   /// The returned object must be released after use, by calling the [release] method.
   Headers varyHeaders(
     Response response,
   ) {
     final _$response = response.reference;
-    return _varyHeaders(reference.pointer,
-            _id_varyHeaders as jni$_.JMethodIDPtr, _$response.pointer)
-        .object<Headers>(const $Headers$Type());
-  }
-
-  static final _id_new$ = _class.constructorId(
-    r'(Lkotlin/jvm/internal/DefaultConstructorMarker;)V',
-  );
-
-  static final _new$ = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_NewObject')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `synthetic public void <init>(kotlin.jvm.internal.DefaultConstructorMarker defaultConstructorMarker)`
-  /// The returned object must be released after use, by calling the [release] method.
-  factory Cache$Companion(
-    jni$_.JObject? defaultConstructorMarker,
-  ) {
-    final _$defaultConstructorMarker =
-        defaultConstructorMarker?.reference ?? jni$_.jNullReference;
-    return Cache$Companion.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$defaultConstructorMarker.pointer)
-        .reference);
+    return _varyHeaders(
+            reference.pointer, _id_varyHeaders.pointer, _$response.pointer)
+        .object<Headers>();
   }
 }
 
-final class $Cache$Companion$NullableType
-    extends jni$_.JObjType<Cache$Companion?> {
+final class $Cache$Companion$Type$ extends jni$_.JType<Cache$Companion> {
   @jni$_.internal
-  const $Cache$Companion$NullableType();
+  const $Cache$Companion$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Cache$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  Cache$Companion? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Cache$Companion.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Cache$Companion?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Cache$Companion$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Cache$Companion$NullableType) &&
-        other is $Cache$Companion$NullableType;
-  }
-}
-
-final class $Cache$Companion$Type extends jni$_.JObjType<Cache$Companion> {
-  @jni$_.internal
-  const $Cache$Companion$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Cache$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  Cache$Companion fromReference(jni$_.JReference reference) =>
-      Cache$Companion.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Cache$Companion?> get nullableType =>
-      const $Cache$Companion$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Cache$Companion$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Cache$Companion$Type) &&
-        other is $Cache$Companion$Type;
-  }
 }
 
 /// from: `okhttp3.Cache$Entry$Companion`
-class JObject$Companion extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<JObject$Companion> $type;
-
-  @jni$_.internal
-  JObject$Companion.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type JObject$Companion._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Cache$Entry$Companion');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $JObject$Companion$NullableType();
-  static const type = $JObject$Companion$Type();
+  static const jni$_.JType<JObject$Companion> type = $JObject$Companion$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Lkotlin/jvm/internal/DefaultConstructorMarker;)V',
   );
@@ -11336,105 +9548,27 @@
   ) {
     final _$defaultConstructorMarker =
         defaultConstructorMarker?.reference ?? jni$_.jNullReference;
-    return JObject$Companion.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$defaultConstructorMarker.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$defaultConstructorMarker.pointer)
+        .object<JObject$Companion>();
   }
 }
 
-final class $JObject$Companion$NullableType
-    extends jni$_.JObjType<JObject$Companion?> {
+final class $JObject$Companion$Type$ extends jni$_.JType<JObject$Companion> {
   @jni$_.internal
-  const $JObject$Companion$NullableType();
+  const $JObject$Companion$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Cache$Entry$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  JObject$Companion? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : JObject$Companion.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<JObject$Companion?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($JObject$Companion$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($JObject$Companion$NullableType) &&
-        other is $JObject$Companion$NullableType;
-  }
-}
-
-final class $JObject$Companion$Type extends jni$_.JObjType<JObject$Companion> {
-  @jni$_.internal
-  const $JObject$Companion$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Cache$Entry$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  JObject$Companion fromReference(jni$_.JReference reference) =>
-      JObject$Companion.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<JObject$Companion?> get nullableType =>
-      const $JObject$Companion$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($JObject$Companion$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($JObject$Companion$Type) &&
-        other is $JObject$Companion$Type;
-  }
 }
 
 /// from: `okhttp3.Cache`
-class Cache extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Cache> $type;
-
-  @jni$_.internal
-  Cache.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Cache._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/Cache');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Cache$NullableType();
-  static const type = $Cache$Type();
+  static const jni$_.JType<Cache> type = $Cache$Type$();
   static final _id_Companion = _class.staticFieldId(
     r'Companion',
     r'Lokhttp3/Cache$Companion;',
@@ -11443,7 +9577,7 @@
   /// from: `static public final okhttp3.Cache$Companion Companion`
   /// The returned object must be released after use, by calling the [release] method.
   static Cache$Companion get Companion =>
-      _id_Companion.get(_class, const $Cache$Companion$Type());
+      _id_Companion.get(_class, Cache$Companion.type) as Cache$Companion;
 
   static final _id_new$ = _class.constructorId(
     r'(Ljava/io/File;JLokhttp3/internal/io/FileSystem;)V',
@@ -11465,48 +9599,21 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>)>();
 
   /// from: `public void <init>(java.io.File file, long j, okhttp3.internal.io.FileSystem fileSystem)`
   /// The returned object must be released after use, by calling the [release] method.
   factory Cache(
     jni$_.JObject file,
-    int j,
+    core$_.int j,
     jni$_.JObject fileSystem,
   ) {
     final _$file = file.reference;
     final _$fileSystem = fileSystem.reference;
-    return Cache.fromReference(_new$(
-            _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
-            _$file.pointer,
-            j,
+    return _new$(_class.reference.pointer, _id_new$.pointer, _$file.pointer, j,
             _$fileSystem.pointer)
-        .reference);
-  }
-
-  static final _id_isClosed = _class.instanceMethodId(
-    r'isClosed',
-    r'()Z',
-  );
-
-  static final _isClosed = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final boolean isClosed()`
-  bool isClosed() {
-    return _isClosed(reference.pointer, _id_isClosed as jni$_.JMethodIDPtr)
-        .boolean;
+        .object<Cache>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -11523,341 +9630,18 @@
           'globalEnv_NewObject')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
 
   /// from: `public void <init>(java.io.File file, long j)`
   /// The returned object must be released after use, by calling the [release] method.
   factory Cache.new$1(
     jni$_.JObject file,
-    int j,
+    core$_.int j,
   ) {
     final _$file = file.reference;
-    return Cache.fromReference(_new$1(_class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr, _$file.pointer, j)
-        .reference);
-  }
-
-  static final _id_initialize = _class.instanceMethodId(
-    r'initialize',
-    r'()V',
-  );
-
-  static final _initialize = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final void initialize()`
-  void initialize() {
-    _initialize(reference.pointer, _id_initialize as jni$_.JMethodIDPtr)
-        .check();
-  }
-
-  static final _id_delete = _class.instanceMethodId(
-    r'delete',
-    r'()V',
-  );
-
-  static final _delete = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final void delete()`
-  void delete() {
-    _delete(reference.pointer, _id_delete as jni$_.JMethodIDPtr).check();
-  }
-
-  static final _id_evictAll = _class.instanceMethodId(
-    r'evictAll',
-    r'()V',
-  );
-
-  static final _evictAll = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final void evictAll()`
-  void evictAll() {
-    _evictAll(reference.pointer, _id_evictAll as jni$_.JMethodIDPtr).check();
-  }
-
-  static final _id_urls = _class.instanceMethodId(
-    r'urls',
-    r'()Ljava/util/Iterator;',
-  );
-
-  static final _urls = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.util.Iterator urls()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JIterator<jni$_.JString> urls() {
-    return _urls(reference.pointer, _id_urls as jni$_.JMethodIDPtr)
-        .object<jni$_.JIterator<jni$_.JString>>(
-            const jni$_.JIteratorType<jni$_.JString>(jni$_.JStringType()));
-  }
-
-  static final _id_writeAbortCount = _class.instanceMethodId(
-    r'writeAbortCount',
-    r'()I',
-  );
-
-  static final _writeAbortCount = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int writeAbortCount()`
-  int writeAbortCount() {
-    return _writeAbortCount(
-            reference.pointer, _id_writeAbortCount as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_writeSuccessCount = _class.instanceMethodId(
-    r'writeSuccessCount',
-    r'()I',
-  );
-
-  static final _writeSuccessCount = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int writeSuccessCount()`
-  int writeSuccessCount() {
-    return _writeSuccessCount(
-            reference.pointer, _id_writeSuccessCount as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_size = _class.instanceMethodId(
-    r'size',
-    r'()J',
-  );
-
-  static final _size = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final long size()`
-  int size() {
-    return _size(reference.pointer, _id_size as jni$_.JMethodIDPtr).long;
-  }
-
-  static final _id_maxSize = _class.instanceMethodId(
-    r'maxSize',
-    r'()J',
-  );
-
-  static final _maxSize = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final long maxSize()`
-  int maxSize() {
-    return _maxSize(reference.pointer, _id_maxSize as jni$_.JMethodIDPtr).long;
-  }
-
-  static final _id_flush = _class.instanceMethodId(
-    r'flush',
-    r'()V',
-  );
-
-  static final _flush = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public void flush()`
-  void flush() {
-    _flush(reference.pointer, _id_flush as jni$_.JMethodIDPtr).check();
-  }
-
-  static final _id_close = _class.instanceMethodId(
-    r'close',
-    r'()V',
-  );
-
-  static final _close = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public void close()`
-  void close() {
-    _close(reference.pointer, _id_close as jni$_.JMethodIDPtr).check();
-  }
-
-  static final _id_directory = _class.instanceMethodId(
-    r'directory',
-    r'()Ljava/io/File;',
-  );
-
-  static final _directory = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.io.File directory()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject directory() {
-    return _directory(reference.pointer, _id_directory as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
-  }
-
-  static final _id_networkCount = _class.instanceMethodId(
-    r'networkCount',
-    r'()I',
-  );
-
-  static final _networkCount = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int networkCount()`
-  int networkCount() {
-    return _networkCount(
-            reference.pointer, _id_networkCount as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_hitCount = _class.instanceMethodId(
-    r'hitCount',
-    r'()I',
-  );
-
-  static final _hitCount = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int hitCount()`
-  int hitCount() {
-    return _hitCount(reference.pointer, _id_hitCount as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_requestCount = _class.instanceMethodId(
-    r'requestCount',
-    r'()I',
-  );
-
-  static final _requestCount = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int requestCount()`
-  int requestCount() {
-    return _requestCount(
-            reference.pointer, _id_requestCount as jni$_.JMethodIDPtr)
-        .integer;
+    return _new$1(
+            _class.reference.pointer, _id_new$1.pointer, _$file.pointer, j)
+        .object<Cache>();
   }
 
   static final _id_key = _class.staticMethodId(
@@ -11882,142 +9666,372 @@
     jni$_.JObject httpUrl,
   ) {
     final _$httpUrl = httpUrl.reference;
-    return _key(_class.reference.pointer, _id_key as jni$_.JMethodIDPtr,
-            _$httpUrl.pointer)
-        .object<jni$_.JString>(const jni$_.JStringType());
+    return _key(_class.reference.pointer, _id_key.pointer, _$httpUrl.pointer)
+        .object<jni$_.JString>();
   }
 }
 
-final class $Cache$NullableType extends jni$_.JObjType<Cache?> {
+extension Cache$$Methods on Cache {
+  static final _id_get$isClosed = Cache._class.instanceMethodId(
+    r'isClosed',
+    r'()Z',
+  );
+
+  static final _get$isClosed = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final boolean isClosed()`
+  core$_.bool get isClosed {
+    return _get$isClosed(reference.pointer, _id_get$isClosed.pointer).boolean;
+  }
+
+  static final _id_initialize = Cache._class.instanceMethodId(
+    r'initialize',
+    r'()V',
+  );
+
+  static final _initialize = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun initialize(): kotlin.Unit`
+  void initialize() {
+    _initialize(reference.pointer, _id_initialize.pointer).check();
+  }
+
+  static final _id_delete = Cache._class.instanceMethodId(
+    r'delete',
+    r'()V',
+  );
+
+  static final _delete = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun delete(): kotlin.Unit`
+  void delete() {
+    _delete(reference.pointer, _id_delete.pointer).check();
+  }
+
+  static final _id_evictAll = Cache._class.instanceMethodId(
+    r'evictAll',
+    r'()V',
+  );
+
+  static final _evictAll = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun evictAll(): kotlin.Unit`
+  void evictAll() {
+    _evictAll(reference.pointer, _id_evictAll.pointer).check();
+  }
+
+  static final _id_urls = Cache._class.instanceMethodId(
+    r'urls',
+    r'()Ljava/util/Iterator;',
+  );
+
+  static final _urls = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun urls(): kotlin.collections.MutableIterator<kotlin.String>`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JIterator<jni$_.JString> urls() {
+    return _urls(reference.pointer, _id_urls.pointer)
+        .object<jni$_.JIterator<jni$_.JString>>();
+  }
+
+  static final _id_writeAbortCount = Cache._class.instanceMethodId(
+    r'writeAbortCount',
+    r'()I',
+  );
+
+  static final _writeAbortCount = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun writeAbortCount(): kotlin.Int`
+  core$_.int writeAbortCount() {
+    return _writeAbortCount(reference.pointer, _id_writeAbortCount.pointer)
+        .integer;
+  }
+
+  static final _id_writeSuccessCount = Cache._class.instanceMethodId(
+    r'writeSuccessCount',
+    r'()I',
+  );
+
+  static final _writeSuccessCount = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun writeSuccessCount(): kotlin.Int`
+  core$_.int writeSuccessCount() {
+    return _writeSuccessCount(reference.pointer, _id_writeSuccessCount.pointer)
+        .integer;
+  }
+
+  static final _id_size = Cache._class.instanceMethodId(
+    r'size',
+    r'()J',
+  );
+
+  static final _size = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun size(): kotlin.Long`
+  core$_.int size() {
+    return _size(reference.pointer, _id_size.pointer).long;
+  }
+
+  static final _id_maxSize = Cache._class.instanceMethodId(
+    r'maxSize',
+    r'()J',
+  );
+
+  static final _maxSize = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun maxSize(): kotlin.Long`
+  core$_.int maxSize() {
+    return _maxSize(reference.pointer, _id_maxSize.pointer).long;
+  }
+
+  static final _id_flush = Cache._class.instanceMethodId(
+    r'flush',
+    r'()V',
+  );
+
+  static final _flush = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun flush(): kotlin.Unit`
+  void flush() {
+    _flush(reference.pointer, _id_flush.pointer).check();
+  }
+
+  static final _id_close = Cache._class.instanceMethodId(
+    r'close',
+    r'()V',
+  );
+
+  static final _close = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun close(): kotlin.Unit`
+  void close() {
+    _close(reference.pointer, _id_close.pointer).check();
+  }
+
+  static final _id_directory = Cache._class.instanceMethodId(
+    r'directory',
+    r'()Ljava/io/File;',
+  );
+
+  static final _directory = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.io.File directory()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject directory() {
+    return _directory(reference.pointer, _id_directory.pointer)
+        .object<jni$_.JObject>();
+  }
+
+  static final _id_networkCount = Cache._class.instanceMethodId(
+    r'networkCount',
+    r'()I',
+  );
+
+  static final _networkCount = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun networkCount(): kotlin.Int`
+  core$_.int networkCount() {
+    return _networkCount(reference.pointer, _id_networkCount.pointer).integer;
+  }
+
+  static final _id_hitCount = Cache._class.instanceMethodId(
+    r'hitCount',
+    r'()I',
+  );
+
+  static final _hitCount = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun hitCount(): kotlin.Int`
+  core$_.int hitCount() {
+    return _hitCount(reference.pointer, _id_hitCount.pointer).integer;
+  }
+
+  static final _id_requestCount = Cache._class.instanceMethodId(
+    r'requestCount',
+    r'()I',
+  );
+
+  static final _requestCount = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun requestCount(): kotlin.Int`
+  core$_.int requestCount() {
+    return _requestCount(reference.pointer, _id_requestCount.pointer).integer;
+  }
+}
+
+final class $Cache$Type$ extends jni$_.JType<Cache> {
   @jni$_.internal
-  const $Cache$NullableType();
+  const $Cache$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/Cache;';
-
-  @jni$_.internal
-  @core$_.override
-  Cache? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Cache.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Cache?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Cache$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Cache$NullableType) &&
-        other is $Cache$NullableType;
-  }
-}
-
-final class $Cache$Type extends jni$_.JObjType<Cache> {
-  @jni$_.internal
-  const $Cache$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/Cache;';
-
-  @jni$_.internal
-  @core$_.override
-  Cache fromReference(jni$_.JReference reference) => Cache.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Cache?> get nullableType => const $Cache$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Cache$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Cache$Type) && other is $Cache$Type;
-  }
 }
 
 /// from: `com.example.ok_http.RedirectReceivedCallback`
-class RedirectReceivedCallback extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<RedirectReceivedCallback> $type;
-
-  @jni$_.internal
-  RedirectReceivedCallback.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type RedirectReceivedCallback._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'com/example/ok_http/RedirectReceivedCallback');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $RedirectReceivedCallback$NullableType();
-  static const type = $RedirectReceivedCallback$Type();
-  static final _id_onRedirectReceived = _class.instanceMethodId(
-    r'onRedirectReceived',
-    r'(Lokhttp3/Response;Ljava/lang/String;)V',
-  );
-
-  static final _onRedirectReceived = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void onRedirectReceived(okhttp3.Response response, java.lang.String string)`
-  void onRedirectReceived(
-    Response response,
-    jni$_.JString string,
-  ) {
-    final _$response = response.reference;
-    final _$string = string.reference;
-    _onRedirectReceived(
-            reference.pointer,
-            _id_onRedirectReceived as jni$_.JMethodIDPtr,
-            _$response.pointer,
-            _$string.pointer)
-        .check();
-  }
+  static const jni$_.JType<RedirectReceivedCallback> type =
+      $RedirectReceivedCallback$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $RedirectReceivedCallback> _$impls = {};
+  static final core$_.Map<core$_.int, $RedirectReceivedCallback> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -12038,7 +10052,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -12046,8 +10060,8 @@
       final $a = $i.args;
       if ($d == r'onRedirectReceived(Lokhttp3/Response;Ljava/lang/String;)V') {
         _$impls[$p]!.onRedirectReceived(
-          $a![0]!.as(const $Response$Type(), releaseOriginal: true),
-          $a![1]!.as(const jni$_.JStringType(), releaseOriginal: true),
+          ($a![0] as Response),
+          ($a![1] as jni$_.JString),
         );
         return jni$_.nullptr;
       }
@@ -12090,9 +10104,44 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return RedirectReceivedCallback.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<RedirectReceivedCallback>();
+  }
+}
+
+extension RedirectReceivedCallback$$Methods on RedirectReceivedCallback {
+  static final _id_onRedirectReceived =
+      RedirectReceivedCallback._class.instanceMethodId(
+    r'onRedirectReceived',
+    r'(Lokhttp3/Response;Ljava/lang/String;)V',
+  );
+
+  static final _onRedirectReceived = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun onRedirectReceived(response: okhttp3.Response, location: kotlin.String): kotlin.Unit`
+  void onRedirectReceived(
+    Response response,
+    jni$_.JString string,
+  ) {
+    final _$response = response.reference;
+    final _$string = string.reference;
+    _onRedirectReceived(reference.pointer, _id_onRedirectReceived.pointer,
+            _$response.pointer, _$string.pointer)
+        .check();
   }
 }
 
@@ -12100,11 +10149,11 @@
   factory $RedirectReceivedCallback({
     required void Function(Response response, jni$_.JString string)
         onRedirectReceived,
-    bool onRedirectReceived$async,
+    core$_.bool onRedirectReceived$async,
   }) = _$RedirectReceivedCallback;
 
   void onRedirectReceived(Response response, jni$_.JString string);
-  bool get onRedirectReceived$async => false;
+  core$_.bool get onRedirectReceived$async => false;
 }
 
 final class _$RedirectReceivedCallback with $RedirectReceivedCallback {
@@ -12116,154 +10165,32 @@
 
   final void Function(Response response, jni$_.JString string)
       _onRedirectReceived;
-  final bool onRedirectReceived$async;
+  final core$_.bool onRedirectReceived$async;
 
   void onRedirectReceived(Response response, jni$_.JString string) {
     return _onRedirectReceived(response, string);
   }
 }
 
-final class $RedirectReceivedCallback$NullableType
-    extends jni$_.JObjType<RedirectReceivedCallback?> {
+final class $RedirectReceivedCallback$Type$
+    extends jni$_.JType<RedirectReceivedCallback> {
   @jni$_.internal
-  const $RedirectReceivedCallback$NullableType();
+  const $RedirectReceivedCallback$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lcom/example/ok_http/RedirectReceivedCallback;';
-
-  @jni$_.internal
-  @core$_.override
-  RedirectReceivedCallback? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : RedirectReceivedCallback.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<RedirectReceivedCallback?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($RedirectReceivedCallback$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($RedirectReceivedCallback$NullableType) &&
-        other is $RedirectReceivedCallback$NullableType;
-  }
-}
-
-final class $RedirectReceivedCallback$Type
-    extends jni$_.JObjType<RedirectReceivedCallback> {
-  @jni$_.internal
-  const $RedirectReceivedCallback$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lcom/example/ok_http/RedirectReceivedCallback;';
-
-  @jni$_.internal
-  @core$_.override
-  RedirectReceivedCallback fromReference(jni$_.JReference reference) =>
-      RedirectReceivedCallback.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<RedirectReceivedCallback?> get nullableType =>
-      const $RedirectReceivedCallback$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($RedirectReceivedCallback$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($RedirectReceivedCallback$Type) &&
-        other is $RedirectReceivedCallback$Type;
-  }
 }
 
 /// from: `com.example.ok_http.RedirectInterceptor$Companion`
-class RedirectInterceptor$Companion extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<RedirectInterceptor$Companion> $type;
-
-  @jni$_.internal
-  RedirectInterceptor$Companion.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type RedirectInterceptor$Companion._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(
       r'com/example/ok_http/RedirectInterceptor$Companion');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $RedirectInterceptor$Companion$NullableType();
-  static const type = $RedirectInterceptor$Companion$Type();
-  static final _id_addRedirectInterceptor = _class.instanceMethodId(
-    r'addRedirectInterceptor',
-    r'(Lokhttp3/OkHttpClient$Builder;IZLcom/example/ok_http/RedirectReceivedCallback;)Lokhttp3/OkHttpClient$Builder;',
-  );
-
-  static final _addRedirectInterceptor = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okhttp3.OkHttpClient$Builder addRedirectInterceptor(okhttp3.OkHttpClient$Builder builder, int i, boolean z, com.example.ok_http.RedirectReceivedCallback redirectReceivedCallback)`
-  /// The returned object must be released after use, by calling the [release] method.
-  OkHttpClient$Builder addRedirectInterceptor(
-    OkHttpClient$Builder builder,
-    int i,
-    bool z,
-    RedirectReceivedCallback redirectReceivedCallback,
-  ) {
-    final _$builder = builder.reference;
-    final _$redirectReceivedCallback = redirectReceivedCallback.reference;
-    return _addRedirectInterceptor(
-            reference.pointer,
-            _id_addRedirectInterceptor as jni$_.JMethodIDPtr,
-            _$builder.pointer,
-            i,
-            z ? 1 : 0,
-            _$redirectReceivedCallback.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
-  }
-
+  static const jni$_.JType<RedirectInterceptor$Companion> type =
+      $RedirectInterceptor$Companion$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Lkotlin/jvm/internal/DefaultConstructorMarker;)V',
   );
@@ -12286,111 +10213,82 @@
   ) {
     final _$defaultConstructorMarker =
         defaultConstructorMarker?.reference ?? jni$_.jNullReference;
-    return RedirectInterceptor$Companion.fromReference(_new$(
-            _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
+    return _new$(_class.reference.pointer, _id_new$.pointer,
             _$defaultConstructorMarker.pointer)
-        .reference);
+        .object<RedirectInterceptor$Companion>();
   }
 }
 
-final class $RedirectInterceptor$Companion$NullableType
-    extends jni$_.JObjType<RedirectInterceptor$Companion?> {
+extension RedirectInterceptor$Companion$$Methods
+    on RedirectInterceptor$Companion {
+  static final _id_addRedirectInterceptor =
+      RedirectInterceptor$Companion._class.instanceMethodId(
+    r'addRedirectInterceptor',
+    r'(Lokhttp3/OkHttpClient$Builder;IZLcom/example/ok_http/RedirectReceivedCallback;)Lokhttp3/OkHttpClient$Builder;',
+  );
+
+  static final _addRedirectInterceptor = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun addRedirectInterceptor(clientBuilder: okhttp3.OkHttpClient.Builder, maxRedirects: kotlin.Int, followRedirects: kotlin.Boolean, redirectCallback: com.example.ok_http.RedirectReceivedCallback): okhttp3.OkHttpClient.Builder`
+  /// The returned object must be released after use, by calling the [release] method.
+  OkHttpClient$Builder addRedirectInterceptor(
+    OkHttpClient$Builder builder,
+    core$_.int i,
+    core$_.bool z,
+    RedirectReceivedCallback redirectReceivedCallback,
+  ) {
+    final _$builder = builder.reference;
+    final _$redirectReceivedCallback = redirectReceivedCallback.reference;
+    return _addRedirectInterceptor(
+            reference.pointer,
+            _id_addRedirectInterceptor.pointer,
+            _$builder.pointer,
+            i,
+            z ? 1 : 0,
+            _$redirectReceivedCallback.pointer)
+        .object<OkHttpClient$Builder>();
+  }
+}
+
+final class $RedirectInterceptor$Companion$Type$
+    extends jni$_.JType<RedirectInterceptor$Companion> {
   @jni$_.internal
-  const $RedirectInterceptor$Companion$NullableType();
+  const $RedirectInterceptor$Companion$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature =>
       r'Lcom/example/ok_http/RedirectInterceptor$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  RedirectInterceptor$Companion? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : RedirectInterceptor$Companion.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<RedirectInterceptor$Companion?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($RedirectInterceptor$Companion$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($RedirectInterceptor$Companion$NullableType) &&
-        other is $RedirectInterceptor$Companion$NullableType;
-  }
-}
-
-final class $RedirectInterceptor$Companion$Type
-    extends jni$_.JObjType<RedirectInterceptor$Companion> {
-  @jni$_.internal
-  const $RedirectInterceptor$Companion$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature =>
-      r'Lcom/example/ok_http/RedirectInterceptor$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  RedirectInterceptor$Companion fromReference(jni$_.JReference reference) =>
-      RedirectInterceptor$Companion.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<RedirectInterceptor$Companion?> get nullableType =>
-      const $RedirectInterceptor$Companion$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($RedirectInterceptor$Companion$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($RedirectInterceptor$Companion$Type) &&
-        other is $RedirectInterceptor$Companion$Type;
-  }
 }
 
 /// from: `com.example.ok_http.RedirectInterceptor`
-class RedirectInterceptor extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<RedirectInterceptor> $type;
-
-  @jni$_.internal
-  RedirectInterceptor.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type RedirectInterceptor._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'com/example/ok_http/RedirectInterceptor');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $RedirectInterceptor$NullableType();
-  static const type = $RedirectInterceptor$Type();
+  static const jni$_.JType<RedirectInterceptor> type =
+      $RedirectInterceptor$Type$();
   static final _id_Companion = _class.staticFieldId(
     r'Companion',
     r'Lcom/example/ok_http/RedirectInterceptor$Companion;',
@@ -12399,7 +10297,8 @@
   /// from: `static public final com.example.ok_http.RedirectInterceptor$Companion Companion`
   /// The returned object must be released after use, by calling the [release] method.
   static RedirectInterceptor$Companion get Companion =>
-      _id_Companion.get(_class, const $RedirectInterceptor$Companion$Type());
+      _id_Companion.get(_class, RedirectInterceptor$Companion.type)
+          as RedirectInterceptor$Companion;
 
   static final _id_new$ = _class.constructorId(
     r'()V',
@@ -12420,107 +10319,30 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory RedirectInterceptor() {
-    return RedirectInterceptor.fromReference(
-        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
-            .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer)
+        .object<RedirectInterceptor>();
   }
 }
 
-final class $RedirectInterceptor$NullableType
-    extends jni$_.JObjType<RedirectInterceptor?> {
+final class $RedirectInterceptor$Type$
+    extends jni$_.JType<RedirectInterceptor> {
   @jni$_.internal
-  const $RedirectInterceptor$NullableType();
+  const $RedirectInterceptor$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lcom/example/ok_http/RedirectInterceptor;';
-
-  @jni$_.internal
-  @core$_.override
-  RedirectInterceptor? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : RedirectInterceptor.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<RedirectInterceptor?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($RedirectInterceptor$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($RedirectInterceptor$NullableType) &&
-        other is $RedirectInterceptor$NullableType;
-  }
-}
-
-final class $RedirectInterceptor$Type
-    extends jni$_.JObjType<RedirectInterceptor> {
-  @jni$_.internal
-  const $RedirectInterceptor$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lcom/example/ok_http/RedirectInterceptor;';
-
-  @jni$_.internal
-  @core$_.override
-  RedirectInterceptor fromReference(jni$_.JReference reference) =>
-      RedirectInterceptor.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<RedirectInterceptor?> get nullableType =>
-      const $RedirectInterceptor$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($RedirectInterceptor$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($RedirectInterceptor$Type) &&
-        other is $RedirectInterceptor$Type;
-  }
 }
 
 /// from: `com.example.ok_http.AsyncInputStreamReader`
-class AsyncInputStreamReader extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<AsyncInputStreamReader> $type;
-
-  @jni$_.internal
-  AsyncInputStreamReader.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type AsyncInputStreamReader._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'com/example/ok_http/AsyncInputStreamReader');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $AsyncInputStreamReader$NullableType();
-  static const type = $AsyncInputStreamReader$Type();
+  static const jni$_.JType<AsyncInputStreamReader> type =
+      $AsyncInputStreamReader$Type$();
   static final _id_new$ = _class.constructorId(
     r'()V',
   );
@@ -12540,12 +10362,13 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory AsyncInputStreamReader() {
-    return AsyncInputStreamReader.fromReference(
-        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
-            .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer)
+        .object<AsyncInputStreamReader>();
   }
+}
 
-  static final _id_readAsync = _class.instanceMethodId(
+extension AsyncInputStreamReader$$Methods on AsyncInputStreamReader {
+  static final _id_readAsync = AsyncInputStreamReader._class.instanceMethodId(
     r'readAsync',
     r'(Ljava/io/InputStream;Lcom/example/ok_http/DataCallback;)Ljava/util/concurrent/Future;',
   );
@@ -12567,7 +10390,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final java.util.concurrent.Future readAsync(java.io.InputStream inputStream, com.example.ok_http.DataCallback dataCallback)`
+  /// from: `public fun readAsync(inputStream: java.io.InputStream, callback: com.example.ok_http.DataCallback): java.util.concurrent.Future<*>`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject readAsync(
     jni$_.JObject inputStream,
@@ -12575,12 +10398,12 @@
   ) {
     final _$inputStream = inputStream.reference;
     final _$dataCallback = dataCallback.reference;
-    return _readAsync(reference.pointer, _id_readAsync as jni$_.JMethodIDPtr,
+    return _readAsync(reference.pointer, _id_readAsync.pointer,
             _$inputStream.pointer, _$dataCallback.pointer)
-        .object<jni$_.JObject>(const jni$_.JObjectType());
+        .object<jni$_.JObject>();
   }
 
-  static final _id_shutdown = _class.instanceMethodId(
+  static final _id_shutdown = AsyncInputStreamReader._class.instanceMethodId(
     r'shutdown',
     r'()V',
   );
@@ -12597,186 +10420,34 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final void shutdown()`
+  /// from: `public fun shutdown(): kotlin.Unit`
   void shutdown() {
-    _shutdown(reference.pointer, _id_shutdown as jni$_.JMethodIDPtr).check();
+    _shutdown(reference.pointer, _id_shutdown.pointer).check();
   }
 }
 
-final class $AsyncInputStreamReader$NullableType
-    extends jni$_.JObjType<AsyncInputStreamReader?> {
+final class $AsyncInputStreamReader$Type$
+    extends jni$_.JType<AsyncInputStreamReader> {
   @jni$_.internal
-  const $AsyncInputStreamReader$NullableType();
+  const $AsyncInputStreamReader$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lcom/example/ok_http/AsyncInputStreamReader;';
-
-  @jni$_.internal
-  @core$_.override
-  AsyncInputStreamReader? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : AsyncInputStreamReader.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<AsyncInputStreamReader?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($AsyncInputStreamReader$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($AsyncInputStreamReader$NullableType) &&
-        other is $AsyncInputStreamReader$NullableType;
-  }
-}
-
-final class $AsyncInputStreamReader$Type
-    extends jni$_.JObjType<AsyncInputStreamReader> {
-  @jni$_.internal
-  const $AsyncInputStreamReader$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lcom/example/ok_http/AsyncInputStreamReader;';
-
-  @jni$_.internal
-  @core$_.override
-  AsyncInputStreamReader fromReference(jni$_.JReference reference) =>
-      AsyncInputStreamReader.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<AsyncInputStreamReader?> get nullableType =>
-      const $AsyncInputStreamReader$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($AsyncInputStreamReader$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($AsyncInputStreamReader$Type) &&
-        other is $AsyncInputStreamReader$Type;
-  }
 }
 
 /// from: `com.example.ok_http.DataCallback`
-class DataCallback extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<DataCallback> $type;
-
-  @jni$_.internal
-  DataCallback.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type DataCallback._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'com/example/ok_http/DataCallback');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $DataCallback$NullableType();
-  static const type = $DataCallback$Type();
-  static final _id_onDataRead = _class.instanceMethodId(
-    r'onDataRead',
-    r'([B)V',
-  );
-
-  static final _onDataRead = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void onDataRead(byte[] bs)`
-  void onDataRead(
-    jni$_.JByteArray bs,
-  ) {
-    final _$bs = bs.reference;
-    _onDataRead(reference.pointer, _id_onDataRead as jni$_.JMethodIDPtr,
-            _$bs.pointer)
-        .check();
-  }
-
-  static final _id_onFinished = _class.instanceMethodId(
-    r'onFinished',
-    r'()V',
-  );
-
-  static final _onFinished = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract void onFinished()`
-  void onFinished() {
-    _onFinished(reference.pointer, _id_onFinished as jni$_.JMethodIDPtr)
-        .check();
-  }
-
-  static final _id_onError = _class.instanceMethodId(
-    r'onError',
-    r'(Ljava/io/IOException;)V',
-  );
-
-  static final _onError = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void onError(java.io.IOException iOException)`
-  void onError(
-    jni$_.JObject iOException,
-  ) {
-    final _$iOException = iOException.reference;
-    _onError(reference.pointer, _id_onError as jni$_.JMethodIDPtr,
-            _$iOException.pointer)
-        .check();
-  }
+  static const jni$_.JType<DataCallback> type = $DataCallback$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $DataCallback> _$impls = {};
+  static final core$_.Map<core$_.int, $DataCallback> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -12797,7 +10468,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -12805,7 +10476,7 @@
       final $a = $i.args;
       if ($d == r'onDataRead([B)V') {
         _$impls[$p]!.onDataRead(
-          $a![0]!.as(const jni$_.JByteArrayType(), releaseOriginal: true),
+          ($a![0] as jni$_.JByteArray),
         );
         return jni$_.nullptr;
       }
@@ -12815,7 +10486,7 @@
       }
       if ($d == r'onError(Ljava/io/IOException;)V') {
         _$impls[$p]!.onError(
-          $a![0]!.as(const jni$_.JObjectType(), releaseOriginal: true),
+          ($a![0] as jni$_.JObject),
         );
         return jni$_.nullptr;
       }
@@ -12859,28 +10530,100 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return DataCallback.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<DataCallback>();
+  }
+}
+
+extension DataCallback$$Methods on DataCallback {
+  static final _id_onDataRead = DataCallback._class.instanceMethodId(
+    r'onDataRead',
+    r'([B)V',
+  );
+
+  static final _onDataRead = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun onDataRead(data: kotlin.ByteArray): kotlin.Unit`
+  void onDataRead(
+    jni$_.JByteArray bs,
+  ) {
+    final _$bs = bs.reference;
+    _onDataRead(reference.pointer, _id_onDataRead.pointer, _$bs.pointer)
+        .check();
+  }
+
+  static final _id_onFinished = DataCallback._class.instanceMethodId(
+    r'onFinished',
+    r'()V',
+  );
+
+  static final _onFinished = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun onFinished(): kotlin.Unit`
+  void onFinished() {
+    _onFinished(reference.pointer, _id_onFinished.pointer).check();
+  }
+
+  static final _id_onError = DataCallback._class.instanceMethodId(
+    r'onError',
+    r'(Ljava/io/IOException;)V',
+  );
+
+  static final _onError = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun onError(e: java.io.IOException): kotlin.Unit`
+  void onError(
+    jni$_.JObject iOException,
+  ) {
+    final _$iOException = iOException.reference;
+    _onError(reference.pointer, _id_onError.pointer, _$iOException.pointer)
+        .check();
   }
 }
 
 abstract base mixin class $DataCallback {
   factory $DataCallback({
     required void Function(jni$_.JByteArray bs) onDataRead,
-    bool onDataRead$async,
+    core$_.bool onDataRead$async,
     required void Function() onFinished,
-    bool onFinished$async,
+    core$_.bool onFinished$async,
     required void Function(jni$_.JObject iOException) onError,
-    bool onError$async,
+    core$_.bool onError$async,
   }) = _$DataCallback;
 
   void onDataRead(jni$_.JByteArray bs);
-  bool get onDataRead$async => false;
+  core$_.bool get onDataRead$async => false;
   void onFinished();
-  bool get onFinished$async => false;
+  core$_.bool get onFinished$async => false;
   void onError(jni$_.JObject iOException);
-  bool get onError$async => false;
+  core$_.bool get onError$async => false;
 }
 
 final class _$DataCallback with $DataCallback {
@@ -12896,11 +10639,11 @@
         _onError = onError;
 
   final void Function(jni$_.JByteArray bs) _onDataRead;
-  final bool onDataRead$async;
+  final core$_.bool onDataRead$async;
   final void Function() _onFinished;
-  final bool onFinished$async;
+  final core$_.bool onFinished$async;
   final void Function(jni$_.JObject iOException) _onError;
-  final bool onError$async;
+  final core$_.bool onError$async;
 
   void onDataRead(jni$_.JByteArray bs) {
     return _onDataRead(bs);
@@ -12915,139 +10658,27 @@
   }
 }
 
-final class $DataCallback$NullableType extends jni$_.JObjType<DataCallback?> {
+final class $DataCallback$Type$ extends jni$_.JType<DataCallback> {
   @jni$_.internal
-  const $DataCallback$NullableType();
+  const $DataCallback$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lcom/example/ok_http/DataCallback;';
-
-  @jni$_.internal
-  @core$_.override
-  DataCallback? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : DataCallback.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<DataCallback?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($DataCallback$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($DataCallback$NullableType) &&
-        other is $DataCallback$NullableType;
-  }
-}
-
-final class $DataCallback$Type extends jni$_.JObjType<DataCallback> {
-  @jni$_.internal
-  const $DataCallback$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lcom/example/ok_http/DataCallback;';
-
-  @jni$_.internal
-  @core$_.override
-  DataCallback fromReference(jni$_.JReference reference) =>
-      DataCallback.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<DataCallback?> get nullableType =>
-      const $DataCallback$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($DataCallback$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($DataCallback$Type) &&
-        other is $DataCallback$Type;
-  }
 }
 
 /// from: `okhttp3.WebSocket$Factory`
-class WebSocket$Factory extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<WebSocket$Factory> $type;
-
-  @jni$_.internal
-  WebSocket$Factory.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type WebSocket$Factory._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/WebSocket$Factory');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $WebSocket$Factory$NullableType();
-  static const type = $WebSocket$Factory$Type();
-  static final _id_newWebSocket = _class.instanceMethodId(
-    r'newWebSocket',
-    r'(Lokhttp3/Request;Lokhttp3/WebSocketListener;)Lokhttp3/WebSocket;',
-  );
-
-  static final _newWebSocket = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract okhttp3.WebSocket newWebSocket(okhttp3.Request request, okhttp3.WebSocketListener webSocketListener)`
-  /// The returned object must be released after use, by calling the [release] method.
-  WebSocket newWebSocket(
-    Request request,
-    jni$_.JObject webSocketListener,
-  ) {
-    final _$request = request.reference;
-    final _$webSocketListener = webSocketListener.reference;
-    return _newWebSocket(
-            reference.pointer,
-            _id_newWebSocket as jni$_.JMethodIDPtr,
-            _$request.pointer,
-            _$webSocketListener.pointer)
-        .object<WebSocket>(const $WebSocket$Type());
-  }
+  static const jni$_.JType<WebSocket$Factory> type = $WebSocket$Factory$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $WebSocket$Factory> _$impls = {};
+  static final core$_.Map<core$_.int, $WebSocket$Factory> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -13068,7 +10699,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -13077,11 +10708,11 @@
       if ($d ==
           r'newWebSocket(Lokhttp3/Request;Lokhttp3/WebSocketListener;)Lokhttp3/WebSocket;') {
         final $r = _$impls[$p]!.newWebSocket(
-          $a![0]!.as(const $Request$Type(), releaseOriginal: true),
-          $a![1]!.as(const jni$_.JObjectType(), releaseOriginal: true),
+          ($a![0] as Request),
+          ($a![1] as jni$_.JObject),
         );
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -13122,9 +10753,44 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return WebSocket$Factory.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<WebSocket$Factory>();
+  }
+}
+
+extension WebSocket$Factory$$Methods on WebSocket$Factory {
+  static final _id_newWebSocket = WebSocket$Factory._class.instanceMethodId(
+    r'newWebSocket',
+    r'(Lokhttp3/Request;Lokhttp3/WebSocketListener;)Lokhttp3/WebSocket;',
+  );
+
+  static final _newWebSocket = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun newWebSocket(request: okhttp3.Request, listener: okhttp3.WebSocketListener): okhttp3.WebSocket`
+  /// The returned object must be released after use, by calling the [release] method.
+  WebSocket newWebSocket(
+    Request request,
+    jni$_.JObject webSocketListener,
+  ) {
+    final _$request = request.reference;
+    final _$webSocketListener = webSocketListener.reference;
+    return _newWebSocket(reference.pointer, _id_newWebSocket.pointer,
+            _$request.pointer, _$webSocketListener.pointer)
+        .object<WebSocket>();
   }
 }
 
@@ -13153,252 +10819,26 @@
   }
 }
 
-final class $WebSocket$Factory$NullableType
-    extends jni$_.JObjType<WebSocket$Factory?> {
+final class $WebSocket$Factory$Type$ extends jni$_.JType<WebSocket$Factory> {
   @jni$_.internal
-  const $WebSocket$Factory$NullableType();
+  const $WebSocket$Factory$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/WebSocket$Factory;';
-
-  @jni$_.internal
-  @core$_.override
-  WebSocket$Factory? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : WebSocket$Factory.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocket$Factory?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($WebSocket$Factory$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($WebSocket$Factory$NullableType) &&
-        other is $WebSocket$Factory$NullableType;
-  }
-}
-
-final class $WebSocket$Factory$Type extends jni$_.JObjType<WebSocket$Factory> {
-  @jni$_.internal
-  const $WebSocket$Factory$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/WebSocket$Factory;';
-
-  @jni$_.internal
-  @core$_.override
-  WebSocket$Factory fromReference(jni$_.JReference reference) =>
-      WebSocket$Factory.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocket$Factory?> get nullableType =>
-      const $WebSocket$Factory$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($WebSocket$Factory$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($WebSocket$Factory$Type) &&
-        other is $WebSocket$Factory$Type;
-  }
 }
 
 /// from: `okhttp3.WebSocket`
-class WebSocket extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<WebSocket> $type;
-
-  @jni$_.internal
-  WebSocket.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type WebSocket._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okhttp3/WebSocket');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $WebSocket$NullableType();
-  static const type = $WebSocket$Type();
-  static final _id_request = _class.instanceMethodId(
-    r'request',
-    r'()Lokhttp3/Request;',
-  );
-
-  static final _request = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract okhttp3.Request request()`
-  /// The returned object must be released after use, by calling the [release] method.
-  Request request() {
-    return _request(reference.pointer, _id_request as jni$_.JMethodIDPtr)
-        .object<Request>(const $Request$Type());
-  }
-
-  static final _id_queueSize = _class.instanceMethodId(
-    r'queueSize',
-    r'()J',
-  );
-
-  static final _queueSize = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract long queueSize()`
-  int queueSize() {
-    return _queueSize(reference.pointer, _id_queueSize as jni$_.JMethodIDPtr)
-        .long;
-  }
-
-  static final _id_send = _class.instanceMethodId(
-    r'send',
-    r'(Ljava/lang/String;)Z',
-  );
-
-  static final _send = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract boolean send(java.lang.String string)`
-  bool send(
-    jni$_.JString string,
-  ) {
-    final _$string = string.reference;
-    return _send(
-            reference.pointer, _id_send as jni$_.JMethodIDPtr, _$string.pointer)
-        .boolean;
-  }
-
-  static final _id_send$1 = _class.instanceMethodId(
-    r'send',
-    r'(Lokio/ByteString;)Z',
-  );
-
-  static final _send$1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract boolean send(okio.ByteString byteString)`
-  bool send$1(
-    ByteString byteString,
-  ) {
-    final _$byteString = byteString.reference;
-    return _send$1(reference.pointer, _id_send$1 as jni$_.JMethodIDPtr,
-            _$byteString.pointer)
-        .boolean;
-  }
-
-  static final _id_close = _class.instanceMethodId(
-    r'close',
-    r'(ILjava/lang/String;)Z',
-  );
-
-  static final _close = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Int32, jni$_.Pointer<jni$_.Void>)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract boolean close(int i, java.lang.String string)`
-  bool close(
-    int i,
-    jni$_.JString? string,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    return _close(reference.pointer, _id_close as jni$_.JMethodIDPtr, i,
-            _$string.pointer)
-        .boolean;
-  }
-
-  static final _id_cancel = _class.instanceMethodId(
-    r'cancel',
-    r'()V',
-  );
-
-  static final _cancel = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract void cancel()`
-  void cancel() {
-    _cancel(reference.pointer, _id_cancel as jni$_.JMethodIDPtr).check();
-  }
+  static const jni$_.JType<WebSocket> type = $WebSocket$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $WebSocket> _$impls = {};
+  static final core$_.Map<core$_.int, $WebSocket> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -13419,7 +10859,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -13428,35 +10868,33 @@
       if ($d == r'request()Lokhttp3/Request;') {
         final $r = _$impls[$p]!.request();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
       }
       if ($d == r'queueSize()J') {
         final $r = _$impls[$p]!.queueSize();
-        return jni$_.JLong($r).reference.toPointer();
+        return $r.toJLong().reference.toPointer();
       }
       if ($d == r'send(Ljava/lang/String;)Z') {
         final $r = _$impls[$p]!.send(
-          $a![0]!.as(const jni$_.JStringType(), releaseOriginal: true),
+          ($a![0] as jni$_.JString),
         );
-        return jni$_.JBoolean($r).reference.toPointer();
+        return $r.toJBoolean().reference.toPointer();
       }
       if ($d == r'send(Lokio/ByteString;)Z') {
         final $r = _$impls[$p]!.send$1(
-          $a![0]!.as(const $ByteString$Type(), releaseOriginal: true),
+          ($a![0] as ByteString),
         );
-        return jni$_.JBoolean($r).reference.toPointer();
+        return $r.toJBoolean().reference.toPointer();
       }
       if ($d == r'close(ILjava/lang/String;)Z') {
         final $r = _$impls[$p]!.close(
-          $a![0]!
-              .as(const jni$_.JIntegerType(), releaseOriginal: true)
-              .intValue(releaseOriginal: true),
-          $a![1]?.as(const jni$_.JStringType(), releaseOriginal: true),
+          ($a![0] as jni$_.JInteger).toDartInt(releaseOriginal: true),
+          ($a![1] as jni$_.JString?),
         );
-        return jni$_.JBoolean($r).reference.toPointer();
+        return $r.toJBoolean().reference.toPointer();
       }
       if ($d == r'cancel()V') {
         _$impls[$p]!.cancel();
@@ -13500,39 +10938,182 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return WebSocket.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<WebSocket>();
+  }
+}
+
+extension WebSocket$$Methods on WebSocket {
+  static final _id_request = WebSocket._class.instanceMethodId(
+    r'request',
+    r'()Lokhttp3/Request;',
+  );
+
+  static final _request = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun request(): okhttp3.Request`
+  /// The returned object must be released after use, by calling the [release] method.
+  Request request() {
+    return _request(reference.pointer, _id_request.pointer).object<Request>();
+  }
+
+  static final _id_queueSize = WebSocket._class.instanceMethodId(
+    r'queueSize',
+    r'()J',
+  );
+
+  static final _queueSize = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun queueSize(): kotlin.Long`
+  core$_.int queueSize() {
+    return _queueSize(reference.pointer, _id_queueSize.pointer).long;
+  }
+
+  static final _id_send = WebSocket._class.instanceMethodId(
+    r'send',
+    r'(Ljava/lang/String;)Z',
+  );
+
+  static final _send = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun send(text: kotlin.String): kotlin.Boolean`
+  core$_.bool send(
+    jni$_.JString string,
+  ) {
+    final _$string = string.reference;
+    return _send(reference.pointer, _id_send.pointer, _$string.pointer).boolean;
+  }
+
+  static final _id_send$1 = WebSocket._class.instanceMethodId(
+    r'send',
+    r'(Lokio/ByteString;)Z',
+  );
+
+  static final _send$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun send(bytes: okio.ByteString): kotlin.Boolean`
+  core$_.bool send$1(
+    ByteString byteString,
+  ) {
+    final _$byteString = byteString.reference;
+    return _send$1(reference.pointer, _id_send$1.pointer, _$byteString.pointer)
+        .boolean;
+  }
+
+  static final _id_close = WebSocket._class.instanceMethodId(
+    r'close',
+    r'(ILjava/lang/String;)Z',
+  );
+
+  static final _close = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Int32, jni$_.Pointer<jni$_.Void>)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, core$_.int, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun close(code: kotlin.Int, reason: kotlin.String?): kotlin.Boolean`
+  core$_.bool close(
+    core$_.int i,
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _close(reference.pointer, _id_close.pointer, i, _$string.pointer)
+        .boolean;
+  }
+
+  static final _id_cancel = WebSocket._class.instanceMethodId(
+    r'cancel',
+    r'()V',
+  );
+
+  static final _cancel = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun cancel(): kotlin.Unit`
+  void cancel() {
+    _cancel(reference.pointer, _id_cancel.pointer).check();
   }
 }
 
 abstract base mixin class $WebSocket {
   factory $WebSocket({
     required Request Function() request,
-    required int Function() queueSize,
-    required bool Function(jni$_.JString string) send,
-    required bool Function(ByteString byteString) send$1,
-    required bool Function(int i, jni$_.JString? string) close,
+    required core$_.int Function() queueSize,
+    required core$_.bool Function(jni$_.JString string) send,
+    required core$_.bool Function(ByteString byteString) send$1,
+    required core$_.bool Function(core$_.int i, jni$_.JString? string) close,
     required void Function() cancel,
-    bool cancel$async,
+    core$_.bool cancel$async,
   }) = _$WebSocket;
 
   Request request();
-  int queueSize();
-  bool send(jni$_.JString string);
-  bool send$1(ByteString byteString);
-  bool close(int i, jni$_.JString? string);
+  core$_.int queueSize();
+  core$_.bool send(jni$_.JString string);
+  core$_.bool send$1(ByteString byteString);
+  core$_.bool close(core$_.int i, jni$_.JString? string);
   void cancel();
-  bool get cancel$async => false;
+  core$_.bool get cancel$async => false;
 }
 
 final class _$WebSocket with $WebSocket {
   _$WebSocket({
     required Request Function() request,
-    required int Function() queueSize,
-    required bool Function(jni$_.JString string) send,
-    required bool Function(ByteString byteString) send$1,
-    required bool Function(int i, jni$_.JString? string) close,
+    required core$_.int Function() queueSize,
+    required core$_.bool Function(jni$_.JString string) send,
+    required core$_.bool Function(ByteString byteString) send$1,
+    required core$_.bool Function(core$_.int i, jni$_.JString? string) close,
     required void Function() cancel,
     this.cancel$async = false,
   })  : _request = request,
@@ -13543,30 +11124,30 @@
         _cancel = cancel;
 
   final Request Function() _request;
-  final int Function() _queueSize;
-  final bool Function(jni$_.JString string) _send;
-  final bool Function(ByteString byteString) _send$1;
-  final bool Function(int i, jni$_.JString? string) _close;
+  final core$_.int Function() _queueSize;
+  final core$_.bool Function(jni$_.JString string) _send;
+  final core$_.bool Function(ByteString byteString) _send$1;
+  final core$_.bool Function(core$_.int i, jni$_.JString? string) _close;
   final void Function() _cancel;
-  final bool cancel$async;
+  final core$_.bool cancel$async;
 
   Request request() {
     return _request();
   }
 
-  int queueSize() {
+  core$_.int queueSize() {
     return _queueSize();
   }
 
-  bool send(jni$_.JString string) {
+  core$_.bool send(jni$_.JString string) {
     return _send(string);
   }
 
-  bool send$1(ByteString byteString) {
+  core$_.bool send$1(ByteString byteString) {
     return _send$1(byteString);
   }
 
-  bool close(int i, jni$_.JString? string) {
+  core$_.bool close(core$_.int i, jni$_.JString? string) {
     return _close(i, string);
   }
 
@@ -13575,280 +11156,30 @@
   }
 }
 
-final class $WebSocket$NullableType extends jni$_.JObjType<WebSocket?> {
+final class $WebSocket$Type$ extends jni$_.JType<WebSocket> {
   @jni$_.internal
-  const $WebSocket$NullableType();
+  const $WebSocket$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokhttp3/WebSocket;';
-
-  @jni$_.internal
-  @core$_.override
-  WebSocket? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : WebSocket.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocket?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($WebSocket$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($WebSocket$NullableType) &&
-        other is $WebSocket$NullableType;
-  }
-}
-
-final class $WebSocket$Type extends jni$_.JObjType<WebSocket> {
-  @jni$_.internal
-  const $WebSocket$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokhttp3/WebSocket;';
-
-  @jni$_.internal
-  @core$_.override
-  WebSocket fromReference(jni$_.JReference reference) =>
-      WebSocket.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocket?> get nullableType =>
-      const $WebSocket$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($WebSocket$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($WebSocket$Type) && other is $WebSocket$Type;
-  }
 }
 
 /// from: `com.example.ok_http.WebSocketListenerProxy$WebSocketListener`
-class WebSocketListenerProxy$WebSocketListener extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<WebSocketListenerProxy$WebSocketListener> $type;
-
-  @jni$_.internal
-  WebSocketListenerProxy$WebSocketListener.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type WebSocketListenerProxy$WebSocketListener._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(
       r'com/example/ok_http/WebSocketListenerProxy$WebSocketListener');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType =
-      $WebSocketListenerProxy$WebSocketListener$NullableType();
-  static const type = $WebSocketListenerProxy$WebSocketListener$Type();
-  static final _id_onOpen = _class.instanceMethodId(
-    r'onOpen',
-    r'(Lokhttp3/WebSocket;Lokhttp3/Response;)V',
-  );
-
-  static final _onOpen = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void onOpen(okhttp3.WebSocket webSocket, okhttp3.Response response)`
-  void onOpen(
-    WebSocket webSocket,
-    Response response,
-  ) {
-    final _$webSocket = webSocket.reference;
-    final _$response = response.reference;
-    _onOpen(reference.pointer, _id_onOpen as jni$_.JMethodIDPtr,
-            _$webSocket.pointer, _$response.pointer)
-        .check();
-  }
-
-  static final _id_onMessage = _class.instanceMethodId(
-    r'onMessage',
-    r'(Lokhttp3/WebSocket;Ljava/lang/String;)V',
-  );
-
-  static final _onMessage = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void onMessage(okhttp3.WebSocket webSocket, java.lang.String string)`
-  void onMessage(
-    WebSocket webSocket,
-    jni$_.JString string,
-  ) {
-    final _$webSocket = webSocket.reference;
-    final _$string = string.reference;
-    _onMessage(reference.pointer, _id_onMessage as jni$_.JMethodIDPtr,
-            _$webSocket.pointer, _$string.pointer)
-        .check();
-  }
-
-  static final _id_onMessage$1 = _class.instanceMethodId(
-    r'onMessage',
-    r'(Lokhttp3/WebSocket;Lokio/ByteString;)V',
-  );
-
-  static final _onMessage$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void onMessage(okhttp3.WebSocket webSocket, okio.ByteString byteString)`
-  void onMessage$1(
-    WebSocket webSocket,
-    ByteString byteString,
-  ) {
-    final _$webSocket = webSocket.reference;
-    final _$byteString = byteString.reference;
-    _onMessage$1(reference.pointer, _id_onMessage$1 as jni$_.JMethodIDPtr,
-            _$webSocket.pointer, _$byteString.pointer)
-        .check();
-  }
-
-  static final _id_onClosing = _class.instanceMethodId(
-    r'onClosing',
-    r'(Lokhttp3/WebSocket;ILjava/lang/String;)V',
-  );
-
-  static final _onClosing = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void onClosing(okhttp3.WebSocket webSocket, int i, java.lang.String string)`
-  void onClosing(
-    WebSocket webSocket,
-    int i,
-    jni$_.JString string,
-  ) {
-    final _$webSocket = webSocket.reference;
-    final _$string = string.reference;
-    _onClosing(reference.pointer, _id_onClosing as jni$_.JMethodIDPtr,
-            _$webSocket.pointer, i, _$string.pointer)
-        .check();
-  }
-
-  static final _id_onFailure = _class.instanceMethodId(
-    r'onFailure',
-    r'(Lokhttp3/WebSocket;Ljava/lang/Throwable;Lokhttp3/Response;)V',
-  );
-
-  static final _onFailure = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void onFailure(okhttp3.WebSocket webSocket, java.lang.Throwable throwable, okhttp3.Response response)`
-  void onFailure(
-    WebSocket webSocket,
-    jni$_.JObject throwable,
-    Response? response,
-  ) {
-    final _$webSocket = webSocket.reference;
-    final _$throwable = throwable.reference;
-    final _$response = response?.reference ?? jni$_.jNullReference;
-    _onFailure(reference.pointer, _id_onFailure as jni$_.JMethodIDPtr,
-            _$webSocket.pointer, _$throwable.pointer, _$response.pointer)
-        .check();
-  }
+  static const jni$_.JType<WebSocketListenerProxy$WebSocketListener> type =
+      $WebSocketListenerProxy$WebSocketListener$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $WebSocketListenerProxy$WebSocketListener>
+  static final core$_.Map<core$_.int, $WebSocketListenerProxy$WebSocketListener>
       _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -13869,7 +11200,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -13877,41 +11208,39 @@
       final $a = $i.args;
       if ($d == r'onOpen(Lokhttp3/WebSocket;Lokhttp3/Response;)V') {
         _$impls[$p]!.onOpen(
-          $a![0]!.as(const $WebSocket$Type(), releaseOriginal: true),
-          $a![1]!.as(const $Response$Type(), releaseOriginal: true),
+          ($a![0] as WebSocket),
+          ($a![1] as Response),
         );
         return jni$_.nullptr;
       }
       if ($d == r'onMessage(Lokhttp3/WebSocket;Ljava/lang/String;)V') {
         _$impls[$p]!.onMessage(
-          $a![0]!.as(const $WebSocket$Type(), releaseOriginal: true),
-          $a![1]!.as(const jni$_.JStringType(), releaseOriginal: true),
+          ($a![0] as WebSocket),
+          ($a![1] as jni$_.JString),
         );
         return jni$_.nullptr;
       }
       if ($d == r'onMessage(Lokhttp3/WebSocket;Lokio/ByteString;)V') {
         _$impls[$p]!.onMessage$1(
-          $a![0]!.as(const $WebSocket$Type(), releaseOriginal: true),
-          $a![1]!.as(const $ByteString$Type(), releaseOriginal: true),
+          ($a![0] as WebSocket),
+          ($a![1] as ByteString),
         );
         return jni$_.nullptr;
       }
       if ($d == r'onClosing(Lokhttp3/WebSocket;ILjava/lang/String;)V') {
         _$impls[$p]!.onClosing(
-          $a![0]!.as(const $WebSocket$Type(), releaseOriginal: true),
-          $a![1]!
-              .as(const jni$_.JIntegerType(), releaseOriginal: true)
-              .intValue(releaseOriginal: true),
-          $a![2]!.as(const jni$_.JStringType(), releaseOriginal: true),
+          ($a![0] as WebSocket),
+          ($a![1] as jni$_.JInteger).toDartInt(releaseOriginal: true),
+          ($a![2] as jni$_.JString),
         );
         return jni$_.nullptr;
       }
       if ($d ==
           r'onFailure(Lokhttp3/WebSocket;Ljava/lang/Throwable;Lokhttp3/Response;)V') {
         _$impls[$p]!.onFailure(
-          $a![0]!.as(const $WebSocket$Type(), releaseOriginal: true),
-          $a![1]!.as(const jni$_.JObjectType(), releaseOriginal: true),
-          $a![2]?.as(const $Response$Type(), releaseOriginal: true),
+          ($a![0] as WebSocket),
+          ($a![1] as jni$_.JObject),
+          ($a![2] as Response?),
         );
         return jni$_.nullptr;
       }
@@ -13962,232 +11291,14 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return WebSocketListenerProxy$WebSocketListener.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<WebSocketListenerProxy$WebSocketListener>();
   }
 }
 
-abstract base mixin class $WebSocketListenerProxy$WebSocketListener {
-  factory $WebSocketListenerProxy$WebSocketListener({
-    required void Function(WebSocket webSocket, Response response) onOpen,
-    bool onOpen$async,
-    required void Function(WebSocket webSocket, jni$_.JString string) onMessage,
-    bool onMessage$async,
-    required void Function(WebSocket webSocket, ByteString byteString)
-        onMessage$1,
-    bool onMessage$1$async,
-    required void Function(WebSocket webSocket, int i, jni$_.JString string)
-        onClosing,
-    bool onClosing$async,
-    required void Function(
-            WebSocket webSocket, jni$_.JObject throwable, Response? response)
-        onFailure,
-    bool onFailure$async,
-  }) = _$WebSocketListenerProxy$WebSocketListener;
-
-  void onOpen(WebSocket webSocket, Response response);
-  bool get onOpen$async => false;
-  void onMessage(WebSocket webSocket, jni$_.JString string);
-  bool get onMessage$async => false;
-  void onMessage$1(WebSocket webSocket, ByteString byteString);
-  bool get onMessage$1$async => false;
-  void onClosing(WebSocket webSocket, int i, jni$_.JString string);
-  bool get onClosing$async => false;
-  void onFailure(
-      WebSocket webSocket, jni$_.JObject throwable, Response? response);
-  bool get onFailure$async => false;
-}
-
-final class _$WebSocketListenerProxy$WebSocketListener
-    with $WebSocketListenerProxy$WebSocketListener {
-  _$WebSocketListenerProxy$WebSocketListener({
-    required void Function(WebSocket webSocket, Response response) onOpen,
-    this.onOpen$async = false,
-    required void Function(WebSocket webSocket, jni$_.JString string) onMessage,
-    this.onMessage$async = false,
-    required void Function(WebSocket webSocket, ByteString byteString)
-        onMessage$1,
-    this.onMessage$1$async = false,
-    required void Function(WebSocket webSocket, int i, jni$_.JString string)
-        onClosing,
-    this.onClosing$async = false,
-    required void Function(
-            WebSocket webSocket, jni$_.JObject throwable, Response? response)
-        onFailure,
-    this.onFailure$async = false,
-  })  : _onOpen = onOpen,
-        _onMessage = onMessage,
-        _onMessage$1 = onMessage$1,
-        _onClosing = onClosing,
-        _onFailure = onFailure;
-
-  final void Function(WebSocket webSocket, Response response) _onOpen;
-  final bool onOpen$async;
-  final void Function(WebSocket webSocket, jni$_.JString string) _onMessage;
-  final bool onMessage$async;
-  final void Function(WebSocket webSocket, ByteString byteString) _onMessage$1;
-  final bool onMessage$1$async;
-  final void Function(WebSocket webSocket, int i, jni$_.JString string)
-      _onClosing;
-  final bool onClosing$async;
-  final void Function(
-          WebSocket webSocket, jni$_.JObject throwable, Response? response)
-      _onFailure;
-  final bool onFailure$async;
-
-  void onOpen(WebSocket webSocket, Response response) {
-    return _onOpen(webSocket, response);
-  }
-
-  void onMessage(WebSocket webSocket, jni$_.JString string) {
-    return _onMessage(webSocket, string);
-  }
-
-  void onMessage$1(WebSocket webSocket, ByteString byteString) {
-    return _onMessage$1(webSocket, byteString);
-  }
-
-  void onClosing(WebSocket webSocket, int i, jni$_.JString string) {
-    return _onClosing(webSocket, i, string);
-  }
-
-  void onFailure(
-      WebSocket webSocket, jni$_.JObject throwable, Response? response) {
-    return _onFailure(webSocket, throwable, response);
-  }
-}
-
-final class $WebSocketListenerProxy$WebSocketListener$NullableType
-    extends jni$_.JObjType<WebSocketListenerProxy$WebSocketListener?> {
-  @jni$_.internal
-  const $WebSocketListenerProxy$WebSocketListener$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature =>
-      r'Lcom/example/ok_http/WebSocketListenerProxy$WebSocketListener;';
-
-  @jni$_.internal
-  @core$_.override
-  WebSocketListenerProxy$WebSocketListener? fromReference(
-          jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : WebSocketListenerProxy$WebSocketListener.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocketListenerProxy$WebSocketListener?> get nullableType =>
-      this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode =>
-      ($WebSocketListenerProxy$WebSocketListener$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType ==
-            ($WebSocketListenerProxy$WebSocketListener$NullableType) &&
-        other is $WebSocketListenerProxy$WebSocketListener$NullableType;
-  }
-}
-
-final class $WebSocketListenerProxy$WebSocketListener$Type
-    extends jni$_.JObjType<WebSocketListenerProxy$WebSocketListener> {
-  @jni$_.internal
-  const $WebSocketListenerProxy$WebSocketListener$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature =>
-      r'Lcom/example/ok_http/WebSocketListenerProxy$WebSocketListener;';
-
-  @jni$_.internal
-  @core$_.override
-  WebSocketListenerProxy$WebSocketListener fromReference(
-          jni$_.JReference reference) =>
-      WebSocketListenerProxy$WebSocketListener.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocketListenerProxy$WebSocketListener?> get nullableType =>
-      const $WebSocketListenerProxy$WebSocketListener$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($WebSocketListenerProxy$WebSocketListener$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType ==
-            ($WebSocketListenerProxy$WebSocketListener$Type) &&
-        other is $WebSocketListenerProxy$WebSocketListener$Type;
-  }
-}
-
-/// from: `com.example.ok_http.WebSocketListenerProxy`
-class WebSocketListenerProxy extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<WebSocketListenerProxy> $type;
-
-  @jni$_.internal
-  WebSocketListenerProxy.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
-  static final _class =
-      jni$_.JClass.forName(r'com/example/ok_http/WebSocketListenerProxy');
-
-  /// The type which includes information such as the signature of this class.
-  static const nullableType = $WebSocketListenerProxy$NullableType();
-  static const type = $WebSocketListenerProxy$Type();
-  static final _id_new$ = _class.constructorId(
-    r'(Lcom/example/ok_http/WebSocketListenerProxy$WebSocketListener;)V',
-  );
-
-  static final _new$ = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_NewObject')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public void <init>(com.example.ok_http.WebSocketListenerProxy$WebSocketListener webSocketListener)`
-  /// The returned object must be released after use, by calling the [release] method.
-  factory WebSocketListenerProxy(
-    WebSocketListenerProxy$WebSocketListener webSocketListener,
-  ) {
-    final _$webSocketListener = webSocketListener.reference;
-    return WebSocketListenerProxy.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$webSocketListener.pointer)
-        .reference);
-  }
-
-  static final _id_onOpen = _class.instanceMethodId(
+extension WebSocketListenerProxy$WebSocketListener$$Methods
+    on WebSocketListenerProxy$WebSocketListener {
+  static final _id_onOpen =
+      WebSocketListenerProxy$WebSocketListener._class.instanceMethodId(
     r'onOpen',
     r'(Lokhttp3/WebSocket;Lokhttp3/Response;)V',
   );
@@ -14209,19 +11320,20 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public void onOpen(okhttp3.WebSocket webSocket, okhttp3.Response response)`
+  /// from: `public fun onOpen(webSocket: okhttp3.WebSocket, response: okhttp3.Response): kotlin.Unit`
   void onOpen(
     WebSocket webSocket,
     Response response,
   ) {
     final _$webSocket = webSocket.reference;
     final _$response = response.reference;
-    _onOpen(reference.pointer, _id_onOpen as jni$_.JMethodIDPtr,
-            _$webSocket.pointer, _$response.pointer)
+    _onOpen(reference.pointer, _id_onOpen.pointer, _$webSocket.pointer,
+            _$response.pointer)
         .check();
   }
 
-  static final _id_onMessage = _class.instanceMethodId(
+  static final _id_onMessage =
+      WebSocketListenerProxy$WebSocketListener._class.instanceMethodId(
     r'onMessage',
     r'(Lokhttp3/WebSocket;Ljava/lang/String;)V',
   );
@@ -14243,19 +11355,20 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public void onMessage(okhttp3.WebSocket webSocket, java.lang.String string)`
+  /// from: `public fun onMessage(webSocket: okhttp3.WebSocket, text: kotlin.String): kotlin.Unit`
   void onMessage(
     WebSocket webSocket,
     jni$_.JString string,
   ) {
     final _$webSocket = webSocket.reference;
     final _$string = string.reference;
-    _onMessage(reference.pointer, _id_onMessage as jni$_.JMethodIDPtr,
-            _$webSocket.pointer, _$string.pointer)
+    _onMessage(reference.pointer, _id_onMessage.pointer, _$webSocket.pointer,
+            _$string.pointer)
         .check();
   }
 
-  static final _id_onMessage$1 = _class.instanceMethodId(
+  static final _id_onMessage$1 =
+      WebSocketListenerProxy$WebSocketListener._class.instanceMethodId(
     r'onMessage',
     r'(Lokhttp3/WebSocket;Lokio/ByteString;)V',
   );
@@ -14277,19 +11390,20 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public void onMessage(okhttp3.WebSocket webSocket, okio.ByteString byteString)`
+  /// from: `public fun onMessage(webSocket: okhttp3.WebSocket, bytes: okio.ByteString): kotlin.Unit`
   void onMessage$1(
     WebSocket webSocket,
     ByteString byteString,
   ) {
     final _$webSocket = webSocket.reference;
     final _$byteString = byteString.reference;
-    _onMessage$1(reference.pointer, _id_onMessage$1 as jni$_.JMethodIDPtr,
+    _onMessage$1(reference.pointer, _id_onMessage$1.pointer,
             _$webSocket.pointer, _$byteString.pointer)
         .check();
   }
 
-  static final _id_onClosing = _class.instanceMethodId(
+  static final _id_onClosing =
+      WebSocketListenerProxy$WebSocketListener._class.instanceMethodId(
     r'onClosing',
     r'(Lokhttp3/WebSocket;ILjava/lang/String;)V',
   );
@@ -14310,23 +11424,24 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public void onClosing(okhttp3.WebSocket webSocket, int i, java.lang.String string)`
+  /// from: `public fun onClosing(webSocket: okhttp3.WebSocket, code: kotlin.Int, reason: kotlin.String): kotlin.Unit`
   void onClosing(
     WebSocket webSocket,
-    int i,
+    core$_.int i,
     jni$_.JString string,
   ) {
     final _$webSocket = webSocket.reference;
     final _$string = string.reference;
-    _onClosing(reference.pointer, _id_onClosing as jni$_.JMethodIDPtr,
-            _$webSocket.pointer, i, _$string.pointer)
+    _onClosing(reference.pointer, _id_onClosing.pointer, _$webSocket.pointer, i,
+            _$string.pointer)
         .check();
   }
 
-  static final _id_onFailure = _class.instanceMethodId(
+  static final _id_onFailure =
+      WebSocketListenerProxy$WebSocketListener._class.instanceMethodId(
     r'onFailure',
     r'(Lokhttp3/WebSocket;Ljava/lang/Throwable;Lokhttp3/Response;)V',
   );
@@ -14350,7 +11465,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public void onFailure(okhttp3.WebSocket webSocket, java.lang.Throwable throwable, okhttp3.Response response)`
+  /// from: `public fun onFailure(webSocket: okhttp3.WebSocket, t: kotlin.Throwable, response: okhttp3.Response?): kotlin.Unit`
   void onFailure(
     WebSocket webSocket,
     jni$_.JObject throwable,
@@ -14359,108 +11474,349 @@
     final _$webSocket = webSocket.reference;
     final _$throwable = throwable.reference;
     final _$response = response?.reference ?? jni$_.jNullReference;
-    _onFailure(reference.pointer, _id_onFailure as jni$_.JMethodIDPtr,
-            _$webSocket.pointer, _$throwable.pointer, _$response.pointer)
+    _onFailure(reference.pointer, _id_onFailure.pointer, _$webSocket.pointer,
+            _$throwable.pointer, _$response.pointer)
         .check();
   }
 }
 
-final class $WebSocketListenerProxy$NullableType
-    extends jni$_.JObjType<WebSocketListenerProxy?> {
-  @jni$_.internal
-  const $WebSocketListenerProxy$NullableType();
+abstract base mixin class $WebSocketListenerProxy$WebSocketListener {
+  factory $WebSocketListenerProxy$WebSocketListener({
+    required void Function(WebSocket webSocket, Response response) onOpen,
+    core$_.bool onOpen$async,
+    required void Function(WebSocket webSocket, jni$_.JString string) onMessage,
+    core$_.bool onMessage$async,
+    required void Function(WebSocket webSocket, ByteString byteString)
+        onMessage$1,
+    core$_.bool onMessage$1$async,
+    required void Function(
+            WebSocket webSocket, core$_.int i, jni$_.JString string)
+        onClosing,
+    core$_.bool onClosing$async,
+    required void Function(
+            WebSocket webSocket, jni$_.JObject throwable, Response? response)
+        onFailure,
+    core$_.bool onFailure$async,
+  }) = _$WebSocketListenerProxy$WebSocketListener;
 
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lcom/example/ok_http/WebSocketListenerProxy;';
+  void onOpen(WebSocket webSocket, Response response);
+  core$_.bool get onOpen$async => false;
+  void onMessage(WebSocket webSocket, jni$_.JString string);
+  core$_.bool get onMessage$async => false;
+  void onMessage$1(WebSocket webSocket, ByteString byteString);
+  core$_.bool get onMessage$1$async => false;
+  void onClosing(WebSocket webSocket, core$_.int i, jni$_.JString string);
+  core$_.bool get onClosing$async => false;
+  void onFailure(
+      WebSocket webSocket, jni$_.JObject throwable, Response? response);
+  core$_.bool get onFailure$async => false;
+}
 
-  @jni$_.internal
-  @core$_.override
-  WebSocketListenerProxy? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : WebSocketListenerProxy.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
+final class _$WebSocketListenerProxy$WebSocketListener
+    with $WebSocketListenerProxy$WebSocketListener {
+  _$WebSocketListenerProxy$WebSocketListener({
+    required void Function(WebSocket webSocket, Response response) onOpen,
+    this.onOpen$async = false,
+    required void Function(WebSocket webSocket, jni$_.JString string) onMessage,
+    this.onMessage$async = false,
+    required void Function(WebSocket webSocket, ByteString byteString)
+        onMessage$1,
+    this.onMessage$1$async = false,
+    required void Function(
+            WebSocket webSocket, core$_.int i, jni$_.JString string)
+        onClosing,
+    this.onClosing$async = false,
+    required void Function(
+            WebSocket webSocket, jni$_.JObject throwable, Response? response)
+        onFailure,
+    this.onFailure$async = false,
+  })  : _onOpen = onOpen,
+        _onMessage = onMessage,
+        _onMessage$1 = onMessage$1,
+        _onClosing = onClosing,
+        _onFailure = onFailure;
 
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocketListenerProxy?> get nullableType => this;
+  final void Function(WebSocket webSocket, Response response) _onOpen;
+  final core$_.bool onOpen$async;
+  final void Function(WebSocket webSocket, jni$_.JString string) _onMessage;
+  final core$_.bool onMessage$async;
+  final void Function(WebSocket webSocket, ByteString byteString) _onMessage$1;
+  final core$_.bool onMessage$1$async;
+  final void Function(WebSocket webSocket, core$_.int i, jni$_.JString string)
+      _onClosing;
+  final core$_.bool onClosing$async;
+  final void Function(
+          WebSocket webSocket, jni$_.JObject throwable, Response? response)
+      _onFailure;
+  final core$_.bool onFailure$async;
 
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
+  void onOpen(WebSocket webSocket, Response response) {
+    return _onOpen(webSocket, response);
+  }
 
-  @core$_.override
-  int get hashCode => ($WebSocketListenerProxy$NullableType).hashCode;
+  void onMessage(WebSocket webSocket, jni$_.JString string) {
+    return _onMessage(webSocket, string);
+  }
 
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($WebSocketListenerProxy$NullableType) &&
-        other is $WebSocketListenerProxy$NullableType;
+  void onMessage$1(WebSocket webSocket, ByteString byteString) {
+    return _onMessage$1(webSocket, byteString);
+  }
+
+  void onClosing(WebSocket webSocket, core$_.int i, jni$_.JString string) {
+    return _onClosing(webSocket, i, string);
+  }
+
+  void onFailure(
+      WebSocket webSocket, jni$_.JObject throwable, Response? response) {
+    return _onFailure(webSocket, throwable, response);
   }
 }
 
-final class $WebSocketListenerProxy$Type
-    extends jni$_.JObjType<WebSocketListenerProxy> {
+final class $WebSocketListenerProxy$WebSocketListener$Type$
+    extends jni$_.JType<WebSocketListenerProxy$WebSocketListener> {
   @jni$_.internal
-  const $WebSocketListenerProxy$Type();
+  const $WebSocketListenerProxy$WebSocketListener$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature =>
+      r'Lcom/example/ok_http/WebSocketListenerProxy$WebSocketListener;';
+}
+
+/// from: `com.example.ok_http.WebSocketListenerProxy`
+extension type WebSocketListenerProxy._(jni$_.JObject _$this)
+    implements jni$_.JObject {
+  static final _class =
+      jni$_.JClass.forName(r'com/example/ok_http/WebSocketListenerProxy');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<WebSocketListenerProxy> type =
+      $WebSocketListenerProxy$Type$();
+  static final _id_new$ = _class.constructorId(
+    r'(Lcom/example/ok_http/WebSocketListenerProxy$WebSocketListener;)V',
+  );
+
+  static final _new$ = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void <init>(com.example.ok_http.WebSocketListenerProxy$WebSocketListener webSocketListener)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory WebSocketListenerProxy(
+    WebSocketListenerProxy$WebSocketListener webSocketListener,
+  ) {
+    final _$webSocketListener = webSocketListener.reference;
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$webSocketListener.pointer)
+        .object<WebSocketListenerProxy>();
+  }
+}
+
+extension WebSocketListenerProxy$$Methods on WebSocketListenerProxy {
+  static final _id_onOpen = WebSocketListenerProxy._class.instanceMethodId(
+    r'onOpen',
+    r'(Lokhttp3/WebSocket;Lokhttp3/Response;)V',
+  );
+
+  static final _onOpen = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun onOpen(webSocket: okhttp3.WebSocket, response: okhttp3.Response): kotlin.Unit`
+  void onOpen(
+    WebSocket webSocket,
+    Response response,
+  ) {
+    final _$webSocket = webSocket.reference;
+    final _$response = response.reference;
+    _onOpen(reference.pointer, _id_onOpen.pointer, _$webSocket.pointer,
+            _$response.pointer)
+        .check();
+  }
+
+  static final _id_onMessage = WebSocketListenerProxy._class.instanceMethodId(
+    r'onMessage',
+    r'(Lokhttp3/WebSocket;Ljava/lang/String;)V',
+  );
+
+  static final _onMessage = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun onMessage(webSocket: okhttp3.WebSocket, text: kotlin.String): kotlin.Unit`
+  void onMessage(
+    WebSocket webSocket,
+    jni$_.JString string,
+  ) {
+    final _$webSocket = webSocket.reference;
+    final _$string = string.reference;
+    _onMessage(reference.pointer, _id_onMessage.pointer, _$webSocket.pointer,
+            _$string.pointer)
+        .check();
+  }
+
+  static final _id_onMessage$1 = WebSocketListenerProxy._class.instanceMethodId(
+    r'onMessage',
+    r'(Lokhttp3/WebSocket;Lokio/ByteString;)V',
+  );
+
+  static final _onMessage$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun onMessage(webSocket: okhttp3.WebSocket, bytes: okio.ByteString): kotlin.Unit`
+  void onMessage$1(
+    WebSocket webSocket,
+    ByteString byteString,
+  ) {
+    final _$webSocket = webSocket.reference;
+    final _$byteString = byteString.reference;
+    _onMessage$1(reference.pointer, _id_onMessage$1.pointer,
+            _$webSocket.pointer, _$byteString.pointer)
+        .check();
+  }
+
+  static final _id_onClosing = WebSocketListenerProxy._class.instanceMethodId(
+    r'onClosing',
+    r'(Lokhttp3/WebSocket;ILjava/lang/String;)V',
+  );
+
+  static final _onClosing = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun onClosing(webSocket: okhttp3.WebSocket, code: kotlin.Int, reason: kotlin.String): kotlin.Unit`
+  void onClosing(
+    WebSocket webSocket,
+    core$_.int i,
+    jni$_.JString string,
+  ) {
+    final _$webSocket = webSocket.reference;
+    final _$string = string.reference;
+    _onClosing(reference.pointer, _id_onClosing.pointer, _$webSocket.pointer, i,
+            _$string.pointer)
+        .check();
+  }
+
+  static final _id_onFailure = WebSocketListenerProxy._class.instanceMethodId(
+    r'onFailure',
+    r'(Lokhttp3/WebSocket;Ljava/lang/Throwable;Lokhttp3/Response;)V',
+  );
+
+  static final _onFailure = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun onFailure(webSocket: okhttp3.WebSocket, t: kotlin.Throwable, response: okhttp3.Response?): kotlin.Unit`
+  void onFailure(
+    WebSocket webSocket,
+    jni$_.JObject throwable,
+    Response? response,
+  ) {
+    final _$webSocket = webSocket.reference;
+    final _$throwable = throwable.reference;
+    final _$response = response?.reference ?? jni$_.jNullReference;
+    _onFailure(reference.pointer, _id_onFailure.pointer, _$webSocket.pointer,
+            _$throwable.pointer, _$response.pointer)
+        .check();
+  }
+}
+
+final class $WebSocketListenerProxy$Type$
+    extends jni$_.JType<WebSocketListenerProxy> {
+  @jni$_.internal
+  const $WebSocketListenerProxy$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lcom/example/ok_http/WebSocketListenerProxy;';
-
-  @jni$_.internal
-  @core$_.override
-  WebSocketListenerProxy fromReference(jni$_.JReference reference) =>
-      WebSocketListenerProxy.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocketListenerProxy?> get nullableType =>
-      const $WebSocketListenerProxy$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($WebSocketListenerProxy$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($WebSocketListenerProxy$Type) &&
-        other is $WebSocketListenerProxy$Type;
-  }
 }
 
 /// from: `com.example.ok_http.FixedResponseX509ExtendedKeyManager`
-class FixedResponseX509ExtendedKeyManager extends X509ExtendedKeyManager {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<FixedResponseX509ExtendedKeyManager> $type;
-
-  @jni$_.internal
-  FixedResponseX509ExtendedKeyManager.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type FixedResponseX509ExtendedKeyManager._(jni$_.JObject _$this)
+    implements X509ExtendedKeyManager {
   static final _class = jni$_.JClass.forName(
       r'com/example/ok_http/FixedResponseX509ExtendedKeyManager');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType =
-      $FixedResponseX509ExtendedKeyManager$NullableType();
-  static const type = $FixedResponseX509ExtendedKeyManager$Type();
+  static const jni$_.JType<FixedResponseX509ExtendedKeyManager> type =
+      $FixedResponseX509ExtendedKeyManager$Type$();
   static final _id_new$ = _class.constructorId(
     r'([Ljava/security/cert/X509Certificate;Ljava/security/PrivateKey;Ljava/lang/String;)V',
   );
@@ -14494,16 +11850,16 @@
     final _$x509Certificates = x509Certificates.reference;
     final _$privateKey = privateKey.reference;
     final _$string = string.reference;
-    return FixedResponseX509ExtendedKeyManager.fromReference(_new$(
-            _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
-            _$x509Certificates.pointer,
-            _$privateKey.pointer,
-            _$string.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$x509Certificates.pointer, _$privateKey.pointer, _$string.pointer)
+        .object<FixedResponseX509ExtendedKeyManager>();
   }
+}
 
-  static final _id_getClientAliases = _class.instanceMethodId(
+extension FixedResponseX509ExtendedKeyManager$$Methods
+    on FixedResponseX509ExtendedKeyManager {
+  static final _id_getClientAliases =
+      FixedResponseX509ExtendedKeyManager._class.instanceMethodId(
     r'getClientAliases',
     r'(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;',
   );
@@ -14525,7 +11881,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public java.lang.String[] getClientAliases(java.lang.String string, java.security.Principal[] principals)`
+  /// from: `public fun getClientAliases(keyType: kotlin.String, issuers: kotlin.Array<java.security.Principal>?): kotlin.Array<kotlin.String>`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JArray<jni$_.JString> getClientAliases(
     jni$_.JString string,
@@ -14533,16 +11889,13 @@
   ) {
     final _$string = string.reference;
     final _$principals = principals?.reference ?? jni$_.jNullReference;
-    return _getClientAliases(
-            reference.pointer,
-            _id_getClientAliases as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$principals.pointer)
-        .object<jni$_.JArray<jni$_.JString>>(
-            const jni$_.JArrayType<jni$_.JString>(jni$_.JStringType()));
+    return _getClientAliases(reference.pointer, _id_getClientAliases.pointer,
+            _$string.pointer, _$principals.pointer)
+        .object<jni$_.JArray<jni$_.JString>>();
   }
 
-  static final _id_chooseClientAlias = _class.instanceMethodId(
+  static final _id_chooseClientAlias =
+      FixedResponseX509ExtendedKeyManager._class.instanceMethodId(
     r'chooseClientAlias',
     r'([Ljava/lang/String;[Ljava/security/Principal;Ljava/net/Socket;)Ljava/lang/String;',
   );
@@ -14566,7 +11919,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public java.lang.String chooseClientAlias(java.lang.String[] strings, java.security.Principal[] principals, java.net.Socket socket)`
+  /// from: `public fun chooseClientAlias(keyType: kotlin.Array<kotlin.String>, issuers: kotlin.Array<java.security.Principal>?, socket: java.net.Socket?): kotlin.String`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString chooseClientAlias(
     jni$_.JArray<jni$_.JString> strings,
@@ -14576,16 +11929,13 @@
     final _$strings = strings.reference;
     final _$principals = principals?.reference ?? jni$_.jNullReference;
     final _$socket = socket?.reference ?? jni$_.jNullReference;
-    return _chooseClientAlias(
-            reference.pointer,
-            _id_chooseClientAlias as jni$_.JMethodIDPtr,
-            _$strings.pointer,
-            _$principals.pointer,
-            _$socket.pointer)
-        .object<jni$_.JString>(const jni$_.JStringType());
+    return _chooseClientAlias(reference.pointer, _id_chooseClientAlias.pointer,
+            _$strings.pointer, _$principals.pointer, _$socket.pointer)
+        .object<jni$_.JString>();
   }
 
-  static final _id_getServerAliases = _class.instanceMethodId(
+  static final _id_getServerAliases =
+      FixedResponseX509ExtendedKeyManager._class.instanceMethodId(
     r'getServerAliases',
     r'(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;',
   );
@@ -14607,7 +11957,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public java.lang.String[] getServerAliases(java.lang.String string, java.security.Principal[] principals)`
+  /// from: `public fun getServerAliases(keyType: kotlin.String, issuers: kotlin.Array<java.security.Principal>?): kotlin.Array<kotlin.String>`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JArray<jni$_.JString> getServerAliases(
     jni$_.JString string,
@@ -14615,16 +11965,13 @@
   ) {
     final _$string = string.reference;
     final _$principals = principals?.reference ?? jni$_.jNullReference;
-    return _getServerAliases(
-            reference.pointer,
-            _id_getServerAliases as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$principals.pointer)
-        .object<jni$_.JArray<jni$_.JString>>(
-            const jni$_.JArrayType<jni$_.JString>(jni$_.JStringType()));
+    return _getServerAliases(reference.pointer, _id_getServerAliases.pointer,
+            _$string.pointer, _$principals.pointer)
+        .object<jni$_.JArray<jni$_.JString>>();
   }
 
-  static final _id_chooseServerAlias = _class.instanceMethodId(
+  static final _id_chooseServerAlias =
+      FixedResponseX509ExtendedKeyManager._class.instanceMethodId(
     r'chooseServerAlias',
     r'(Ljava/lang/String;[Ljava/security/Principal;Ljava/net/Socket;)Ljava/lang/String;',
   );
@@ -14648,7 +11995,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public java.lang.String chooseServerAlias(java.lang.String string, java.security.Principal[] principals, java.net.Socket socket)`
+  /// from: `public fun chooseServerAlias(keyType: kotlin.String, issuers: kotlin.Array<java.security.Principal>?, socket: java.net.Socket?): kotlin.String`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString chooseServerAlias(
     jni$_.JString string,
@@ -14658,16 +12005,13 @@
     final _$string = string.reference;
     final _$principals = principals?.reference ?? jni$_.jNullReference;
     final _$socket = socket?.reference ?? jni$_.jNullReference;
-    return _chooseServerAlias(
-            reference.pointer,
-            _id_chooseServerAlias as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$principals.pointer,
-            _$socket.pointer)
-        .object<jni$_.JString>(const jni$_.JStringType());
+    return _chooseServerAlias(reference.pointer, _id_chooseServerAlias.pointer,
+            _$string.pointer, _$principals.pointer, _$socket.pointer)
+        .object<jni$_.JString>();
   }
 
-  static final _id_getCertificateChain = _class.instanceMethodId(
+  static final _id_getCertificateChain =
+      FixedResponseX509ExtendedKeyManager._class.instanceMethodId(
     r'getCertificateChain',
     r'(Ljava/lang/String;)[Ljava/security/cert/X509Certificate;',
   );
@@ -14683,19 +12027,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public java.security.cert.X509Certificate[] getCertificateChain(java.lang.String string)`
+  /// from: `public fun getCertificateChain(alias: kotlin.String): kotlin.Array<java.security.cert.X509Certificate>`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JArray<X509Certificate> getCertificateChain(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
     return _getCertificateChain(reference.pointer,
-            _id_getCertificateChain as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<jni$_.JArray<X509Certificate>>(
-            const jni$_.JArrayType<X509Certificate>($X509Certificate$Type()));
+            _id_getCertificateChain.pointer, _$string.pointer)
+        .object<jni$_.JArray<X509Certificate>>();
   }
 
-  static final _id_getPrivateKey = _class.instanceMethodId(
+  static final _id_getPrivateKey =
+      FixedResponseX509ExtendedKeyManager._class.instanceMethodId(
     r'getPrivateKey',
     r'(Ljava/lang/String;)Ljava/security/PrivateKey;',
   );
@@ -14711,18 +12055,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public java.security.PrivateKey getPrivateKey(java.lang.String string)`
+  /// from: `public fun getPrivateKey(alias: kotlin.String): java.security.PrivateKey`
   /// The returned object must be released after use, by calling the [release] method.
   PrivateKey getPrivateKey(
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _getPrivateKey(reference.pointer,
-            _id_getPrivateKey as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<PrivateKey>(const $PrivateKey$Type());
+    return _getPrivateKey(
+            reference.pointer, _id_getPrivateKey.pointer, _$string.pointer)
+        .object<PrivateKey>();
   }
 
-  static final _id_chooseEngineClientAlias = _class.instanceMethodId(
+  static final _id_chooseEngineClientAlias =
+      FixedResponseX509ExtendedKeyManager._class.instanceMethodId(
     r'chooseEngineClientAlias',
     r'([Ljava/lang/String;[Ljava/security/Principal;Ljavax/net/ssl/SSLEngine;)Ljava/lang/String;',
   );
@@ -14746,7 +12091,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public java.lang.String chooseEngineClientAlias(java.lang.String[] strings, java.security.Principal[] principals, javax.net.ssl.SSLEngine sSLEngine)`
+  /// from: `public fun chooseEngineClientAlias(keyType: kotlin.Array<kotlin.String?>?, issuers: kotlin.Array<java.security.Principal?>?, engine: javax.net.ssl.SSLEngine?): kotlin.String`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString chooseEngineClientAlias(
     jni$_.JArray<jni$_.JString?>? strings,
@@ -14758,14 +12103,15 @@
     final _$sSLEngine = sSLEngine?.reference ?? jni$_.jNullReference;
     return _chooseEngineClientAlias(
             reference.pointer,
-            _id_chooseEngineClientAlias as jni$_.JMethodIDPtr,
+            _id_chooseEngineClientAlias.pointer,
             _$strings.pointer,
             _$principals.pointer,
             _$sSLEngine.pointer)
-        .object<jni$_.JString>(const jni$_.JStringType());
+        .object<jni$_.JString>();
   }
 
-  static final _id_chooseEngineServerAlias = _class.instanceMethodId(
+  static final _id_chooseEngineServerAlias =
+      FixedResponseX509ExtendedKeyManager._class.instanceMethodId(
     r'chooseEngineServerAlias',
     r'(Ljava/lang/String;[Ljava/security/Principal;Ljavax/net/ssl/SSLEngine;)Ljava/lang/String;',
   );
@@ -14789,7 +12135,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public java.lang.String chooseEngineServerAlias(java.lang.String string, java.security.Principal[] principals, javax.net.ssl.SSLEngine sSLEngine)`
+  /// from: `public fun chooseEngineServerAlias(keyType: kotlin.String?, issuers: kotlin.Array<java.security.Principal?>?, engine: javax.net.ssl.SSLEngine?): kotlin.String`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString chooseEngineServerAlias(
     jni$_.JString? string,
@@ -14801,348 +12147,33 @@
     final _$sSLEngine = sSLEngine?.reference ?? jni$_.jNullReference;
     return _chooseEngineServerAlias(
             reference.pointer,
-            _id_chooseEngineServerAlias as jni$_.JMethodIDPtr,
+            _id_chooseEngineServerAlias.pointer,
             _$string.pointer,
             _$principals.pointer,
             _$sSLEngine.pointer)
-        .object<jni$_.JString>(const jni$_.JStringType());
+        .object<jni$_.JString>();
   }
 }
 
-final class $FixedResponseX509ExtendedKeyManager$NullableType
-    extends jni$_.JObjType<FixedResponseX509ExtendedKeyManager?> {
+final class $FixedResponseX509ExtendedKeyManager$Type$
+    extends jni$_.JType<FixedResponseX509ExtendedKeyManager> {
   @jni$_.internal
-  const $FixedResponseX509ExtendedKeyManager$NullableType();
+  const $FixedResponseX509ExtendedKeyManager$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature =>
       r'Lcom/example/ok_http/FixedResponseX509ExtendedKeyManager;';
-
-  @jni$_.internal
-  @core$_.override
-  FixedResponseX509ExtendedKeyManager? fromReference(
-          jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : FixedResponseX509ExtendedKeyManager.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const $X509ExtendedKeyManager$Type();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<FixedResponseX509ExtendedKeyManager?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 2;
-
-  @core$_.override
-  int get hashCode =>
-      ($FixedResponseX509ExtendedKeyManager$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType ==
-            ($FixedResponseX509ExtendedKeyManager$NullableType) &&
-        other is $FixedResponseX509ExtendedKeyManager$NullableType;
-  }
-}
-
-final class $FixedResponseX509ExtendedKeyManager$Type
-    extends jni$_.JObjType<FixedResponseX509ExtendedKeyManager> {
-  @jni$_.internal
-  const $FixedResponseX509ExtendedKeyManager$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature =>
-      r'Lcom/example/ok_http/FixedResponseX509ExtendedKeyManager;';
-
-  @jni$_.internal
-  @core$_.override
-  FixedResponseX509ExtendedKeyManager fromReference(
-          jni$_.JReference reference) =>
-      FixedResponseX509ExtendedKeyManager.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const $X509ExtendedKeyManager$Type();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<FixedResponseX509ExtendedKeyManager?> get nullableType =>
-      const $FixedResponseX509ExtendedKeyManager$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 2;
-
-  @core$_.override
-  int get hashCode => ($FixedResponseX509ExtendedKeyManager$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($FixedResponseX509ExtendedKeyManager$Type) &&
-        other is $FixedResponseX509ExtendedKeyManager$Type;
-  }
 }
 
 /// from: `okio.ByteString$Companion`
-class ByteString$Companion extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<ByteString$Companion> $type;
-
-  @jni$_.internal
-  ByteString$Companion.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type ByteString$Companion._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okio/ByteString$Companion');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $ByteString$Companion$NullableType();
-  static const type = $ByteString$Companion$Type();
-  static final _id_of = _class.instanceMethodId(
-    r'of',
-    r'([B)Lokio/ByteString;',
-  );
-
-  static final _of = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okio.ByteString of(byte[] bs)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString of(
-    jni$_.JByteArray bs,
-  ) {
-    final _$bs = bs.reference;
-    return _of(reference.pointer, _id_of as jni$_.JMethodIDPtr, _$bs.pointer)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_of$1 = _class.instanceMethodId(
-    r'of',
-    r'([BII)Lokio/ByteString;',
-  );
-
-  static final _of$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `public final okio.ByteString of(byte[] bs, int i, int i1)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString of$1(
-    jni$_.JByteArray bs,
-    int i,
-    int i1,
-  ) {
-    final _$bs = bs.reference;
-    return _of$1(reference.pointer, _id_of$1 as jni$_.JMethodIDPtr,
-            _$bs.pointer, i, i1)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_of$2 = _class.instanceMethodId(
-    r'of',
-    r'(Ljava/nio/ByteBuffer;)Lokio/ByteString;',
-  );
-
-  static final _of$2 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okio.ByteString of(java.nio.ByteBuffer byteBuffer)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString of$2(
-    jni$_.JByteBuffer byteBuffer,
-  ) {
-    final _$byteBuffer = byteBuffer.reference;
-    return _of$2(reference.pointer, _id_of$2 as jni$_.JMethodIDPtr,
-            _$byteBuffer.pointer)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_encodeUtf8 = _class.instanceMethodId(
-    r'encodeUtf8',
-    r'(Ljava/lang/String;)Lokio/ByteString;',
-  );
-
-  static final _encodeUtf8 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okio.ByteString encodeUtf8(java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString encodeUtf8(
-    jni$_.JString string,
-  ) {
-    final _$string = string.reference;
-    return _encodeUtf8(reference.pointer, _id_encodeUtf8 as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_encodeString = _class.instanceMethodId(
-    r'encodeString',
-    r'(Ljava/lang/String;Ljava/nio/charset/Charset;)Lokio/ByteString;',
-  );
-
-  static final _encodeString = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okio.ByteString encodeString(java.lang.String string, java.nio.charset.Charset charset)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString encodeString(
-    jni$_.JString string,
-    jni$_.JObject charset,
-  ) {
-    final _$string = string.reference;
-    final _$charset = charset.reference;
-    return _encodeString(
-            reference.pointer,
-            _id_encodeString as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$charset.pointer)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_decodeBase64 = _class.instanceMethodId(
-    r'decodeBase64',
-    r'(Ljava/lang/String;)Lokio/ByteString;',
-  );
-
-  static final _decodeBase64 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okio.ByteString decodeBase64(java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString? decodeBase64(
-    jni$_.JString string,
-  ) {
-    final _$string = string.reference;
-    return _decodeBase64(reference.pointer,
-            _id_decodeBase64 as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<ByteString?>(const $ByteString$NullableType());
-  }
-
-  static final _id_decodeHex = _class.instanceMethodId(
-    r'decodeHex',
-    r'(Ljava/lang/String;)Lokio/ByteString;',
-  );
-
-  static final _decodeHex = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final okio.ByteString decodeHex(java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString decodeHex(
-    jni$_.JString string,
-  ) {
-    final _$string = string.reference;
-    return _decodeHex(reference.pointer, _id_decodeHex as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_read = _class.instanceMethodId(
-    r'read',
-    r'(Ljava/io/InputStream;I)Lokio/ByteString;',
-  );
-
-  static final _read = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `public final okio.ByteString read(java.io.InputStream inputStream, int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString read(
-    jni$_.JObject inputStream,
-    int i,
-  ) {
-    final _$inputStream = inputStream.reference;
-    return _read(reference.pointer, _id_read as jni$_.JMethodIDPtr,
-            _$inputStream.pointer, i)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
+  static const jni$_.JType<ByteString$Companion> type =
+      $ByteString$Companion$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Lkotlin/jvm/internal/DefaultConstructorMarker;)V',
   );
@@ -15165,106 +12196,262 @@
   ) {
     final _$defaultConstructorMarker =
         defaultConstructorMarker?.reference ?? jni$_.jNullReference;
-    return ByteString$Companion.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$defaultConstructorMarker.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$defaultConstructorMarker.pointer)
+        .object<ByteString$Companion>();
   }
 }
 
-final class $ByteString$Companion$NullableType
-    extends jni$_.JObjType<ByteString$Companion?> {
+extension ByteString$Companion$$Methods on ByteString$Companion {
+  static final _id_of = ByteString$Companion._class.instanceMethodId(
+    r'of',
+    r'([B)Lokio/ByteString;',
+  );
+
+  static final _of = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun of(vararg data: kotlin.Byte): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString of(
+    jni$_.JByteArray bs,
+  ) {
+    final _$bs = bs.reference;
+    return _of(reference.pointer, _id_of.pointer, _$bs.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_of$1 = ByteString$Companion._class.instanceMethodId(
+    r'of',
+    r'([BII)Lokio/ByteString;',
+  );
+
+  static final _of$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `public fun toByteString(offset: kotlin.Int, byteCount: kotlin.Int): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString of$1(
+    jni$_.JByteArray bs,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$bs = bs.reference;
+    return _of$1(reference.pointer, _id_of$1.pointer, _$bs.pointer, i, i1)
+        .object<ByteString>();
+  }
+
+  static final _id_of$2 = ByteString$Companion._class.instanceMethodId(
+    r'of',
+    r'(Ljava/nio/ByteBuffer;)Lokio/ByteString;',
+  );
+
+  static final _of$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun toByteString(): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString of$2(
+    jni$_.JByteBuffer byteBuffer,
+  ) {
+    final _$byteBuffer = byteBuffer.reference;
+    return _of$2(reference.pointer, _id_of$2.pointer, _$byteBuffer.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_encodeUtf8 = ByteString$Companion._class.instanceMethodId(
+    r'encodeUtf8',
+    r'(Ljava/lang/String;)Lokio/ByteString;',
+  );
+
+  static final _encodeUtf8 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun encodeUtf8(): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString encodeUtf8(
+    jni$_.JString string,
+  ) {
+    final _$string = string.reference;
+    return _encodeUtf8(
+            reference.pointer, _id_encodeUtf8.pointer, _$string.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_encodeString = ByteString$Companion._class.instanceMethodId(
+    r'encodeString',
+    r'(Ljava/lang/String;Ljava/nio/charset/Charset;)Lokio/ByteString;',
+  );
+
+  static final _encodeString = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun encode(charset: java.nio.charset.Charset): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString encodeString(
+    jni$_.JString string,
+    jni$_.JObject charset,
+  ) {
+    final _$string = string.reference;
+    final _$charset = charset.reference;
+    return _encodeString(reference.pointer, _id_encodeString.pointer,
+            _$string.pointer, _$charset.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_decodeBase64 = ByteString$Companion._class.instanceMethodId(
+    r'decodeBase64',
+    r'(Ljava/lang/String;)Lokio/ByteString;',
+  );
+
+  static final _decodeBase64 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun decodeBase64(): okio.ByteString?`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString? decodeBase64(
+    jni$_.JString string,
+  ) {
+    final _$string = string.reference;
+    return _decodeBase64(
+            reference.pointer, _id_decodeBase64.pointer, _$string.pointer)
+        .object<ByteString?>();
+  }
+
+  static final _id_decodeHex = ByteString$Companion._class.instanceMethodId(
+    r'decodeHex',
+    r'(Ljava/lang/String;)Lokio/ByteString;',
+  );
+
+  static final _decodeHex = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun decodeHex(): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString decodeHex(
+    jni$_.JString string,
+  ) {
+    final _$string = string.reference;
+    return _decodeHex(
+            reference.pointer, _id_decodeHex.pointer, _$string.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_read = ByteString$Companion._class.instanceMethodId(
+    r'read',
+    r'(Ljava/io/InputStream;I)Lokio/ByteString;',
+  );
+
+  static final _read = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `public fun readByteString(byteCount: kotlin.Int): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString read(
+    jni$_.JObject inputStream,
+    core$_.int i,
+  ) {
+    final _$inputStream = inputStream.reference;
+    return _read(reference.pointer, _id_read.pointer, _$inputStream.pointer, i)
+        .object<ByteString>();
+  }
+}
+
+final class $ByteString$Companion$Type$
+    extends jni$_.JType<ByteString$Companion> {
   @jni$_.internal
-  const $ByteString$Companion$NullableType();
+  const $ByteString$Companion$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lokio/ByteString$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  ByteString$Companion? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : ByteString$Companion.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ByteString$Companion?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ByteString$Companion$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ByteString$Companion$NullableType) &&
-        other is $ByteString$Companion$NullableType;
-  }
-}
-
-final class $ByteString$Companion$Type
-    extends jni$_.JObjType<ByteString$Companion> {
-  @jni$_.internal
-  const $ByteString$Companion$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokio/ByteString$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  ByteString$Companion fromReference(jni$_.JReference reference) =>
-      ByteString$Companion.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ByteString$Companion?> get nullableType =>
-      const $ByteString$Companion$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ByteString$Companion$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ByteString$Companion$Type) &&
-        other is $ByteString$Companion$Type;
-  }
 }
 
 /// from: `okio.ByteString`
-class ByteString extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<ByteString> $type;
-
-  @jni$_.internal
-  ByteString.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type ByteString._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'okio/ByteString');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $ByteString$NullableType();
-  static const type = $ByteString$Type();
+  static const jni$_.JType<ByteString> type = $ByteString$Type$();
   static final _id_Companion = _class.staticFieldId(
     r'Companion',
     r'Lokio/ByteString$Companion;',
@@ -15273,7 +12460,8 @@
   /// from: `static public final okio.ByteString$Companion Companion`
   /// The returned object must be released after use, by calling the [release] method.
   static ByteString$Companion get Companion =>
-      _id_Companion.get(_class, const $ByteString$Companion$Type());
+      _id_Companion.get(_class, ByteString$Companion.type)
+          as ByteString$Companion;
 
   static final _id_EMPTY = _class.staticFieldId(
     r'EMPTY',
@@ -15283,7 +12471,7 @@
   /// from: `static public final okio.ByteString EMPTY`
   /// The returned object must be released after use, by calling the [release] method.
   static ByteString get EMPTY =>
-      _id_EMPTY.get(_class, const $ByteString$Type());
+      _id_EMPTY.get(_class, ByteString.type) as ByteString;
 
   static final _id_new$ = _class.constructorId(
     r'([B)V',
@@ -15306,1083 +12494,8 @@
     jni$_.JByteArray bs,
   ) {
     final _$bs = bs.reference;
-    return ByteString.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$bs.pointer)
-        .reference);
-  }
-
-  static final _id_utf8 = _class.instanceMethodId(
-    r'utf8',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _utf8 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.lang.String utf8()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString utf8() {
-    return _utf8(reference.pointer, _id_utf8 as jni$_.JMethodIDPtr)
-        .object<jni$_.JString>(const jni$_.JStringType());
-  }
-
-  static final _id_string = _class.instanceMethodId(
-    r'string',
-    r'(Ljava/nio/charset/Charset;)Ljava/lang/String;',
-  );
-
-  static final _string = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public java.lang.String string(java.nio.charset.Charset charset)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString string(
-    jni$_.JObject charset,
-  ) {
-    final _$charset = charset.reference;
-    return _string(reference.pointer, _id_string as jni$_.JMethodIDPtr,
-            _$charset.pointer)
-        .object<jni$_.JString>(const jni$_.JStringType());
-  }
-
-  static final _id_base64 = _class.instanceMethodId(
-    r'base64',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _base64 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.lang.String base64()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString base64() {
-    return _base64(reference.pointer, _id_base64 as jni$_.JMethodIDPtr)
-        .object<jni$_.JString>(const jni$_.JStringType());
-  }
-
-  static final _id_md5 = _class.instanceMethodId(
-    r'md5',
-    r'()Lokio/ByteString;',
-  );
-
-  static final _md5 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okio.ByteString md5()`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString md5() {
-    return _md5(reference.pointer, _id_md5 as jni$_.JMethodIDPtr)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_sha1 = _class.instanceMethodId(
-    r'sha1',
-    r'()Lokio/ByteString;',
-  );
-
-  static final _sha1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okio.ByteString sha1()`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString sha1() {
-    return _sha1(reference.pointer, _id_sha1 as jni$_.JMethodIDPtr)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_sha256 = _class.instanceMethodId(
-    r'sha256',
-    r'()Lokio/ByteString;',
-  );
-
-  static final _sha256 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okio.ByteString sha256()`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString sha256() {
-    return _sha256(reference.pointer, _id_sha256 as jni$_.JMethodIDPtr)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_sha512 = _class.instanceMethodId(
-    r'sha512',
-    r'()Lokio/ByteString;',
-  );
-
-  static final _sha512 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okio.ByteString sha512()`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString sha512() {
-    return _sha512(reference.pointer, _id_sha512 as jni$_.JMethodIDPtr)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_hmacSha1 = _class.instanceMethodId(
-    r'hmacSha1',
-    r'(Lokio/ByteString;)Lokio/ByteString;',
-  );
-
-  static final _hmacSha1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public okio.ByteString hmacSha1(okio.ByteString byteString)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString hmacSha1(
-    ByteString byteString,
-  ) {
-    final _$byteString = byteString.reference;
-    return _hmacSha1(reference.pointer, _id_hmacSha1 as jni$_.JMethodIDPtr,
-            _$byteString.pointer)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_hmacSha256 = _class.instanceMethodId(
-    r'hmacSha256',
-    r'(Lokio/ByteString;)Lokio/ByteString;',
-  );
-
-  static final _hmacSha256 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public okio.ByteString hmacSha256(okio.ByteString byteString)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString hmacSha256(
-    ByteString byteString,
-  ) {
-    final _$byteString = byteString.reference;
-    return _hmacSha256(reference.pointer, _id_hmacSha256 as jni$_.JMethodIDPtr,
-            _$byteString.pointer)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_hmacSha512 = _class.instanceMethodId(
-    r'hmacSha512',
-    r'(Lokio/ByteString;)Lokio/ByteString;',
-  );
-
-  static final _hmacSha512 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public okio.ByteString hmacSha512(okio.ByteString byteString)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString hmacSha512(
-    ByteString byteString,
-  ) {
-    final _$byteString = byteString.reference;
-    return _hmacSha512(reference.pointer, _id_hmacSha512 as jni$_.JMethodIDPtr,
-            _$byteString.pointer)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_base64Url = _class.instanceMethodId(
-    r'base64Url',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _base64Url = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.lang.String base64Url()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString base64Url() {
-    return _base64Url(reference.pointer, _id_base64Url as jni$_.JMethodIDPtr)
-        .object<jni$_.JString>(const jni$_.JStringType());
-  }
-
-  static final _id_hex = _class.instanceMethodId(
-    r'hex',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _hex = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.lang.String hex()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString hex() {
-    return _hex(reference.pointer, _id_hex as jni$_.JMethodIDPtr)
-        .object<jni$_.JString>(const jni$_.JStringType());
-  }
-
-  static final _id_toAsciiLowercase = _class.instanceMethodId(
-    r'toAsciiLowercase',
-    r'()Lokio/ByteString;',
-  );
-
-  static final _toAsciiLowercase = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public okio.ByteString toAsciiLowercase()`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString toAsciiLowercase() {
-    return _toAsciiLowercase(
-            reference.pointer, _id_toAsciiLowercase as jni$_.JMethodIDPtr)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_toAsciiUppercase = _class.instanceMethodId(
-    r'toAsciiUppercase',
-    r'()Lokio/ByteString;',
-  );
-
-  static final _toAsciiUppercase = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public okio.ByteString toAsciiUppercase()`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString toAsciiUppercase() {
-    return _toAsciiUppercase(
-            reference.pointer, _id_toAsciiUppercase as jni$_.JMethodIDPtr)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_substring = _class.instanceMethodId(
-    r'substring',
-    r'(II)Lokio/ByteString;',
-  );
-
-  static final _substring = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Int32, jni$_.Int32)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int, int)>();
-
-  /// from: `public okio.ByteString substring(int i, int i1)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString substring(
-    int i,
-    int i1,
-  ) {
-    return _substring(
-            reference.pointer, _id_substring as jni$_.JMethodIDPtr, i, i1)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_getByte = _class.instanceMethodId(
-    r'getByte',
-    r'(I)B',
-  );
-
-  static final _getByte = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallByteMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public final byte getByte(int i)`
-  int getByte(
-    int i,
-  ) {
-    return _getByte(reference.pointer, _id_getByte as jni$_.JMethodIDPtr, i)
-        .byte;
-  }
-
-  static final _id_size = _class.instanceMethodId(
-    r'size',
-    r'()I',
-  );
-
-  static final _size = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int size()`
-  int size() {
-    return _size(reference.pointer, _id_size as jni$_.JMethodIDPtr).integer;
-  }
-
-  static final _id_toByteArray = _class.instanceMethodId(
-    r'toByteArray',
-    r'()[B',
-  );
-
-  static final _toByteArray = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public byte[] toByteArray()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JByteArray toByteArray() {
-    return _toByteArray(
-            reference.pointer, _id_toByteArray as jni$_.JMethodIDPtr)
-        .object<jni$_.JByteArray>(const jni$_.JByteArrayType());
-  }
-
-  static final _id_asByteBuffer = _class.instanceMethodId(
-    r'asByteBuffer',
-    r'()Ljava/nio/ByteBuffer;',
-  );
-
-  static final _asByteBuffer = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.nio.ByteBuffer asByteBuffer()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JByteBuffer asByteBuffer() {
-    return _asByteBuffer(
-            reference.pointer, _id_asByteBuffer as jni$_.JMethodIDPtr)
-        .object<jni$_.JByteBuffer>(const jni$_.JByteBufferType());
-  }
-
-  static final _id_write = _class.instanceMethodId(
-    r'write',
-    r'(Ljava/io/OutputStream;)V',
-  );
-
-  static final _write = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public void write(java.io.OutputStream outputStream)`
-  void write(
-    jni$_.JObject outputStream,
-  ) {
-    final _$outputStream = outputStream.reference;
-    _write(reference.pointer, _id_write as jni$_.JMethodIDPtr,
-            _$outputStream.pointer)
-        .check();
-  }
-
-  static final _id_rangeEquals = _class.instanceMethodId(
-    r'rangeEquals',
-    r'(ILokio/ByteString;II)Z',
-  );
-
-  static final _rangeEquals = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `public boolean rangeEquals(int i, okio.ByteString byteString, int i1, int i2)`
-  bool rangeEquals(
-    int i,
-    ByteString byteString,
-    int i1,
-    int i2,
-  ) {
-    final _$byteString = byteString.reference;
-    return _rangeEquals(
-            reference.pointer,
-            _id_rangeEquals as jni$_.JMethodIDPtr,
-            i,
-            _$byteString.pointer,
-            i1,
-            i2)
-        .boolean;
-  }
-
-  static final _id_rangeEquals$1 = _class.instanceMethodId(
-    r'rangeEquals',
-    r'(I[BII)Z',
-  );
-
-  static final _rangeEquals$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `public boolean rangeEquals(int i, byte[] bs, int i1, int i2)`
-  bool rangeEquals$1(
-    int i,
-    jni$_.JByteArray bs,
-    int i1,
-    int i2,
-  ) {
-    final _$bs = bs.reference;
-    return _rangeEquals$1(reference.pointer,
-            _id_rangeEquals$1 as jni$_.JMethodIDPtr, i, _$bs.pointer, i1, i2)
-        .boolean;
-  }
-
-  static final _id_copyInto = _class.instanceMethodId(
-    r'copyInto',
-    r'(I[BII)V',
-  );
-
-  static final _copyInto = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `public void copyInto(int i, byte[] bs, int i1, int i2)`
-  void copyInto(
-    int i,
-    jni$_.JByteArray bs,
-    int i1,
-    int i2,
-  ) {
-    final _$bs = bs.reference;
-    _copyInto(reference.pointer, _id_copyInto as jni$_.JMethodIDPtr, i,
-            _$bs.pointer, i1, i2)
-        .check();
-  }
-
-  static final _id_startsWith = _class.instanceMethodId(
-    r'startsWith',
-    r'(Lokio/ByteString;)Z',
-  );
-
-  static final _startsWith = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final boolean startsWith(okio.ByteString byteString)`
-  bool startsWith(
-    ByteString byteString,
-  ) {
-    final _$byteString = byteString.reference;
-    return _startsWith(reference.pointer, _id_startsWith as jni$_.JMethodIDPtr,
-            _$byteString.pointer)
-        .boolean;
-  }
-
-  static final _id_startsWith$1 = _class.instanceMethodId(
-    r'startsWith',
-    r'([B)Z',
-  );
-
-  static final _startsWith$1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final boolean startsWith(byte[] bs)`
-  bool startsWith$1(
-    jni$_.JByteArray bs,
-  ) {
-    final _$bs = bs.reference;
-    return _startsWith$1(reference.pointer,
-            _id_startsWith$1 as jni$_.JMethodIDPtr, _$bs.pointer)
-        .boolean;
-  }
-
-  static final _id_endsWith = _class.instanceMethodId(
-    r'endsWith',
-    r'(Lokio/ByteString;)Z',
-  );
-
-  static final _endsWith = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final boolean endsWith(okio.ByteString byteString)`
-  bool endsWith(
-    ByteString byteString,
-  ) {
-    final _$byteString = byteString.reference;
-    return _endsWith(reference.pointer, _id_endsWith as jni$_.JMethodIDPtr,
-            _$byteString.pointer)
-        .boolean;
-  }
-
-  static final _id_endsWith$1 = _class.instanceMethodId(
-    r'endsWith',
-    r'([B)Z',
-  );
-
-  static final _endsWith$1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final boolean endsWith(byte[] bs)`
-  bool endsWith$1(
-    jni$_.JByteArray bs,
-  ) {
-    final _$bs = bs.reference;
-    return _endsWith$1(reference.pointer, _id_endsWith$1 as jni$_.JMethodIDPtr,
-            _$bs.pointer)
-        .boolean;
-  }
-
-  static final _id_indexOf = _class.instanceMethodId(
-    r'indexOf',
-    r'(Lokio/ByteString;I)I',
-  );
-
-  static final _indexOf = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `public final int indexOf(okio.ByteString byteString, int i)`
-  int indexOf(
-    ByteString byteString,
-    int i,
-  ) {
-    final _$byteString = byteString.reference;
-    return _indexOf(reference.pointer, _id_indexOf as jni$_.JMethodIDPtr,
-            _$byteString.pointer, i)
-        .integer;
-  }
-
-  static final _id_indexOf$1 = _class.instanceMethodId(
-    r'indexOf',
-    r'([BI)I',
-  );
-
-  static final _indexOf$1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `public int indexOf(byte[] bs, int i)`
-  int indexOf$1(
-    jni$_.JByteArray bs,
-    int i,
-  ) {
-    final _$bs = bs.reference;
-    return _indexOf$1(reference.pointer, _id_indexOf$1 as jni$_.JMethodIDPtr,
-            _$bs.pointer, i)
-        .integer;
-  }
-
-  static final _id_lastIndexOf = _class.instanceMethodId(
-    r'lastIndexOf',
-    r'(Lokio/ByteString;I)I',
-  );
-
-  static final _lastIndexOf = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `public final int lastIndexOf(okio.ByteString byteString, int i)`
-  int lastIndexOf(
-    ByteString byteString,
-    int i,
-  ) {
-    final _$byteString = byteString.reference;
-    return _lastIndexOf(reference.pointer,
-            _id_lastIndexOf as jni$_.JMethodIDPtr, _$byteString.pointer, i)
-        .integer;
-  }
-
-  static final _id_lastIndexOf$1 = _class.instanceMethodId(
-    r'lastIndexOf',
-    r'([BI)I',
-  );
-
-  static final _lastIndexOf$1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `public int lastIndexOf(byte[] bs, int i)`
-  int lastIndexOf$1(
-    jni$_.JByteArray bs,
-    int i,
-  ) {
-    final _$bs = bs.reference;
-    return _lastIndexOf$1(reference.pointer,
-            _id_lastIndexOf$1 as jni$_.JMethodIDPtr, _$bs.pointer, i)
-        .integer;
-  }
-
-  static final _id_equals = _class.instanceMethodId(
-    r'equals',
-    r'(Ljava/lang/Object;)Z',
-  );
-
-  static final _equals = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public boolean equals(java.lang.Object object)`
-  bool equals(
-    jni$_.JObject? object,
-  ) {
-    final _$object = object?.reference ?? jni$_.jNullReference;
-    return _equals(reference.pointer, _id_equals as jni$_.JMethodIDPtr,
-            _$object.pointer)
-        .boolean;
-  }
-
-  static final _id_hashCode$1 = _class.instanceMethodId(
-    r'hashCode',
-    r'()I',
-  );
-
-  static final _hashCode$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public int hashCode()`
-  int hashCode$1() {
-    return _hashCode$1(reference.pointer, _id_hashCode$1 as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_compareTo = _class.instanceMethodId(
-    r'compareTo',
-    r'(Lokio/ByteString;)I',
-  );
-
-  static final _compareTo = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public int compareTo(okio.ByteString byteString)`
-  int compareTo(
-    ByteString byteString,
-  ) {
-    final _$byteString = byteString.reference;
-    return _compareTo(reference.pointer, _id_compareTo as jni$_.JMethodIDPtr,
-            _$byteString.pointer)
-        .integer;
-  }
-
-  static final _id_toString$1 = _class.instanceMethodId(
-    r'toString',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _toString$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.lang.String toString()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString toString$1() {
-    return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr)
-        .object<jni$_.JString>(const jni$_.JStringType());
-  }
-
-  static final _id_substring$1 = _class.instanceMethodId(
-    r'substring',
-    r'(I)Lokio/ByteString;',
-  );
-
-  static final _substring$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public final okio.ByteString substring(int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString substring$1(
-    int i,
-  ) {
-    return _substring$1(
-            reference.pointer, _id_substring$1 as jni$_.JMethodIDPtr, i)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_substring$2 = _class.instanceMethodId(
-    r'substring',
-    r'()Lokio/ByteString;',
-  );
-
-  static final _substring$2 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final okio.ByteString substring()`
-  /// The returned object must be released after use, by calling the [release] method.
-  ByteString substring$2() {
-    return _substring$2(
-            reference.pointer, _id_substring$2 as jni$_.JMethodIDPtr)
-        .object<ByteString>(const $ByteString$Type());
-  }
-
-  static final _id_indexOf$2 = _class.instanceMethodId(
-    r'indexOf',
-    r'(Lokio/ByteString;)I',
-  );
-
-  static final _indexOf$2 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final int indexOf(okio.ByteString byteString)`
-  int indexOf$2(
-    ByteString byteString,
-  ) {
-    final _$byteString = byteString.reference;
-    return _indexOf$2(reference.pointer, _id_indexOf$2 as jni$_.JMethodIDPtr,
-            _$byteString.pointer)
-        .integer;
-  }
-
-  static final _id_indexOf$3 = _class.instanceMethodId(
-    r'indexOf',
-    r'([B)I',
-  );
-
-  static final _indexOf$3 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final int indexOf(byte[] bs)`
-  int indexOf$3(
-    jni$_.JByteArray bs,
-  ) {
-    final _$bs = bs.reference;
-    return _indexOf$3(reference.pointer, _id_indexOf$3 as jni$_.JMethodIDPtr,
-            _$bs.pointer)
-        .integer;
-  }
-
-  static final _id_lastIndexOf$2 = _class.instanceMethodId(
-    r'lastIndexOf',
-    r'(Lokio/ByteString;)I',
-  );
-
-  static final _lastIndexOf$2 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final int lastIndexOf(okio.ByteString byteString)`
-  int lastIndexOf$2(
-    ByteString byteString,
-  ) {
-    final _$byteString = byteString.reference;
-    return _lastIndexOf$2(reference.pointer,
-            _id_lastIndexOf$2 as jni$_.JMethodIDPtr, _$byteString.pointer)
-        .integer;
-  }
-
-  static final _id_lastIndexOf$3 = _class.instanceMethodId(
-    r'lastIndexOf',
-    r'([B)I',
-  );
-
-  static final _lastIndexOf$3 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final int lastIndexOf(byte[] bs)`
-  int lastIndexOf$3(
-    jni$_.JByteArray bs,
-  ) {
-    final _$bs = bs.reference;
-    return _lastIndexOf$3(reference.pointer,
-            _id_lastIndexOf$3 as jni$_.JMethodIDPtr, _$bs.pointer)
-        .integer;
+    return _new$(_class.reference.pointer, _id_new$.pointer, _$bs.pointer)
+        .object<ByteString>();
   }
 
   static final _id_of = _class.staticMethodId(
@@ -16407,9 +12520,8 @@
     jni$_.JByteArray bs,
   ) {
     final _$bs = bs.reference;
-    return _of(_class.reference.pointer, _id_of as jni$_.JMethodIDPtr,
-            _$bs.pointer)
-        .object<ByteString>(const $ByteString$Type());
+    return _of(_class.reference.pointer, _id_of.pointer, _$bs.pointer)
+        .object<ByteString>();
   }
 
   static final _id_of$1 = _class.staticMethodId(
@@ -16429,20 +12541,24 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
   /// from: `static public final okio.ByteString of(byte[] bs, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
   static ByteString of$1(
     jni$_.JByteArray bs,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$bs = bs.reference;
-    return _of$1(_class.reference.pointer, _id_of$1 as jni$_.JMethodIDPtr,
-            _$bs.pointer, i, i1)
-        .object<ByteString>(const $ByteString$Type());
+    return _of$1(
+            _class.reference.pointer, _id_of$1.pointer, _$bs.pointer, i, i1)
+        .object<ByteString>();
   }
 
   static final _id_of$2 = _class.staticMethodId(
@@ -16467,9 +12583,9 @@
     jni$_.JByteBuffer byteBuffer,
   ) {
     final _$byteBuffer = byteBuffer.reference;
-    return _of$2(_class.reference.pointer, _id_of$2 as jni$_.JMethodIDPtr,
-            _$byteBuffer.pointer)
-        .object<ByteString>(const $ByteString$Type());
+    return _of$2(
+            _class.reference.pointer, _id_of$2.pointer, _$byteBuffer.pointer)
+        .object<ByteString>();
   }
 
   static final _id_encodeUtf8 = _class.staticMethodId(
@@ -16494,9 +12610,9 @@
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _encodeUtf8(_class.reference.pointer,
-            _id_encodeUtf8 as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<ByteString>(const $ByteString$Type());
+    return _encodeUtf8(
+            _class.reference.pointer, _id_encodeUtf8.pointer, _$string.pointer)
+        .object<ByteString>();
   }
 
   static final _id_encodeString = _class.staticMethodId(
@@ -16529,12 +12645,9 @@
   ) {
     final _$string = string.reference;
     final _$charset = charset.reference;
-    return _encodeString(
-            _class.reference.pointer,
-            _id_encodeString as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$charset.pointer)
-        .object<ByteString>(const $ByteString$Type());
+    return _encodeString(_class.reference.pointer, _id_encodeString.pointer,
+            _$string.pointer, _$charset.pointer)
+        .object<ByteString>();
   }
 
   static final _id_decodeBase64 = _class.staticMethodId(
@@ -16559,9 +12672,9 @@
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _decodeBase64(_class.reference.pointer,
-            _id_decodeBase64 as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<ByteString?>(const $ByteString$NullableType());
+    return _decodeBase64(_class.reference.pointer, _id_decodeBase64.pointer,
+            _$string.pointer)
+        .object<ByteString?>();
   }
 
   static final _id_decodeHex = _class.staticMethodId(
@@ -16586,9 +12699,9 @@
     jni$_.JString string,
   ) {
     final _$string = string.reference;
-    return _decodeHex(_class.reference.pointer,
-            _id_decodeHex as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<ByteString>(const $ByteString$Type());
+    return _decodeHex(
+            _class.reference.pointer, _id_decodeHex.pointer, _$string.pointer)
+        .object<ByteString>();
   }
 
   static final _id_read = _class.staticMethodId(
@@ -16606,118 +12719,51 @@
           'globalEnv_CallStaticObjectMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
 
   /// from: `static public final okio.ByteString read(java.io.InputStream inputStream, int i)`
   /// The returned object must be released after use, by calling the [release] method.
   static ByteString read(
     jni$_.JObject inputStream,
-    int i,
+    core$_.int i,
   ) {
     final _$inputStream = inputStream.reference;
-    return _read(_class.reference.pointer, _id_read as jni$_.JMethodIDPtr,
+    return _read(_class.reference.pointer, _id_read.pointer,
             _$inputStream.pointer, i)
-        .object<ByteString>(const $ByteString$Type());
+        .object<ByteString>();
   }
 }
 
-final class $ByteString$NullableType extends jni$_.JObjType<ByteString?> {
-  @jni$_.internal
-  const $ByteString$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokio/ByteString;';
-
-  @jni$_.internal
-  @core$_.override
-  ByteString? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : ByteString.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ByteString?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ByteString$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ByteString$NullableType) &&
-        other is $ByteString$NullableType;
-  }
-}
-
-final class $ByteString$Type extends jni$_.JObjType<ByteString> {
-  @jni$_.internal
-  const $ByteString$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lokio/ByteString;';
-
-  @jni$_.internal
-  @core$_.override
-  ByteString fromReference(jni$_.JReference reference) =>
-      ByteString.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ByteString?> get nullableType =>
-      const $ByteString$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ByteString$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ByteString$Type) && other is $ByteString$Type;
-  }
-}
-
-/// from: `com.example.ok_http.WebSocketInterceptor$Companion`
-class WebSocketInterceptor$Companion extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<WebSocketInterceptor$Companion> $type;
-
-  @jni$_.internal
-  WebSocketInterceptor$Companion.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
-  static final _class = jni$_.JClass.forName(
-      r'com/example/ok_http/WebSocketInterceptor$Companion');
-
-  /// The type which includes information such as the signature of this class.
-  static const nullableType = $WebSocketInterceptor$Companion$NullableType();
-  static const type = $WebSocketInterceptor$Companion$Type();
-  static final _id_addWSInterceptor = _class.instanceMethodId(
-    r'addWSInterceptor',
-    r'(Lokhttp3/OkHttpClient$Builder;)Lokhttp3/OkHttpClient$Builder;',
+extension ByteString$$Methods on ByteString {
+  static final _id_utf8 = ByteString._class.instanceMethodId(
+    r'utf8',
+    r'()Ljava/lang/String;',
   );
 
-  static final _addWSInterceptor = jni$_.ProtectedJniExtensions.lookup<
+  static final _utf8 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun utf8(): kotlin.String`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString utf8() {
+    return _utf8(reference.pointer, _id_utf8.pointer).object<jni$_.JString>();
+  }
+
+  static final _id_string = ByteString._class.instanceMethodId(
+    r'string',
+    r'(Ljava/nio/charset/Charset;)Ljava/lang/String;',
+  );
+
+  static final _string = jni$_.ProtectedJniExtensions.lookup<
               jni$_.NativeFunction<
                   jni$_.JniResult Function(
                       jni$_.Pointer<jni$_.Void>,
@@ -16728,17 +12774,1064 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final okhttp3.OkHttpClient$Builder addWSInterceptor(okhttp3.OkHttpClient$Builder builder)`
+  /// from: `public fun string(charset: java.nio.charset.Charset): kotlin.String`
   /// The returned object must be released after use, by calling the [release] method.
-  OkHttpClient$Builder addWSInterceptor(
-    OkHttpClient$Builder builder,
+  jni$_.JString string(
+    jni$_.JObject charset,
   ) {
-    final _$builder = builder.reference;
-    return _addWSInterceptor(reference.pointer,
-            _id_addWSInterceptor as jni$_.JMethodIDPtr, _$builder.pointer)
-        .object<OkHttpClient$Builder>(const $OkHttpClient$Builder$Type());
+    final _$charset = charset.reference;
+    return _string(reference.pointer, _id_string.pointer, _$charset.pointer)
+        .object<jni$_.JString>();
   }
 
+  static final _id_base64 = ByteString._class.instanceMethodId(
+    r'base64',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _base64 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun base64(): kotlin.String`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString base64() {
+    return _base64(reference.pointer, _id_base64.pointer)
+        .object<jni$_.JString>();
+  }
+
+  static final _id_md5 = ByteString._class.instanceMethodId(
+    r'md5',
+    r'()Lokio/ByteString;',
+  );
+
+  static final _md5 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun md5(): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString md5() {
+    return _md5(reference.pointer, _id_md5.pointer).object<ByteString>();
+  }
+
+  static final _id_sha1 = ByteString._class.instanceMethodId(
+    r'sha1',
+    r'()Lokio/ByteString;',
+  );
+
+  static final _sha1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun sha1(): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString sha1() {
+    return _sha1(reference.pointer, _id_sha1.pointer).object<ByteString>();
+  }
+
+  static final _id_sha256 = ByteString._class.instanceMethodId(
+    r'sha256',
+    r'()Lokio/ByteString;',
+  );
+
+  static final _sha256 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun sha256(): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString sha256() {
+    return _sha256(reference.pointer, _id_sha256.pointer).object<ByteString>();
+  }
+
+  static final _id_sha512 = ByteString._class.instanceMethodId(
+    r'sha512',
+    r'()Lokio/ByteString;',
+  );
+
+  static final _sha512 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun sha512(): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString sha512() {
+    return _sha512(reference.pointer, _id_sha512.pointer).object<ByteString>();
+  }
+
+  static final _id_hmacSha1 = ByteString._class.instanceMethodId(
+    r'hmacSha1',
+    r'(Lokio/ByteString;)Lokio/ByteString;',
+  );
+
+  static final _hmacSha1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun hmacSha1(key: okio.ByteString): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString hmacSha1(
+    ByteString byteString,
+  ) {
+    final _$byteString = byteString.reference;
+    return _hmacSha1(
+            reference.pointer, _id_hmacSha1.pointer, _$byteString.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_hmacSha256 = ByteString._class.instanceMethodId(
+    r'hmacSha256',
+    r'(Lokio/ByteString;)Lokio/ByteString;',
+  );
+
+  static final _hmacSha256 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun hmacSha256(key: okio.ByteString): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString hmacSha256(
+    ByteString byteString,
+  ) {
+    final _$byteString = byteString.reference;
+    return _hmacSha256(
+            reference.pointer, _id_hmacSha256.pointer, _$byteString.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_hmacSha512 = ByteString._class.instanceMethodId(
+    r'hmacSha512',
+    r'(Lokio/ByteString;)Lokio/ByteString;',
+  );
+
+  static final _hmacSha512 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun hmacSha512(key: okio.ByteString): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString hmacSha512(
+    ByteString byteString,
+  ) {
+    final _$byteString = byteString.reference;
+    return _hmacSha512(
+            reference.pointer, _id_hmacSha512.pointer, _$byteString.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_base64Url = ByteString._class.instanceMethodId(
+    r'base64Url',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _base64Url = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun base64Url(): kotlin.String`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString base64Url() {
+    return _base64Url(reference.pointer, _id_base64Url.pointer)
+        .object<jni$_.JString>();
+  }
+
+  static final _id_hex = ByteString._class.instanceMethodId(
+    r'hex',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _hex = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun hex(): kotlin.String`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString hex() {
+    return _hex(reference.pointer, _id_hex.pointer).object<jni$_.JString>();
+  }
+
+  static final _id_toAsciiLowercase = ByteString._class.instanceMethodId(
+    r'toAsciiLowercase',
+    r'()Lokio/ByteString;',
+  );
+
+  static final _toAsciiLowercase = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun toAsciiLowercase(): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString toAsciiLowercase() {
+    return _toAsciiLowercase(reference.pointer, _id_toAsciiLowercase.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_toAsciiUppercase = ByteString._class.instanceMethodId(
+    r'toAsciiUppercase',
+    r'()Lokio/ByteString;',
+  );
+
+  static final _toAsciiUppercase = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun toAsciiUppercase(): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString toAsciiUppercase() {
+    return _toAsciiUppercase(reference.pointer, _id_toAsciiUppercase.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_substring = ByteString._class.instanceMethodId(
+    r'substring',
+    r'(II)Lokio/ByteString;',
+  );
+
+  static final _substring = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Int32, jni$_.Int32)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, core$_.int, core$_.int)>();
+
+  /// from: `public fun substring(beginIndex: kotlin.Int, endIndex: kotlin.Int): okio.ByteString`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString substring(
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    return _substring(reference.pointer, _id_substring.pointer, i, i1)
+        .object<ByteString>();
+  }
+
+  static final _id_getByte = ByteString._class.instanceMethodId(
+    r'getByte',
+    r'(I)B',
+  );
+
+  static final _getByte = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallByteMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public operator fun get(index: kotlin.Int): kotlin.Byte`
+  core$_.int getByte(
+    core$_.int i,
+  ) {
+    return _getByte(reference.pointer, _id_getByte.pointer, i).byte;
+  }
+
+  static final _id_size = ByteString._class.instanceMethodId(
+    r'size',
+    r'()I',
+  );
+
+  static final _size = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final int size()`
+  core$_.int size() {
+    return _size(reference.pointer, _id_size.pointer).integer;
+  }
+
+  static final _id_toByteArray = ByteString._class.instanceMethodId(
+    r'toByteArray',
+    r'()[B',
+  );
+
+  static final _toByteArray = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun toByteArray(): kotlin.ByteArray`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JByteArray toByteArray() {
+    return _toByteArray(reference.pointer, _id_toByteArray.pointer)
+        .object<jni$_.JByteArray>();
+  }
+
+  static final _id_asByteBuffer = ByteString._class.instanceMethodId(
+    r'asByteBuffer',
+    r'()Ljava/nio/ByteBuffer;',
+  );
+
+  static final _asByteBuffer = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun asByteBuffer(): java.nio.ByteBuffer`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JByteBuffer asByteBuffer() {
+    return _asByteBuffer(reference.pointer, _id_asByteBuffer.pointer)
+        .object<jni$_.JByteBuffer>();
+  }
+
+  static final _id_write = ByteString._class.instanceMethodId(
+    r'write',
+    r'(Ljava/io/OutputStream;)V',
+  );
+
+  static final _write = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun write(out: java.io.OutputStream): kotlin.Unit`
+  void write(
+    jni$_.JObject outputStream,
+  ) {
+    final _$outputStream = outputStream.reference;
+    _write(reference.pointer, _id_write.pointer, _$outputStream.pointer)
+        .check();
+  }
+
+  static final _id_rangeEquals = ByteString._class.instanceMethodId(
+    r'rangeEquals',
+    r'(ILokio/ByteString;II)Z',
+  );
+
+  static final _rangeEquals = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `public fun rangeEquals(offset: kotlin.Int, other: okio.ByteString, otherOffset: kotlin.Int, byteCount: kotlin.Int): kotlin.Boolean`
+  core$_.bool rangeEquals(
+    core$_.int i,
+    ByteString byteString,
+    core$_.int i1,
+    core$_.int i2,
+  ) {
+    final _$byteString = byteString.reference;
+    return _rangeEquals(reference.pointer, _id_rangeEquals.pointer, i,
+            _$byteString.pointer, i1, i2)
+        .boolean;
+  }
+
+  static final _id_rangeEquals$1 = ByteString._class.instanceMethodId(
+    r'rangeEquals',
+    r'(I[BII)Z',
+  );
+
+  static final _rangeEquals$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `public fun rangeEquals(offset: kotlin.Int, other: kotlin.ByteArray, otherOffset: kotlin.Int, byteCount: kotlin.Int): kotlin.Boolean`
+  core$_.bool rangeEquals$1(
+    core$_.int i,
+    jni$_.JByteArray bs,
+    core$_.int i1,
+    core$_.int i2,
+  ) {
+    final _$bs = bs.reference;
+    return _rangeEquals$1(reference.pointer, _id_rangeEquals$1.pointer, i,
+            _$bs.pointer, i1, i2)
+        .boolean;
+  }
+
+  static final _id_copyInto = ByteString._class.instanceMethodId(
+    r'copyInto',
+    r'(I[BII)V',
+  );
+
+  static final _copyInto = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `public fun copyInto(offset: kotlin.Int, target: kotlin.ByteArray, targetOffset: kotlin.Int, byteCount: kotlin.Int): kotlin.Unit`
+  void copyInto(
+    core$_.int i,
+    jni$_.JByteArray bs,
+    core$_.int i1,
+    core$_.int i2,
+  ) {
+    final _$bs = bs.reference;
+    _copyInto(reference.pointer, _id_copyInto.pointer, i, _$bs.pointer, i1, i2)
+        .check();
+  }
+
+  static final _id_startsWith = ByteString._class.instanceMethodId(
+    r'startsWith',
+    r'(Lokio/ByteString;)Z',
+  );
+
+  static final _startsWith = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun startsWith(prefix: okio.ByteString): kotlin.Boolean`
+  core$_.bool startsWith(
+    ByteString byteString,
+  ) {
+    final _$byteString = byteString.reference;
+    return _startsWith(
+            reference.pointer, _id_startsWith.pointer, _$byteString.pointer)
+        .boolean;
+  }
+
+  static final _id_startsWith$1 = ByteString._class.instanceMethodId(
+    r'startsWith',
+    r'([B)Z',
+  );
+
+  static final _startsWith$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun startsWith(prefix: kotlin.ByteArray): kotlin.Boolean`
+  core$_.bool startsWith$1(
+    jni$_.JByteArray bs,
+  ) {
+    final _$bs = bs.reference;
+    return _startsWith$1(
+            reference.pointer, _id_startsWith$1.pointer, _$bs.pointer)
+        .boolean;
+  }
+
+  static final _id_endsWith = ByteString._class.instanceMethodId(
+    r'endsWith',
+    r'(Lokio/ByteString;)Z',
+  );
+
+  static final _endsWith = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun endsWith(suffix: okio.ByteString): kotlin.Boolean`
+  core$_.bool endsWith(
+    ByteString byteString,
+  ) {
+    final _$byteString = byteString.reference;
+    return _endsWith(
+            reference.pointer, _id_endsWith.pointer, _$byteString.pointer)
+        .boolean;
+  }
+
+  static final _id_endsWith$1 = ByteString._class.instanceMethodId(
+    r'endsWith',
+    r'([B)Z',
+  );
+
+  static final _endsWith$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun endsWith(suffix: kotlin.ByteArray): kotlin.Boolean`
+  core$_.bool endsWith$1(
+    jni$_.JByteArray bs,
+  ) {
+    final _$bs = bs.reference;
+    return _endsWith$1(reference.pointer, _id_endsWith$1.pointer, _$bs.pointer)
+        .boolean;
+  }
+
+  static final _id_indexOf = ByteString._class.instanceMethodId(
+    r'indexOf',
+    r'(Lokio/ByteString;I)I',
+  );
+
+  static final _indexOf = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `public fun indexOf(other: okio.ByteString, fromIndex: kotlin.Int): kotlin.Int`
+  core$_.int indexOf(
+    ByteString byteString,
+    core$_.int i,
+  ) {
+    final _$byteString = byteString.reference;
+    return _indexOf(
+            reference.pointer, _id_indexOf.pointer, _$byteString.pointer, i)
+        .integer;
+  }
+
+  static final _id_indexOf$1 = ByteString._class.instanceMethodId(
+    r'indexOf',
+    r'([BI)I',
+  );
+
+  static final _indexOf$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `public fun indexOf(other: kotlin.ByteArray, fromIndex: kotlin.Int): kotlin.Int`
+  core$_.int indexOf$1(
+    jni$_.JByteArray bs,
+    core$_.int i,
+  ) {
+    final _$bs = bs.reference;
+    return _indexOf$1(reference.pointer, _id_indexOf$1.pointer, _$bs.pointer, i)
+        .integer;
+  }
+
+  static final _id_lastIndexOf = ByteString._class.instanceMethodId(
+    r'lastIndexOf',
+    r'(Lokio/ByteString;I)I',
+  );
+
+  static final _lastIndexOf = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `public fun lastIndexOf(other: okio.ByteString, fromIndex: kotlin.Int): kotlin.Int`
+  core$_.int lastIndexOf(
+    ByteString byteString,
+    core$_.int i,
+  ) {
+    final _$byteString = byteString.reference;
+    return _lastIndexOf(
+            reference.pointer, _id_lastIndexOf.pointer, _$byteString.pointer, i)
+        .integer;
+  }
+
+  static final _id_lastIndexOf$1 = ByteString._class.instanceMethodId(
+    r'lastIndexOf',
+    r'([BI)I',
+  );
+
+  static final _lastIndexOf$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `public fun lastIndexOf(other: kotlin.ByteArray, fromIndex: kotlin.Int): kotlin.Int`
+  core$_.int lastIndexOf$1(
+    jni$_.JByteArray bs,
+    core$_.int i,
+  ) {
+    final _$bs = bs.reference;
+    return _lastIndexOf$1(
+            reference.pointer, _id_lastIndexOf$1.pointer, _$bs.pointer, i)
+        .integer;
+  }
+
+  static final _id_equals = ByteString._class.instanceMethodId(
+    r'equals',
+    r'(Ljava/lang/Object;)Z',
+  );
+
+  static final _equals = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public operator fun equals(other: kotlin.Any?): kotlin.Boolean`
+  core$_.bool equals(
+    jni$_.JObject? object,
+  ) {
+    final _$object = object?.reference ?? jni$_.jNullReference;
+    return _equals(reference.pointer, _id_equals.pointer, _$object.pointer)
+        .boolean;
+  }
+
+  static final _id_hashCode$1 = ByteString._class.instanceMethodId(
+    r'hashCode',
+    r'()I',
+  );
+
+  static final _hashCode$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun hashCode(): kotlin.Int`
+  core$_.int hashCode$1() {
+    return _hashCode$1(reference.pointer, _id_hashCode$1.pointer).integer;
+  }
+
+  static final _id_compareTo = ByteString._class.instanceMethodId(
+    r'compareTo',
+    r'(Lokio/ByteString;)I',
+  );
+
+  static final _compareTo = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public operator fun compareTo(other: okio.ByteString): kotlin.Int`
+  core$_.int compareTo(
+    ByteString byteString,
+  ) {
+    final _$byteString = byteString.reference;
+    return _compareTo(
+            reference.pointer, _id_compareTo.pointer, _$byteString.pointer)
+        .integer;
+  }
+
+  static final _id_toString$1 = ByteString._class.instanceMethodId(
+    r'toString',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _toString$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public fun toString(): kotlin.String`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString toString$1() {
+    return _toString$1(reference.pointer, _id_toString$1.pointer)
+        .object<jni$_.JString>();
+  }
+
+  static final _id_substring$1 = ByteString._class.instanceMethodId(
+    r'substring',
+    r'(I)Lokio/ByteString;',
+  );
+
+  static final _substring$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public final okio.ByteString substring(int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString substring$1(
+    core$_.int i,
+  ) {
+    return _substring$1(reference.pointer, _id_substring$1.pointer, i)
+        .object<ByteString>();
+  }
+
+  static final _id_substring$2 = ByteString._class.instanceMethodId(
+    r'substring',
+    r'()Lokio/ByteString;',
+  );
+
+  static final _substring$2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final okio.ByteString substring()`
+  /// The returned object must be released after use, by calling the [release] method.
+  ByteString substring$2() {
+    return _substring$2(reference.pointer, _id_substring$2.pointer)
+        .object<ByteString>();
+  }
+
+  static final _id_indexOf$2 = ByteString._class.instanceMethodId(
+    r'indexOf',
+    r'(Lokio/ByteString;)I',
+  );
+
+  static final _indexOf$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final int indexOf(okio.ByteString byteString)`
+  core$_.int indexOf$2(
+    ByteString byteString,
+  ) {
+    final _$byteString = byteString.reference;
+    return _indexOf$2(
+            reference.pointer, _id_indexOf$2.pointer, _$byteString.pointer)
+        .integer;
+  }
+
+  static final _id_indexOf$3 = ByteString._class.instanceMethodId(
+    r'indexOf',
+    r'([B)I',
+  );
+
+  static final _indexOf$3 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final int indexOf(byte[] bs)`
+  core$_.int indexOf$3(
+    jni$_.JByteArray bs,
+  ) {
+    final _$bs = bs.reference;
+    return _indexOf$3(reference.pointer, _id_indexOf$3.pointer, _$bs.pointer)
+        .integer;
+  }
+
+  static final _id_lastIndexOf$2 = ByteString._class.instanceMethodId(
+    r'lastIndexOf',
+    r'(Lokio/ByteString;)I',
+  );
+
+  static final _lastIndexOf$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final int lastIndexOf(okio.ByteString byteString)`
+  core$_.int lastIndexOf$2(
+    ByteString byteString,
+  ) {
+    final _$byteString = byteString.reference;
+    return _lastIndexOf$2(
+            reference.pointer, _id_lastIndexOf$2.pointer, _$byteString.pointer)
+        .integer;
+  }
+
+  static final _id_lastIndexOf$3 = ByteString._class.instanceMethodId(
+    r'lastIndexOf',
+    r'([B)I',
+  );
+
+  static final _lastIndexOf$3 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final int lastIndexOf(byte[] bs)`
+  core$_.int lastIndexOf$3(
+    jni$_.JByteArray bs,
+  ) {
+    final _$bs = bs.reference;
+    return _lastIndexOf$3(
+            reference.pointer, _id_lastIndexOf$3.pointer, _$bs.pointer)
+        .integer;
+  }
+
+  core$_.bool operator <(ByteString byteString) {
+    return compareTo(byteString) < 0;
+  }
+
+  core$_.bool operator <=(ByteString byteString) {
+    return compareTo(byteString) <= 0;
+  }
+
+  core$_.bool operator >(ByteString byteString) {
+    return compareTo(byteString) > 0;
+  }
+
+  core$_.bool operator >=(ByteString byteString) {
+    return compareTo(byteString) >= 0;
+  }
+}
+
+final class $ByteString$Type$ extends jni$_.JType<ByteString> {
+  @jni$_.internal
+  const $ByteString$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Lokio/ByteString;';
+}
+
+/// from: `com.example.ok_http.WebSocketInterceptor$Companion`
+extension type WebSocketInterceptor$Companion._(jni$_.JObject _$this)
+    implements jni$_.JObject {
+  static final _class = jni$_.JClass.forName(
+      r'com/example/ok_http/WebSocketInterceptor$Companion');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<WebSocketInterceptor$Companion> type =
+      $WebSocketInterceptor$Companion$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Lkotlin/jvm/internal/DefaultConstructorMarker;)V',
   );
@@ -16761,112 +13854,63 @@
   ) {
     final _$defaultConstructorMarker =
         defaultConstructorMarker?.reference ?? jni$_.jNullReference;
-    return WebSocketInterceptor$Companion.fromReference(_new$(
-            _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
+    return _new$(_class.reference.pointer, _id_new$.pointer,
             _$defaultConstructorMarker.pointer)
-        .reference);
+        .object<WebSocketInterceptor$Companion>();
   }
 }
 
-final class $WebSocketInterceptor$Companion$NullableType
-    extends jni$_.JObjType<WebSocketInterceptor$Companion?> {
+extension WebSocketInterceptor$Companion$$Methods
+    on WebSocketInterceptor$Companion {
+  static final _id_addWSInterceptor =
+      WebSocketInterceptor$Companion._class.instanceMethodId(
+    r'addWSInterceptor',
+    r'(Lokhttp3/OkHttpClient$Builder;)Lokhttp3/OkHttpClient$Builder;',
+  );
+
+  static final _addWSInterceptor = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public fun addWSInterceptor(clientBuilder: okhttp3.OkHttpClient.Builder): okhttp3.OkHttpClient.Builder`
+  /// The returned object must be released after use, by calling the [release] method.
+  OkHttpClient$Builder addWSInterceptor(
+    OkHttpClient$Builder builder,
+  ) {
+    final _$builder = builder.reference;
+    return _addWSInterceptor(
+            reference.pointer, _id_addWSInterceptor.pointer, _$builder.pointer)
+        .object<OkHttpClient$Builder>();
+  }
+}
+
+final class $WebSocketInterceptor$Companion$Type$
+    extends jni$_.JType<WebSocketInterceptor$Companion> {
   @jni$_.internal
-  const $WebSocketInterceptor$Companion$NullableType();
+  const $WebSocketInterceptor$Companion$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature =>
       r'Lcom/example/ok_http/WebSocketInterceptor$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  WebSocketInterceptor$Companion? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : WebSocketInterceptor$Companion.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocketInterceptor$Companion?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($WebSocketInterceptor$Companion$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType ==
-            ($WebSocketInterceptor$Companion$NullableType) &&
-        other is $WebSocketInterceptor$Companion$NullableType;
-  }
-}
-
-final class $WebSocketInterceptor$Companion$Type
-    extends jni$_.JObjType<WebSocketInterceptor$Companion> {
-  @jni$_.internal
-  const $WebSocketInterceptor$Companion$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature =>
-      r'Lcom/example/ok_http/WebSocketInterceptor$Companion;';
-
-  @jni$_.internal
-  @core$_.override
-  WebSocketInterceptor$Companion fromReference(jni$_.JReference reference) =>
-      WebSocketInterceptor$Companion.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocketInterceptor$Companion?> get nullableType =>
-      const $WebSocketInterceptor$Companion$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($WebSocketInterceptor$Companion$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($WebSocketInterceptor$Companion$Type) &&
-        other is $WebSocketInterceptor$Companion$Type;
-  }
 }
 
 /// from: `com.example.ok_http.WebSocketInterceptor`
-class WebSocketInterceptor extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<WebSocketInterceptor> $type;
-
-  @jni$_.internal
-  WebSocketInterceptor.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type WebSocketInterceptor._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'com/example/ok_http/WebSocketInterceptor');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $WebSocketInterceptor$NullableType();
-  static const type = $WebSocketInterceptor$Type();
+  static const jni$_.JType<WebSocketInterceptor> type =
+      $WebSocketInterceptor$Type$();
   static final _id_Companion = _class.staticFieldId(
     r'Companion',
     r'Lcom/example/ok_http/WebSocketInterceptor$Companion;',
@@ -16875,7 +13919,8 @@
   /// from: `static public final com.example.ok_http.WebSocketInterceptor$Companion Companion`
   /// The returned object must be released after use, by calling the [release] method.
   static WebSocketInterceptor$Companion get Companion =>
-      _id_Companion.get(_class, const $WebSocketInterceptor$Companion$Type());
+      _id_Companion.get(_class, WebSocketInterceptor$Companion.type)
+          as WebSocketInterceptor$Companion;
 
   static final _id_new$ = _class.constructorId(
     r'()V',
@@ -16896,115 +13941,44 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory WebSocketInterceptor() {
-    return WebSocketInterceptor.fromReference(
-        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
-            .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer)
+        .object<WebSocketInterceptor>();
   }
 }
 
-final class $WebSocketInterceptor$NullableType
-    extends jni$_.JObjType<WebSocketInterceptor?> {
+final class $WebSocketInterceptor$Type$
+    extends jni$_.JType<WebSocketInterceptor> {
   @jni$_.internal
-  const $WebSocketInterceptor$NullableType();
+  const $WebSocketInterceptor$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Lcom/example/ok_http/WebSocketInterceptor;';
-
-  @jni$_.internal
-  @core$_.override
-  WebSocketInterceptor? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : WebSocketInterceptor.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocketInterceptor?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($WebSocketInterceptor$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($WebSocketInterceptor$NullableType) &&
-        other is $WebSocketInterceptor$NullableType;
-  }
-}
-
-final class $WebSocketInterceptor$Type
-    extends jni$_.JObjType<WebSocketInterceptor> {
-  @jni$_.internal
-  const $WebSocketInterceptor$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Lcom/example/ok_http/WebSocketInterceptor;';
-
-  @jni$_.internal
-  @core$_.override
-  WebSocketInterceptor fromReference(jni$_.JReference reference) =>
-      WebSocketInterceptor.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<WebSocketInterceptor?> get nullableType =>
-      const $WebSocketInterceptor$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($WebSocketInterceptor$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($WebSocketInterceptor$Type) &&
-        other is $WebSocketInterceptor$Type;
-  }
 }
 
 /// from: `java.util.concurrent.TimeUnit`
-class TimeUnit extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<TimeUnit> $type;
-
-  @jni$_.internal
-  TimeUnit.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type TimeUnit._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'java/util/concurrent/TimeUnit');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $TimeUnit$NullableType();
-  static const type = $TimeUnit$Type();
-  static final _id_NANOSECONDS = _class.staticFieldId(
-    r'NANOSECONDS',
+  static const jni$_.JType<TimeUnit> type = $TimeUnit$Type$();
+  static final _id_DAYS = _class.staticFieldId(
+    r'DAYS',
     r'Ljava/util/concurrent/TimeUnit;',
   );
 
-  /// from: `static public final java.util.concurrent.TimeUnit NANOSECONDS`
+  /// from: `static public final java.util.concurrent.TimeUnit DAYS`
   /// The returned object must be released after use, by calling the [release] method.
-  static TimeUnit get NANOSECONDS =>
-      _id_NANOSECONDS.get(_class, const $TimeUnit$Type());
+  static TimeUnit get DAYS => _id_DAYS.get(_class, TimeUnit.type) as TimeUnit;
+
+  static final _id_HOURS = _class.staticFieldId(
+    r'HOURS',
+    r'Ljava/util/concurrent/TimeUnit;',
+  );
+
+  /// from: `static public final java.util.concurrent.TimeUnit HOURS`
+  /// The returned object must be released after use, by calling the [release] method.
+  static TimeUnit get HOURS => _id_HOURS.get(_class, TimeUnit.type) as TimeUnit;
 
   static final _id_MICROSECONDS = _class.staticFieldId(
     r'MICROSECONDS',
@@ -17014,7 +13988,7 @@
   /// from: `static public final java.util.concurrent.TimeUnit MICROSECONDS`
   /// The returned object must be released after use, by calling the [release] method.
   static TimeUnit get MICROSECONDS =>
-      _id_MICROSECONDS.get(_class, const $TimeUnit$Type());
+      _id_MICROSECONDS.get(_class, TimeUnit.type) as TimeUnit;
 
   static final _id_MILLISECONDS = _class.staticFieldId(
     r'MILLISECONDS',
@@ -17024,17 +13998,7 @@
   /// from: `static public final java.util.concurrent.TimeUnit MILLISECONDS`
   /// The returned object must be released after use, by calling the [release] method.
   static TimeUnit get MILLISECONDS =>
-      _id_MILLISECONDS.get(_class, const $TimeUnit$Type());
-
-  static final _id_SECONDS = _class.staticFieldId(
-    r'SECONDS',
-    r'Ljava/util/concurrent/TimeUnit;',
-  );
-
-  /// from: `static public final java.util.concurrent.TimeUnit SECONDS`
-  /// The returned object must be released after use, by calling the [release] method.
-  static TimeUnit get SECONDS =>
-      _id_SECONDS.get(_class, const $TimeUnit$Type());
+      _id_MILLISECONDS.get(_class, TimeUnit.type) as TimeUnit;
 
   static final _id_MINUTES = _class.staticFieldId(
     r'MINUTES',
@@ -17044,25 +14008,27 @@
   /// from: `static public final java.util.concurrent.TimeUnit MINUTES`
   /// The returned object must be released after use, by calling the [release] method.
   static TimeUnit get MINUTES =>
-      _id_MINUTES.get(_class, const $TimeUnit$Type());
+      _id_MINUTES.get(_class, TimeUnit.type) as TimeUnit;
 
-  static final _id_HOURS = _class.staticFieldId(
-    r'HOURS',
+  static final _id_NANOSECONDS = _class.staticFieldId(
+    r'NANOSECONDS',
     r'Ljava/util/concurrent/TimeUnit;',
   );
 
-  /// from: `static public final java.util.concurrent.TimeUnit HOURS`
+  /// from: `static public final java.util.concurrent.TimeUnit NANOSECONDS`
   /// The returned object must be released after use, by calling the [release] method.
-  static TimeUnit get HOURS => _id_HOURS.get(_class, const $TimeUnit$Type());
+  static TimeUnit get NANOSECONDS =>
+      _id_NANOSECONDS.get(_class, TimeUnit.type) as TimeUnit;
 
-  static final _id_DAYS = _class.staticFieldId(
-    r'DAYS',
+  static final _id_SECONDS = _class.staticFieldId(
+    r'SECONDS',
     r'Ljava/util/concurrent/TimeUnit;',
   );
 
-  /// from: `static public final java.util.concurrent.TimeUnit DAYS`
+  /// from: `static public final java.util.concurrent.TimeUnit SECONDS`
   /// The returned object must be released after use, by calling the [release] method.
-  static TimeUnit get DAYS => _id_DAYS.get(_class, const $TimeUnit$Type());
+  static TimeUnit get SECONDS =>
+      _id_SECONDS.get(_class, TimeUnit.type) as TimeUnit;
 
   static final _id_values = _class.staticMethodId(
     r'values',
@@ -17084,10 +14050,8 @@
   /// from: `static public java.util.concurrent.TimeUnit[] values()`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JArray<TimeUnit?>? values() {
-    return _values(_class.reference.pointer, _id_values as jni$_.JMethodIDPtr)
-        .object<jni$_.JArray<TimeUnit?>?>(
-            const jni$_.JArrayNullableType<TimeUnit?>(
-                $TimeUnit$NullableType()));
+    return _values(_class.reference.pointer, _id_values.pointer)
+        .object<jni$_.JArray<TimeUnit?>?>();
   }
 
   static final _id_valueOf = _class.staticMethodId(
@@ -17112,326 +14076,9 @@
     jni$_.JString? synthetic,
   ) {
     final _$synthetic = synthetic?.reference ?? jni$_.jNullReference;
-    return _valueOf(_class.reference.pointer, _id_valueOf as jni$_.JMethodIDPtr,
-            _$synthetic.pointer)
-        .object<TimeUnit?>(const $TimeUnit$NullableType());
-  }
-
-  static final _id_convert = _class.instanceMethodId(
-    r'convert',
-    r'(JLjava/util/concurrent/TimeUnit;)J',
-  );
-
-  static final _convert = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Int64, jni$_.Pointer<jni$_.Void>)>)>>(
-          'globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public long convert(long j, java.util.concurrent.TimeUnit timeUnit)`
-  int convert(
-    int j,
-    TimeUnit? timeUnit,
-  ) {
-    final _$timeUnit = timeUnit?.reference ?? jni$_.jNullReference;
-    return _convert(reference.pointer, _id_convert as jni$_.JMethodIDPtr, j,
-            _$timeUnit.pointer)
-        .long;
-  }
-
-  static final _id_convert$1 = _class.instanceMethodId(
-    r'convert',
-    r'(Ljava/time/Duration;)J',
-  );
-
-  static final _convert$1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public long convert(java.time.Duration duration)`
-  int convert$1(
-    jni$_.JObject? duration,
-  ) {
-    final _$duration = duration?.reference ?? jni$_.jNullReference;
-    return _convert$1(reference.pointer, _id_convert$1 as jni$_.JMethodIDPtr,
-            _$duration.pointer)
-        .long;
-  }
-
-  static final _id_toNanos = _class.instanceMethodId(
-    r'toNanos',
-    r'(J)J',
-  );
-
-  static final _toNanos = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public long toNanos(long j)`
-  int toNanos(
-    int j,
-  ) {
-    return _toNanos(reference.pointer, _id_toNanos as jni$_.JMethodIDPtr, j)
-        .long;
-  }
-
-  static final _id_toMicros = _class.instanceMethodId(
-    r'toMicros',
-    r'(J)J',
-  );
-
-  static final _toMicros = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public long toMicros(long j)`
-  int toMicros(
-    int j,
-  ) {
-    return _toMicros(reference.pointer, _id_toMicros as jni$_.JMethodIDPtr, j)
-        .long;
-  }
-
-  static final _id_toMillis = _class.instanceMethodId(
-    r'toMillis',
-    r'(J)J',
-  );
-
-  static final _toMillis = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public long toMillis(long j)`
-  int toMillis(
-    int j,
-  ) {
-    return _toMillis(reference.pointer, _id_toMillis as jni$_.JMethodIDPtr, j)
-        .long;
-  }
-
-  static final _id_toSeconds = _class.instanceMethodId(
-    r'toSeconds',
-    r'(J)J',
-  );
-
-  static final _toSeconds = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public long toSeconds(long j)`
-  int toSeconds(
-    int j,
-  ) {
-    return _toSeconds(reference.pointer, _id_toSeconds as jni$_.JMethodIDPtr, j)
-        .long;
-  }
-
-  static final _id_toMinutes = _class.instanceMethodId(
-    r'toMinutes',
-    r'(J)J',
-  );
-
-  static final _toMinutes = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public long toMinutes(long j)`
-  int toMinutes(
-    int j,
-  ) {
-    return _toMinutes(reference.pointer, _id_toMinutes as jni$_.JMethodIDPtr, j)
-        .long;
-  }
-
-  static final _id_toHours = _class.instanceMethodId(
-    r'toHours',
-    r'(J)J',
-  );
-
-  static final _toHours = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public long toHours(long j)`
-  int toHours(
-    int j,
-  ) {
-    return _toHours(reference.pointer, _id_toHours as jni$_.JMethodIDPtr, j)
-        .long;
-  }
-
-  static final _id_toDays = _class.instanceMethodId(
-    r'toDays',
-    r'(J)J',
-  );
-
-  static final _toDays = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public long toDays(long j)`
-  int toDays(
-    int j,
-  ) {
-    return _toDays(reference.pointer, _id_toDays as jni$_.JMethodIDPtr, j).long;
-  }
-
-  static final _id_timedWait = _class.instanceMethodId(
-    r'timedWait',
-    r'(Ljava/lang/Object;J)V',
-  );
-
-  static final _timedWait = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int64)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `public void timedWait(java.lang.Object object, long j)`
-  void timedWait(
-    jni$_.JObject? object,
-    int j,
-  ) {
-    final _$object = object?.reference ?? jni$_.jNullReference;
-    _timedWait(reference.pointer, _id_timedWait as jni$_.JMethodIDPtr,
-            _$object.pointer, j)
-        .check();
-  }
-
-  static final _id_timedJoin = _class.instanceMethodId(
-    r'timedJoin',
-    r'(Ljava/lang/Thread;J)V',
-  );
-
-  static final _timedJoin = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int64)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `public void timedJoin(java.lang.Thread thread, long j)`
-  void timedJoin(
-    jni$_.JObject? thread,
-    int j,
-  ) {
-    final _$thread = thread?.reference ?? jni$_.jNullReference;
-    _timedJoin(reference.pointer, _id_timedJoin as jni$_.JMethodIDPtr,
-            _$thread.pointer, j)
-        .check();
-  }
-
-  static final _id_sleep = _class.instanceMethodId(
-    r'sleep',
-    r'(J)V',
-  );
-
-  static final _sleep = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public void sleep(long j)`
-  void sleep(
-    int j,
-  ) {
-    _sleep(reference.pointer, _id_sleep as jni$_.JMethodIDPtr, j).check();
-  }
-
-  static final _id_toChronoUnit = _class.instanceMethodId(
-    r'toChronoUnit',
-    r'()Ljava/time/temporal/ChronoUnit;',
-  );
-
-  static final _toChronoUnit = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.time.temporal.ChronoUnit toChronoUnit()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? toChronoUnit() {
-    return _toChronoUnit(
-            reference.pointer, _id_toChronoUnit as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _valueOf(
+            _class.reference.pointer, _id_valueOf.pointer, _$synthetic.pointer)
+        .object<TimeUnit?>();
   }
 
   static final _id_of = _class.staticMethodId(
@@ -17456,182 +14103,147 @@
     jni$_.JObject? chronoUnit,
   ) {
     final _$chronoUnit = chronoUnit?.reference ?? jni$_.jNullReference;
-    return _of(_class.reference.pointer, _id_of as jni$_.JMethodIDPtr,
-            _$chronoUnit.pointer)
-        .object<TimeUnit?>(const $TimeUnit$NullableType());
+    return _of(_class.reference.pointer, _id_of.pointer, _$chronoUnit.pointer)
+        .object<TimeUnit?>();
   }
 }
 
-final class $TimeUnit$NullableType extends jni$_.JObjType<TimeUnit?> {
-  @jni$_.internal
-  const $TimeUnit$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/util/concurrent/TimeUnit;';
-
-  @jni$_.internal
-  @core$_.override
-  TimeUnit? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : TimeUnit.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<TimeUnit?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($TimeUnit$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($TimeUnit$NullableType) &&
-        other is $TimeUnit$NullableType;
-  }
-}
-
-final class $TimeUnit$Type extends jni$_.JObjType<TimeUnit> {
-  @jni$_.internal
-  const $TimeUnit$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/util/concurrent/TimeUnit;';
-
-  @jni$_.internal
-  @core$_.override
-  TimeUnit fromReference(jni$_.JReference reference) => TimeUnit.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<TimeUnit?> get nullableType => const $TimeUnit$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($TimeUnit$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($TimeUnit$Type) && other is $TimeUnit$Type;
-  }
-}
-
-/// from: `javax.net.ssl.X509TrustManager`
-class X509TrustManager extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<X509TrustManager> $type;
-
-  @jni$_.internal
-  X509TrustManager.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
-  static final _class = jni$_.JClass.forName(r'javax/net/ssl/X509TrustManager');
-
-  /// The type which includes information such as the signature of this class.
-  static const nullableType = $X509TrustManager$NullableType();
-  static const type = $X509TrustManager$Type();
-  static final _id_checkClientTrusted = _class.instanceMethodId(
-    r'checkClientTrusted',
-    r'([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V',
+extension TimeUnit$$Methods on TimeUnit {
+  static final _id_convert = TimeUnit._class.instanceMethodId(
+    r'convert',
+    r'(Ljava/time/Duration;)J',
   );
 
-  static final _checkClientTrusted = jni$_.ProtectedJniExtensions.lookup<
+  static final _convert = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public long convert(java.time.Duration duration)`
+  core$_.int convert(
+    jni$_.JObject? duration,
+  ) {
+    final _$duration = duration?.reference ?? jni$_.jNullReference;
+    return _convert(reference.pointer, _id_convert.pointer, _$duration.pointer)
+        .long;
+  }
+
+  static final _id_convert$1 = TimeUnit._class.instanceMethodId(
+    r'convert',
+    r'(JLjava/util/concurrent/TimeUnit;)J',
+  );
+
+  static final _convert$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Int64, jni$_.Pointer<jni$_.Void>)>)>>(
+          'globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, core$_.int, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public long convert(long j, java.util.concurrent.TimeUnit timeUnit)`
+  core$_.int convert$1(
+    core$_.int j,
+    TimeUnit? timeUnit,
+  ) {
+    final _$timeUnit = timeUnit?.reference ?? jni$_.jNullReference;
+    return _convert$1(
+            reference.pointer, _id_convert$1.pointer, j, _$timeUnit.pointer)
+        .long;
+  }
+
+  static final _id_sleep = TimeUnit._class.instanceMethodId(
+    r'sleep',
+    r'(J)V',
+  );
+
+  static final _sleep = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JThrowablePtr Function(
                   jni$_.Pointer<jni$_.Void>,
                   jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
+                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallVoidMethod')
       .asFunction<
           jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
 
-  /// from: `public abstract void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, java.lang.String string)`
-  void checkClientTrusted(
-    jni$_.JArray<X509Certificate?>? x509Certificates,
-    jni$_.JString? string,
+  /// from: `public void sleep(long j)`
+  void sleep(
+    core$_.int j,
   ) {
-    final _$x509Certificates =
-        x509Certificates?.reference ?? jni$_.jNullReference;
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    _checkClientTrusted(
-            reference.pointer,
-            _id_checkClientTrusted as jni$_.JMethodIDPtr,
-            _$x509Certificates.pointer,
-            _$string.pointer)
+    _sleep(reference.pointer, _id_sleep.pointer, j).check();
+  }
+
+  static final _id_timedJoin = TimeUnit._class.instanceMethodId(
+    r'timedJoin',
+    r'(Ljava/lang/Thread;J)V',
+  );
+
+  static final _timedJoin = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int64)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `public void timedJoin(java.lang.Thread thread, long j)`
+  void timedJoin(
+    jni$_.JObject? thread,
+    core$_.int j,
+  ) {
+    final _$thread = thread?.reference ?? jni$_.jNullReference;
+    _timedJoin(reference.pointer, _id_timedJoin.pointer, _$thread.pointer, j)
         .check();
   }
 
-  static final _id_checkServerTrusted = _class.instanceMethodId(
-    r'checkServerTrusted',
-    r'([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V',
+  static final _id_timedWait = TimeUnit._class.instanceMethodId(
+    r'timedWait',
+    r'(Ljava/lang/Object;J)V',
   );
 
-  static final _checkServerTrusted = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
+  static final _timedWait = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int64)>)>>(
+          'globalEnv_CallVoidMethod')
       .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
 
-  /// from: `public abstract void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, java.lang.String string)`
-  void checkServerTrusted(
-    jni$_.JArray<X509Certificate?>? x509Certificates,
-    jni$_.JString? string,
+  /// from: `public void timedWait(java.lang.Object object, long j)`
+  void timedWait(
+    jni$_.JObject? object,
+    core$_.int j,
   ) {
-    final _$x509Certificates =
-        x509Certificates?.reference ?? jni$_.jNullReference;
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    _checkServerTrusted(
-            reference.pointer,
-            _id_checkServerTrusted as jni$_.JMethodIDPtr,
-            _$x509Certificates.pointer,
-            _$string.pointer)
+    final _$object = object?.reference ?? jni$_.jNullReference;
+    _timedWait(reference.pointer, _id_timedWait.pointer, _$object.pointer, j)
         .check();
   }
 
-  static final _id_getAcceptedIssuers = _class.instanceMethodId(
-    r'getAcceptedIssuers',
-    r'()[Ljava/security/cert/X509Certificate;',
+  static final _id_toChronoUnit = TimeUnit._class.instanceMethodId(
+    r'toChronoUnit',
+    r'()Ljava/time/temporal/ChronoUnit;',
   );
 
-  static final _getAcceptedIssuers = jni$_.ProtectedJniExtensions.lookup<
+  static final _toChronoUnit = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -17643,20 +14255,189 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public abstract java.security.cert.X509Certificate[] getAcceptedIssuers()`
+  /// from: `public java.time.temporal.ChronoUnit toChronoUnit()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JArray<X509Certificate?>? getAcceptedIssuers() {
-    return _getAcceptedIssuers(
-            reference.pointer, _id_getAcceptedIssuers as jni$_.JMethodIDPtr)
-        .object<jni$_.JArray<X509Certificate?>?>(
-            const jni$_.JArrayNullableType<X509Certificate?>(
-                $X509Certificate$NullableType()));
+  jni$_.JObject? toChronoUnit() {
+    return _toChronoUnit(reference.pointer, _id_toChronoUnit.pointer)
+        .object<jni$_.JObject?>();
   }
 
+  static final _id_toDays = TimeUnit._class.instanceMethodId(
+    r'toDays',
+    r'(J)J',
+  );
+
+  static final _toDays = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public long toDays(long j)`
+  core$_.int toDays(
+    core$_.int j,
+  ) {
+    return _toDays(reference.pointer, _id_toDays.pointer, j).long;
+  }
+
+  static final _id_toHours = TimeUnit._class.instanceMethodId(
+    r'toHours',
+    r'(J)J',
+  );
+
+  static final _toHours = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public long toHours(long j)`
+  core$_.int toHours(
+    core$_.int j,
+  ) {
+    return _toHours(reference.pointer, _id_toHours.pointer, j).long;
+  }
+
+  static final _id_toMicros = TimeUnit._class.instanceMethodId(
+    r'toMicros',
+    r'(J)J',
+  );
+
+  static final _toMicros = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public long toMicros(long j)`
+  core$_.int toMicros(
+    core$_.int j,
+  ) {
+    return _toMicros(reference.pointer, _id_toMicros.pointer, j).long;
+  }
+
+  static final _id_toMillis = TimeUnit._class.instanceMethodId(
+    r'toMillis',
+    r'(J)J',
+  );
+
+  static final _toMillis = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public long toMillis(long j)`
+  core$_.int toMillis(
+    core$_.int j,
+  ) {
+    return _toMillis(reference.pointer, _id_toMillis.pointer, j).long;
+  }
+
+  static final _id_toMinutes = TimeUnit._class.instanceMethodId(
+    r'toMinutes',
+    r'(J)J',
+  );
+
+  static final _toMinutes = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public long toMinutes(long j)`
+  core$_.int toMinutes(
+    core$_.int j,
+  ) {
+    return _toMinutes(reference.pointer, _id_toMinutes.pointer, j).long;
+  }
+
+  static final _id_toNanos = TimeUnit._class.instanceMethodId(
+    r'toNanos',
+    r'(J)J',
+  );
+
+  static final _toNanos = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public long toNanos(long j)`
+  core$_.int toNanos(
+    core$_.int j,
+  ) {
+    return _toNanos(reference.pointer, _id_toNanos.pointer, j).long;
+  }
+
+  static final _id_toSeconds = TimeUnit._class.instanceMethodId(
+    r'toSeconds',
+    r'(J)J',
+  );
+
+  static final _toSeconds = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public long toSeconds(long j)`
+  core$_.int toSeconds(
+    core$_.int j,
+  ) {
+    return _toSeconds(reference.pointer, _id_toSeconds.pointer, j).long;
+  }
+}
+
+final class $TimeUnit$Type$ extends jni$_.JType<TimeUnit> {
+  @jni$_.internal
+  const $TimeUnit$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Ljava/util/concurrent/TimeUnit;';
+}
+
+/// from: `javax.net.ssl.X509TrustManager`
+extension type X509TrustManager._(jni$_.JObject _$this)
+    implements jni$_.JObject, TrustManager {
+  static final _class = jni$_.JClass.forName(r'javax/net/ssl/X509TrustManager');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<X509TrustManager> type = $X509TrustManager$Type$();
+
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $X509TrustManager> _$impls = {};
+  static final core$_.Map<core$_.int, $X509TrustManager> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -17677,7 +14458,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -17686,29 +14467,23 @@
       if ($d ==
           r'checkClientTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V') {
         _$impls[$p]!.checkClientTrusted(
-          $a![0]?.as(
-              const jni$_.JArrayType<X509Certificate?>(
-                  $X509Certificate$NullableType()),
-              releaseOriginal: true),
-          $a![1]?.as(const jni$_.JStringType(), releaseOriginal: true),
+          ($a![0] as jni$_.JArray<X509Certificate?>?),
+          ($a![1] as jni$_.JString?),
         );
         return jni$_.nullptr;
       }
       if ($d ==
           r'checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V') {
         _$impls[$p]!.checkServerTrusted(
-          $a![0]?.as(
-              const jni$_.JArrayType<X509Certificate?>(
-                  $X509Certificate$NullableType()),
-              releaseOriginal: true),
-          $a![1]?.as(const jni$_.JStringType(), releaseOriginal: true),
+          ($a![0] as jni$_.JArray<X509Certificate?>?),
+          ($a![1] as jni$_.JString?),
         );
         return jni$_.nullptr;
       }
       if ($d == r'getAcceptedIssuers()[Ljava/security/cert/X509Certificate;') {
         final $r = _$impls[$p]!.getAcceptedIssuers();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -17754,9 +14529,107 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return X509TrustManager.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<X509TrustManager>();
+  }
+}
+
+extension X509TrustManager$$Methods on X509TrustManager {
+  static final _id_checkClientTrusted =
+      X509TrustManager._class.instanceMethodId(
+    r'checkClientTrusted',
+    r'([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V',
+  );
+
+  static final _checkClientTrusted = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, java.lang.String string)`
+  void checkClientTrusted(
+    jni$_.JArray<X509Certificate?>? x509Certificates,
+    jni$_.JString? string,
+  ) {
+    final _$x509Certificates =
+        x509Certificates?.reference ?? jni$_.jNullReference;
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    _checkClientTrusted(reference.pointer, _id_checkClientTrusted.pointer,
+            _$x509Certificates.pointer, _$string.pointer)
+        .check();
+  }
+
+  static final _id_checkServerTrusted =
+      X509TrustManager._class.instanceMethodId(
+    r'checkServerTrusted',
+    r'([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V',
+  );
+
+  static final _checkServerTrusted = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, java.lang.String string)`
+  void checkServerTrusted(
+    jni$_.JArray<X509Certificate?>? x509Certificates,
+    jni$_.JString? string,
+  ) {
+    final _$x509Certificates =
+        x509Certificates?.reference ?? jni$_.jNullReference;
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    _checkServerTrusted(reference.pointer, _id_checkServerTrusted.pointer,
+            _$x509Certificates.pointer, _$string.pointer)
+        .check();
+  }
+
+  static final _id_getAcceptedIssuers =
+      X509TrustManager._class.instanceMethodId(
+    r'getAcceptedIssuers',
+    r'()[Ljava/security/cert/X509Certificate;',
+  );
+
+  static final _getAcceptedIssuers = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.security.cert.X509Certificate[] getAcceptedIssuers()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<X509Certificate?>? getAcceptedIssuers() {
+    return _getAcceptedIssuers(
+            reference.pointer, _id_getAcceptedIssuers.pointer)
+        .object<jni$_.JArray<X509Certificate?>?>();
   }
 }
 
@@ -17765,20 +14638,20 @@
     required void Function(jni$_.JArray<X509Certificate?>? x509Certificates,
             jni$_.JString? string)
         checkClientTrusted,
-    bool checkClientTrusted$async,
+    core$_.bool checkClientTrusted$async,
     required void Function(jni$_.JArray<X509Certificate?>? x509Certificates,
             jni$_.JString? string)
         checkServerTrusted,
-    bool checkServerTrusted$async,
+    core$_.bool checkServerTrusted$async,
     required jni$_.JArray<X509Certificate?>? Function() getAcceptedIssuers,
   }) = _$X509TrustManager;
 
   void checkClientTrusted(
       jni$_.JArray<X509Certificate?>? x509Certificates, jni$_.JString? string);
-  bool get checkClientTrusted$async => false;
+  core$_.bool get checkClientTrusted$async => false;
   void checkServerTrusted(
       jni$_.JArray<X509Certificate?>? x509Certificates, jni$_.JString? string);
-  bool get checkServerTrusted$async => false;
+  core$_.bool get checkServerTrusted$async => false;
   jni$_.JArray<X509Certificate?>? getAcceptedIssuers();
 }
 
@@ -17799,10 +14672,10 @@
 
   final void Function(jni$_.JArray<X509Certificate?>? x509Certificates,
       jni$_.JString? string) _checkClientTrusted;
-  final bool checkClientTrusted$async;
+  final core$_.bool checkClientTrusted$async;
   final void Function(jni$_.JArray<X509Certificate?>? x509Certificates,
       jni$_.JString? string) _checkServerTrusted;
-  final bool checkServerTrusted$async;
+  final core$_.bool checkServerTrusted$async;
   final jni$_.JArray<X509Certificate?>? Function() _getAcceptedIssuers;
 
   void checkClientTrusted(
@@ -17820,105 +14693,27 @@
   }
 }
 
-final class $X509TrustManager$NullableType
-    extends jni$_.JObjType<X509TrustManager?> {
+final class $X509TrustManager$Type$ extends jni$_.JType<X509TrustManager> {
   @jni$_.internal
-  const $X509TrustManager$NullableType();
+  const $X509TrustManager$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljavax/net/ssl/X509TrustManager;';
-
-  @jni$_.internal
-  @core$_.override
-  X509TrustManager? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : X509TrustManager.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<X509TrustManager?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($X509TrustManager$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($X509TrustManager$NullableType) &&
-        other is $X509TrustManager$NullableType;
-  }
-}
-
-final class $X509TrustManager$Type extends jni$_.JObjType<X509TrustManager> {
-  @jni$_.internal
-  const $X509TrustManager$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/ssl/X509TrustManager;';
-
-  @jni$_.internal
-  @core$_.override
-  X509TrustManager fromReference(jni$_.JReference reference) =>
-      X509TrustManager.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<X509TrustManager?> get nullableType =>
-      const $X509TrustManager$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($X509TrustManager$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($X509TrustManager$Type) &&
-        other is $X509TrustManager$Type;
-  }
 }
 
 /// from: `javax.net.SocketFactory`
-class SocketFactory extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<SocketFactory> $type;
-
-  @jni$_.internal
-  SocketFactory.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type SocketFactory._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'javax/net/SocketFactory');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $SocketFactory$NullableType();
-  static const type = $SocketFactory$Type();
-  static final _id_getDefault = _class.staticMethodId(
+  static const jni$_.JType<SocketFactory> type = $SocketFactory$Type$();
+  static final _id_get$default$ = _class.staticMethodId(
     r'getDefault',
     r'()Ljavax/net/SocketFactory;',
   );
 
-  static final _getDefault = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$default$ = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -17932,13 +14727,14 @@
 
   /// from: `static public javax.net.SocketFactory getDefault()`
   /// The returned object must be released after use, by calling the [release] method.
-  static SocketFactory? getDefault() {
-    return _getDefault(
-            _class.reference.pointer, _id_getDefault as jni$_.JMethodIDPtr)
-        .object<SocketFactory?>(const $SocketFactory$NullableType());
+  static SocketFactory? get default$ {
+    return _get$default$(_class.reference.pointer, _id_get$default$.pointer)
+        .object<SocketFactory?>();
   }
+}
 
-  static final _id_createSocket = _class.instanceMethodId(
+extension SocketFactory$$Methods on SocketFactory {
+  static final _id_createSocket = SocketFactory._class.instanceMethodId(
     r'createSocket',
     r'()Ljava/net/Socket;',
   );
@@ -17958,12 +14754,11 @@
   /// from: `public java.net.Socket createSocket()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject? createSocket() {
-    return _createSocket(
-            reference.pointer, _id_createSocket as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _createSocket(reference.pointer, _id_createSocket.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_createSocket$1 = _class.instanceMethodId(
+  static final _id_createSocket$1 = SocketFactory._class.instanceMethodId(
     r'createSocket',
     r'(Ljava/lang/String;I)Ljava/net/Socket;',
   );
@@ -17978,21 +14773,21 @@
           'globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
 
   /// from: `public abstract java.net.Socket createSocket(java.lang.String string, int i)`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject? createSocket$1(
     jni$_.JString? string,
-    int i,
+    core$_.int i,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
-    return _createSocket$1(reference.pointer,
-            _id_createSocket$1 as jni$_.JMethodIDPtr, _$string.pointer, i)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _createSocket$1(
+            reference.pointer, _id_createSocket$1.pointer, _$string.pointer, i)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_createSocket$2 = _class.instanceMethodId(
+  static final _id_createSocket$2 = SocketFactory._class.instanceMethodId(
     r'createSocket',
     r'(Ljava/lang/String;ILjava/net/InetAddress;I)Ljava/net/Socket;',
   );
@@ -18014,31 +14809,26 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>,
-              int)>();
+              core$_.int)>();
 
   /// from: `public abstract java.net.Socket createSocket(java.lang.String string, int i, java.net.InetAddress inetAddress, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject? createSocket$2(
     jni$_.JString? string,
-    int i,
+    core$_.int i,
     jni$_.JObject? inetAddress,
-    int i1,
+    core$_.int i1,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$inetAddress = inetAddress?.reference ?? jni$_.jNullReference;
-    return _createSocket$2(
-            reference.pointer,
-            _id_createSocket$2 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            i,
-            _$inetAddress.pointer,
-            i1)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _createSocket$2(reference.pointer, _id_createSocket$2.pointer,
+            _$string.pointer, i, _$inetAddress.pointer, i1)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_createSocket$3 = _class.instanceMethodId(
+  static final _id_createSocket$3 = SocketFactory._class.instanceMethodId(
     r'createSocket',
     r'(Ljava/net/InetAddress;I)Ljava/net/Socket;',
   );
@@ -18053,21 +14843,21 @@
           'globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
 
   /// from: `public abstract java.net.Socket createSocket(java.net.InetAddress inetAddress, int i)`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject? createSocket$3(
     jni$_.JObject? inetAddress,
-    int i,
+    core$_.int i,
   ) {
     final _$inetAddress = inetAddress?.reference ?? jni$_.jNullReference;
-    return _createSocket$3(reference.pointer,
-            _id_createSocket$3 as jni$_.JMethodIDPtr, _$inetAddress.pointer, i)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _createSocket$3(reference.pointer, _id_createSocket$3.pointer,
+            _$inetAddress.pointer, i)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_createSocket$4 = _class.instanceMethodId(
+  static final _id_createSocket$4 = SocketFactory._class.instanceMethodId(
     r'createSocket',
     r'(Ljava/net/InetAddress;ILjava/net/InetAddress;I)Ljava/net/Socket;',
   );
@@ -18089,128 +14879,48 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>,
-              int)>();
+              core$_.int)>();
 
   /// from: `public abstract java.net.Socket createSocket(java.net.InetAddress inetAddress, int i, java.net.InetAddress inetAddress1, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject? createSocket$4(
     jni$_.JObject? inetAddress,
-    int i,
+    core$_.int i,
     jni$_.JObject? inetAddress1,
-    int i1,
+    core$_.int i1,
   ) {
     final _$inetAddress = inetAddress?.reference ?? jni$_.jNullReference;
     final _$inetAddress1 = inetAddress1?.reference ?? jni$_.jNullReference;
-    return _createSocket$4(
-            reference.pointer,
-            _id_createSocket$4 as jni$_.JMethodIDPtr,
-            _$inetAddress.pointer,
-            i,
-            _$inetAddress1.pointer,
-            i1)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _createSocket$4(reference.pointer, _id_createSocket$4.pointer,
+            _$inetAddress.pointer, i, _$inetAddress1.pointer, i1)
+        .object<jni$_.JObject?>();
   }
 }
 
-final class $SocketFactory$NullableType extends jni$_.JObjType<SocketFactory?> {
+final class $SocketFactory$Type$ extends jni$_.JType<SocketFactory> {
   @jni$_.internal
-  const $SocketFactory$NullableType();
+  const $SocketFactory$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljavax/net/SocketFactory;';
-
-  @jni$_.internal
-  @core$_.override
-  SocketFactory? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : SocketFactory.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<SocketFactory?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($SocketFactory$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($SocketFactory$NullableType) &&
-        other is $SocketFactory$NullableType;
-  }
-}
-
-final class $SocketFactory$Type extends jni$_.JObjType<SocketFactory> {
-  @jni$_.internal
-  const $SocketFactory$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/SocketFactory;';
-
-  @jni$_.internal
-  @core$_.override
-  SocketFactory fromReference(jni$_.JReference reference) =>
-      SocketFactory.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<SocketFactory?> get nullableType =>
-      const $SocketFactory$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($SocketFactory$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($SocketFactory$Type) &&
-        other is $SocketFactory$Type;
-  }
 }
 
 /// from: `javax.net.ssl.SSLSocketFactory`
-class SSLSocketFactory extends SocketFactory {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<SSLSocketFactory> $type;
-
-  @jni$_.internal
-  SSLSocketFactory.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type SSLSocketFactory._(jni$_.JObject _$this)
+    implements SocketFactory {
   static final _class = jni$_.JClass.forName(r'javax/net/ssl/SSLSocketFactory');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $SSLSocketFactory$NullableType();
-  static const type = $SSLSocketFactory$Type();
-  static final _id_getDefault = _class.staticMethodId(
+  static const jni$_.JType<SSLSocketFactory> type = $SSLSocketFactory$Type$();
+  static final _id_get$default$ = _class.staticMethodId(
     r'getDefault',
     r'()Ljavax/net/SocketFactory;',
   );
 
-  static final _getDefault = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$default$ = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -18224,67 +14934,14 @@
 
   /// from: `static public javax.net.SocketFactory getDefault()`
   /// The returned object must be released after use, by calling the [release] method.
-  static SocketFactory? getDefault() {
-    return _getDefault(
-            _class.reference.pointer, _id_getDefault as jni$_.JMethodIDPtr)
-        .object<SocketFactory?>(const $SocketFactory$NullableType());
+  static SocketFactory? get default$ {
+    return _get$default$(_class.reference.pointer, _id_get$default$.pointer)
+        .object<SocketFactory?>();
   }
+}
 
-  static final _id_getDefaultCipherSuites = _class.instanceMethodId(
-    r'getDefaultCipherSuites',
-    r'()[Ljava/lang/String;',
-  );
-
-  static final _getDefaultCipherSuites = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.lang.String[] getDefaultCipherSuites()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JArray<jni$_.JString?>? getDefaultCipherSuites() {
-    return _getDefaultCipherSuites(
-            reference.pointer, _id_getDefaultCipherSuites as jni$_.JMethodIDPtr)
-        .object<jni$_.JArray<jni$_.JString?>?>(
-            const jni$_.JArrayNullableType<jni$_.JString?>(
-                jni$_.JStringNullableType()));
-  }
-
-  static final _id_getSupportedCipherSuites = _class.instanceMethodId(
-    r'getSupportedCipherSuites',
-    r'()[Ljava/lang/String;',
-  );
-
-  static final _getSupportedCipherSuites = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.lang.String[] getSupportedCipherSuites()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JArray<jni$_.JString?>? getSupportedCipherSuites() {
-    return _getSupportedCipherSuites(reference.pointer,
-            _id_getSupportedCipherSuites as jni$_.JMethodIDPtr)
-        .object<jni$_.JArray<jni$_.JString?>?>(
-            const jni$_.JArrayNullableType<jni$_.JString?>(
-                jni$_.JStringNullableType()));
-  }
-
-  static final _id_createSocket$5 = _class.instanceMethodId(
+extension SSLSocketFactory$$Methods on SSLSocketFactory {
+  static final _id_createSocket$5 = SSLSocketFactory._class.instanceMethodId(
     r'createSocket',
     r'(Ljava/net/Socket;Ljava/lang/String;IZ)Ljava/net/Socket;',
   );
@@ -18307,129 +14964,98 @@
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+              core$_.int,
+              core$_.int)>();
 
   /// from: `public abstract java.net.Socket createSocket(java.net.Socket socket, java.lang.String string, int i, boolean z)`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JObject? createSocket$5(
     jni$_.JObject? socket,
     jni$_.JString? string,
-    int i,
-    bool z,
+    core$_.int i,
+    core$_.bool z,
   ) {
     final _$socket = socket?.reference ?? jni$_.jNullReference;
     final _$string = string?.reference ?? jni$_.jNullReference;
-    return _createSocket$5(
-            reference.pointer,
-            _id_createSocket$5 as jni$_.JMethodIDPtr,
-            _$socket.pointer,
-            _$string.pointer,
-            i,
-            z ? 1 : 0)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _createSocket$5(reference.pointer, _id_createSocket$5.pointer,
+            _$socket.pointer, _$string.pointer, i, z ? 1 : 0)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_get$defaultCipherSuites =
+      SSLSocketFactory._class.instanceMethodId(
+    r'getDefaultCipherSuites',
+    r'()[Ljava/lang/String;',
+  );
+
+  static final _get$defaultCipherSuites = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.lang.String[] getDefaultCipherSuites()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<jni$_.JString?>? get defaultCipherSuites {
+    return _get$defaultCipherSuites(
+            reference.pointer, _id_get$defaultCipherSuites.pointer)
+        .object<jni$_.JArray<jni$_.JString?>?>();
+  }
+
+  static final _id_get$supportedCipherSuites =
+      SSLSocketFactory._class.instanceMethodId(
+    r'getSupportedCipherSuites',
+    r'()[Ljava/lang/String;',
+  );
+
+  static final _get$supportedCipherSuites = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.lang.String[] getSupportedCipherSuites()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<jni$_.JString?>? get supportedCipherSuites {
+    return _get$supportedCipherSuites(
+            reference.pointer, _id_get$supportedCipherSuites.pointer)
+        .object<jni$_.JArray<jni$_.JString?>?>();
   }
 }
 
-final class $SSLSocketFactory$NullableType
-    extends jni$_.JObjType<SSLSocketFactory?> {
+final class $SSLSocketFactory$Type$ extends jni$_.JType<SSLSocketFactory> {
   @jni$_.internal
-  const $SSLSocketFactory$NullableType();
+  const $SSLSocketFactory$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljavax/net/ssl/SSLSocketFactory;';
-
-  @jni$_.internal
-  @core$_.override
-  SSLSocketFactory? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : SSLSocketFactory.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const $SocketFactory$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<SSLSocketFactory?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 2;
-
-  @core$_.override
-  int get hashCode => ($SSLSocketFactory$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($SSLSocketFactory$NullableType) &&
-        other is $SSLSocketFactory$NullableType;
-  }
-}
-
-final class $SSLSocketFactory$Type extends jni$_.JObjType<SSLSocketFactory> {
-  @jni$_.internal
-  const $SSLSocketFactory$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/ssl/SSLSocketFactory;';
-
-  @jni$_.internal
-  @core$_.override
-  SSLSocketFactory fromReference(jni$_.JReference reference) =>
-      SSLSocketFactory.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const $SocketFactory$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<SSLSocketFactory?> get nullableType =>
-      const $SSLSocketFactory$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 2;
-
-  @core$_.override
-  int get hashCode => ($SSLSocketFactory$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($SSLSocketFactory$Type) &&
-        other is $SSLSocketFactory$Type;
-  }
 }
 
 /// from: `javax.net.ssl.SSLContext`
-class SSLContext extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<SSLContext> $type;
-
-  @jni$_.internal
-  SSLContext.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type SSLContext._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'javax/net/ssl/SSLContext');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $SSLContext$NullableType();
-  static const type = $SSLContext$Type();
-  static final _id_getDefault = _class.staticMethodId(
+  static const jni$_.JType<SSLContext> type = $SSLContext$Type$();
+  static final _id_get$default$ = _class.staticMethodId(
     r'getDefault',
     r'()Ljavax/net/ssl/SSLContext;',
   );
 
-  static final _getDefault = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$default$ = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -18443,36 +15069,9 @@
 
   /// from: `static public javax.net.ssl.SSLContext getDefault()`
   /// The returned object must be released after use, by calling the [release] method.
-  static SSLContext? getDefault() {
-    return _getDefault(
-            _class.reference.pointer, _id_getDefault as jni$_.JMethodIDPtr)
-        .object<SSLContext?>(const $SSLContext$NullableType());
-  }
-
-  static final _id_setDefault = _class.staticMethodId(
-    r'setDefault',
-    r'(Ljavax/net/ssl/SSLContext;)V',
-  );
-
-  static final _setDefault = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void setDefault(javax.net.ssl.SSLContext sSLContext)`
-  static void setDefault(
-    SSLContext? sSLContext,
-  ) {
-    final _$sSLContext = sSLContext?.reference ?? jni$_.jNullReference;
-    _setDefault(_class.reference.pointer, _id_setDefault as jni$_.JMethodIDPtr,
-            _$sSLContext.pointer)
-        .check();
+  static SSLContext? get default$ {
+    return _get$default$(_class.reference.pointer, _id_get$default$.pointer)
+        .object<SSLContext?>();
   }
 
   static final _id_getInstance = _class.staticMethodId(
@@ -18497,9 +15096,9 @@
     jni$_.JString? string,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getInstance(_class.reference.pointer,
-            _id_getInstance as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<SSLContext?>(const $SSLContext$NullableType());
+    return _getInstance(
+            _class.reference.pointer, _id_getInstance.pointer, _$string.pointer)
+        .object<SSLContext?>();
   }
 
   static final _id_getInstance$1 = _class.staticMethodId(
@@ -18532,12 +15131,9 @@
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$string1 = string1?.reference ?? jni$_.jNullReference;
-    return _getInstance$1(
-            _class.reference.pointer,
-            _id_getInstance$1 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$string1.pointer)
-        .object<SSLContext?>(const $SSLContext$NullableType());
+    return _getInstance$1(_class.reference.pointer, _id_getInstance$1.pointer,
+            _$string.pointer, _$string1.pointer)
+        .object<SSLContext?>();
   }
 
   static final _id_getInstance$2 = _class.staticMethodId(
@@ -18570,20 +15166,148 @@
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$provider = provider?.reference ?? jni$_.jNullReference;
-    return _getInstance$2(
-            _class.reference.pointer,
-            _id_getInstance$2 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$provider.pointer)
-        .object<SSLContext?>(const $SSLContext$NullableType());
+    return _getInstance$2(_class.reference.pointer, _id_getInstance$2.pointer,
+            _$string.pointer, _$provider.pointer)
+        .object<SSLContext?>();
   }
 
-  static final _id_getProtocol = _class.instanceMethodId(
+  static final _id_set$default$ = _class.staticMethodId(
+    r'setDefault',
+    r'(Ljavax/net/ssl/SSLContext;)V',
+  );
+
+  static final _set$default$ = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void setDefault(javax.net.ssl.SSLContext sSLContext)`
+  static set default$(SSLContext? sSLContext) {
+    final _$sSLContext = sSLContext?.reference ?? jni$_.jNullReference;
+    _set$default$(_class.reference.pointer, _id_set$default$.pointer,
+            _$sSLContext.pointer)
+        .check();
+  }
+}
+
+extension SSLContext$$Methods on SSLContext {
+  static final _id_createSSLEngine = SSLContext._class.instanceMethodId(
+    r'createSSLEngine',
+    r'()Ljavax/net/ssl/SSLEngine;',
+  );
+
+  static final _createSSLEngine = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.ssl.SSLEngine createSSLEngine()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? createSSLEngine() {
+    return _createSSLEngine(reference.pointer, _id_createSSLEngine.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_createSSLEngine$1 = SSLContext._class.instanceMethodId(
+    r'createSSLEngine',
+    r'(Ljava/lang/String;I)Ljavax/net/ssl/SSLEngine;',
+  );
+
+  static final _createSSLEngine$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `public final javax.net.ssl.SSLEngine createSSLEngine(java.lang.String string, int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? createSSLEngine$1(
+    jni$_.JString? string,
+    core$_.int i,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _createSSLEngine$1(reference.pointer, _id_createSSLEngine$1.pointer,
+            _$string.pointer, i)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_get$clientSessionContext =
+      SSLContext._class.instanceMethodId(
+    r'getClientSessionContext',
+    r'()Ljavax/net/ssl/SSLSessionContext;',
+  );
+
+  static final _get$clientSessionContext = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.ssl.SSLSessionContext getClientSessionContext()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get clientSessionContext {
+    return _get$clientSessionContext(
+            reference.pointer, _id_get$clientSessionContext.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_get$defaultSSLParameters =
+      SSLContext._class.instanceMethodId(
+    r'getDefaultSSLParameters',
+    r'()Ljavax/net/ssl/SSLParameters;',
+  );
+
+  static final _get$defaultSSLParameters = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.ssl.SSLParameters getDefaultSSLParameters()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get defaultSSLParameters {
+    return _get$defaultSSLParameters(
+            reference.pointer, _id_get$defaultSSLParameters.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_get$protocol = SSLContext._class.instanceMethodId(
     r'getProtocol',
     r'()Ljava/lang/String;',
   );
 
-  static final _getProtocol = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$protocol = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -18597,18 +15321,17 @@
 
   /// from: `public final java.lang.String getProtocol()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getProtocol() {
-    return _getProtocol(
-            reference.pointer, _id_getProtocol as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+  jni$_.JString? get protocol {
+    return _get$protocol(reference.pointer, _id_get$protocol.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_getProvider = _class.instanceMethodId(
+  static final _id_get$provider = SSLContext._class.instanceMethodId(
     r'getProvider',
     r'()Ljava/security/Provider;',
   );
 
-  static final _getProvider = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$provider = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -18622,13 +15345,114 @@
 
   /// from: `public final java.security.Provider getProvider()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getProvider() {
-    return _getProvider(
-            reference.pointer, _id_getProvider as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  jni$_.JObject? get provider {
+    return _get$provider(reference.pointer, _id_get$provider.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_init = _class.instanceMethodId(
+  static final _id_get$serverSessionContext =
+      SSLContext._class.instanceMethodId(
+    r'getServerSessionContext',
+    r'()Ljavax/net/ssl/SSLSessionContext;',
+  );
+
+  static final _get$serverSessionContext = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.ssl.SSLSessionContext getServerSessionContext()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get serverSessionContext {
+    return _get$serverSessionContext(
+            reference.pointer, _id_get$serverSessionContext.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_get$serverSocketFactory = SSLContext._class.instanceMethodId(
+    r'getServerSocketFactory',
+    r'()Ljavax/net/ssl/SSLServerSocketFactory;',
+  );
+
+  static final _get$serverSocketFactory = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.ssl.SSLServerSocketFactory getServerSocketFactory()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get serverSocketFactory {
+    return _get$serverSocketFactory(
+            reference.pointer, _id_get$serverSocketFactory.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_get$socketFactory = SSLContext._class.instanceMethodId(
+    r'getSocketFactory',
+    r'()Ljavax/net/ssl/SSLSocketFactory;',
+  );
+
+  static final _get$socketFactory = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.ssl.SSLSocketFactory getSocketFactory()`
+  /// The returned object must be released after use, by calling the [release] method.
+  SSLSocketFactory? get socketFactory {
+    return _get$socketFactory(reference.pointer, _id_get$socketFactory.pointer)
+        .object<SSLSocketFactory?>();
+  }
+
+  static final _id_get$supportedSSLParameters =
+      SSLContext._class.instanceMethodId(
+    r'getSupportedSSLParameters',
+    r'()Ljavax/net/ssl/SSLParameters;',
+  );
+
+  static final _get$supportedSSLParameters =
+      jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                    jni$_.Pointer<jni$_.Void>,
+                    jni$_.JMethodIDPtr,
+                  )>>('globalEnv_CallObjectMethod')
+          .asFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>();
+
+  /// from: `public final javax.net.ssl.SSLParameters getSupportedSSLParameters()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get supportedSSLParameters {
+    return _get$supportedSSLParameters(
+            reference.pointer, _id_get$supportedSSLParameters.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_init = SSLContext._class.instanceMethodId(
     r'init',
     r'([Ljavax/net/ssl/KeyManager;[Ljavax/net/ssl/TrustManager;Ljava/security/SecureRandom;)V',
   );
@@ -18661,317 +15485,36 @@
     final _$keyManagers = keyManagers?.reference ?? jni$_.jNullReference;
     final _$trustManagers = trustManagers?.reference ?? jni$_.jNullReference;
     final _$secureRandom = secureRandom?.reference ?? jni$_.jNullReference;
-    _init(
-            reference.pointer,
-            _id_init as jni$_.JMethodIDPtr,
-            _$keyManagers.pointer,
-            _$trustManagers.pointer,
-            _$secureRandom.pointer)
+    _init(reference.pointer, _id_init.pointer, _$keyManagers.pointer,
+            _$trustManagers.pointer, _$secureRandom.pointer)
         .check();
   }
-
-  static final _id_getSocketFactory = _class.instanceMethodId(
-    r'getSocketFactory',
-    r'()Ljavax/net/ssl/SSLSocketFactory;',
-  );
-
-  static final _getSocketFactory = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.SSLSocketFactory getSocketFactory()`
-  /// The returned object must be released after use, by calling the [release] method.
-  SSLSocketFactory? getSocketFactory() {
-    return _getSocketFactory(
-            reference.pointer, _id_getSocketFactory as jni$_.JMethodIDPtr)
-        .object<SSLSocketFactory?>(const $SSLSocketFactory$NullableType());
-  }
-
-  static final _id_getServerSocketFactory = _class.instanceMethodId(
-    r'getServerSocketFactory',
-    r'()Ljavax/net/ssl/SSLServerSocketFactory;',
-  );
-
-  static final _getServerSocketFactory = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.SSLServerSocketFactory getServerSocketFactory()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getServerSocketFactory() {
-    return _getServerSocketFactory(
-            reference.pointer, _id_getServerSocketFactory as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_createSSLEngine = _class.instanceMethodId(
-    r'createSSLEngine',
-    r'()Ljavax/net/ssl/SSLEngine;',
-  );
-
-  static final _createSSLEngine = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.SSLEngine createSSLEngine()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? createSSLEngine() {
-    return _createSSLEngine(
-            reference.pointer, _id_createSSLEngine as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_createSSLEngine$1 = _class.instanceMethodId(
-    r'createSSLEngine',
-    r'(Ljava/lang/String;I)Ljavax/net/ssl/SSLEngine;',
-  );
-
-  static final _createSSLEngine$1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `public final javax.net.ssl.SSLEngine createSSLEngine(java.lang.String string, int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? createSSLEngine$1(
-    jni$_.JString? string,
-    int i,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    return _createSSLEngine$1(reference.pointer,
-            _id_createSSLEngine$1 as jni$_.JMethodIDPtr, _$string.pointer, i)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_getServerSessionContext = _class.instanceMethodId(
-    r'getServerSessionContext',
-    r'()Ljavax/net/ssl/SSLSessionContext;',
-  );
-
-  static final _getServerSessionContext = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.SSLSessionContext getServerSessionContext()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getServerSessionContext() {
-    return _getServerSessionContext(reference.pointer,
-            _id_getServerSessionContext as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_getClientSessionContext = _class.instanceMethodId(
-    r'getClientSessionContext',
-    r'()Ljavax/net/ssl/SSLSessionContext;',
-  );
-
-  static final _getClientSessionContext = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.SSLSessionContext getClientSessionContext()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getClientSessionContext() {
-    return _getClientSessionContext(reference.pointer,
-            _id_getClientSessionContext as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_getDefaultSSLParameters = _class.instanceMethodId(
-    r'getDefaultSSLParameters',
-    r'()Ljavax/net/ssl/SSLParameters;',
-  );
-
-  static final _getDefaultSSLParameters = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.SSLParameters getDefaultSSLParameters()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getDefaultSSLParameters() {
-    return _getDefaultSSLParameters(reference.pointer,
-            _id_getDefaultSSLParameters as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_getSupportedSSLParameters = _class.instanceMethodId(
-    r'getSupportedSSLParameters',
-    r'()Ljavax/net/ssl/SSLParameters;',
-  );
-
-  static final _getSupportedSSLParameters = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.SSLParameters getSupportedSSLParameters()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getSupportedSSLParameters() {
-    return _getSupportedSSLParameters(reference.pointer,
-            _id_getSupportedSSLParameters as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
 }
 
-final class $SSLContext$NullableType extends jni$_.JObjType<SSLContext?> {
+final class $SSLContext$Type$ extends jni$_.JType<SSLContext> {
   @jni$_.internal
-  const $SSLContext$NullableType();
+  const $SSLContext$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljavax/net/ssl/SSLContext;';
-
-  @jni$_.internal
-  @core$_.override
-  SSLContext? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : SSLContext.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<SSLContext?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($SSLContext$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($SSLContext$NullableType) &&
-        other is $SSLContext$NullableType;
-  }
-}
-
-final class $SSLContext$Type extends jni$_.JObjType<SSLContext> {
-  @jni$_.internal
-  const $SSLContext$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/ssl/SSLContext;';
-
-  @jni$_.internal
-  @core$_.override
-  SSLContext fromReference(jni$_.JReference reference) =>
-      SSLContext.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<SSLContext?> get nullableType =>
-      const $SSLContext$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($SSLContext$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($SSLContext$Type) && other is $SSLContext$Type;
-  }
 }
 
 /// from: `javax.net.ssl.TrustManagerFactory`
-class TrustManagerFactory extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<TrustManagerFactory> $type;
-
-  @jni$_.internal
-  TrustManagerFactory.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type TrustManagerFactory._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'javax/net/ssl/TrustManagerFactory');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $TrustManagerFactory$NullableType();
-  static const type = $TrustManagerFactory$Type();
-  static final _id_getDefaultAlgorithm = _class.staticMethodId(
+  static const jni$_.JType<TrustManagerFactory> type =
+      $TrustManagerFactory$Type$();
+  static final _id_get$defaultAlgorithm = _class.staticMethodId(
     r'getDefaultAlgorithm',
     r'()Ljava/lang/String;',
   );
 
-  static final _getDefaultAlgorithm = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$defaultAlgorithm = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -18985,35 +15528,10 @@
 
   /// from: `static public final java.lang.String getDefaultAlgorithm()`
   /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? getDefaultAlgorithm() {
-    return _getDefaultAlgorithm(_class.reference.pointer,
-            _id_getDefaultAlgorithm as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getAlgorithm = _class.instanceMethodId(
-    r'getAlgorithm',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _getAlgorithm = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.lang.String getAlgorithm()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getAlgorithm() {
-    return _getAlgorithm(
-            reference.pointer, _id_getAlgorithm as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+  static jni$_.JString? get defaultAlgorithm {
+    return _get$defaultAlgorithm(
+            _class.reference.pointer, _id_get$defaultAlgorithm.pointer)
+        .object<jni$_.JString?>();
   }
 
   static final _id_getInstance = _class.staticMethodId(
@@ -19038,10 +15556,9 @@
     jni$_.JString? string,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getInstance(_class.reference.pointer,
-            _id_getInstance as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<TrustManagerFactory?>(
-            const $TrustManagerFactory$NullableType());
+    return _getInstance(
+            _class.reference.pointer, _id_getInstance.pointer, _$string.pointer)
+        .object<TrustManagerFactory?>();
   }
 
   static final _id_getInstance$1 = _class.staticMethodId(
@@ -19074,13 +15591,9 @@
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$string1 = string1?.reference ?? jni$_.jNullReference;
-    return _getInstance$1(
-            _class.reference.pointer,
-            _id_getInstance$1 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$string1.pointer)
-        .object<TrustManagerFactory?>(
-            const $TrustManagerFactory$NullableType());
+    return _getInstance$1(_class.reference.pointer, _id_getInstance$1.pointer,
+            _$string.pointer, _$string1.pointer)
+        .object<TrustManagerFactory?>();
   }
 
   static final _id_getInstance$2 = _class.staticMethodId(
@@ -19113,21 +15626,43 @@
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$provider = provider?.reference ?? jni$_.jNullReference;
-    return _getInstance$2(
-            _class.reference.pointer,
-            _id_getInstance$2 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$provider.pointer)
-        .object<TrustManagerFactory?>(
-            const $TrustManagerFactory$NullableType());
+    return _getInstance$2(_class.reference.pointer, _id_getInstance$2.pointer,
+            _$string.pointer, _$provider.pointer)
+        .object<TrustManagerFactory?>();
+  }
+}
+
+extension TrustManagerFactory$$Methods on TrustManagerFactory {
+  static final _id_get$algorithm = TrustManagerFactory._class.instanceMethodId(
+    r'getAlgorithm',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _get$algorithm = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.lang.String getAlgorithm()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? get algorithm {
+    return _get$algorithm(reference.pointer, _id_get$algorithm.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_getProvider = _class.instanceMethodId(
+  static final _id_get$provider = TrustManagerFactory._class.instanceMethodId(
     r'getProvider',
     r'()Ljava/security/Provider;',
   );
 
-  static final _getProvider = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$provider = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -19141,13 +15676,37 @@
 
   /// from: `public final java.security.Provider getProvider()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getProvider() {
-    return _getProvider(
-            reference.pointer, _id_getProvider as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  jni$_.JObject? get provider {
+    return _get$provider(reference.pointer, _id_get$provider.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_init = _class.instanceMethodId(
+  static final _id_get$trustManagers =
+      TrustManagerFactory._class.instanceMethodId(
+    r'getTrustManagers',
+    r'()[Ljavax/net/ssl/TrustManager;',
+  );
+
+  static final _get$trustManagers = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.ssl.TrustManager[] getTrustManagers()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<TrustManager?>? get trustManagers {
+    return _get$trustManagers(reference.pointer, _id_get$trustManagers.pointer)
+        .object<jni$_.JArray<TrustManager?>?>();
+  }
+
+  static final _id_init = TrustManagerFactory._class.instanceMethodId(
     r'init',
     r'(Ljava/security/KeyStore;)V',
   );
@@ -19168,11 +15727,10 @@
     KeyStore? keyStore,
   ) {
     final _$keyStore = keyStore?.reference ?? jni$_.jNullReference;
-    _init(reference.pointer, _id_init as jni$_.JMethodIDPtr, _$keyStore.pointer)
-        .check();
+    _init(reference.pointer, _id_init.pointer, _$keyStore.pointer).check();
   }
 
-  static final _id_init$1 = _class.instanceMethodId(
+  static final _id_init$1 = TrustManagerFactory._class.instanceMethodId(
     r'init',
     r'(Ljavax/net/ssl/ManagerFactoryParameters;)V',
   );
@@ -19194,138 +15752,33 @@
   ) {
     final _$managerFactoryParameters =
         managerFactoryParameters?.reference ?? jni$_.jNullReference;
-    _init$1(reference.pointer, _id_init$1 as jni$_.JMethodIDPtr,
+    _init$1(reference.pointer, _id_init$1.pointer,
             _$managerFactoryParameters.pointer)
         .check();
   }
-
-  static final _id_getTrustManagers = _class.instanceMethodId(
-    r'getTrustManagers',
-    r'()[Ljavax/net/ssl/TrustManager;',
-  );
-
-  static final _getTrustManagers = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.TrustManager[] getTrustManagers()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JArray<TrustManager?>? getTrustManagers() {
-    return _getTrustManagers(
-            reference.pointer, _id_getTrustManagers as jni$_.JMethodIDPtr)
-        .object<jni$_.JArray<TrustManager?>?>(
-            const jni$_.JArrayNullableType<TrustManager?>(
-                $TrustManager$NullableType()));
-  }
 }
 
-final class $TrustManagerFactory$NullableType
-    extends jni$_.JObjType<TrustManagerFactory?> {
+final class $TrustManagerFactory$Type$
+    extends jni$_.JType<TrustManagerFactory> {
   @jni$_.internal
-  const $TrustManagerFactory$NullableType();
+  const $TrustManagerFactory$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljavax/net/ssl/TrustManagerFactory;';
-
-  @jni$_.internal
-  @core$_.override
-  TrustManagerFactory? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : TrustManagerFactory.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<TrustManagerFactory?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($TrustManagerFactory$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($TrustManagerFactory$NullableType) &&
-        other is $TrustManagerFactory$NullableType;
-  }
-}
-
-final class $TrustManagerFactory$Type
-    extends jni$_.JObjType<TrustManagerFactory> {
-  @jni$_.internal
-  const $TrustManagerFactory$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/ssl/TrustManagerFactory;';
-
-  @jni$_.internal
-  @core$_.override
-  TrustManagerFactory fromReference(jni$_.JReference reference) =>
-      TrustManagerFactory.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<TrustManagerFactory?> get nullableType =>
-      const $TrustManagerFactory$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($TrustManagerFactory$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($TrustManagerFactory$Type) &&
-        other is $TrustManagerFactory$Type;
-  }
 }
 
 /// from: `javax.net.ssl.TrustManager`
-class TrustManager extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<TrustManager> $type;
-
-  @jni$_.internal
-  TrustManager.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type TrustManager._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'javax/net/ssl/TrustManager');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $TrustManager$NullableType();
-  static const type = $TrustManager$Type();
+  static const jni$_.JType<TrustManager> type = $TrustManager$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $TrustManager> _$impls = {};
+  static final core$_.Map<core$_.int, $TrustManager> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -19346,7 +15799,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -19388,9 +15841,7 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return TrustManager.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<TrustManager>();
   }
 }
 
@@ -19402,153 +15853,25 @@
   _$TrustManager();
 }
 
-final class $TrustManager$NullableType extends jni$_.JObjType<TrustManager?> {
+final class $TrustManager$Type$ extends jni$_.JType<TrustManager> {
   @jni$_.internal
-  const $TrustManager$NullableType();
+  const $TrustManager$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljavax/net/ssl/TrustManager;';
-
-  @jni$_.internal
-  @core$_.override
-  TrustManager? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : TrustManager.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<TrustManager?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($TrustManager$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($TrustManager$NullableType) &&
-        other is $TrustManager$NullableType;
-  }
-}
-
-final class $TrustManager$Type extends jni$_.JObjType<TrustManager> {
-  @jni$_.internal
-  const $TrustManager$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/ssl/TrustManager;';
-
-  @jni$_.internal
-  @core$_.override
-  TrustManager fromReference(jni$_.JReference reference) =>
-      TrustManager.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<TrustManager?> get nullableType =>
-      const $TrustManager$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($TrustManager$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($TrustManager$Type) &&
-        other is $TrustManager$Type;
-  }
 }
 
 /// from: `java.security.KeyStore$Builder`
-class KeyStore$Builder extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyStore$Builder> $type;
-
-  @jni$_.internal
-  KeyStore$Builder.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyStore$Builder._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'java/security/KeyStore$Builder');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyStore$Builder$NullableType();
-  static const type = $KeyStore$Builder$Type();
-  static final _id_getKeyStore = _class.instanceMethodId(
-    r'getKeyStore',
-    r'()Ljava/security/KeyStore;',
-  );
-
-  static final _getKeyStore = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.security.KeyStore getKeyStore()`
-  /// The returned object must be released after use, by calling the [release] method.
-  KeyStore? getKeyStore() {
-    return _getKeyStore(
-            reference.pointer, _id_getKeyStore as jni$_.JMethodIDPtr)
-        .object<KeyStore?>(const $KeyStore$NullableType());
-  }
-
-  static final _id_getProtectionParameter = _class.instanceMethodId(
-    r'getProtectionParameter',
-    r'(Ljava/lang/String;)Ljava/security/KeyStore$ProtectionParameter;',
-  );
-
-  static final _getProtectionParameter = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.security.KeyStore$ProtectionParameter getProtectionParameter(java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  KeyStore$ProtectionParameter? getProtectionParameter(
-    jni$_.JString? string,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getProtectionParameter(reference.pointer,
-            _id_getProtectionParameter as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<KeyStore$ProtectionParameter?>(
-            const $KeyStore$ProtectionParameter$NullableType());
-  }
-
+  static const jni$_.JType<KeyStore$Builder> type = $KeyStore$Builder$Type$();
   static final _id_newInstance = _class.staticMethodId(
     r'newInstance',
-    r'(Ljava/security/KeyStore;Ljava/security/KeyStore$ProtectionParameter;)Ljava/security/KeyStore$Builder;',
+    r'(Ljava/io/File;Ljava/security/KeyStore$ProtectionParameter;)Ljava/security/KeyStore$Builder;',
   );
 
   static final _newInstance = jni$_.ProtectedJniExtensions.lookup<
@@ -19568,21 +15891,18 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public java.security.KeyStore$Builder newInstance(java.security.KeyStore keyStore, java.security.KeyStore$ProtectionParameter protectionParameter)`
+  /// from: `static public java.security.KeyStore$Builder newInstance(java.io.File file, java.security.KeyStore$ProtectionParameter protectionParameter)`
   /// The returned object must be released after use, by calling the [release] method.
   static KeyStore$Builder? newInstance(
-    KeyStore? keyStore,
+    jni$_.JObject? file,
     KeyStore$ProtectionParameter? protectionParameter,
   ) {
-    final _$keyStore = keyStore?.reference ?? jni$_.jNullReference;
+    final _$file = file?.reference ?? jni$_.jNullReference;
     final _$protectionParameter =
         protectionParameter?.reference ?? jni$_.jNullReference;
-    return _newInstance(
-            _class.reference.pointer,
-            _id_newInstance as jni$_.JMethodIDPtr,
-            _$keyStore.pointer,
-            _$protectionParameter.pointer)
-        .object<KeyStore$Builder?>(const $KeyStore$Builder$NullableType());
+    return _newInstance(_class.reference.pointer, _id_newInstance.pointer,
+            _$file.pointer, _$protectionParameter.pointer)
+        .object<KeyStore$Builder?>();
   }
 
   static final _id_newInstance$1 = _class.staticMethodId(
@@ -19626,59 +15946,20 @@
         protectionParameter?.reference ?? jni$_.jNullReference;
     return _newInstance$1(
             _class.reference.pointer,
-            _id_newInstance$1 as jni$_.JMethodIDPtr,
+            _id_newInstance$1.pointer,
             _$string.pointer,
             _$provider.pointer,
             _$file.pointer,
             _$protectionParameter.pointer)
-        .object<KeyStore$Builder?>(const $KeyStore$Builder$NullableType());
+        .object<KeyStore$Builder?>();
   }
 
   static final _id_newInstance$2 = _class.staticMethodId(
     r'newInstance',
-    r'(Ljava/io/File;Ljava/security/KeyStore$ProtectionParameter;)Ljava/security/KeyStore$Builder;',
-  );
-
-  static final _newInstance$2 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public java.security.KeyStore$Builder newInstance(java.io.File file, java.security.KeyStore$ProtectionParameter protectionParameter)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static KeyStore$Builder? newInstance$2(
-    jni$_.JObject? file,
-    KeyStore$ProtectionParameter? protectionParameter,
-  ) {
-    final _$file = file?.reference ?? jni$_.jNullReference;
-    final _$protectionParameter =
-        protectionParameter?.reference ?? jni$_.jNullReference;
-    return _newInstance$2(
-            _class.reference.pointer,
-            _id_newInstance$2 as jni$_.JMethodIDPtr,
-            _$file.pointer,
-            _$protectionParameter.pointer)
-        .object<KeyStore$Builder?>(const $KeyStore$Builder$NullableType());
-  }
-
-  static final _id_newInstance$3 = _class.staticMethodId(
-    r'newInstance',
     r'(Ljava/lang/String;Ljava/security/Provider;Ljava/security/KeyStore$ProtectionParameter;)Ljava/security/KeyStore$Builder;',
   );
 
-  static final _newInstance$3 = jni$_.ProtectedJniExtensions.lookup<
+  static final _newInstance$2 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -19699,7 +15980,7 @@
 
   /// from: `static public java.security.KeyStore$Builder newInstance(java.lang.String string, java.security.Provider provider, java.security.KeyStore$ProtectionParameter protectionParameter)`
   /// The returned object must be released after use, by calling the [release] method.
-  static KeyStore$Builder? newInstance$3(
+  static KeyStore$Builder? newInstance$2(
     jni$_.JString? string,
     jni$_.JObject? provider,
     KeyStore$ProtectionParameter? protectionParameter,
@@ -19708,111 +15989,120 @@
     final _$provider = provider?.reference ?? jni$_.jNullReference;
     final _$protectionParameter =
         protectionParameter?.reference ?? jni$_.jNullReference;
-    return _newInstance$3(
-            _class.reference.pointer,
-            _id_newInstance$3 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$provider.pointer,
-            _$protectionParameter.pointer)
-        .object<KeyStore$Builder?>(const $KeyStore$Builder$NullableType());
+    return _newInstance$2(_class.reference.pointer, _id_newInstance$2.pointer,
+            _$string.pointer, _$provider.pointer, _$protectionParameter.pointer)
+        .object<KeyStore$Builder?>();
+  }
+
+  static final _id_newInstance$3 = _class.staticMethodId(
+    r'newInstance',
+    r'(Ljava/security/KeyStore;Ljava/security/KeyStore$ProtectionParameter;)Ljava/security/KeyStore$Builder;',
+  );
+
+  static final _newInstance$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public java.security.KeyStore$Builder newInstance(java.security.KeyStore keyStore, java.security.KeyStore$ProtectionParameter protectionParameter)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static KeyStore$Builder? newInstance$3(
+    KeyStore? keyStore,
+    KeyStore$ProtectionParameter? protectionParameter,
+  ) {
+    final _$keyStore = keyStore?.reference ?? jni$_.jNullReference;
+    final _$protectionParameter =
+        protectionParameter?.reference ?? jni$_.jNullReference;
+    return _newInstance$3(_class.reference.pointer, _id_newInstance$3.pointer,
+            _$keyStore.pointer, _$protectionParameter.pointer)
+        .object<KeyStore$Builder?>();
   }
 }
 
-final class $KeyStore$Builder$NullableType
-    extends jni$_.JObjType<KeyStore$Builder?> {
+extension KeyStore$Builder$$Methods on KeyStore$Builder {
+  static final _id_get$keyStore = KeyStore$Builder._class.instanceMethodId(
+    r'getKeyStore',
+    r'()Ljava/security/KeyStore;',
+  );
+
+  static final _get$keyStore = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.security.KeyStore getKeyStore()`
+  /// The returned object must be released after use, by calling the [release] method.
+  KeyStore? get keyStore {
+    return _get$keyStore(reference.pointer, _id_get$keyStore.pointer)
+        .object<KeyStore?>();
+  }
+
+  static final _id_getProtectionParameter =
+      KeyStore$Builder._class.instanceMethodId(
+    r'getProtectionParameter',
+    r'(Ljava/lang/String;)Ljava/security/KeyStore$ProtectionParameter;',
+  );
+
+  static final _getProtectionParameter = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.security.KeyStore$ProtectionParameter getProtectionParameter(java.lang.String string)`
+  /// The returned object must be released after use, by calling the [release] method.
+  KeyStore$ProtectionParameter? getProtectionParameter(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _getProtectionParameter(reference.pointer,
+            _id_getProtectionParameter.pointer, _$string.pointer)
+        .object<KeyStore$ProtectionParameter?>();
+  }
+}
+
+final class $KeyStore$Builder$Type$ extends jni$_.JType<KeyStore$Builder> {
   @jni$_.internal
-  const $KeyStore$Builder$NullableType();
+  const $KeyStore$Builder$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyStore$Builder;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$Builder? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyStore$Builder.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$Builder?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$Builder$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$Builder$NullableType) &&
-        other is $KeyStore$Builder$NullableType;
-  }
-}
-
-final class $KeyStore$Builder$Type extends jni$_.JObjType<KeyStore$Builder> {
-  @jni$_.internal
-  const $KeyStore$Builder$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyStore$Builder;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$Builder fromReference(jni$_.JReference reference) =>
-      KeyStore$Builder.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$Builder?> get nullableType =>
-      const $KeyStore$Builder$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$Builder$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$Builder$Type) &&
-        other is $KeyStore$Builder$Type;
-  }
 }
 
 /// from: `java.security.KeyStore$CallbackHandlerProtection`
-class KeyStore$CallbackHandlerProtection extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyStore$CallbackHandlerProtection> $type;
-
-  @jni$_.internal
-  KeyStore$CallbackHandlerProtection.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyStore$CallbackHandlerProtection._(jni$_.JObject _$this)
+    implements jni$_.JObject, KeyStore$ProtectionParameter {
   static final _class =
       jni$_.JClass.forName(r'java/security/KeyStore$CallbackHandlerProtection');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType =
-      $KeyStore$CallbackHandlerProtection$NullableType();
-  static const type = $KeyStore$CallbackHandlerProtection$Type();
+  static const jni$_.JType<KeyStore$CallbackHandlerProtection> type =
+      $KeyStore$CallbackHandlerProtection$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Ljavax/security/auth/callback/CallbackHandler;)V',
   );
@@ -19835,19 +16125,21 @@
   ) {
     final _$callbackHandler =
         callbackHandler?.reference ?? jni$_.jNullReference;
-    return KeyStore$CallbackHandlerProtection.fromReference(_new$(
-            _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
+    return _new$(_class.reference.pointer, _id_new$.pointer,
             _$callbackHandler.pointer)
-        .reference);
+        .object<KeyStore$CallbackHandlerProtection>();
   }
+}
 
-  static final _id_getCallbackHandler = _class.instanceMethodId(
+extension KeyStore$CallbackHandlerProtection$$Methods
+    on KeyStore$CallbackHandlerProtection {
+  static final _id_get$callbackHandler =
+      KeyStore$CallbackHandlerProtection._class.instanceMethodId(
     r'getCallbackHandler',
     r'()Ljavax/security/auth/callback/CallbackHandler;',
   );
 
-  static final _getCallbackHandler = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$callbackHandler = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -19861,164 +16153,37 @@
 
   /// from: `public javax.security.auth.callback.CallbackHandler getCallbackHandler()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getCallbackHandler() {
-    return _getCallbackHandler(
-            reference.pointer, _id_getCallbackHandler as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  jni$_.JObject? get callbackHandler {
+    return _get$callbackHandler(
+            reference.pointer, _id_get$callbackHandler.pointer)
+        .object<jni$_.JObject?>();
   }
 }
 
-final class $KeyStore$CallbackHandlerProtection$NullableType
-    extends jni$_.JObjType<KeyStore$CallbackHandlerProtection?> {
+final class $KeyStore$CallbackHandlerProtection$Type$
+    extends jni$_.JType<KeyStore$CallbackHandlerProtection> {
   @jni$_.internal
-  const $KeyStore$CallbackHandlerProtection$NullableType();
+  const $KeyStore$CallbackHandlerProtection$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyStore$CallbackHandlerProtection;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$CallbackHandlerProtection? fromReference(
-          jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyStore$CallbackHandlerProtection.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$CallbackHandlerProtection?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode =>
-      ($KeyStore$CallbackHandlerProtection$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType ==
-            ($KeyStore$CallbackHandlerProtection$NullableType) &&
-        other is $KeyStore$CallbackHandlerProtection$NullableType;
-  }
-}
-
-final class $KeyStore$CallbackHandlerProtection$Type
-    extends jni$_.JObjType<KeyStore$CallbackHandlerProtection> {
-  @jni$_.internal
-  const $KeyStore$CallbackHandlerProtection$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyStore$CallbackHandlerProtection;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$CallbackHandlerProtection fromReference(
-          jni$_.JReference reference) =>
-      KeyStore$CallbackHandlerProtection.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$CallbackHandlerProtection?> get nullableType =>
-      const $KeyStore$CallbackHandlerProtection$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$CallbackHandlerProtection$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$CallbackHandlerProtection$Type) &&
-        other is $KeyStore$CallbackHandlerProtection$Type;
-  }
 }
 
 /// from: `java.security.KeyStore$Entry$Attribute`
-class KeyStore$Entry$Attribute extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyStore$Entry$Attribute> $type;
-
-  @jni$_.internal
-  KeyStore$Entry$Attribute.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyStore$Entry$Attribute._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'java/security/KeyStore$Entry$Attribute');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyStore$Entry$Attribute$NullableType();
-  static const type = $KeyStore$Entry$Attribute$Type();
-  static final _id_getName = _class.instanceMethodId(
-    r'getName',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _getName = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.lang.String getName()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getName() {
-    return _getName(reference.pointer, _id_getName as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getValue = _class.instanceMethodId(
-    r'getValue',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _getValue = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.lang.String getValue()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getValue() {
-    return _getValue(reference.pointer, _id_getValue as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
+  static const jni$_.JType<KeyStore$Entry$Attribute> type =
+      $KeyStore$Entry$Attribute$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $KeyStore$Entry$Attribute> _$impls = {};
+  static final core$_.Map<core$_.int, $KeyStore$Entry$Attribute> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -20039,7 +16204,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -20048,7 +16213,7 @@
       if ($d == r'getName()Ljava/lang/String;') {
         final $r = _$impls[$p]!.getName();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -20056,7 +16221,7 @@
       if ($d == r'getValue()Ljava/lang/String;') {
         final $r = _$impls[$p]!.getValue();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -20097,9 +16262,57 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return KeyStore$Entry$Attribute.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<KeyStore$Entry$Attribute>();
+  }
+}
+
+extension KeyStore$Entry$Attribute$$Methods on KeyStore$Entry$Attribute {
+  static final _id_getName = KeyStore$Entry$Attribute._class.instanceMethodId(
+    r'getName',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _getName = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.lang.String getName()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? getName() {
+    return _getName(reference.pointer, _id_getName.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_getValue = KeyStore$Entry$Attribute._class.instanceMethodId(
+    r'getValue',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _getValue = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.lang.String getValue()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? getValue() {
+    return _getValue(reference.pointer, _id_getValue.pointer)
+        .object<jni$_.JString?>();
   }
 }
 
@@ -20132,131 +16345,27 @@
   }
 }
 
-final class $KeyStore$Entry$Attribute$NullableType
-    extends jni$_.JObjType<KeyStore$Entry$Attribute?> {
+final class $KeyStore$Entry$Attribute$Type$
+    extends jni$_.JType<KeyStore$Entry$Attribute> {
   @jni$_.internal
-  const $KeyStore$Entry$Attribute$NullableType();
+  const $KeyStore$Entry$Attribute$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyStore$Entry$Attribute;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$Entry$Attribute? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyStore$Entry$Attribute.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$Entry$Attribute?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$Entry$Attribute$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$Entry$Attribute$NullableType) &&
-        other is $KeyStore$Entry$Attribute$NullableType;
-  }
-}
-
-final class $KeyStore$Entry$Attribute$Type
-    extends jni$_.JObjType<KeyStore$Entry$Attribute> {
-  @jni$_.internal
-  const $KeyStore$Entry$Attribute$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyStore$Entry$Attribute;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$Entry$Attribute fromReference(jni$_.JReference reference) =>
-      KeyStore$Entry$Attribute.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$Entry$Attribute?> get nullableType =>
-      const $KeyStore$Entry$Attribute$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$Entry$Attribute$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$Entry$Attribute$Type) &&
-        other is $KeyStore$Entry$Attribute$Type;
-  }
 }
 
 /// from: `java.security.KeyStore$Entry`
-class KeyStore$Entry extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyStore$Entry> $type;
-
-  @jni$_.internal
-  KeyStore$Entry.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyStore$Entry._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'java/security/KeyStore$Entry');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyStore$Entry$NullableType();
-  static const type = $KeyStore$Entry$Type();
-  static final _id_getAttributes = _class.instanceMethodId(
-    r'getAttributes',
-    r'()Ljava/util/Set;',
-  );
-
-  static final _getAttributes = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.util.Set getAttributes()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JSet<KeyStore$Entry$Attribute?>? getAttributes() {
-    return _getAttributes(
-            reference.pointer, _id_getAttributes as jni$_.JMethodIDPtr)
-        .object<jni$_.JSet<KeyStore$Entry$Attribute?>?>(
-            const jni$_.JSetNullableType<KeyStore$Entry$Attribute?>(
-                $KeyStore$Entry$Attribute$NullableType()));
-  }
+  static const jni$_.JType<KeyStore$Entry> type = $KeyStore$Entry$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $KeyStore$Entry> _$impls = {};
+  static final core$_.Map<core$_.int, $KeyStore$Entry> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -20277,7 +16386,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -20286,7 +16395,7 @@
       if ($d == r'getAttributes()Ljava/util/Set;') {
         final $r = _$impls[$p]!.getAttributes();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -20327,9 +16436,33 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return KeyStore$Entry.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<KeyStore$Entry>();
+  }
+}
+
+extension KeyStore$Entry$$Methods on KeyStore$Entry {
+  static final _id_getAttributes = KeyStore$Entry._class.instanceMethodId(
+    r'getAttributes',
+    r'()Ljava/util/Set;',
+  );
+
+  static final _getAttributes = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.util.Set<java.security.KeyStore$Entry$Attribute> getAttributes()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JSet<KeyStore$Entry$Attribute?>? getAttributes() {
+    return _getAttributes(reference.pointer, _id_getAttributes.pointer)
+        .object<jni$_.JSet<KeyStore$Entry$Attribute?>?>();
   }
 }
 
@@ -20353,129 +16486,30 @@
   }
 }
 
-final class $KeyStore$Entry$NullableType
-    extends jni$_.JObjType<KeyStore$Entry?> {
+final class $KeyStore$Entry$Type$ extends jni$_.JType<KeyStore$Entry> {
   @jni$_.internal
-  const $KeyStore$Entry$NullableType();
+  const $KeyStore$Entry$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyStore$Entry;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$Entry? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : KeyStore$Entry.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$Entry?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$Entry$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$Entry$NullableType) &&
-        other is $KeyStore$Entry$NullableType;
-  }
-}
-
-final class $KeyStore$Entry$Type extends jni$_.JObjType<KeyStore$Entry> {
-  @jni$_.internal
-  const $KeyStore$Entry$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyStore$Entry;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$Entry fromReference(jni$_.JReference reference) =>
-      KeyStore$Entry.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$Entry?> get nullableType =>
-      const $KeyStore$Entry$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$Entry$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$Entry$Type) &&
-        other is $KeyStore$Entry$Type;
-  }
 }
 
 /// from: `java.security.KeyStore$LoadStoreParameter`
-class KeyStore$LoadStoreParameter extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyStore$LoadStoreParameter> $type;
-
-  @jni$_.internal
-  KeyStore$LoadStoreParameter.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyStore$LoadStoreParameter._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'java/security/KeyStore$LoadStoreParameter');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyStore$LoadStoreParameter$NullableType();
-  static const type = $KeyStore$LoadStoreParameter$Type();
-  static final _id_getProtectionParameter = _class.instanceMethodId(
-    r'getProtectionParameter',
-    r'()Ljava/security/KeyStore$ProtectionParameter;',
-  );
-
-  static final _getProtectionParameter = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.security.KeyStore$ProtectionParameter getProtectionParameter()`
-  /// The returned object must be released after use, by calling the [release] method.
-  KeyStore$ProtectionParameter? getProtectionParameter() {
-    return _getProtectionParameter(
-            reference.pointer, _id_getProtectionParameter as jni$_.JMethodIDPtr)
-        .object<KeyStore$ProtectionParameter?>(
-            const $KeyStore$ProtectionParameter$NullableType());
-  }
+  static const jni$_.JType<KeyStore$LoadStoreParameter> type =
+      $KeyStore$LoadStoreParameter$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $KeyStore$LoadStoreParameter> _$impls = {};
+  static final core$_.Map<core$_.int, $KeyStore$LoadStoreParameter> _$impls =
+      {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -20496,7 +16530,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -20506,7 +16540,7 @@
           r'getProtectionParameter()Ljava/security/KeyStore$ProtectionParameter;') {
         final $r = _$impls[$p]!.getProtectionParameter();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -20547,9 +16581,35 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return KeyStore$LoadStoreParameter.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<KeyStore$LoadStoreParameter>();
+  }
+}
+
+extension KeyStore$LoadStoreParameter$$Methods on KeyStore$LoadStoreParameter {
+  static final _id_getProtectionParameter =
+      KeyStore$LoadStoreParameter._class.instanceMethodId(
+    r'getProtectionParameter',
+    r'()Ljava/security/KeyStore$ProtectionParameter;',
+  );
+
+  static final _getProtectionParameter = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.security.KeyStore$ProtectionParameter getProtectionParameter()`
+  /// The returned object must be released after use, by calling the [release] method.
+  KeyStore$ProtectionParameter? getProtectionParameter() {
+    return _getProtectionParameter(
+            reference.pointer, _id_getProtectionParameter.pointer)
+        .object<KeyStore$ProtectionParameter?>();
   }
 }
 
@@ -20573,101 +16633,25 @@
   }
 }
 
-final class $KeyStore$LoadStoreParameter$NullableType
-    extends jni$_.JObjType<KeyStore$LoadStoreParameter?> {
+final class $KeyStore$LoadStoreParameter$Type$
+    extends jni$_.JType<KeyStore$LoadStoreParameter> {
   @jni$_.internal
-  const $KeyStore$LoadStoreParameter$NullableType();
+  const $KeyStore$LoadStoreParameter$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyStore$LoadStoreParameter;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$LoadStoreParameter? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyStore$LoadStoreParameter.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$LoadStoreParameter?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$LoadStoreParameter$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$LoadStoreParameter$NullableType) &&
-        other is $KeyStore$LoadStoreParameter$NullableType;
-  }
-}
-
-final class $KeyStore$LoadStoreParameter$Type
-    extends jni$_.JObjType<KeyStore$LoadStoreParameter> {
-  @jni$_.internal
-  const $KeyStore$LoadStoreParameter$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyStore$LoadStoreParameter;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$LoadStoreParameter fromReference(jni$_.JReference reference) =>
-      KeyStore$LoadStoreParameter.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$LoadStoreParameter?> get nullableType =>
-      const $KeyStore$LoadStoreParameter$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$LoadStoreParameter$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$LoadStoreParameter$Type) &&
-        other is $KeyStore$LoadStoreParameter$Type;
-  }
 }
 
 /// from: `java.security.KeyStore$PasswordProtection`
-class KeyStore$PasswordProtection extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyStore$PasswordProtection> $type;
-
-  @jni$_.internal
-  KeyStore$PasswordProtection.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyStore$PasswordProtection._(jni$_.JObject _$this)
+    implements jni$_.JObject, KeyStore$ProtectionParameter {
   static final _class =
       jni$_.JClass.forName(r'java/security/KeyStore$PasswordProtection');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyStore$PasswordProtection$NullableType();
-  static const type = $KeyStore$PasswordProtection$Type();
+  static const jni$_.JType<KeyStore$PasswordProtection> type =
+      $KeyStore$PasswordProtection$Type$();
   static final _id_new$ = _class.constructorId(
     r'([C)V',
   );
@@ -20689,11 +16673,8 @@
     jni$_.JCharArray? cs,
   ) {
     final _$cs = cs?.reference ?? jni$_.jNullReference;
-    return KeyStore$PasswordProtection.fromReference(_new$(
-            _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
-            _$cs.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer, _$cs.pointer)
+        .object<KeyStore$PasswordProtection>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -20730,91 +16711,15 @@
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$algorithmParameterSpec =
         algorithmParameterSpec?.reference ?? jni$_.jNullReference;
-    return KeyStore$PasswordProtection.fromReference(_new$1(
-            _class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr,
-            _$cs.pointer,
-            _$string.pointer,
-            _$algorithmParameterSpec.pointer)
-        .reference);
+    return _new$1(_class.reference.pointer, _id_new$1.pointer, _$cs.pointer,
+            _$string.pointer, _$algorithmParameterSpec.pointer)
+        .object<KeyStore$PasswordProtection>();
   }
+}
 
-  static final _id_getProtectionAlgorithm = _class.instanceMethodId(
-    r'getProtectionAlgorithm',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _getProtectionAlgorithm = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.lang.String getProtectionAlgorithm()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getProtectionAlgorithm() {
-    return _getProtectionAlgorithm(
-            reference.pointer, _id_getProtectionAlgorithm as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getProtectionParameters = _class.instanceMethodId(
-    r'getProtectionParameters',
-    r'()Ljava/security/spec/AlgorithmParameterSpec;',
-  );
-
-  static final _getProtectionParameters = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.security.spec.AlgorithmParameterSpec getProtectionParameters()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getProtectionParameters() {
-    return _getProtectionParameters(reference.pointer,
-            _id_getProtectionParameters as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_getPassword = _class.instanceMethodId(
-    r'getPassword',
-    r'()[C',
-  );
-
-  static final _getPassword = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public char[] getPassword()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JCharArray? getPassword() {
-    return _getPassword(
-            reference.pointer, _id_getPassword as jni$_.JMethodIDPtr)
-        .object<jni$_.JCharArray?>(const jni$_.JCharArrayNullableType());
-  }
-
-  static final _id_destroy = _class.instanceMethodId(
+extension KeyStore$PasswordProtection$$Methods on KeyStore$PasswordProtection {
+  static final _id_destroy =
+      KeyStore$PasswordProtection._class.instanceMethodId(
     r'destroy',
     r'()V',
   );
@@ -20833,15 +16738,93 @@
 
   /// from: `public void destroy()`
   void destroy() {
-    _destroy(reference.pointer, _id_destroy as jni$_.JMethodIDPtr).check();
+    _destroy(reference.pointer, _id_destroy.pointer).check();
   }
 
-  static final _id_isDestroyed = _class.instanceMethodId(
+  static final _id_get$password =
+      KeyStore$PasswordProtection._class.instanceMethodId(
+    r'getPassword',
+    r'()[C',
+  );
+
+  static final _get$password = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public char[] getPassword()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JCharArray? get password {
+    return _get$password(reference.pointer, _id_get$password.pointer)
+        .object<jni$_.JCharArray?>();
+  }
+
+  static final _id_get$protectionAlgorithm =
+      KeyStore$PasswordProtection._class.instanceMethodId(
+    r'getProtectionAlgorithm',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _get$protectionAlgorithm = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.lang.String getProtectionAlgorithm()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? get protectionAlgorithm {
+    return _get$protectionAlgorithm(
+            reference.pointer, _id_get$protectionAlgorithm.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_get$protectionParameters =
+      KeyStore$PasswordProtection._class.instanceMethodId(
+    r'getProtectionParameters',
+    r'()Ljava/security/spec/AlgorithmParameterSpec;',
+  );
+
+  static final _get$protectionParameters = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.security.spec.AlgorithmParameterSpec getProtectionParameters()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get protectionParameters {
+    return _get$protectionParameters(
+            reference.pointer, _id_get$protectionParameters.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_get$isDestroyed =
+      KeyStore$PasswordProtection._class.instanceMethodId(
     r'isDestroyed',
     r'()Z',
   );
 
-  static final _isDestroyed = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$isDestroyed = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -20854,108 +16837,31 @@
           )>();
 
   /// from: `public boolean isDestroyed()`
-  bool isDestroyed() {
-    return _isDestroyed(
-            reference.pointer, _id_isDestroyed as jni$_.JMethodIDPtr)
+  core$_.bool get isDestroyed {
+    return _get$isDestroyed(reference.pointer, _id_get$isDestroyed.pointer)
         .boolean;
   }
 }
 
-final class $KeyStore$PasswordProtection$NullableType
-    extends jni$_.JObjType<KeyStore$PasswordProtection?> {
+final class $KeyStore$PasswordProtection$Type$
+    extends jni$_.JType<KeyStore$PasswordProtection> {
   @jni$_.internal
-  const $KeyStore$PasswordProtection$NullableType();
+  const $KeyStore$PasswordProtection$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyStore$PasswordProtection;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$PasswordProtection? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyStore$PasswordProtection.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$PasswordProtection?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$PasswordProtection$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$PasswordProtection$NullableType) &&
-        other is $KeyStore$PasswordProtection$NullableType;
-  }
-}
-
-final class $KeyStore$PasswordProtection$Type
-    extends jni$_.JObjType<KeyStore$PasswordProtection> {
-  @jni$_.internal
-  const $KeyStore$PasswordProtection$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyStore$PasswordProtection;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$PasswordProtection fromReference(jni$_.JReference reference) =>
-      KeyStore$PasswordProtection.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$PasswordProtection?> get nullableType =>
-      const $KeyStore$PasswordProtection$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$PasswordProtection$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$PasswordProtection$Type) &&
-        other is $KeyStore$PasswordProtection$Type;
-  }
 }
 
 /// from: `java.security.KeyStore$PrivateKeyEntry`
-class KeyStore$PrivateKeyEntry extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyStore$PrivateKeyEntry> $type;
-
-  @jni$_.internal
-  KeyStore$PrivateKeyEntry.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyStore$PrivateKeyEntry._(jni$_.JObject _$this)
+    implements jni$_.JObject, KeyStore$Entry {
   static final _class =
       jni$_.JClass.forName(r'java/security/KeyStore$PrivateKeyEntry');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyStore$PrivateKeyEntry$NullableType();
-  static const type = $KeyStore$PrivateKeyEntry$Type();
+  static const jni$_.JType<KeyStore$PrivateKeyEntry> type =
+      $KeyStore$PrivateKeyEntry$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Ljava/security/PrivateKey;[Ljava/security/cert/Certificate;)V',
   );
@@ -20985,12 +16891,9 @@
   ) {
     final _$privateKey = privateKey?.reference ?? jni$_.jNullReference;
     final _$certificates = certificates?.reference ?? jni$_.jNullReference;
-    return KeyStore$PrivateKeyEntry.fromReference(_new$(
-            _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
-            _$privateKey.pointer,
-            _$certificates.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$privateKey.pointer, _$certificates.pointer)
+        .object<KeyStore$PrivateKeyEntry>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -21016,7 +16919,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public void <init>(java.security.PrivateKey privateKey, java.lang.Object[] certificates, java.util.Set set)`
+  /// from: `public void <init>(java.security.PrivateKey privateKey, java.security.cert.Certificate[] certificates, java.util.Set<java.security.KeyStore$Entry$Attribute> set)`
   /// The returned object must be released after use, by calling the [release] method.
   factory KeyStore$PrivateKeyEntry.new$1(
     PrivateKey? privateKey,
@@ -21026,21 +16929,20 @@
     final _$privateKey = privateKey?.reference ?? jni$_.jNullReference;
     final _$certificates = certificates?.reference ?? jni$_.jNullReference;
     final _$set = set?.reference ?? jni$_.jNullReference;
-    return KeyStore$PrivateKeyEntry.fromReference(_new$1(
-            _class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr,
-            _$privateKey.pointer,
-            _$certificates.pointer,
-            _$set.pointer)
-        .reference);
+    return _new$1(_class.reference.pointer, _id_new$1.pointer,
+            _$privateKey.pointer, _$certificates.pointer, _$set.pointer)
+        .object<KeyStore$PrivateKeyEntry>();
   }
+}
 
-  static final _id_getPrivateKey = _class.instanceMethodId(
-    r'getPrivateKey',
-    r'()Ljava/security/PrivateKey;',
+extension KeyStore$PrivateKeyEntry$$Methods on KeyStore$PrivateKeyEntry {
+  static final _id_get$attributes =
+      KeyStore$PrivateKeyEntry._class.instanceMethodId(
+    r'getAttributes',
+    r'()Ljava/util/Set;',
   );
 
-  static final _getPrivateKey = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$attributes = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -21052,47 +16954,20 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public java.security.PrivateKey getPrivateKey()`
+  /// from: `public java.util.Set<java.security.KeyStore$Entry$Attribute> getAttributes()`
   /// The returned object must be released after use, by calling the [release] method.
-  PrivateKey? getPrivateKey() {
-    return _getPrivateKey(
-            reference.pointer, _id_getPrivateKey as jni$_.JMethodIDPtr)
-        .object<PrivateKey?>(const $PrivateKey$NullableType());
+  jni$_.JSet<KeyStore$Entry$Attribute?>? get attributes {
+    return _get$attributes(reference.pointer, _id_get$attributes.pointer)
+        .object<jni$_.JSet<KeyStore$Entry$Attribute?>?>();
   }
 
-  static final _id_getCertificateChain = _class.instanceMethodId(
-    r'getCertificateChain',
-    r'()[Ljava/security/cert/Certificate;',
-  );
-
-  static final _getCertificateChain = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.security.cert.Certificate[] getCertificateChain()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JArray<Certificate?>? getCertificateChain() {
-    return _getCertificateChain(
-            reference.pointer, _id_getCertificateChain as jni$_.JMethodIDPtr)
-        .object<jni$_.JArray<Certificate?>?>(
-            const jni$_.JArrayNullableType<Certificate?>(
-                $Certificate$NullableType()));
-  }
-
-  static final _id_getCertificate = _class.instanceMethodId(
+  static final _id_get$certificate =
+      KeyStore$PrivateKeyEntry._class.instanceMethodId(
     r'getCertificate',
     r'()Ljava/security/cert/Certificate;',
   );
 
-  static final _getCertificate = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$certificate = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -21106,18 +16981,18 @@
 
   /// from: `public java.security.cert.Certificate getCertificate()`
   /// The returned object must be released after use, by calling the [release] method.
-  Certificate? getCertificate() {
-    return _getCertificate(
-            reference.pointer, _id_getCertificate as jni$_.JMethodIDPtr)
-        .object<Certificate?>(const $Certificate$NullableType());
+  Certificate? get certificate {
+    return _get$certificate(reference.pointer, _id_get$certificate.pointer)
+        .object<Certificate?>();
   }
 
-  static final _id_getAttributes = _class.instanceMethodId(
-    r'getAttributes',
-    r'()Ljava/util/Set;',
+  static final _id_get$certificateChain =
+      KeyStore$PrivateKeyEntry._class.instanceMethodId(
+    r'getCertificateChain',
+    r'()[Ljava/security/cert/Certificate;',
   );
 
-  static final _getAttributes = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$certificateChain = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -21129,17 +17004,41 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public java.util.Set getAttributes()`
+  /// from: `public java.security.cert.Certificate[] getCertificateChain()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JSet<KeyStore$Entry$Attribute?>? getAttributes() {
-    return _getAttributes(
-            reference.pointer, _id_getAttributes as jni$_.JMethodIDPtr)
-        .object<jni$_.JSet<KeyStore$Entry$Attribute?>?>(
-            const jni$_.JSetNullableType<KeyStore$Entry$Attribute?>(
-                $KeyStore$Entry$Attribute$NullableType()));
+  jni$_.JArray<Certificate?>? get certificateChain {
+    return _get$certificateChain(
+            reference.pointer, _id_get$certificateChain.pointer)
+        .object<jni$_.JArray<Certificate?>?>();
   }
 
-  static final _id_toString$1 = _class.instanceMethodId(
+  static final _id_get$privateKey =
+      KeyStore$PrivateKeyEntry._class.instanceMethodId(
+    r'getPrivateKey',
+    r'()Ljava/security/PrivateKey;',
+  );
+
+  static final _get$privateKey = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.security.PrivateKey getPrivateKey()`
+  /// The returned object must be released after use, by calling the [release] method.
+  PrivateKey? get privateKey {
+    return _get$privateKey(reference.pointer, _id_get$privateKey.pointer)
+        .object<PrivateKey?>();
+  }
+
+  static final _id_toString$1 =
+      KeyStore$PrivateKeyEntry._class.instanceMethodId(
     r'toString',
     r'()Ljava/lang/String;',
   );
@@ -21159,111 +17058,36 @@
   /// from: `public java.lang.String toString()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString? toString$1() {
-    return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+    return _toString$1(reference.pointer, _id_toString$1.pointer)
+        .object<jni$_.JString?>();
   }
 }
 
-final class $KeyStore$PrivateKeyEntry$NullableType
-    extends jni$_.JObjType<KeyStore$PrivateKeyEntry?> {
+final class $KeyStore$PrivateKeyEntry$Type$
+    extends jni$_.JType<KeyStore$PrivateKeyEntry> {
   @jni$_.internal
-  const $KeyStore$PrivateKeyEntry$NullableType();
+  const $KeyStore$PrivateKeyEntry$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyStore$PrivateKeyEntry;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$PrivateKeyEntry? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyStore$PrivateKeyEntry.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$PrivateKeyEntry?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$PrivateKeyEntry$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$PrivateKeyEntry$NullableType) &&
-        other is $KeyStore$PrivateKeyEntry$NullableType;
-  }
-}
-
-final class $KeyStore$PrivateKeyEntry$Type
-    extends jni$_.JObjType<KeyStore$PrivateKeyEntry> {
-  @jni$_.internal
-  const $KeyStore$PrivateKeyEntry$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyStore$PrivateKeyEntry;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$PrivateKeyEntry fromReference(jni$_.JReference reference) =>
-      KeyStore$PrivateKeyEntry.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$PrivateKeyEntry?> get nullableType =>
-      const $KeyStore$PrivateKeyEntry$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$PrivateKeyEntry$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$PrivateKeyEntry$Type) &&
-        other is $KeyStore$PrivateKeyEntry$Type;
-  }
 }
 
 /// from: `java.security.KeyStore$ProtectionParameter`
-class KeyStore$ProtectionParameter extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyStore$ProtectionParameter> $type;
-
-  @jni$_.internal
-  KeyStore$ProtectionParameter.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyStore$ProtectionParameter._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'java/security/KeyStore$ProtectionParameter');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyStore$ProtectionParameter$NullableType();
-  static const type = $KeyStore$ProtectionParameter$Type();
+  static const jni$_.JType<KeyStore$ProtectionParameter> type =
+      $KeyStore$ProtectionParameter$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $KeyStore$ProtectionParameter> _$impls = {};
+  static final core$_.Map<core$_.int, $KeyStore$ProtectionParameter> _$impls =
+      {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -21284,7 +17108,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -21326,9 +17150,7 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return KeyStore$ProtectionParameter.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<KeyStore$ProtectionParameter>();
   }
 }
 
@@ -21340,101 +17162,25 @@
   _$KeyStore$ProtectionParameter();
 }
 
-final class $KeyStore$ProtectionParameter$NullableType
-    extends jni$_.JObjType<KeyStore$ProtectionParameter?> {
+final class $KeyStore$ProtectionParameter$Type$
+    extends jni$_.JType<KeyStore$ProtectionParameter> {
   @jni$_.internal
-  const $KeyStore$ProtectionParameter$NullableType();
+  const $KeyStore$ProtectionParameter$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyStore$ProtectionParameter;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$ProtectionParameter? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyStore$ProtectionParameter.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$ProtectionParameter?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$ProtectionParameter$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$ProtectionParameter$NullableType) &&
-        other is $KeyStore$ProtectionParameter$NullableType;
-  }
-}
-
-final class $KeyStore$ProtectionParameter$Type
-    extends jni$_.JObjType<KeyStore$ProtectionParameter> {
-  @jni$_.internal
-  const $KeyStore$ProtectionParameter$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyStore$ProtectionParameter;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$ProtectionParameter fromReference(jni$_.JReference reference) =>
-      KeyStore$ProtectionParameter.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$ProtectionParameter?> get nullableType =>
-      const $KeyStore$ProtectionParameter$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$ProtectionParameter$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$ProtectionParameter$Type) &&
-        other is $KeyStore$ProtectionParameter$Type;
-  }
 }
 
 /// from: `java.security.KeyStore$SecretKeyEntry`
-class KeyStore$SecretKeyEntry extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyStore$SecretKeyEntry> $type;
-
-  @jni$_.internal
-  KeyStore$SecretKeyEntry.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyStore$SecretKeyEntry._(jni$_.JObject _$this)
+    implements jni$_.JObject, KeyStore$Entry {
   static final _class =
       jni$_.JClass.forName(r'java/security/KeyStore$SecretKeyEntry');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyStore$SecretKeyEntry$NullableType();
-  static const type = $KeyStore$SecretKeyEntry$Type();
+  static const jni$_.JType<KeyStore$SecretKeyEntry> type =
+      $KeyStore$SecretKeyEntry$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Ljavax/crypto/SecretKey;)V',
   );
@@ -21456,9 +17202,9 @@
     jni$_.JObject? secretKey,
   ) {
     final _$secretKey = secretKey?.reference ?? jni$_.jNullReference;
-    return KeyStore$SecretKeyEntry.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$secretKey.pointer)
-        .reference);
+    return _new$(
+            _class.reference.pointer, _id_new$.pointer, _$secretKey.pointer)
+        .object<KeyStore$SecretKeyEntry>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -21482,7 +17228,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public void <init>(javax.crypto.SecretKey secretKey, java.util.Set set)`
+  /// from: `public void <init>(javax.crypto.SecretKey secretKey, java.util.Set<java.security.KeyStore$Entry$Attribute> set)`
   /// The returned object must be released after use, by calling the [release] method.
   factory KeyStore$SecretKeyEntry.new$1(
     jni$_.JObject? secretKey,
@@ -21490,20 +17236,45 @@
   ) {
     final _$secretKey = secretKey?.reference ?? jni$_.jNullReference;
     final _$set = set?.reference ?? jni$_.jNullReference;
-    return KeyStore$SecretKeyEntry.fromReference(_new$1(
-            _class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr,
-            _$secretKey.pointer,
-            _$set.pointer)
-        .reference);
+    return _new$1(_class.reference.pointer, _id_new$1.pointer,
+            _$secretKey.pointer, _$set.pointer)
+        .object<KeyStore$SecretKeyEntry>();
+  }
+}
+
+extension KeyStore$SecretKeyEntry$$Methods on KeyStore$SecretKeyEntry {
+  static final _id_get$attributes =
+      KeyStore$SecretKeyEntry._class.instanceMethodId(
+    r'getAttributes',
+    r'()Ljava/util/Set;',
+  );
+
+  static final _get$attributes = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.util.Set<java.security.KeyStore$Entry$Attribute> getAttributes()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JSet<KeyStore$Entry$Attribute?>? get attributes {
+    return _get$attributes(reference.pointer, _id_get$attributes.pointer)
+        .object<jni$_.JSet<KeyStore$Entry$Attribute?>?>();
   }
 
-  static final _id_getSecretKey = _class.instanceMethodId(
+  static final _id_get$secretKey =
+      KeyStore$SecretKeyEntry._class.instanceMethodId(
     r'getSecretKey',
     r'()Ljavax/crypto/SecretKey;',
   );
 
-  static final _getSecretKey = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$secretKey = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -21517,40 +17288,12 @@
 
   /// from: `public javax.crypto.SecretKey getSecretKey()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getSecretKey() {
-    return _getSecretKey(
-            reference.pointer, _id_getSecretKey as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  jni$_.JObject? get secretKey {
+    return _get$secretKey(reference.pointer, _id_get$secretKey.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_getAttributes = _class.instanceMethodId(
-    r'getAttributes',
-    r'()Ljava/util/Set;',
-  );
-
-  static final _getAttributes = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.util.Set getAttributes()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JSet<KeyStore$Entry$Attribute?>? getAttributes() {
-    return _getAttributes(
-            reference.pointer, _id_getAttributes as jni$_.JMethodIDPtr)
-        .object<jni$_.JSet<KeyStore$Entry$Attribute?>?>(
-            const jni$_.JSetNullableType<KeyStore$Entry$Attribute?>(
-                $KeyStore$Entry$Attribute$NullableType()));
-  }
-
-  static final _id_toString$1 = _class.instanceMethodId(
+  static final _id_toString$1 = KeyStore$SecretKeyEntry._class.instanceMethodId(
     r'toString',
     r'()Ljava/lang/String;',
   );
@@ -21570,106 +17313,30 @@
   /// from: `public java.lang.String toString()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString? toString$1() {
-    return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+    return _toString$1(reference.pointer, _id_toString$1.pointer)
+        .object<jni$_.JString?>();
   }
 }
 
-final class $KeyStore$SecretKeyEntry$NullableType
-    extends jni$_.JObjType<KeyStore$SecretKeyEntry?> {
+final class $KeyStore$SecretKeyEntry$Type$
+    extends jni$_.JType<KeyStore$SecretKeyEntry> {
   @jni$_.internal
-  const $KeyStore$SecretKeyEntry$NullableType();
+  const $KeyStore$SecretKeyEntry$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyStore$SecretKeyEntry;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$SecretKeyEntry? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyStore$SecretKeyEntry.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$SecretKeyEntry?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$SecretKeyEntry$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$SecretKeyEntry$NullableType) &&
-        other is $KeyStore$SecretKeyEntry$NullableType;
-  }
-}
-
-final class $KeyStore$SecretKeyEntry$Type
-    extends jni$_.JObjType<KeyStore$SecretKeyEntry> {
-  @jni$_.internal
-  const $KeyStore$SecretKeyEntry$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyStore$SecretKeyEntry;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$SecretKeyEntry fromReference(jni$_.JReference reference) =>
-      KeyStore$SecretKeyEntry.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$SecretKeyEntry?> get nullableType =>
-      const $KeyStore$SecretKeyEntry$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$SecretKeyEntry$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$SecretKeyEntry$Type) &&
-        other is $KeyStore$SecretKeyEntry$Type;
-  }
 }
 
 /// from: `java.security.KeyStore$TrustedCertificateEntry`
-class KeyStore$TrustedCertificateEntry extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyStore$TrustedCertificateEntry> $type;
-
-  @jni$_.internal
-  KeyStore$TrustedCertificateEntry.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyStore$TrustedCertificateEntry._(jni$_.JObject _$this)
+    implements jni$_.JObject, KeyStore$Entry {
   static final _class =
       jni$_.JClass.forName(r'java/security/KeyStore$TrustedCertificateEntry');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyStore$TrustedCertificateEntry$NullableType();
-  static const type = $KeyStore$TrustedCertificateEntry$Type();
+  static const jni$_.JType<KeyStore$TrustedCertificateEntry> type =
+      $KeyStore$TrustedCertificateEntry$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Ljava/security/cert/Certificate;)V',
   );
@@ -21691,11 +17358,9 @@
     Certificate? certificate,
   ) {
     final _$certificate = certificate?.reference ?? jni$_.jNullReference;
-    return KeyStore$TrustedCertificateEntry.fromReference(_new$(
-            _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
-            _$certificate.pointer)
-        .reference);
+    return _new$(
+            _class.reference.pointer, _id_new$.pointer, _$certificate.pointer)
+        .object<KeyStore$TrustedCertificateEntry>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -21719,7 +17384,7 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public void <init>(java.security.cert.Certificate certificate, java.util.Set set)`
+  /// from: `public void <init>(java.security.cert.Certificate certificate, java.util.Set<java.security.KeyStore$Entry$Attribute> set)`
   /// The returned object must be released after use, by calling the [release] method.
   factory KeyStore$TrustedCertificateEntry.new$1(
     Certificate? certificate,
@@ -21727,20 +17392,46 @@
   ) {
     final _$certificate = certificate?.reference ?? jni$_.jNullReference;
     final _$set = set?.reference ?? jni$_.jNullReference;
-    return KeyStore$TrustedCertificateEntry.fromReference(_new$1(
-            _class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr,
-            _$certificate.pointer,
-            _$set.pointer)
-        .reference);
+    return _new$1(_class.reference.pointer, _id_new$1.pointer,
+            _$certificate.pointer, _$set.pointer)
+        .object<KeyStore$TrustedCertificateEntry>();
+  }
+}
+
+extension KeyStore$TrustedCertificateEntry$$Methods
+    on KeyStore$TrustedCertificateEntry {
+  static final _id_get$attributes =
+      KeyStore$TrustedCertificateEntry._class.instanceMethodId(
+    r'getAttributes',
+    r'()Ljava/util/Set;',
+  );
+
+  static final _get$attributes = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.util.Set<java.security.KeyStore$Entry$Attribute> getAttributes()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JSet<KeyStore$Entry$Attribute?>? get attributes {
+    return _get$attributes(reference.pointer, _id_get$attributes.pointer)
+        .object<jni$_.JSet<KeyStore$Entry$Attribute?>?>();
   }
 
-  static final _id_getTrustedCertificate = _class.instanceMethodId(
+  static final _id_get$trustedCertificate =
+      KeyStore$TrustedCertificateEntry._class.instanceMethodId(
     r'getTrustedCertificate',
     r'()Ljava/security/cert/Certificate;',
   );
 
-  static final _getTrustedCertificate = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$trustedCertificate = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -21754,40 +17445,14 @@
 
   /// from: `public java.security.cert.Certificate getTrustedCertificate()`
   /// The returned object must be released after use, by calling the [release] method.
-  Certificate? getTrustedCertificate() {
-    return _getTrustedCertificate(
-            reference.pointer, _id_getTrustedCertificate as jni$_.JMethodIDPtr)
-        .object<Certificate?>(const $Certificate$NullableType());
+  Certificate? get trustedCertificate {
+    return _get$trustedCertificate(
+            reference.pointer, _id_get$trustedCertificate.pointer)
+        .object<Certificate?>();
   }
 
-  static final _id_getAttributes = _class.instanceMethodId(
-    r'getAttributes',
-    r'()Ljava/util/Set;',
-  );
-
-  static final _getAttributes = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.util.Set getAttributes()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JSet<KeyStore$Entry$Attribute?>? getAttributes() {
-    return _getAttributes(
-            reference.pointer, _id_getAttributes as jni$_.JMethodIDPtr)
-        .object<jni$_.JSet<KeyStore$Entry$Attribute?>?>(
-            const jni$_.JSetNullableType<KeyStore$Entry$Attribute?>(
-                $KeyStore$Entry$Attribute$NullableType()));
-  }
-
-  static final _id_toString$1 = _class.instanceMethodId(
+  static final _id_toString$1 =
+      KeyStore$TrustedCertificateEntry._class.instanceMethodId(
     r'toString',
     r'()Ljava/lang/String;',
   );
@@ -21807,136 +17472,90 @@
   /// from: `public java.lang.String toString()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString? toString$1() {
-    return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+    return _toString$1(reference.pointer, _id_toString$1.pointer)
+        .object<jni$_.JString?>();
   }
 }
 
-final class $KeyStore$TrustedCertificateEntry$NullableType
-    extends jni$_.JObjType<KeyStore$TrustedCertificateEntry?> {
+final class $KeyStore$TrustedCertificateEntry$Type$
+    extends jni$_.JType<KeyStore$TrustedCertificateEntry> {
   @jni$_.internal
-  const $KeyStore$TrustedCertificateEntry$NullableType();
+  const $KeyStore$TrustedCertificateEntry$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyStore$TrustedCertificateEntry;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$TrustedCertificateEntry? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyStore$TrustedCertificateEntry.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$TrustedCertificateEntry?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$TrustedCertificateEntry$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType ==
-            ($KeyStore$TrustedCertificateEntry$NullableType) &&
-        other is $KeyStore$TrustedCertificateEntry$NullableType;
-  }
-}
-
-final class $KeyStore$TrustedCertificateEntry$Type
-    extends jni$_.JObjType<KeyStore$TrustedCertificateEntry> {
-  @jni$_.internal
-  const $KeyStore$TrustedCertificateEntry$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyStore$TrustedCertificateEntry;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore$TrustedCertificateEntry fromReference(jni$_.JReference reference) =>
-      KeyStore$TrustedCertificateEntry.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore$TrustedCertificateEntry?> get nullableType =>
-      const $KeyStore$TrustedCertificateEntry$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$TrustedCertificateEntry$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$TrustedCertificateEntry$Type) &&
-        other is $KeyStore$TrustedCertificateEntry$Type;
-  }
 }
 
 /// from: `java.security.KeyStore`
-class KeyStore extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyStore> $type;
-
-  @jni$_.internal
-  KeyStore.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyStore._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'java/security/KeyStore');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyStore$NullableType();
-  static const type = $KeyStore$Type();
+  static const jni$_.JType<KeyStore> type = $KeyStore$Type$();
+  static final _id_get$defaultType = _class.staticMethodId(
+    r'getDefaultType',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _get$defaultType = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `static public final java.lang.String getDefaultType()`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JString? get defaultType {
+    return _get$defaultType(
+            _class.reference.pointer, _id_get$defaultType.pointer)
+        .object<jni$_.JString?>();
+  }
+
   static final _id_getInstance = _class.staticMethodId(
     r'getInstance',
-    r'(Ljava/lang/String;)Ljava/security/KeyStore;',
+    r'(Ljava/io/File;[C)Ljava/security/KeyStore;',
   );
 
   static final _getInstance = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public java.security.KeyStore getInstance(java.lang.String string)`
+  /// from: `static public final java.security.KeyStore getInstance(java.io.File file, char[] cs)`
   /// The returned object must be released after use, by calling the [release] method.
   static KeyStore? getInstance(
-    jni$_.JString? string,
+    jni$_.JObject? file,
+    jni$_.JCharArray? cs,
   ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getInstance(_class.reference.pointer,
-            _id_getInstance as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<KeyStore?>(const $KeyStore$NullableType());
+    final _$file = file?.reference ?? jni$_.jNullReference;
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    return _getInstance(_class.reference.pointer, _id_getInstance.pointer,
+            _$file.pointer, _$cs.pointer)
+        .object<KeyStore?>();
   }
 
   static final _id_getInstance$1 = _class.staticMethodId(
     r'getInstance',
-    r'(Ljava/lang/String;Ljava/lang/String;)Ljava/security/KeyStore;',
+    r'(Ljava/io/File;Ljava/security/KeyStore$LoadStoreParameter;)Ljava/security/KeyStore;',
   );
 
   static final _getInstance$1 = jni$_.ProtectedJniExtensions.lookup<
@@ -21956,28 +17575,88 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public java.security.KeyStore getInstance(java.lang.String string, java.lang.String string1)`
+  /// from: `static public final java.security.KeyStore getInstance(java.io.File file, java.security.KeyStore$LoadStoreParameter loadStoreParameter)`
   /// The returned object must be released after use, by calling the [release] method.
   static KeyStore? getInstance$1(
+    jni$_.JObject? file,
+    KeyStore$LoadStoreParameter? loadStoreParameter,
+  ) {
+    final _$file = file?.reference ?? jni$_.jNullReference;
+    final _$loadStoreParameter =
+        loadStoreParameter?.reference ?? jni$_.jNullReference;
+    return _getInstance$1(_class.reference.pointer, _id_getInstance$1.pointer,
+            _$file.pointer, _$loadStoreParameter.pointer)
+        .object<KeyStore?>();
+  }
+
+  static final _id_getInstance$2 = _class.staticMethodId(
+    r'getInstance',
+    r'(Ljava/lang/String;)Ljava/security/KeyStore;',
+  );
+
+  static final _getInstance$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public java.security.KeyStore getInstance(java.lang.String string)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static KeyStore? getInstance$2(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _getInstance$2(_class.reference.pointer, _id_getInstance$2.pointer,
+            _$string.pointer)
+        .object<KeyStore?>();
+  }
+
+  static final _id_getInstance$3 = _class.staticMethodId(
+    r'getInstance',
+    r'(Ljava/lang/String;Ljava/lang/String;)Ljava/security/KeyStore;',
+  );
+
+  static final _getInstance$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public java.security.KeyStore getInstance(java.lang.String string, java.lang.String string1)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static KeyStore? getInstance$3(
     jni$_.JString? string,
     jni$_.JString? string1,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$string1 = string1?.reference ?? jni$_.jNullReference;
-    return _getInstance$1(
-            _class.reference.pointer,
-            _id_getInstance$1 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$string1.pointer)
-        .object<KeyStore?>(const $KeyStore$NullableType());
+    return _getInstance$3(_class.reference.pointer, _id_getInstance$3.pointer,
+            _$string.pointer, _$string1.pointer)
+        .object<KeyStore?>();
   }
 
-  static final _id_getInstance$2 = _class.staticMethodId(
+  static final _id_getInstance$4 = _class.staticMethodId(
     r'getInstance',
     r'(Ljava/lang/String;Ljava/security/Provider;)Ljava/security/KeyStore;',
   );
 
-  static final _getInstance$2 = jni$_.ProtectedJniExtensions.lookup<
+  static final _getInstance$4 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -21996,51 +17675,25 @@
 
   /// from: `static public java.security.KeyStore getInstance(java.lang.String string, java.security.Provider provider)`
   /// The returned object must be released after use, by calling the [release] method.
-  static KeyStore? getInstance$2(
+  static KeyStore? getInstance$4(
     jni$_.JString? string,
     jni$_.JObject? provider,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$provider = provider?.reference ?? jni$_.jNullReference;
-    return _getInstance$2(
-            _class.reference.pointer,
-            _id_getInstance$2 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$provider.pointer)
-        .object<KeyStore?>(const $KeyStore$NullableType());
+    return _getInstance$4(_class.reference.pointer, _id_getInstance$4.pointer,
+            _$string.pointer, _$provider.pointer)
+        .object<KeyStore?>();
   }
+}
 
-  static final _id_getDefaultType = _class.staticMethodId(
-    r'getDefaultType',
-    r'()Ljava/lang/String;',
+extension KeyStore$$Methods on KeyStore {
+  static final _id_aliases = KeyStore._class.instanceMethodId(
+    r'aliases',
+    r'()Ljava/util/Enumeration;',
   );
 
-  static final _getDefaultType = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `static public final java.lang.String getDefaultType()`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? getDefaultType() {
-    return _getDefaultType(
-            _class.reference.pointer, _id_getDefaultType as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getProvider = _class.instanceMethodId(
-    r'getProvider',
-    r'()Ljava/security/Provider;',
-  );
-
-  static final _getProvider = jni$_.ProtectedJniExtensions.lookup<
+  static final _aliases = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -22052,44 +17705,70 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final java.security.Provider getProvider()`
+  /// from: `public final java.util.Enumeration<java.lang.String> aliases()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getProvider() {
-    return _getProvider(
-            reference.pointer, _id_getProvider as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  Enumeration<jni$_.JString?>? aliases() {
+    return _aliases(reference.pointer, _id_aliases.pointer)
+        .object<Enumeration<jni$_.JString?>?>();
   }
 
-  static final _id_getType = _class.instanceMethodId(
-    r'getType',
-    r'()Ljava/lang/String;',
+  static final _id_containsAlias = KeyStore._class.instanceMethodId(
+    r'containsAlias',
+    r'(Ljava/lang/String;)Z',
   );
 
-  static final _getType = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
+  static final _containsAlias = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallBooleanMethod')
       .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final java.lang.String getType()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getType() {
-    return _getType(reference.pointer, _id_getType as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+  /// from: `public final boolean containsAlias(java.lang.String string)`
+  core$_.bool containsAlias(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _containsAlias(
+            reference.pointer, _id_containsAlias.pointer, _$string.pointer)
+        .boolean;
   }
 
-  static final _id_getKey = _class.instanceMethodId(
-    r'getKey',
-    r'(Ljava/lang/String;[C)Ljava/security/Key;',
+  static final _id_deleteEntry = KeyStore._class.instanceMethodId(
+    r'deleteEntry',
+    r'(Ljava/lang/String;)V',
   );
 
-  static final _getKey = jni$_.ProtectedJniExtensions.lookup<
+  static final _deleteEntry = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final void deleteEntry(java.lang.String string)`
+  void deleteEntry(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    _deleteEntry(reference.pointer, _id_deleteEntry.pointer, _$string.pointer)
+        .check();
+  }
+
+  static final _id_entryInstanceOf = KeyStore._class.instanceMethodId(
+    r'entryInstanceOf',
+    r'(Ljava/lang/String;Ljava/lang/Class;)Z',
+  );
+
+  static final _entryInstanceOf = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -22098,7 +17777,7 @@
                       (
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
+                      )>)>>('globalEnv_CallBooleanMethod')
       .asFunction<
           jni$_.JniResult Function(
               jni$_.Pointer<jni$_.Void>,
@@ -22106,20 +17785,73 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final java.security.Key getKey(java.lang.String string, char[] cs)`
-  /// The returned object must be released after use, by calling the [release] method.
-  Key? getKey(
+  /// from: `public final boolean entryInstanceOf(java.lang.String string, java.lang.Class<? extends java.security.KeyStore$Entry> class)`
+  core$_.bool entryInstanceOf(
     jni$_.JString? string,
-    jni$_.JCharArray? cs,
+    jni$_.JObject? class$,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    return _getKey(reference.pointer, _id_getKey as jni$_.JMethodIDPtr,
-            _$string.pointer, _$cs.pointer)
-        .object<Key?>(const $Key$NullableType());
+    final _$class$ = class$?.reference ?? jni$_.jNullReference;
+    return _entryInstanceOf(reference.pointer, _id_entryInstanceOf.pointer,
+            _$string.pointer, _$class$.pointer)
+        .boolean;
   }
 
-  static final _id_getCertificateChain = _class.instanceMethodId(
+  static final _id_getCertificate = KeyStore._class.instanceMethodId(
+    r'getCertificate',
+    r'(Ljava/lang/String;)Ljava/security/cert/Certificate;',
+  );
+
+  static final _getCertificate = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final java.security.cert.Certificate getCertificate(java.lang.String string)`
+  /// The returned object must be released after use, by calling the [release] method.
+  Certificate? getCertificate(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _getCertificate(
+            reference.pointer, _id_getCertificate.pointer, _$string.pointer)
+        .object<Certificate?>();
+  }
+
+  static final _id_getCertificateAlias = KeyStore._class.instanceMethodId(
+    r'getCertificateAlias',
+    r'(Ljava/security/cert/Certificate;)Ljava/lang/String;',
+  );
+
+  static final _getCertificateAlias = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final java.lang.String getCertificateAlias(java.security.cert.Certificate certificate)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? getCertificateAlias(
+    Certificate? certificate,
+  ) {
+    final _$certificate = certificate?.reference ?? jni$_.jNullReference;
+    return _getCertificateAlias(reference.pointer,
+            _id_getCertificateAlias.pointer, _$certificate.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_getCertificateChain = KeyStore._class.instanceMethodId(
     r'getCertificateChain',
     r'(Ljava/lang/String;)[Ljava/security/cert/Certificate;',
   );
@@ -22142,40 +17874,11 @@
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     return _getCertificateChain(reference.pointer,
-            _id_getCertificateChain as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<jni$_.JArray<Certificate?>?>(
-            const jni$_.JArrayNullableType<Certificate?>(
-                $Certificate$NullableType()));
+            _id_getCertificateChain.pointer, _$string.pointer)
+        .object<jni$_.JArray<Certificate?>?>();
   }
 
-  static final _id_getCertificate = _class.instanceMethodId(
-    r'getCertificate',
-    r'(Ljava/lang/String;)Ljava/security/cert/Certificate;',
-  );
-
-  static final _getCertificate = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final java.security.cert.Certificate getCertificate(java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  Certificate? getCertificate(
-    jni$_.JString? string,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getCertificate(reference.pointer,
-            _id_getCertificate as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<Certificate?>(const $Certificate$NullableType());
-  }
-
-  static final _id_getCreationDate = _class.instanceMethodId(
+  static final _id_getCreationDate = KeyStore._class.instanceMethodId(
     r'getCreationDate',
     r'(Ljava/lang/String;)Ljava/util/Date;',
   );
@@ -22197,437 +17900,12 @@
     jni$_.JString? string,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getCreationDate(reference.pointer,
-            _id_getCreationDate as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _getCreationDate(
+            reference.pointer, _id_getCreationDate.pointer, _$string.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_setKeyEntry = _class.instanceMethodId(
-    r'setKeyEntry',
-    r'(Ljava/lang/String;Ljava/security/Key;[C[Ljava/security/cert/Certificate;)V',
-  );
-
-  static final _setKeyEntry = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final void setKeyEntry(java.lang.String string, java.security.Key key, char[] cs, java.security.cert.Certificate[] certificates)`
-  void setKeyEntry(
-    jni$_.JString? string,
-    Key? key,
-    jni$_.JCharArray? cs,
-    jni$_.JArray<Certificate?>? certificates,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    final _$key = key?.reference ?? jni$_.jNullReference;
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    final _$certificates = certificates?.reference ?? jni$_.jNullReference;
-    _setKeyEntry(
-            reference.pointer,
-            _id_setKeyEntry as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$key.pointer,
-            _$cs.pointer,
-            _$certificates.pointer)
-        .check();
-  }
-
-  static final _id_setKeyEntry$1 = _class.instanceMethodId(
-    r'setKeyEntry',
-    r'(Ljava/lang/String;[B[Ljava/security/cert/Certificate;)V',
-  );
-
-  static final _setKeyEntry$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final void setKeyEntry(java.lang.String string, byte[] bs, java.security.cert.Certificate[] certificates)`
-  void setKeyEntry$1(
-    jni$_.JString? string,
-    jni$_.JByteArray? bs,
-    jni$_.JArray<Certificate?>? certificates,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    final _$certificates = certificates?.reference ?? jni$_.jNullReference;
-    _setKeyEntry$1(reference.pointer, _id_setKeyEntry$1 as jni$_.JMethodIDPtr,
-            _$string.pointer, _$bs.pointer, _$certificates.pointer)
-        .check();
-  }
-
-  static final _id_setCertificateEntry = _class.instanceMethodId(
-    r'setCertificateEntry',
-    r'(Ljava/lang/String;Ljava/security/cert/Certificate;)V',
-  );
-
-  static final _setCertificateEntry = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final void setCertificateEntry(java.lang.String string, java.security.cert.Certificate certificate)`
-  void setCertificateEntry(
-    jni$_.JString? string,
-    Certificate? certificate,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    final _$certificate = certificate?.reference ?? jni$_.jNullReference;
-    _setCertificateEntry(
-            reference.pointer,
-            _id_setCertificateEntry as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$certificate.pointer)
-        .check();
-  }
-
-  static final _id_deleteEntry = _class.instanceMethodId(
-    r'deleteEntry',
-    r'(Ljava/lang/String;)V',
-  );
-
-  static final _deleteEntry = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final void deleteEntry(java.lang.String string)`
-  void deleteEntry(
-    jni$_.JString? string,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    _deleteEntry(reference.pointer, _id_deleteEntry as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .check();
-  }
-
-  static final _id_aliases = _class.instanceMethodId(
-    r'aliases',
-    r'()Ljava/util/Enumeration;',
-  );
-
-  static final _aliases = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.util.Enumeration aliases()`
-  /// The returned object must be released after use, by calling the [release] method.
-  Enumeration<jni$_.JString?>? aliases() {
-    return _aliases(reference.pointer, _id_aliases as jni$_.JMethodIDPtr)
-        .object<Enumeration<jni$_.JString?>?>(
-            const $Enumeration$NullableType<jni$_.JString?>(
-                jni$_.JStringNullableType()));
-  }
-
-  static final _id_containsAlias = _class.instanceMethodId(
-    r'containsAlias',
-    r'(Ljava/lang/String;)Z',
-  );
-
-  static final _containsAlias = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final boolean containsAlias(java.lang.String string)`
-  bool containsAlias(
-    jni$_.JString? string,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    return _containsAlias(reference.pointer,
-            _id_containsAlias as jni$_.JMethodIDPtr, _$string.pointer)
-        .boolean;
-  }
-
-  static final _id_size = _class.instanceMethodId(
-    r'size',
-    r'()I',
-  );
-
-  static final _size = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final int size()`
-  int size() {
-    return _size(reference.pointer, _id_size as jni$_.JMethodIDPtr).integer;
-  }
-
-  static final _id_isKeyEntry = _class.instanceMethodId(
-    r'isKeyEntry',
-    r'(Ljava/lang/String;)Z',
-  );
-
-  static final _isKeyEntry = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final boolean isKeyEntry(java.lang.String string)`
-  bool isKeyEntry(
-    jni$_.JString? string,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    return _isKeyEntry(reference.pointer, _id_isKeyEntry as jni$_.JMethodIDPtr,
-            _$string.pointer)
-        .boolean;
-  }
-
-  static final _id_isCertificateEntry = _class.instanceMethodId(
-    r'isCertificateEntry',
-    r'(Ljava/lang/String;)Z',
-  );
-
-  static final _isCertificateEntry = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final boolean isCertificateEntry(java.lang.String string)`
-  bool isCertificateEntry(
-    jni$_.JString? string,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    return _isCertificateEntry(reference.pointer,
-            _id_isCertificateEntry as jni$_.JMethodIDPtr, _$string.pointer)
-        .boolean;
-  }
-
-  static final _id_getCertificateAlias = _class.instanceMethodId(
-    r'getCertificateAlias',
-    r'(Ljava/security/cert/Certificate;)Ljava/lang/String;',
-  );
-
-  static final _getCertificateAlias = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final java.lang.String getCertificateAlias(java.security.cert.Certificate certificate)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getCertificateAlias(
-    Certificate? certificate,
-  ) {
-    final _$certificate = certificate?.reference ?? jni$_.jNullReference;
-    return _getCertificateAlias(
-            reference.pointer,
-            _id_getCertificateAlias as jni$_.JMethodIDPtr,
-            _$certificate.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_store = _class.instanceMethodId(
-    r'store',
-    r'(Ljava/io/OutputStream;[C)V',
-  );
-
-  static final _store = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final void store(java.io.OutputStream outputStream, char[] cs)`
-  void store(
-    jni$_.JObject? outputStream,
-    jni$_.JCharArray? cs,
-  ) {
-    final _$outputStream = outputStream?.reference ?? jni$_.jNullReference;
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    _store(reference.pointer, _id_store as jni$_.JMethodIDPtr,
-            _$outputStream.pointer, _$cs.pointer)
-        .check();
-  }
-
-  static final _id_store$1 = _class.instanceMethodId(
-    r'store',
-    r'(Ljava/security/KeyStore$LoadStoreParameter;)V',
-  );
-
-  static final _store$1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final void store(java.security.KeyStore$LoadStoreParameter loadStoreParameter)`
-  void store$1(
-    KeyStore$LoadStoreParameter? loadStoreParameter,
-  ) {
-    final _$loadStoreParameter =
-        loadStoreParameter?.reference ?? jni$_.jNullReference;
-    _store$1(reference.pointer, _id_store$1 as jni$_.JMethodIDPtr,
-            _$loadStoreParameter.pointer)
-        .check();
-  }
-
-  static final _id_load = _class.instanceMethodId(
-    r'load',
-    r'(Ljava/io/InputStream;[C)V',
-  );
-
-  static final _load = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final void load(java.io.InputStream inputStream, char[] cs)`
-  void load(
-    jni$_.JObject? inputStream,
-    jni$_.JCharArray? cs,
-  ) {
-    final _$inputStream = inputStream?.reference ?? jni$_.jNullReference;
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    _load(reference.pointer, _id_load as jni$_.JMethodIDPtr,
-            _$inputStream.pointer, _$cs.pointer)
-        .check();
-  }
-
-  static final _id_load$1 = _class.instanceMethodId(
-    r'load',
-    r'(Ljava/security/KeyStore$LoadStoreParameter;)V',
-  );
-
-  static final _load$1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public final void load(java.security.KeyStore$LoadStoreParameter loadStoreParameter)`
-  void load$1(
-    KeyStore$LoadStoreParameter? loadStoreParameter,
-  ) {
-    final _$loadStoreParameter =
-        loadStoreParameter?.reference ?? jni$_.jNullReference;
-    _load$1(reference.pointer, _id_load$1 as jni$_.JMethodIDPtr,
-            _$loadStoreParameter.pointer)
-        .check();
-  }
-
-  static final _id_getEntry = _class.instanceMethodId(
+  static final _id_getEntry = KeyStore._class.instanceMethodId(
     r'getEntry',
     r'(Ljava/lang/String;Ljava/security/KeyStore$ProtectionParameter;)Ljava/security/KeyStore$Entry;',
   );
@@ -22658,12 +17936,241 @@
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$protectionParameter =
         protectionParameter?.reference ?? jni$_.jNullReference;
-    return _getEntry(reference.pointer, _id_getEntry as jni$_.JMethodIDPtr,
-            _$string.pointer, _$protectionParameter.pointer)
-        .object<KeyStore$Entry?>(const $KeyStore$Entry$NullableType());
+    return _getEntry(reference.pointer, _id_getEntry.pointer, _$string.pointer,
+            _$protectionParameter.pointer)
+        .object<KeyStore$Entry?>();
   }
 
-  static final _id_setEntry = _class.instanceMethodId(
+  static final _id_getKey = KeyStore._class.instanceMethodId(
+    r'getKey',
+    r'(Ljava/lang/String;[C)Ljava/security/Key;',
+  );
+
+  static final _getKey = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final java.security.Key getKey(java.lang.String string, char[] cs)`
+  /// The returned object must be released after use, by calling the [release] method.
+  Key? getKey(
+    jni$_.JString? string,
+    jni$_.JCharArray? cs,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    return _getKey(reference.pointer, _id_getKey.pointer, _$string.pointer,
+            _$cs.pointer)
+        .object<Key?>();
+  }
+
+  static final _id_get$provider = KeyStore._class.instanceMethodId(
+    r'getProvider',
+    r'()Ljava/security/Provider;',
+  );
+
+  static final _get$provider = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.security.Provider getProvider()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get provider {
+    return _get$provider(reference.pointer, _id_get$provider.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_get$type$1 = KeyStore._class.instanceMethodId(
+    r'getType',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _get$type$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.lang.String getType()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? get type$1 {
+    return _get$type$1(reference.pointer, _id_get$type$1.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_isCertificateEntry = KeyStore._class.instanceMethodId(
+    r'isCertificateEntry',
+    r'(Ljava/lang/String;)Z',
+  );
+
+  static final _isCertificateEntry = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final boolean isCertificateEntry(java.lang.String string)`
+  core$_.bool isCertificateEntry(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _isCertificateEntry(
+            reference.pointer, _id_isCertificateEntry.pointer, _$string.pointer)
+        .boolean;
+  }
+
+  static final _id_isKeyEntry = KeyStore._class.instanceMethodId(
+    r'isKeyEntry',
+    r'(Ljava/lang/String;)Z',
+  );
+
+  static final _isKeyEntry = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final boolean isKeyEntry(java.lang.String string)`
+  core$_.bool isKeyEntry(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _isKeyEntry(
+            reference.pointer, _id_isKeyEntry.pointer, _$string.pointer)
+        .boolean;
+  }
+
+  static final _id_load = KeyStore._class.instanceMethodId(
+    r'load',
+    r'(Ljava/io/InputStream;[C)V',
+  );
+
+  static final _load = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final void load(java.io.InputStream inputStream, char[] cs)`
+  void load(
+    jni$_.JObject? inputStream,
+    jni$_.JCharArray? cs,
+  ) {
+    final _$inputStream = inputStream?.reference ?? jni$_.jNullReference;
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    _load(reference.pointer, _id_load.pointer, _$inputStream.pointer,
+            _$cs.pointer)
+        .check();
+  }
+
+  static final _id_load$1 = KeyStore._class.instanceMethodId(
+    r'load',
+    r'(Ljava/security/KeyStore$LoadStoreParameter;)V',
+  );
+
+  static final _load$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final void load(java.security.KeyStore$LoadStoreParameter loadStoreParameter)`
+  void load$1(
+    KeyStore$LoadStoreParameter? loadStoreParameter,
+  ) {
+    final _$loadStoreParameter =
+        loadStoreParameter?.reference ?? jni$_.jNullReference;
+    _load$1(reference.pointer, _id_load$1.pointer, _$loadStoreParameter.pointer)
+        .check();
+  }
+
+  static final _id_setCertificateEntry = KeyStore._class.instanceMethodId(
+    r'setCertificateEntry',
+    r'(Ljava/lang/String;Ljava/security/cert/Certificate;)V',
+  );
+
+  static final _setCertificateEntry = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final void setCertificateEntry(java.lang.String string, java.security.cert.Certificate certificate)`
+  void setCertificateEntry(
+    jni$_.JString? string,
+    Certificate? certificate,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$certificate = certificate?.reference ?? jni$_.jNullReference;
+    _setCertificateEntry(reference.pointer, _id_setCertificateEntry.pointer,
+            _$string.pointer, _$certificate.pointer)
+        .check();
+  }
+
+  static final _id_setEntry = KeyStore._class.instanceMethodId(
     r'setEntry',
     r'(Ljava/lang/String;Ljava/security/KeyStore$Entry;Ljava/security/KeyStore$ProtectionParameter;)V',
   );
@@ -22697,219 +18204,200 @@
     final _$entry = entry?.reference ?? jni$_.jNullReference;
     final _$protectionParameter =
         protectionParameter?.reference ?? jni$_.jNullReference;
-    _setEntry(reference.pointer, _id_setEntry as jni$_.JMethodIDPtr,
-            _$string.pointer, _$entry.pointer, _$protectionParameter.pointer)
+    _setEntry(reference.pointer, _id_setEntry.pointer, _$string.pointer,
+            _$entry.pointer, _$protectionParameter.pointer)
         .check();
   }
 
-  static final _id_entryInstanceOf = _class.instanceMethodId(
-    r'entryInstanceOf',
-    r'(Ljava/lang/String;Ljava/lang/Class;)Z',
+  static final _id_setKeyEntry = KeyStore._class.instanceMethodId(
+    r'setKeyEntry',
+    r'(Ljava/lang/String;[B[Ljava/security/cert/Certificate;)V',
   );
 
-  static final _entryInstanceOf = jni$_.ProtectedJniExtensions.lookup<
+  static final _setKeyEntry = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
-              jni$_.JniResult Function(
+              jni$_.JThrowablePtr Function(
                   jni$_.Pointer<jni$_.Void>,
                   jni$_.JMethodIDPtr,
                   jni$_.VarArgs<
                       (
                         jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
                         jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallBooleanMethod')
+                      )>)>>('globalEnv_CallVoidMethod')
       .asFunction<
-          jni$_.JniResult Function(
+          jni$_.JThrowablePtr Function(
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public final boolean entryInstanceOf(java.lang.String string, java.lang.Class class)`
-  bool entryInstanceOf(
+  /// from: `public final void setKeyEntry(java.lang.String string, byte[] bs, java.security.cert.Certificate[] certificates)`
+  void setKeyEntry(
     jni$_.JString? string,
-    jni$_.JObject? class$,
+    jni$_.JByteArray? bs,
+    jni$_.JArray<Certificate?>? certificates,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
-    final _$class$ = class$?.reference ?? jni$_.jNullReference;
-    return _entryInstanceOf(
-            reference.pointer,
-            _id_entryInstanceOf as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$class$.pointer)
-        .boolean;
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    final _$certificates = certificates?.reference ?? jni$_.jNullReference;
+    _setKeyEntry(reference.pointer, _id_setKeyEntry.pointer, _$string.pointer,
+            _$bs.pointer, _$certificates.pointer)
+        .check();
   }
 
-  static final _id_getInstance$3 = _class.staticMethodId(
-    r'getInstance',
-    r'(Ljava/io/File;[C)Ljava/security/KeyStore;',
+  static final _id_setKeyEntry$1 = KeyStore._class.instanceMethodId(
+    r'setKeyEntry',
+    r'(Ljava/lang/String;Ljava/security/Key;[C[Ljava/security/cert/Certificate;)V',
   );
 
-  static final _getInstance$3 = jni$_.ProtectedJniExtensions.lookup<
+  static final _setKeyEntry$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final void setKeyEntry(java.lang.String string, java.security.Key key, char[] cs, java.security.cert.Certificate[] certificates)`
+  void setKeyEntry$1(
+    jni$_.JString? string,
+    Key? key,
+    jni$_.JCharArray? cs,
+    jni$_.JArray<Certificate?>? certificates,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$key = key?.reference ?? jni$_.jNullReference;
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    final _$certificates = certificates?.reference ?? jni$_.jNullReference;
+    _setKeyEntry$1(
+            reference.pointer,
+            _id_setKeyEntry$1.pointer,
+            _$string.pointer,
+            _$key.pointer,
+            _$cs.pointer,
+            _$certificates.pointer)
+        .check();
+  }
+
+  static final _id_size = KeyStore._class.instanceMethodId(
+    r'size',
+    r'()I',
+  );
+
+  static final _size = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final int size()`
+  core$_.int size() {
+    return _size(reference.pointer, _id_size.pointer).integer;
+  }
+
+  static final _id_store = KeyStore._class.instanceMethodId(
+    r'store',
+    r'(Ljava/io/OutputStream;[C)V',
+  );
+
+  static final _store = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
                   jni$_.Pointer<jni$_.Void>,
                   jni$_.JMethodIDPtr,
                   jni$_.VarArgs<
                       (
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticObjectMethod')
+                      )>)>>('globalEnv_CallVoidMethod')
       .asFunction<
-          jni$_.JniResult Function(
+          jni$_.JThrowablePtr Function(
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public final java.security.KeyStore getInstance(java.io.File file, char[] cs)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static KeyStore? getInstance$3(
-    jni$_.JObject? file,
+  /// from: `public final void store(java.io.OutputStream outputStream, char[] cs)`
+  void store(
+    jni$_.JObject? outputStream,
     jni$_.JCharArray? cs,
   ) {
-    final _$file = file?.reference ?? jni$_.jNullReference;
+    final _$outputStream = outputStream?.reference ?? jni$_.jNullReference;
     final _$cs = cs?.reference ?? jni$_.jNullReference;
-    return _getInstance$3(
-            _class.reference.pointer,
-            _id_getInstance$3 as jni$_.JMethodIDPtr,
-            _$file.pointer,
+    _store(reference.pointer, _id_store.pointer, _$outputStream.pointer,
             _$cs.pointer)
-        .object<KeyStore?>(const $KeyStore$NullableType());
+        .check();
   }
 
-  static final _id_getInstance$4 = _class.staticMethodId(
-    r'getInstance',
-    r'(Ljava/io/File;Ljava/security/KeyStore$LoadStoreParameter;)Ljava/security/KeyStore;',
+  static final _id_store$1 = KeyStore._class.instanceMethodId(
+    r'store',
+    r'(Ljava/security/KeyStore$LoadStoreParameter;)V',
   );
 
-  static final _getInstance$4 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticObjectMethod')
+  static final _store$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
       .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public final java.security.KeyStore getInstance(java.io.File file, java.security.KeyStore$LoadStoreParameter loadStoreParameter)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static KeyStore? getInstance$4(
-    jni$_.JObject? file,
+  /// from: `public final void store(java.security.KeyStore$LoadStoreParameter loadStoreParameter)`
+  void store$1(
     KeyStore$LoadStoreParameter? loadStoreParameter,
   ) {
-    final _$file = file?.reference ?? jni$_.jNullReference;
     final _$loadStoreParameter =
         loadStoreParameter?.reference ?? jni$_.jNullReference;
-    return _getInstance$4(
-            _class.reference.pointer,
-            _id_getInstance$4 as jni$_.JMethodIDPtr,
-            _$file.pointer,
+    _store$1(reference.pointer, _id_store$1.pointer,
             _$loadStoreParameter.pointer)
-        .object<KeyStore?>(const $KeyStore$NullableType());
+        .check();
   }
 }
 
-final class $KeyStore$NullableType extends jni$_.JObjType<KeyStore?> {
+final class $KeyStore$Type$ extends jni$_.JType<KeyStore> {
   @jni$_.internal
-  const $KeyStore$NullableType();
+  const $KeyStore$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyStore;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : KeyStore.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$NullableType) &&
-        other is $KeyStore$NullableType;
-  }
-}
-
-final class $KeyStore$Type extends jni$_.JObjType<KeyStore> {
-  @jni$_.internal
-  const $KeyStore$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyStore;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyStore fromReference(jni$_.JReference reference) => KeyStore.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyStore?> get nullableType => const $KeyStore$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyStore$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyStore$Type) && other is $KeyStore$Type;
-  }
 }
 
 /// from: `javax.net.ssl.KeyManager`
-class KeyManager extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyManager> $type;
-
-  @jni$_.internal
-  KeyManager.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyManager._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'javax/net/ssl/KeyManager');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyManager$NullableType();
-  static const type = $KeyManager$Type();
+  static const jni$_.JType<KeyManager> type = $KeyManager$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $KeyManager> _$impls = {};
+  static final core$_.Map<core$_.int, $KeyManager> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -22930,7 +18418,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -22972,9 +18460,7 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return KeyManager.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<KeyManager>();
   }
 }
 
@@ -22986,96 +18472,21 @@
   _$KeyManager();
 }
 
-final class $KeyManager$NullableType extends jni$_.JObjType<KeyManager?> {
+final class $KeyManager$Type$ extends jni$_.JType<KeyManager> {
   @jni$_.internal
-  const $KeyManager$NullableType();
+  const $KeyManager$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljavax/net/ssl/KeyManager;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyManager? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : KeyManager.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyManager?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyManager$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyManager$NullableType) &&
-        other is $KeyManager$NullableType;
-  }
-}
-
-final class $KeyManager$Type extends jni$_.JObjType<KeyManager> {
-  @jni$_.internal
-  const $KeyManager$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/ssl/KeyManager;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyManager fromReference(jni$_.JReference reference) =>
-      KeyManager.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyManager?> get nullableType =>
-      const $KeyManager$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyManager$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyManager$Type) && other is $KeyManager$Type;
-  }
 }
 
 /// from: `java.security.SecureRandom`
-class SecureRandom extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<SecureRandom> $type;
-
-  @jni$_.internal
-  SecureRandom.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type SecureRandom._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'java/security/SecureRandom');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $SecureRandom$NullableType();
-  static const type = $SecureRandom$Type();
+  static const jni$_.JType<SecureRandom> type = $SecureRandom$Type$();
   static final _id_new$ = _class.constructorId(
     r'()V',
   );
@@ -23095,9 +18506,8 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory SecureRandom() {
-    return SecureRandom.fromReference(
-        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
-            .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer)
+        .object<SecureRandom>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -23121,9 +18531,8 @@
     jni$_.JByteArray? bs,
   ) {
     final _$bs = bs?.reference ?? jni$_.jNullReference;
-    return SecureRandom.fromReference(_new$1(_class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr, _$bs.pointer)
-        .reference);
+    return _new$1(_class.reference.pointer, _id_new$1.pointer, _$bs.pointer)
+        .object<SecureRandom>();
   }
 
   static final _id_getInstance = _class.staticMethodId(
@@ -23148,9 +18557,9 @@
     jni$_.JString? string,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getInstance(_class.reference.pointer,
-            _id_getInstance as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<SecureRandom?>(const $SecureRandom$NullableType());
+    return _getInstance(
+            _class.reference.pointer, _id_getInstance.pointer, _$string.pointer)
+        .object<SecureRandom?>();
   }
 
   static final _id_getInstance$1 = _class.staticMethodId(
@@ -23183,12 +18592,9 @@
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$string1 = string1?.reference ?? jni$_.jNullReference;
-    return _getInstance$1(
-            _class.reference.pointer,
-            _id_getInstance$1 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$string1.pointer)
-        .object<SecureRandom?>(const $SecureRandom$NullableType());
+    return _getInstance$1(_class.reference.pointer, _id_getInstance$1.pointer,
+            _$string.pointer, _$string1.pointer)
+        .object<SecureRandom?>();
   }
 
   static final _id_getInstance$2 = _class.staticMethodId(
@@ -23221,12 +18627,9 @@
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$provider = provider?.reference ?? jni$_.jNullReference;
-    return _getInstance$2(
-            _class.reference.pointer,
-            _id_getInstance$2 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$provider.pointer)
-        .object<SecureRandom?>(const $SecureRandom$NullableType());
+    return _getInstance$2(_class.reference.pointer, _id_getInstance$2.pointer,
+            _$string.pointer, _$provider.pointer)
+        .object<SecureRandom?>();
   }
 
   static final _id_getInstance$3 = _class.staticMethodId(
@@ -23260,12 +18663,9 @@
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$secureRandomParameters =
         secureRandomParameters?.reference ?? jni$_.jNullReference;
-    return _getInstance$3(
-            _class.reference.pointer,
-            _id_getInstance$3 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$secureRandomParameters.pointer)
-        .object<SecureRandom?>(const $SecureRandom$NullableType());
+    return _getInstance$3(_class.reference.pointer, _id_getInstance$3.pointer,
+            _$string.pointer, _$secureRandomParameters.pointer)
+        .object<SecureRandom?>();
   }
 
   static final _id_getInstance$4 = _class.staticMethodId(
@@ -23305,11 +18705,11 @@
     final _$string1 = string1?.reference ?? jni$_.jNullReference;
     return _getInstance$4(
             _class.reference.pointer,
-            _id_getInstance$4 as jni$_.JMethodIDPtr,
+            _id_getInstance$4.pointer,
             _$string.pointer,
             _$secureRandomParameters.pointer,
             _$string1.pointer)
-        .object<SecureRandom?>(const $SecureRandom$NullableType());
+        .object<SecureRandom?>();
   }
 
   static final _id_getInstance$5 = _class.staticMethodId(
@@ -23349,44 +18749,93 @@
     final _$provider = provider?.reference ?? jni$_.jNullReference;
     return _getInstance$5(
             _class.reference.pointer,
-            _id_getInstance$5 as jni$_.JMethodIDPtr,
+            _id_getInstance$5.pointer,
             _$string.pointer,
             _$secureRandomParameters.pointer,
             _$provider.pointer)
-        .object<SecureRandom?>(const $SecureRandom$NullableType());
+        .object<SecureRandom?>();
   }
 
-  static final _id_getProvider = _class.instanceMethodId(
-    r'getProvider',
-    r'()Ljava/security/Provider;',
+  static final _id_get$instanceStrong = _class.staticMethodId(
+    r'getInstanceStrong',
+    r'()Ljava/security/SecureRandom;',
   );
 
-  static final _getProvider = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$instanceStrong = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
                 jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
+              )>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
           jni$_.JniResult Function(
             jni$_.Pointer<jni$_.Void>,
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final java.security.Provider getProvider()`
+  /// from: `static public java.security.SecureRandom getInstanceStrong()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getProvider() {
-    return _getProvider(
-            reference.pointer, _id_getProvider as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  static SecureRandom? get instanceStrong {
+    return _get$instanceStrong(
+            _class.reference.pointer, _id_get$instanceStrong.pointer)
+        .object<SecureRandom?>();
   }
 
-  static final _id_getAlgorithm = _class.instanceMethodId(
+  static final _id_getSeed = _class.staticMethodId(
+    r'getSeed',
+    r'(I)[B',
+  );
+
+  static final _getSeed = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Int32,)>)>>(
+          'globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `static public byte[] getSeed(int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JByteArray? getSeed(
+    core$_.int i,
+  ) {
+    return _getSeed(_class.reference.pointer, _id_getSeed.pointer, i)
+        .object<jni$_.JByteArray?>();
+  }
+}
+
+extension SecureRandom$$Methods on SecureRandom {
+  static final _id_generateSeed = SecureRandom._class.instanceMethodId(
+    r'generateSeed',
+    r'(I)[B',
+  );
+
+  static final _generateSeed = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public byte[] generateSeed(int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JByteArray? generateSeed(
+    core$_.int i,
+  ) {
+    return _generateSeed(reference.pointer, _id_generateSeed.pointer, i)
+        .object<jni$_.JByteArray?>();
+  }
+
+  static final _id_get$algorithm = SecureRandom._class.instanceMethodId(
     r'getAlgorithm',
     r'()Ljava/lang/String;',
   );
 
-  static final _getAlgorithm = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$algorithm = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -23400,42 +18849,17 @@
 
   /// from: `public java.lang.String getAlgorithm()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getAlgorithm() {
-    return _getAlgorithm(
-            reference.pointer, _id_getAlgorithm as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+  jni$_.JString? get algorithm {
+    return _get$algorithm(reference.pointer, _id_get$algorithm.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_toString$1 = _class.instanceMethodId(
-    r'toString',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _toString$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.lang.String toString()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? toString$1() {
-    return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getParameters = _class.instanceMethodId(
+  static final _id_get$parameters = SecureRandom._class.instanceMethodId(
     r'getParameters',
     r'()Ljava/security/SecureRandomParameters;',
   );
 
-  static final _getParameters = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$parameters = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -23449,61 +18873,36 @@
 
   /// from: `public java.security.SecureRandomParameters getParameters()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getParameters() {
-    return _getParameters(
-            reference.pointer, _id_getParameters as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  jni$_.JObject? get parameters {
+    return _get$parameters(reference.pointer, _id_get$parameters.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_setSeed = _class.instanceMethodId(
-    r'setSeed',
-    r'([B)V',
+  static final _id_get$provider = SecureRandom._class.instanceMethodId(
+    r'getProvider',
+    r'()Ljava/security/Provider;',
   );
 
-  static final _setSeed = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public void setSeed(byte[] bs)`
-  void setSeed(
-    jni$_.JByteArray? bs,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    _setSeed(reference.pointer, _id_setSeed as jni$_.JMethodIDPtr, _$bs.pointer)
-        .check();
-  }
-
-  static final _id_setSeed$1 = _class.instanceMethodId(
-    r'setSeed',
-    r'(J)V',
-  );
-
-  static final _setSeed$1 = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$provider = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallVoidMethod')
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
       .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
 
-  /// from: `public void setSeed(long j)`
-  void setSeed$1(
-    int j,
-  ) {
-    _setSeed$1(reference.pointer, _id_setSeed$1 as jni$_.JMethodIDPtr, j)
-        .check();
+  /// from: `public final java.security.Provider getProvider()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get provider {
+    return _get$provider(reference.pointer, _id_get$provider.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_nextBytes = _class.instanceMethodId(
+  static final _id_nextBytes = SecureRandom._class.instanceMethodId(
     r'nextBytes',
     r'([B)V',
   );
@@ -23524,12 +18923,10 @@
     jni$_.JByteArray? bs,
   ) {
     final _$bs = bs?.reference ?? jni$_.jNullReference;
-    _nextBytes(reference.pointer, _id_nextBytes as jni$_.JMethodIDPtr,
-            _$bs.pointer)
-        .check();
+    _nextBytes(reference.pointer, _id_nextBytes.pointer, _$bs.pointer).check();
   }
 
-  static final _id_nextBytes$1 = _class.instanceMethodId(
+  static final _id_nextBytes$1 = SecureRandom._class.instanceMethodId(
     r'nextBytes',
     r'([BLjava/security/SecureRandomParameters;)V',
   );
@@ -23559,86 +18956,12 @@
     final _$bs = bs?.reference ?? jni$_.jNullReference;
     final _$secureRandomParameters =
         secureRandomParameters?.reference ?? jni$_.jNullReference;
-    _nextBytes$1(reference.pointer, _id_nextBytes$1 as jni$_.JMethodIDPtr,
-            _$bs.pointer, _$secureRandomParameters.pointer)
+    _nextBytes$1(reference.pointer, _id_nextBytes$1.pointer, _$bs.pointer,
+            _$secureRandomParameters.pointer)
         .check();
   }
 
-  static final _id_getSeed = _class.staticMethodId(
-    r'getSeed',
-    r'(I)[B',
-  );
-
-  static final _getSeed = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr, jni$_.VarArgs<(jni$_.Int32,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `static public byte[] getSeed(int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JByteArray? getSeed(
-    int i,
-  ) {
-    return _getSeed(
-            _class.reference.pointer, _id_getSeed as jni$_.JMethodIDPtr, i)
-        .object<jni$_.JByteArray?>(const jni$_.JByteArrayNullableType());
-  }
-
-  static final _id_generateSeed = _class.instanceMethodId(
-    r'generateSeed',
-    r'(I)[B',
-  );
-
-  static final _generateSeed = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public byte[] generateSeed(int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JByteArray? generateSeed(
-    int i,
-  ) {
-    return _generateSeed(
-            reference.pointer, _id_generateSeed as jni$_.JMethodIDPtr, i)
-        .object<jni$_.JByteArray?>(const jni$_.JByteArrayNullableType());
-  }
-
-  static final _id_getInstanceStrong = _class.staticMethodId(
-    r'getInstanceStrong',
-    r'()Ljava/security/SecureRandom;',
-  );
-
-  static final _getInstanceStrong = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `static public java.security.SecureRandom getInstanceStrong()`
-  /// The returned object must be released after use, by calling the [release] method.
-  static SecureRandom? getInstanceStrong() {
-    return _getInstanceStrong(_class.reference.pointer,
-            _id_getInstanceStrong as jni$_.JMethodIDPtr)
-        .object<SecureRandom?>(const $SecureRandom$NullableType());
-  }
-
-  static final _id_reseed = _class.instanceMethodId(
+  static final _id_reseed = SecureRandom._class.instanceMethodId(
     r'reseed',
     r'()V',
   );
@@ -23657,10 +18980,10 @@
 
   /// from: `public void reseed()`
   void reseed() {
-    _reseed(reference.pointer, _id_reseed as jni$_.JMethodIDPtr).check();
+    _reseed(reference.pointer, _id_reseed.pointer).check();
   }
 
-  static final _id_reseed$1 = _class.instanceMethodId(
+  static final _id_reseed$1 = SecureRandom._class.instanceMethodId(
     r'reseed',
     r'(Ljava/security/SecureRandomParameters;)V',
   );
@@ -23682,329 +19005,99 @@
   ) {
     final _$secureRandomParameters =
         secureRandomParameters?.reference ?? jni$_.jNullReference;
-    _reseed$1(reference.pointer, _id_reseed$1 as jni$_.JMethodIDPtr,
+    _reseed$1(reference.pointer, _id_reseed$1.pointer,
             _$secureRandomParameters.pointer)
         .check();
   }
+
+  static final _id_set$seed = SecureRandom._class.instanceMethodId(
+    r'setSeed',
+    r'([B)V',
+  );
+
+  static final _set$seed = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void setSeed(byte[] bs)`
+  set seed(jni$_.JByteArray? bs) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    _set$seed(reference.pointer, _id_set$seed.pointer, _$bs.pointer).check();
+  }
+
+  static final _id_set$seed$1 = SecureRandom._class.instanceMethodId(
+    r'setSeed',
+    r'(J)V',
+  );
+
+  static final _set$seed$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public void setSeed(long j)`
+  set seed$1(core$_.int j) {
+    _set$seed$1(reference.pointer, _id_set$seed$1.pointer, j).check();
+  }
+
+  static final _id_toString$1 = SecureRandom._class.instanceMethodId(
+    r'toString',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _toString$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.lang.String toString()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? toString$1() {
+    return _toString$1(reference.pointer, _id_toString$1.pointer)
+        .object<jni$_.JString?>();
+  }
 }
 
-final class $SecureRandom$NullableType extends jni$_.JObjType<SecureRandom?> {
+final class $SecureRandom$Type$ extends jni$_.JType<SecureRandom> {
   @jni$_.internal
-  const $SecureRandom$NullableType();
+  const $SecureRandom$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/SecureRandom;';
-
-  @jni$_.internal
-  @core$_.override
-  SecureRandom? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : SecureRandom.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<SecureRandom?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($SecureRandom$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($SecureRandom$NullableType) &&
-        other is $SecureRandom$NullableType;
-  }
-}
-
-final class $SecureRandom$Type extends jni$_.JObjType<SecureRandom> {
-  @jni$_.internal
-  const $SecureRandom$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/SecureRandom;';
-
-  @jni$_.internal
-  @core$_.override
-  SecureRandom fromReference(jni$_.JReference reference) =>
-      SecureRandom.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<SecureRandom?> get nullableType =>
-      const $SecureRandom$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($SecureRandom$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($SecureRandom$Type) &&
-        other is $SecureRandom$Type;
-  }
 }
 
 /// from: `javax.net.ssl.X509KeyManager`
-class X509KeyManager extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<X509KeyManager> $type;
-
-  @jni$_.internal
-  X509KeyManager.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type X509KeyManager._(jni$_.JObject _$this)
+    implements jni$_.JObject, KeyManager {
   static final _class = jni$_.JClass.forName(r'javax/net/ssl/X509KeyManager');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $X509KeyManager$NullableType();
-  static const type = $X509KeyManager$Type();
-  static final _id_getClientAliases = _class.instanceMethodId(
-    r'getClientAliases',
-    r'(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;',
-  );
-
-  static final _getClientAliases = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.lang.String[] getClientAliases(java.lang.String string, java.security.Principal[] principals)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JArray<jni$_.JString?>? getClientAliases(
-    jni$_.JString? string,
-    jni$_.JArray<jni$_.JObject?>? principals,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    final _$principals = principals?.reference ?? jni$_.jNullReference;
-    return _getClientAliases(
-            reference.pointer,
-            _id_getClientAliases as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$principals.pointer)
-        .object<jni$_.JArray<jni$_.JString?>?>(
-            const jni$_.JArrayNullableType<jni$_.JString?>(
-                jni$_.JStringNullableType()));
-  }
-
-  static final _id_chooseClientAlias = _class.instanceMethodId(
-    r'chooseClientAlias',
-    r'([Ljava/lang/String;[Ljava/security/Principal;Ljava/net/Socket;)Ljava/lang/String;',
-  );
-
-  static final _chooseClientAlias = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.lang.String chooseClientAlias(java.lang.String[] strings, java.security.Principal[] principals, java.net.Socket socket)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? chooseClientAlias(
-    jni$_.JArray<jni$_.JString?>? strings,
-    jni$_.JArray<jni$_.JObject?>? principals,
-    jni$_.JObject? socket,
-  ) {
-    final _$strings = strings?.reference ?? jni$_.jNullReference;
-    final _$principals = principals?.reference ?? jni$_.jNullReference;
-    final _$socket = socket?.reference ?? jni$_.jNullReference;
-    return _chooseClientAlias(
-            reference.pointer,
-            _id_chooseClientAlias as jni$_.JMethodIDPtr,
-            _$strings.pointer,
-            _$principals.pointer,
-            _$socket.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getServerAliases = _class.instanceMethodId(
-    r'getServerAliases',
-    r'(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;',
-  );
-
-  static final _getServerAliases = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.lang.String[] getServerAliases(java.lang.String string, java.security.Principal[] principals)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JArray<jni$_.JString?>? getServerAliases(
-    jni$_.JString? string,
-    jni$_.JArray<jni$_.JObject?>? principals,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    final _$principals = principals?.reference ?? jni$_.jNullReference;
-    return _getServerAliases(
-            reference.pointer,
-            _id_getServerAliases as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$principals.pointer)
-        .object<jni$_.JArray<jni$_.JString?>?>(
-            const jni$_.JArrayNullableType<jni$_.JString?>(
-                jni$_.JStringNullableType()));
-  }
-
-  static final _id_chooseServerAlias = _class.instanceMethodId(
-    r'chooseServerAlias',
-    r'(Ljava/lang/String;[Ljava/security/Principal;Ljava/net/Socket;)Ljava/lang/String;',
-  );
-
-  static final _chooseServerAlias = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.lang.String chooseServerAlias(java.lang.String string, java.security.Principal[] principals, java.net.Socket socket)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? chooseServerAlias(
-    jni$_.JString? string,
-    jni$_.JArray<jni$_.JObject?>? principals,
-    jni$_.JObject? socket,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    final _$principals = principals?.reference ?? jni$_.jNullReference;
-    final _$socket = socket?.reference ?? jni$_.jNullReference;
-    return _chooseServerAlias(
-            reference.pointer,
-            _id_chooseServerAlias as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$principals.pointer,
-            _$socket.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getCertificateChain = _class.instanceMethodId(
-    r'getCertificateChain',
-    r'(Ljava/lang/String;)[Ljava/security/cert/X509Certificate;',
-  );
-
-  static final _getCertificateChain = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.security.cert.X509Certificate[] getCertificateChain(java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JArray<X509Certificate?>? getCertificateChain(
-    jni$_.JString? string,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getCertificateChain(reference.pointer,
-            _id_getCertificateChain as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<jni$_.JArray<X509Certificate?>?>(
-            const jni$_.JArrayNullableType<X509Certificate?>(
-                $X509Certificate$NullableType()));
-  }
-
-  static final _id_getPrivateKey = _class.instanceMethodId(
-    r'getPrivateKey',
-    r'(Ljava/lang/String;)Ljava/security/PrivateKey;',
-  );
-
-  static final _getPrivateKey = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract java.security.PrivateKey getPrivateKey(java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  PrivateKey? getPrivateKey(
-    jni$_.JString? string,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getPrivateKey(reference.pointer,
-            _id_getPrivateKey as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<PrivateKey?>(const $PrivateKey$NullableType());
-  }
+  static const jni$_.JType<X509KeyManager> type = $X509KeyManager$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $X509KeyManager> _$impls = {};
+  static final core$_.Map<core$_.int, $X509KeyManager> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -24025,57 +19118,21 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
       final $d = $i.methodDescriptor.toDartString(releaseOriginal: true);
       final $a = $i.args;
       if ($d ==
-          r'getClientAliases(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;') {
-        final $r = _$impls[$p]!.getClientAliases(
-          $a![0]?.as(const jni$_.JStringType(), releaseOriginal: true),
-          $a![1]?.as(
-              const jni$_.JArrayType<jni$_.JObject?>(
-                  jni$_.JObjectNullableType()),
-              releaseOriginal: true),
-        );
-        return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
-                .reference
-                .toPointer() ??
-            jni$_.nullptr;
-      }
-      if ($d ==
           r'chooseClientAlias([Ljava/lang/String;[Ljava/security/Principal;Ljava/net/Socket;)Ljava/lang/String;') {
         final $r = _$impls[$p]!.chooseClientAlias(
-          $a![0]?.as(
-              const jni$_.JArrayType<jni$_.JString?>(
-                  jni$_.JStringNullableType()),
-              releaseOriginal: true),
-          $a![1]?.as(
-              const jni$_.JArrayType<jni$_.JObject?>(
-                  jni$_.JObjectNullableType()),
-              releaseOriginal: true),
-          $a![2]?.as(const jni$_.JObjectType(), releaseOriginal: true),
+          ($a![0] as jni$_.JArray<jni$_.JString?>?),
+          ($a![1] as jni$_.JArray<jni$_.JObject?>?),
+          ($a![2] as jni$_.JObject?),
         );
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
-                .reference
-                .toPointer() ??
-            jni$_.nullptr;
-      }
-      if ($d ==
-          r'getServerAliases(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;') {
-        final $r = _$impls[$p]!.getServerAliases(
-          $a![0]?.as(const jni$_.JStringType(), releaseOriginal: true),
-          $a![1]?.as(
-              const jni$_.JArrayType<jni$_.JObject?>(
-                  jni$_.JObjectNullableType()),
-              releaseOriginal: true),
-        );
-        return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -24083,15 +19140,12 @@
       if ($d ==
           r'chooseServerAlias(Ljava/lang/String;[Ljava/security/Principal;Ljava/net/Socket;)Ljava/lang/String;') {
         final $r = _$impls[$p]!.chooseServerAlias(
-          $a![0]?.as(const jni$_.JStringType(), releaseOriginal: true),
-          $a![1]?.as(
-              const jni$_.JArrayType<jni$_.JObject?>(
-                  jni$_.JObjectNullableType()),
-              releaseOriginal: true),
-          $a![2]?.as(const jni$_.JObjectType(), releaseOriginal: true),
+          ($a![0] as jni$_.JString?),
+          ($a![1] as jni$_.JArray<jni$_.JObject?>?),
+          ($a![2] as jni$_.JObject?),
         );
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -24099,10 +19153,22 @@
       if ($d ==
           r'getCertificateChain(Ljava/lang/String;)[Ljava/security/cert/X509Certificate;') {
         final $r = _$impls[$p]!.getCertificateChain(
-          $a![0]?.as(const jni$_.JStringType(), releaseOriginal: true),
+          ($a![0] as jni$_.JString?),
         );
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
+      if ($d ==
+          r'getClientAliases(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;') {
+        final $r = _$impls[$p]!.getClientAliases(
+          ($a![0] as jni$_.JString?),
+          ($a![1] as jni$_.JArray<jni$_.JObject?>?),
+        );
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -24110,10 +19176,22 @@
       if ($d ==
           r'getPrivateKey(Ljava/lang/String;)Ljava/security/PrivateKey;') {
         final $r = _$impls[$p]!.getPrivateKey(
-          $a![0]?.as(const jni$_.JStringType(), releaseOriginal: true),
+          ($a![0] as jni$_.JString?),
         );
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
+      if ($d ==
+          r'getServerAliases(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;') {
+        final $r = _$impls[$p]!.getServerAliases(
+          ($a![0] as jni$_.JString?),
+          ($a![1] as jni$_.JArray<jni$_.JObject?>?),
+        );
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -24154,100 +19232,292 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return X509KeyManager.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<X509KeyManager>();
+  }
+}
+
+extension X509KeyManager$$Methods on X509KeyManager {
+  static final _id_chooseClientAlias = X509KeyManager._class.instanceMethodId(
+    r'chooseClientAlias',
+    r'([Ljava/lang/String;[Ljava/security/Principal;Ljava/net/Socket;)Ljava/lang/String;',
+  );
+
+  static final _chooseClientAlias = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.lang.String chooseClientAlias(java.lang.String[] strings, java.security.Principal[] principals, java.net.Socket socket)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? chooseClientAlias(
+    jni$_.JArray<jni$_.JString?>? strings,
+    jni$_.JArray<jni$_.JObject?>? principals,
+    jni$_.JObject? socket,
+  ) {
+    final _$strings = strings?.reference ?? jni$_.jNullReference;
+    final _$principals = principals?.reference ?? jni$_.jNullReference;
+    final _$socket = socket?.reference ?? jni$_.jNullReference;
+    return _chooseClientAlias(reference.pointer, _id_chooseClientAlias.pointer,
+            _$strings.pointer, _$principals.pointer, _$socket.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_chooseServerAlias = X509KeyManager._class.instanceMethodId(
+    r'chooseServerAlias',
+    r'(Ljava/lang/String;[Ljava/security/Principal;Ljava/net/Socket;)Ljava/lang/String;',
+  );
+
+  static final _chooseServerAlias = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.lang.String chooseServerAlias(java.lang.String string, java.security.Principal[] principals, java.net.Socket socket)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? chooseServerAlias(
+    jni$_.JString? string,
+    jni$_.JArray<jni$_.JObject?>? principals,
+    jni$_.JObject? socket,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$principals = principals?.reference ?? jni$_.jNullReference;
+    final _$socket = socket?.reference ?? jni$_.jNullReference;
+    return _chooseServerAlias(reference.pointer, _id_chooseServerAlias.pointer,
+            _$string.pointer, _$principals.pointer, _$socket.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_getCertificateChain = X509KeyManager._class.instanceMethodId(
+    r'getCertificateChain',
+    r'(Ljava/lang/String;)[Ljava/security/cert/X509Certificate;',
+  );
+
+  static final _getCertificateChain = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.security.cert.X509Certificate[] getCertificateChain(java.lang.String string)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<X509Certificate?>? getCertificateChain(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _getCertificateChain(reference.pointer,
+            _id_getCertificateChain.pointer, _$string.pointer)
+        .object<jni$_.JArray<X509Certificate?>?>();
+  }
+
+  static final _id_getClientAliases = X509KeyManager._class.instanceMethodId(
+    r'getClientAliases',
+    r'(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;',
+  );
+
+  static final _getClientAliases = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.lang.String[] getClientAliases(java.lang.String string, java.security.Principal[] principals)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<jni$_.JString?>? getClientAliases(
+    jni$_.JString? string,
+    jni$_.JArray<jni$_.JObject?>? principals,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$principals = principals?.reference ?? jni$_.jNullReference;
+    return _getClientAliases(reference.pointer, _id_getClientAliases.pointer,
+            _$string.pointer, _$principals.pointer)
+        .object<jni$_.JArray<jni$_.JString?>?>();
+  }
+
+  static final _id_getPrivateKey = X509KeyManager._class.instanceMethodId(
+    r'getPrivateKey',
+    r'(Ljava/lang/String;)Ljava/security/PrivateKey;',
+  );
+
+  static final _getPrivateKey = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.security.PrivateKey getPrivateKey(java.lang.String string)`
+  /// The returned object must be released after use, by calling the [release] method.
+  PrivateKey? getPrivateKey(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _getPrivateKey(
+            reference.pointer, _id_getPrivateKey.pointer, _$string.pointer)
+        .object<PrivateKey?>();
+  }
+
+  static final _id_getServerAliases = X509KeyManager._class.instanceMethodId(
+    r'getServerAliases',
+    r'(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;',
+  );
+
+  static final _getServerAliases = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.lang.String[] getServerAliases(java.lang.String string, java.security.Principal[] principals)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<jni$_.JString?>? getServerAliases(
+    jni$_.JString? string,
+    jni$_.JArray<jni$_.JObject?>? principals,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$principals = principals?.reference ?? jni$_.jNullReference;
+    return _getServerAliases(reference.pointer, _id_getServerAliases.pointer,
+            _$string.pointer, _$principals.pointer)
+        .object<jni$_.JArray<jni$_.JString?>?>();
   }
 }
 
 abstract base mixin class $X509KeyManager {
   factory $X509KeyManager({
-    required jni$_.JArray<jni$_.JString?>? Function(
-            jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
-        getClientAliases,
     required jni$_.JString? Function(jni$_.JArray<jni$_.JString?>? strings,
             jni$_.JArray<jni$_.JObject?>? principals, jni$_.JObject? socket)
         chooseClientAlias,
-    required jni$_.JArray<jni$_.JString?>? Function(
-            jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
-        getServerAliases,
     required jni$_.JString? Function(jni$_.JString? string,
             jni$_.JArray<jni$_.JObject?>? principals, jni$_.JObject? socket)
         chooseServerAlias,
     required jni$_.JArray<X509Certificate?>? Function(jni$_.JString? string)
         getCertificateChain,
+    required jni$_.JArray<jni$_.JString?>? Function(
+            jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
+        getClientAliases,
     required PrivateKey? Function(jni$_.JString? string) getPrivateKey,
+    required jni$_.JArray<jni$_.JString?>? Function(
+            jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
+        getServerAliases,
   }) = _$X509KeyManager;
 
-  jni$_.JArray<jni$_.JString?>? getClientAliases(
-      jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals);
   jni$_.JString? chooseClientAlias(jni$_.JArray<jni$_.JString?>? strings,
       jni$_.JArray<jni$_.JObject?>? principals, jni$_.JObject? socket);
-  jni$_.JArray<jni$_.JString?>? getServerAliases(
-      jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals);
   jni$_.JString? chooseServerAlias(jni$_.JString? string,
       jni$_.JArray<jni$_.JObject?>? principals, jni$_.JObject? socket);
   jni$_.JArray<X509Certificate?>? getCertificateChain(jni$_.JString? string);
+  jni$_.JArray<jni$_.JString?>? getClientAliases(
+      jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals);
   PrivateKey? getPrivateKey(jni$_.JString? string);
+  jni$_.JArray<jni$_.JString?>? getServerAliases(
+      jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals);
 }
 
 final class _$X509KeyManager with $X509KeyManager {
   _$X509KeyManager({
-    required jni$_.JArray<jni$_.JString?>? Function(
-            jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
-        getClientAliases,
     required jni$_.JString? Function(jni$_.JArray<jni$_.JString?>? strings,
             jni$_.JArray<jni$_.JObject?>? principals, jni$_.JObject? socket)
         chooseClientAlias,
-    required jni$_.JArray<jni$_.JString?>? Function(
-            jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
-        getServerAliases,
     required jni$_.JString? Function(jni$_.JString? string,
             jni$_.JArray<jni$_.JObject?>? principals, jni$_.JObject? socket)
         chooseServerAlias,
     required jni$_.JArray<X509Certificate?>? Function(jni$_.JString? string)
         getCertificateChain,
+    required jni$_.JArray<jni$_.JString?>? Function(
+            jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
+        getClientAliases,
     required PrivateKey? Function(jni$_.JString? string) getPrivateKey,
-  })  : _getClientAliases = getClientAliases,
-        _chooseClientAlias = chooseClientAlias,
-        _getServerAliases = getServerAliases,
+    required jni$_.JArray<jni$_.JString?>? Function(
+            jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
+        getServerAliases,
+  })  : _chooseClientAlias = chooseClientAlias,
         _chooseServerAlias = chooseServerAlias,
         _getCertificateChain = getCertificateChain,
-        _getPrivateKey = getPrivateKey;
+        _getClientAliases = getClientAliases,
+        _getPrivateKey = getPrivateKey,
+        _getServerAliases = getServerAliases;
 
-  final jni$_.JArray<jni$_.JString?>? Function(
-          jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
-      _getClientAliases;
   final jni$_.JString? Function(
       jni$_.JArray<jni$_.JString?>? strings,
       jni$_.JArray<jni$_.JObject?>? principals,
       jni$_.JObject? socket) _chooseClientAlias;
-  final jni$_.JArray<jni$_.JString?>? Function(
-          jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
-      _getServerAliases;
   final jni$_.JString? Function(
       jni$_.JString? string,
       jni$_.JArray<jni$_.JObject?>? principals,
       jni$_.JObject? socket) _chooseServerAlias;
   final jni$_.JArray<X509Certificate?>? Function(jni$_.JString? string)
       _getCertificateChain;
+  final jni$_.JArray<jni$_.JString?>? Function(
+          jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
+      _getClientAliases;
   final PrivateKey? Function(jni$_.JString? string) _getPrivateKey;
-
-  jni$_.JArray<jni$_.JString?>? getClientAliases(
-      jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals) {
-    return _getClientAliases(string, principals);
-  }
+  final jni$_.JArray<jni$_.JString?>? Function(
+          jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals)
+      _getServerAliases;
 
   jni$_.JString? chooseClientAlias(jni$_.JArray<jni$_.JString?>? strings,
       jni$_.JArray<jni$_.JObject?>? principals, jni$_.JObject? socket) {
     return _chooseClientAlias(strings, principals, socket);
   }
 
-  jni$_.JArray<jni$_.JString?>? getServerAliases(
-      jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals) {
-    return _getServerAliases(string, principals);
-  }
-
   jni$_.JString? chooseServerAlias(jni$_.JString? string,
       jni$_.JArray<jni$_.JObject?>? principals, jni$_.JObject? socket) {
     return _chooseServerAlias(string, principals, socket);
@@ -24257,105 +19527,44 @@
     return _getCertificateChain(string);
   }
 
+  jni$_.JArray<jni$_.JString?>? getClientAliases(
+      jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals) {
+    return _getClientAliases(string, principals);
+  }
+
   PrivateKey? getPrivateKey(jni$_.JString? string) {
     return _getPrivateKey(string);
   }
+
+  jni$_.JArray<jni$_.JString?>? getServerAliases(
+      jni$_.JString? string, jni$_.JArray<jni$_.JObject?>? principals) {
+    return _getServerAliases(string, principals);
+  }
 }
 
-final class $X509KeyManager$NullableType
-    extends jni$_.JObjType<X509KeyManager?> {
+final class $X509KeyManager$Type$ extends jni$_.JType<X509KeyManager> {
   @jni$_.internal
-  const $X509KeyManager$NullableType();
+  const $X509KeyManager$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljavax/net/ssl/X509KeyManager;';
-
-  @jni$_.internal
-  @core$_.override
-  X509KeyManager? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : X509KeyManager.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<X509KeyManager?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($X509KeyManager$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($X509KeyManager$NullableType) &&
-        other is $X509KeyManager$NullableType;
-  }
-}
-
-final class $X509KeyManager$Type extends jni$_.JObjType<X509KeyManager> {
-  @jni$_.internal
-  const $X509KeyManager$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/ssl/X509KeyManager;';
-
-  @jni$_.internal
-  @core$_.override
-  X509KeyManager fromReference(jni$_.JReference reference) =>
-      X509KeyManager.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<X509KeyManager?> get nullableType =>
-      const $X509KeyManager$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($X509KeyManager$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($X509KeyManager$Type) &&
-        other is $X509KeyManager$Type;
-  }
 }
 
 /// from: `javax.net.ssl.X509ExtendedKeyManager`
-class X509ExtendedKeyManager extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<X509ExtendedKeyManager> $type;
-
-  @jni$_.internal
-  X509ExtendedKeyManager.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type X509ExtendedKeyManager._(jni$_.JObject _$this)
+    implements jni$_.JObject, X509KeyManager {
   static final _class =
       jni$_.JClass.forName(r'javax/net/ssl/X509ExtendedKeyManager');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $X509ExtendedKeyManager$NullableType();
-  static const type = $X509ExtendedKeyManager$Type();
-  static final _id_chooseEngineClientAlias = _class.instanceMethodId(
+  static const jni$_.JType<X509ExtendedKeyManager> type =
+      $X509ExtendedKeyManager$Type$();
+}
+
+extension X509ExtendedKeyManager$$Methods on X509ExtendedKeyManager {
+  static final _id_chooseEngineClientAlias =
+      X509ExtendedKeyManager._class.instanceMethodId(
     r'chooseEngineClientAlias',
     r'([Ljava/lang/String;[Ljava/security/Principal;Ljavax/net/ssl/SSLEngine;)Ljava/lang/String;',
   );
@@ -24391,14 +19600,15 @@
     final _$sSLEngine = sSLEngine?.reference ?? jni$_.jNullReference;
     return _chooseEngineClientAlias(
             reference.pointer,
-            _id_chooseEngineClientAlias as jni$_.JMethodIDPtr,
+            _id_chooseEngineClientAlias.pointer,
             _$strings.pointer,
             _$principals.pointer,
             _$sSLEngine.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+        .object<jni$_.JString?>();
   }
 
-  static final _id_chooseEngineServerAlias = _class.instanceMethodId(
+  static final _id_chooseEngineServerAlias =
+      X509ExtendedKeyManager._class.instanceMethodId(
     r'chooseEngineServerAlias',
     r'(Ljava/lang/String;[Ljava/security/Principal;Ljavax/net/ssl/SSLEngine;)Ljava/lang/String;',
   );
@@ -24434,114 +19644,128 @@
     final _$sSLEngine = sSLEngine?.reference ?? jni$_.jNullReference;
     return _chooseEngineServerAlias(
             reference.pointer,
-            _id_chooseEngineServerAlias as jni$_.JMethodIDPtr,
+            _id_chooseEngineServerAlias.pointer,
             _$string.pointer,
             _$principals.pointer,
             _$sSLEngine.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+        .object<jni$_.JString?>();
   }
-}
 
-final class $X509ExtendedKeyManager$NullableType
-    extends jni$_.JObjType<X509ExtendedKeyManager?> {
-  @jni$_.internal
-  const $X509ExtendedKeyManager$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/ssl/X509ExtendedKeyManager;';
-
-  @jni$_.internal
-  @core$_.override
-  X509ExtendedKeyManager? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : X509ExtendedKeyManager.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<X509ExtendedKeyManager?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($X509ExtendedKeyManager$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($X509ExtendedKeyManager$NullableType) &&
-        other is $X509ExtendedKeyManager$NullableType;
-  }
-}
-
-final class $X509ExtendedKeyManager$Type
-    extends jni$_.JObjType<X509ExtendedKeyManager> {
-  @jni$_.internal
-  const $X509ExtendedKeyManager$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/ssl/X509ExtendedKeyManager;';
-
-  @jni$_.internal
-  @core$_.override
-  X509ExtendedKeyManager fromReference(jni$_.JReference reference) =>
-      X509ExtendedKeyManager.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<X509ExtendedKeyManager?> get nullableType =>
-      const $X509ExtendedKeyManager$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($X509ExtendedKeyManager$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($X509ExtendedKeyManager$Type) &&
-        other is $X509ExtendedKeyManager$Type;
-  }
-}
-
-/// from: `javax.net.ssl.HostnameVerifier`
-class HostnameVerifier extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<HostnameVerifier> $type;
-
-  @jni$_.internal
-  HostnameVerifier.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
-  static final _class = jni$_.JClass.forName(r'javax/net/ssl/HostnameVerifier');
-
-  /// The type which includes information such as the signature of this class.
-  static const nullableType = $HostnameVerifier$NullableType();
-  static const type = $HostnameVerifier$Type();
-  static final _id_verify = _class.instanceMethodId(
-    r'verify',
-    r'(Ljava/lang/String;Ljavax/net/ssl/SSLSession;)Z',
+  static final _id_chooseClientAlias =
+      X509ExtendedKeyManager._class.instanceMethodId(
+    r'chooseClientAlias',
+    r'([Ljava/lang/String;[Ljava/security/Principal;Ljava/net/Socket;)Ljava/lang/String;',
   );
 
-  static final _verify = jni$_.ProtectedJniExtensions.lookup<
+  static final _chooseClientAlias = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.lang.String chooseClientAlias(java.lang.String[] strings, java.security.Principal[] principals, java.net.Socket socket)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? chooseClientAlias(
+    jni$_.JArray<jni$_.JString?>? strings,
+    jni$_.JArray<jni$_.JObject?>? principals,
+    jni$_.JObject? socket,
+  ) {
+    final _$strings = strings?.reference ?? jni$_.jNullReference;
+    final _$principals = principals?.reference ?? jni$_.jNullReference;
+    final _$socket = socket?.reference ?? jni$_.jNullReference;
+    return _chooseClientAlias(reference.pointer, _id_chooseClientAlias.pointer,
+            _$strings.pointer, _$principals.pointer, _$socket.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_chooseServerAlias =
+      X509ExtendedKeyManager._class.instanceMethodId(
+    r'chooseServerAlias',
+    r'(Ljava/lang/String;[Ljava/security/Principal;Ljava/net/Socket;)Ljava/lang/String;',
+  );
+
+  static final _chooseServerAlias = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.lang.String chooseServerAlias(java.lang.String string, java.security.Principal[] principals, java.net.Socket socket)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? chooseServerAlias(
+    jni$_.JString? string,
+    jni$_.JArray<jni$_.JObject?>? principals,
+    jni$_.JObject? socket,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$principals = principals?.reference ?? jni$_.jNullReference;
+    final _$socket = socket?.reference ?? jni$_.jNullReference;
+    return _chooseServerAlias(reference.pointer, _id_chooseServerAlias.pointer,
+            _$string.pointer, _$principals.pointer, _$socket.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_getCertificateChain =
+      X509ExtendedKeyManager._class.instanceMethodId(
+    r'getCertificateChain',
+    r'(Ljava/lang/String;)[Ljava/security/cert/X509Certificate;',
+  );
+
+  static final _getCertificateChain = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.security.cert.X509Certificate[] getCertificateChain(java.lang.String string)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<X509Certificate?>? getCertificateChain(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _getCertificateChain(reference.pointer,
+            _id_getCertificateChain.pointer, _$string.pointer)
+        .object<jni$_.JArray<X509Certificate?>?>();
+  }
+
+  static final _id_getClientAliases =
+      X509ExtendedKeyManager._class.instanceMethodId(
+    r'getClientAliases',
+    r'(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;',
+  );
+
+  static final _getClientAliases = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -24550,7 +19774,7 @@
                       (
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallBooleanMethod')
+                      )>)>>('globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(
               jni$_.Pointer<jni$_.Void>,
@@ -24558,22 +19782,106 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `public abstract boolean verify(java.lang.String string, javax.net.ssl.SSLSession sSLSession)`
-  bool verify(
+  /// from: `public abstract java.lang.String[] getClientAliases(java.lang.String string, java.security.Principal[] principals)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<jni$_.JString?>? getClientAliases(
     jni$_.JString? string,
-    jni$_.JObject? sSLSession,
+    jni$_.JArray<jni$_.JObject?>? principals,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
-    final _$sSLSession = sSLSession?.reference ?? jni$_.jNullReference;
-    return _verify(reference.pointer, _id_verify as jni$_.JMethodIDPtr,
-            _$string.pointer, _$sSLSession.pointer)
-        .boolean;
+    final _$principals = principals?.reference ?? jni$_.jNullReference;
+    return _getClientAliases(reference.pointer, _id_getClientAliases.pointer,
+            _$string.pointer, _$principals.pointer)
+        .object<jni$_.JArray<jni$_.JString?>?>();
   }
 
+  static final _id_getPrivateKey =
+      X509ExtendedKeyManager._class.instanceMethodId(
+    r'getPrivateKey',
+    r'(Ljava/lang/String;)Ljava/security/PrivateKey;',
+  );
+
+  static final _getPrivateKey = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.security.PrivateKey getPrivateKey(java.lang.String string)`
+  /// The returned object must be released after use, by calling the [release] method.
+  PrivateKey? getPrivateKey(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _getPrivateKey(
+            reference.pointer, _id_getPrivateKey.pointer, _$string.pointer)
+        .object<PrivateKey?>();
+  }
+
+  static final _id_getServerAliases =
+      X509ExtendedKeyManager._class.instanceMethodId(
+    r'getServerAliases',
+    r'(Ljava/lang/String;[Ljava/security/Principal;)[Ljava/lang/String;',
+  );
+
+  static final _getServerAliases = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract java.lang.String[] getServerAliases(java.lang.String string, java.security.Principal[] principals)`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<jni$_.JString?>? getServerAliases(
+    jni$_.JString? string,
+    jni$_.JArray<jni$_.JObject?>? principals,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$principals = principals?.reference ?? jni$_.jNullReference;
+    return _getServerAliases(reference.pointer, _id_getServerAliases.pointer,
+            _$string.pointer, _$principals.pointer)
+        .object<jni$_.JArray<jni$_.JString?>?>();
+  }
+}
+
+final class $X509ExtendedKeyManager$Type$
+    extends jni$_.JType<X509ExtendedKeyManager> {
+  @jni$_.internal
+  const $X509ExtendedKeyManager$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Ljavax/net/ssl/X509ExtendedKeyManager;';
+}
+
+/// from: `javax.net.ssl.HostnameVerifier`
+extension type HostnameVerifier._(jni$_.JObject _$this)
+    implements jni$_.JObject {
+  static final _class = jni$_.JClass.forName(r'javax/net/ssl/HostnameVerifier');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<HostnameVerifier> type = $HostnameVerifier$Type$();
+
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $HostnameVerifier> _$impls = {};
+  static final core$_.Map<core$_.int, $HostnameVerifier> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -24594,7 +19902,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -24602,10 +19910,10 @@
       final $a = $i.args;
       if ($d == r'verify(Ljava/lang/String;Ljavax/net/ssl/SSLSession;)Z') {
         final $r = _$impls[$p]!.verify(
-          $a![0]?.as(const jni$_.JStringType(), releaseOriginal: true),
-          $a![1]?.as(const jni$_.JObjectType(), releaseOriginal: true),
+          ($a![0] as jni$_.JString?),
+          ($a![1] as jni$_.JObject?),
         );
-        return jni$_.JBoolean($r).reference.toPointer();
+        return $r.toJBoolean().reference.toPointer();
       }
     } catch (e) {
       return jni$_.ProtectedJniExtensions.newDartException(e);
@@ -24643,129 +19951,92 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return HostnameVerifier.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<HostnameVerifier>();
+  }
+}
+
+extension HostnameVerifier$$Methods on HostnameVerifier {
+  static final _id_verify = HostnameVerifier._class.instanceMethodId(
+    r'verify',
+    r'(Ljava/lang/String;Ljavax/net/ssl/SSLSession;)Z',
+  );
+
+  static final _verify = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract boolean verify(java.lang.String string, javax.net.ssl.SSLSession sSLSession)`
+  core$_.bool verify(
+    jni$_.JString? string,
+    jni$_.JObject? sSLSession,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$sSLSession = sSLSession?.reference ?? jni$_.jNullReference;
+    return _verify(reference.pointer, _id_verify.pointer, _$string.pointer,
+            _$sSLSession.pointer)
+        .boolean;
   }
 }
 
 abstract base mixin class $HostnameVerifier {
   factory $HostnameVerifier({
-    required bool Function(jni$_.JString? string, jni$_.JObject? sSLSession)
+    required core$_.bool Function(
+            jni$_.JString? string, jni$_.JObject? sSLSession)
         verify,
   }) = _$HostnameVerifier;
 
-  bool verify(jni$_.JString? string, jni$_.JObject? sSLSession);
+  core$_.bool verify(jni$_.JString? string, jni$_.JObject? sSLSession);
 }
 
 final class _$HostnameVerifier with $HostnameVerifier {
   _$HostnameVerifier({
-    required bool Function(jni$_.JString? string, jni$_.JObject? sSLSession)
+    required core$_.bool Function(
+            jni$_.JString? string, jni$_.JObject? sSLSession)
         verify,
   }) : _verify = verify;
 
-  final bool Function(jni$_.JString? string, jni$_.JObject? sSLSession) _verify;
+  final core$_.bool Function(jni$_.JString? string, jni$_.JObject? sSLSession)
+      _verify;
 
-  bool verify(jni$_.JString? string, jni$_.JObject? sSLSession) {
+  core$_.bool verify(jni$_.JString? string, jni$_.JObject? sSLSession) {
     return _verify(string, sSLSession);
   }
 }
 
-final class $HostnameVerifier$NullableType
-    extends jni$_.JObjType<HostnameVerifier?> {
+final class $HostnameVerifier$Type$ extends jni$_.JType<HostnameVerifier> {
   @jni$_.internal
-  const $HostnameVerifier$NullableType();
+  const $HostnameVerifier$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljavax/net/ssl/HostnameVerifier;';
-
-  @jni$_.internal
-  @core$_.override
-  HostnameVerifier? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : HostnameVerifier.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<HostnameVerifier?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($HostnameVerifier$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($HostnameVerifier$NullableType) &&
-        other is $HostnameVerifier$NullableType;
-  }
-}
-
-final class $HostnameVerifier$Type extends jni$_.JObjType<HostnameVerifier> {
-  @jni$_.internal
-  const $HostnameVerifier$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/ssl/HostnameVerifier;';
-
-  @jni$_.internal
-  @core$_.override
-  HostnameVerifier fromReference(jni$_.JReference reference) =>
-      HostnameVerifier.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<HostnameVerifier?> get nullableType =>
-      const $HostnameVerifier$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($HostnameVerifier$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($HostnameVerifier$Type) &&
-        other is $HostnameVerifier$Type;
-  }
 }
 
 /// from: `java.security.cert.X509Certificate`
-class X509Certificate extends Certificate {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<X509Certificate> $type;
-
-  @jni$_.internal
-  X509Certificate.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type X509Certificate._(jni$_.JObject _$this)
+    implements Certificate, jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'java/security/cert/X509Certificate');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $X509Certificate$NullableType();
-  static const type = $X509Certificate$Type();
-  static final _id_checkValidity = _class.instanceMethodId(
+  static const jni$_.JType<X509Certificate> type = $X509Certificate$Type$();
+}
+
+extension X509Certificate$$Methods on X509Certificate {
+  static final _id_checkValidity = X509Certificate._class.instanceMethodId(
     r'checkValidity',
     r'()V',
   );
@@ -24784,11 +20055,10 @@
 
   /// from: `public abstract void checkValidity()`
   void checkValidity() {
-    _checkValidity(reference.pointer, _id_checkValidity as jni$_.JMethodIDPtr)
-        .check();
+    _checkValidity(reference.pointer, _id_checkValidity.pointer).check();
   }
 
-  static final _id_checkValidity$1 = _class.instanceMethodId(
+  static final _id_checkValidity$1 = X509Certificate._class.instanceMethodId(
     r'checkValidity',
     r'(Ljava/util/Date;)V',
   );
@@ -24809,17 +20079,18 @@
     jni$_.JObject? date,
   ) {
     final _$date = date?.reference ?? jni$_.jNullReference;
-    _checkValidity$1(reference.pointer,
-            _id_checkValidity$1 as jni$_.JMethodIDPtr, _$date.pointer)
+    _checkValidity$1(
+            reference.pointer, _id_checkValidity$1.pointer, _$date.pointer)
         .check();
   }
 
-  static final _id_getVersion = _class.instanceMethodId(
-    r'getVersion',
+  static final _id_get$basicConstraints =
+      X509Certificate._class.instanceMethodId(
+    r'getBasicConstraints',
     r'()I',
   );
 
-  static final _getVersion = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$basicConstraints = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -24831,18 +20102,20 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public abstract int getVersion()`
-  int getVersion() {
-    return _getVersion(reference.pointer, _id_getVersion as jni$_.JMethodIDPtr)
+  /// from: `public abstract int getBasicConstraints()`
+  core$_.int get basicConstraints {
+    return _get$basicConstraints(
+            reference.pointer, _id_get$basicConstraints.pointer)
         .integer;
   }
 
-  static final _id_getSerialNumber = _class.instanceMethodId(
-    r'getSerialNumber',
-    r'()Ljava/math/BigInteger;',
+  static final _id_get$extendedKeyUsage =
+      X509Certificate._class.instanceMethodId(
+    r'getExtendedKeyUsage',
+    r'()Ljava/util/List;',
   );
 
-  static final _getSerialNumber = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$extendedKeyUsage = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -24854,20 +20127,47 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public abstract java.math.BigInteger getSerialNumber()`
+  /// from: `public java.util.List<java.lang.String> getExtendedKeyUsage()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getSerialNumber() {
-    return _getSerialNumber(
-            reference.pointer, _id_getSerialNumber as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  jni$_.JList<jni$_.JString?>? get extendedKeyUsage {
+    return _get$extendedKeyUsage(
+            reference.pointer, _id_get$extendedKeyUsage.pointer)
+        .object<jni$_.JList<jni$_.JString?>?>();
   }
 
-  static final _id_getIssuerDN = _class.instanceMethodId(
+  static final _id_get$issuerAlternativeNames =
+      X509Certificate._class.instanceMethodId(
+    r'getIssuerAlternativeNames',
+    r'()Ljava/util/Collection;',
+  );
+
+  static final _get$issuerAlternativeNames =
+      jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                    jni$_.Pointer<jni$_.Void>,
+                    jni$_.JMethodIDPtr,
+                  )>>('globalEnv_CallObjectMethod')
+          .asFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>();
+
+  /// from: `public java.util.Collection<java.util.List<?>> getIssuerAlternativeNames()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get issuerAlternativeNames {
+    return _get$issuerAlternativeNames(
+            reference.pointer, _id_get$issuerAlternativeNames.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_get$issuerDN = X509Certificate._class.instanceMethodId(
     r'getIssuerDN',
     r'()Ljava/security/Principal;',
   );
 
-  static final _getIssuerDN = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$issuerDN = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -24881,268 +20181,17 @@
 
   /// from: `public abstract java.security.Principal getIssuerDN()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getIssuerDN() {
-    return _getIssuerDN(
-            reference.pointer, _id_getIssuerDN as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  jni$_.JObject? get issuerDN {
+    return _get$issuerDN(reference.pointer, _id_get$issuerDN.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_getIssuerX500Principal = _class.instanceMethodId(
-    r'getIssuerX500Principal',
-    r'()Ljavax/security/auth/x500/X500Principal;',
-  );
-
-  static final _getIssuerX500Principal = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public javax.security.auth.x500.X500Principal getIssuerX500Principal()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getIssuerX500Principal() {
-    return _getIssuerX500Principal(
-            reference.pointer, _id_getIssuerX500Principal as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_getSubjectDN = _class.instanceMethodId(
-    r'getSubjectDN',
-    r'()Ljava/security/Principal;',
-  );
-
-  static final _getSubjectDN = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.security.Principal getSubjectDN()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getSubjectDN() {
-    return _getSubjectDN(
-            reference.pointer, _id_getSubjectDN as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_getSubjectX500Principal = _class.instanceMethodId(
-    r'getSubjectX500Principal',
-    r'()Ljavax/security/auth/x500/X500Principal;',
-  );
-
-  static final _getSubjectX500Principal = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public javax.security.auth.x500.X500Principal getSubjectX500Principal()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getSubjectX500Principal() {
-    return _getSubjectX500Principal(reference.pointer,
-            _id_getSubjectX500Principal as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_getNotBefore = _class.instanceMethodId(
-    r'getNotBefore',
-    r'()Ljava/util/Date;',
-  );
-
-  static final _getNotBefore = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.util.Date getNotBefore()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getNotBefore() {
-    return _getNotBefore(
-            reference.pointer, _id_getNotBefore as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_getNotAfter = _class.instanceMethodId(
-    r'getNotAfter',
-    r'()Ljava/util/Date;',
-  );
-
-  static final _getNotAfter = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.util.Date getNotAfter()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getNotAfter() {
-    return _getNotAfter(
-            reference.pointer, _id_getNotAfter as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_getTBSCertificate = _class.instanceMethodId(
-    r'getTBSCertificate',
-    r'()[B',
-  );
-
-  static final _getTBSCertificate = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract byte[] getTBSCertificate()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JByteArray? getTBSCertificate() {
-    return _getTBSCertificate(
-            reference.pointer, _id_getTBSCertificate as jni$_.JMethodIDPtr)
-        .object<jni$_.JByteArray?>(const jni$_.JByteArrayNullableType());
-  }
-
-  static final _id_getSignature = _class.instanceMethodId(
-    r'getSignature',
-    r'()[B',
-  );
-
-  static final _getSignature = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract byte[] getSignature()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JByteArray? getSignature() {
-    return _getSignature(
-            reference.pointer, _id_getSignature as jni$_.JMethodIDPtr)
-        .object<jni$_.JByteArray?>(const jni$_.JByteArrayNullableType());
-  }
-
-  static final _id_getSigAlgName = _class.instanceMethodId(
-    r'getSigAlgName',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _getSigAlgName = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.lang.String getSigAlgName()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getSigAlgName() {
-    return _getSigAlgName(
-            reference.pointer, _id_getSigAlgName as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getSigAlgOID = _class.instanceMethodId(
-    r'getSigAlgOID',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _getSigAlgOID = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.lang.String getSigAlgOID()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getSigAlgOID() {
-    return _getSigAlgOID(
-            reference.pointer, _id_getSigAlgOID as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getSigAlgParams = _class.instanceMethodId(
-    r'getSigAlgParams',
-    r'()[B',
-  );
-
-  static final _getSigAlgParams = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract byte[] getSigAlgParams()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JByteArray? getSigAlgParams() {
-    return _getSigAlgParams(
-            reference.pointer, _id_getSigAlgParams as jni$_.JMethodIDPtr)
-        .object<jni$_.JByteArray?>(const jni$_.JByteArrayNullableType());
-  }
-
-  static final _id_getIssuerUniqueID = _class.instanceMethodId(
+  static final _id_get$issuerUniqueID = X509Certificate._class.instanceMethodId(
     r'getIssuerUniqueID',
     r'()[Z',
   );
 
-  static final _getIssuerUniqueID = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$issuerUniqueID = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -25156,18 +20205,19 @@
 
   /// from: `public abstract boolean[] getIssuerUniqueID()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JBooleanArray? getIssuerUniqueID() {
-    return _getIssuerUniqueID(
-            reference.pointer, _id_getIssuerUniqueID as jni$_.JMethodIDPtr)
-        .object<jni$_.JBooleanArray?>(const jni$_.JBooleanArrayNullableType());
+  jni$_.JBooleanArray? get issuerUniqueID {
+    return _get$issuerUniqueID(
+            reference.pointer, _id_get$issuerUniqueID.pointer)
+        .object<jni$_.JBooleanArray?>();
   }
 
-  static final _id_getSubjectUniqueID = _class.instanceMethodId(
-    r'getSubjectUniqueID',
-    r'()[Z',
+  static final _id_get$issuerX500Principal =
+      X509Certificate._class.instanceMethodId(
+    r'getIssuerX500Principal',
+    r'()Ljavax/security/auth/x500/X500Principal;',
   );
 
-  static final _getSubjectUniqueID = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$issuerX500Principal = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -25179,20 +20229,20 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public abstract boolean[] getSubjectUniqueID()`
+  /// from: `public javax.security.auth.x500.X500Principal getIssuerX500Principal()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JBooleanArray? getSubjectUniqueID() {
-    return _getSubjectUniqueID(
-            reference.pointer, _id_getSubjectUniqueID as jni$_.JMethodIDPtr)
-        .object<jni$_.JBooleanArray?>(const jni$_.JBooleanArrayNullableType());
+  jni$_.JObject? get issuerX500Principal {
+    return _get$issuerX500Principal(
+            reference.pointer, _id_get$issuerX500Principal.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_getKeyUsage = _class.instanceMethodId(
+  static final _id_get$keyUsage = X509Certificate._class.instanceMethodId(
     r'getKeyUsage',
     r'()[Z',
   );
 
-  static final _getKeyUsage = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$keyUsage = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -25206,18 +20256,17 @@
 
   /// from: `public abstract boolean[] getKeyUsage()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JBooleanArray? getKeyUsage() {
-    return _getKeyUsage(
-            reference.pointer, _id_getKeyUsage as jni$_.JMethodIDPtr)
-        .object<jni$_.JBooleanArray?>(const jni$_.JBooleanArrayNullableType());
+  jni$_.JBooleanArray? get keyUsage {
+    return _get$keyUsage(reference.pointer, _id_get$keyUsage.pointer)
+        .object<jni$_.JBooleanArray?>();
   }
 
-  static final _id_getExtendedKeyUsage = _class.instanceMethodId(
-    r'getExtendedKeyUsage',
-    r'()Ljava/util/List;',
+  static final _id_get$notAfter = X509Certificate._class.instanceMethodId(
+    r'getNotAfter',
+    r'()Ljava/util/Date;',
   );
 
-  static final _getExtendedKeyUsage = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$notAfter = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -25229,46 +20278,164 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public java.util.List getExtendedKeyUsage()`
+  /// from: `public abstract java.util.Date getNotAfter()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JList<jni$_.JString?>? getExtendedKeyUsage() {
-    return _getExtendedKeyUsage(
-            reference.pointer, _id_getExtendedKeyUsage as jni$_.JMethodIDPtr)
-        .object<jni$_.JList<jni$_.JString?>?>(
-            const jni$_.JListNullableType<jni$_.JString?>(
-                jni$_.JStringNullableType()));
+  jni$_.JObject? get notAfter {
+    return _get$notAfter(reference.pointer, _id_get$notAfter.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_getBasicConstraints = _class.instanceMethodId(
-    r'getBasicConstraints',
-    r'()I',
+  static final _id_get$notBefore = X509Certificate._class.instanceMethodId(
+    r'getNotBefore',
+    r'()Ljava/util/Date;',
   );
 
-  static final _getBasicConstraints = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$notBefore = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
                 jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
+              )>>('globalEnv_CallObjectMethod')
       .asFunction<
           jni$_.JniResult Function(
             jni$_.Pointer<jni$_.Void>,
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public abstract int getBasicConstraints()`
-  int getBasicConstraints() {
-    return _getBasicConstraints(
-            reference.pointer, _id_getBasicConstraints as jni$_.JMethodIDPtr)
-        .integer;
+  /// from: `public abstract java.util.Date getNotBefore()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get notBefore {
+    return _get$notBefore(reference.pointer, _id_get$notBefore.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_getSubjectAlternativeNames = _class.instanceMethodId(
+  static final _id_get$serialNumber = X509Certificate._class.instanceMethodId(
+    r'getSerialNumber',
+    r'()Ljava/math/BigInteger;',
+  );
+
+  static final _get$serialNumber = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.math.BigInteger getSerialNumber()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get serialNumber {
+    return _get$serialNumber(reference.pointer, _id_get$serialNumber.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_get$sigAlgName = X509Certificate._class.instanceMethodId(
+    r'getSigAlgName',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _get$sigAlgName = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.lang.String getSigAlgName()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? get sigAlgName {
+    return _get$sigAlgName(reference.pointer, _id_get$sigAlgName.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_get$sigAlgOID = X509Certificate._class.instanceMethodId(
+    r'getSigAlgOID',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _get$sigAlgOID = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.lang.String getSigAlgOID()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? get sigAlgOID {
+    return _get$sigAlgOID(reference.pointer, _id_get$sigAlgOID.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_get$sigAlgParams = X509Certificate._class.instanceMethodId(
+    r'getSigAlgParams',
+    r'()[B',
+  );
+
+  static final _get$sigAlgParams = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract byte[] getSigAlgParams()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JByteArray? get sigAlgParams {
+    return _get$sigAlgParams(reference.pointer, _id_get$sigAlgParams.pointer)
+        .object<jni$_.JByteArray?>();
+  }
+
+  static final _id_get$signature = X509Certificate._class.instanceMethodId(
+    r'getSignature',
+    r'()[B',
+  );
+
+  static final _get$signature = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract byte[] getSignature()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JByteArray? get signature {
+    return _get$signature(reference.pointer, _id_get$signature.pointer)
+        .object<jni$_.JByteArray?>();
+  }
+
+  static final _id_get$subjectAlternativeNames =
+      X509Certificate._class.instanceMethodId(
     r'getSubjectAlternativeNames',
     r'()Ljava/util/Collection;',
   );
 
-  static final _getSubjectAlternativeNames =
+  static final _get$subjectAlternativeNames =
       jni$_.ProtectedJniExtensions.lookup<
               jni$_.NativeFunction<
                   jni$_.JniResult Function(
@@ -25281,20 +20448,20 @@
                 jni$_.JMethodIDPtr,
               )>();
 
-  /// from: `public java.util.Collection getSubjectAlternativeNames()`
+  /// from: `public java.util.Collection<java.util.List<?>> getSubjectAlternativeNames()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getSubjectAlternativeNames() {
-    return _getSubjectAlternativeNames(reference.pointer,
-            _id_getSubjectAlternativeNames as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  jni$_.JObject? get subjectAlternativeNames {
+    return _get$subjectAlternativeNames(
+            reference.pointer, _id_get$subjectAlternativeNames.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_getIssuerAlternativeNames = _class.instanceMethodId(
-    r'getIssuerAlternativeNames',
-    r'()Ljava/util/Collection;',
+  static final _id_get$subjectDN = X509Certificate._class.instanceMethodId(
+    r'getSubjectDN',
+    r'()Ljava/security/Principal;',
   );
 
-  static final _getIssuerAlternativeNames = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$subjectDN = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -25306,15 +20473,113 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public java.util.Collection getIssuerAlternativeNames()`
+  /// from: `public abstract java.security.Principal getSubjectDN()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getIssuerAlternativeNames() {
-    return _getIssuerAlternativeNames(reference.pointer,
-            _id_getIssuerAlternativeNames as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  jni$_.JObject? get subjectDN {
+    return _get$subjectDN(reference.pointer, _id_get$subjectDN.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_verify2 = _class.instanceMethodId(
+  static final _id_get$subjectUniqueID =
+      X509Certificate._class.instanceMethodId(
+    r'getSubjectUniqueID',
+    r'()[Z',
+  );
+
+  static final _get$subjectUniqueID = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract boolean[] getSubjectUniqueID()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JBooleanArray? get subjectUniqueID {
+    return _get$subjectUniqueID(
+            reference.pointer, _id_get$subjectUniqueID.pointer)
+        .object<jni$_.JBooleanArray?>();
+  }
+
+  static final _id_get$subjectX500Principal =
+      X509Certificate._class.instanceMethodId(
+    r'getSubjectX500Principal',
+    r'()Ljavax/security/auth/x500/X500Principal;',
+  );
+
+  static final _get$subjectX500Principal = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public javax.security.auth.x500.X500Principal getSubjectX500Principal()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JObject? get subjectX500Principal {
+    return _get$subjectX500Principal(
+            reference.pointer, _id_get$subjectX500Principal.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_get$tBSCertificate = X509Certificate._class.instanceMethodId(
+    r'getTBSCertificate',
+    r'()[B',
+  );
+
+  static final _get$tBSCertificate = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract byte[] getTBSCertificate()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JByteArray? get tBSCertificate {
+    return _get$tBSCertificate(
+            reference.pointer, _id_get$tBSCertificate.pointer)
+        .object<jni$_.JByteArray?>();
+  }
+
+  static final _id_get$version = X509Certificate._class.instanceMethodId(
+    r'getVersion',
+    r'()I',
+  );
+
+  static final _get$version = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract int getVersion()`
+  core$_.int get version {
+    return _get$version(reference.pointer, _id_get$version.pointer).integer;
+  }
+
+  static final _id_verify2 = X509Certificate._class.instanceMethodId(
     r'verify',
     r'(Ljava/security/PublicKey;Ljava/security/Provider;)V',
   );
@@ -25343,104 +20608,27 @@
   ) {
     final _$publicKey = publicKey?.reference ?? jni$_.jNullReference;
     final _$provider = provider?.reference ?? jni$_.jNullReference;
-    _verify2(reference.pointer, _id_verify2 as jni$_.JMethodIDPtr,
-            _$publicKey.pointer, _$provider.pointer)
+    _verify2(reference.pointer, _id_verify2.pointer, _$publicKey.pointer,
+            _$provider.pointer)
         .check();
   }
 }
 
-final class $X509Certificate$NullableType
-    extends jni$_.JObjType<X509Certificate?> {
+final class $X509Certificate$Type$ extends jni$_.JType<X509Certificate> {
   @jni$_.internal
-  const $X509Certificate$NullableType();
+  const $X509Certificate$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/cert/X509Certificate;';
-
-  @jni$_.internal
-  @core$_.override
-  X509Certificate? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : X509Certificate.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const $Certificate$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<X509Certificate?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 2;
-
-  @core$_.override
-  int get hashCode => ($X509Certificate$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($X509Certificate$NullableType) &&
-        other is $X509Certificate$NullableType;
-  }
-}
-
-final class $X509Certificate$Type extends jni$_.JObjType<X509Certificate> {
-  @jni$_.internal
-  const $X509Certificate$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/cert/X509Certificate;';
-
-  @jni$_.internal
-  @core$_.override
-  X509Certificate fromReference(jni$_.JReference reference) =>
-      X509Certificate.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const $Certificate$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<X509Certificate?> get nullableType =>
-      const $X509Certificate$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 2;
-
-  @core$_.override
-  int get hashCode => ($X509Certificate$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($X509Certificate$Type) &&
-        other is $X509Certificate$Type;
-  }
 }
 
 /// from: `android.security.KeyChain`
-class KeyChain extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyChain> $type;
-
-  @jni$_.internal
-  KeyChain.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyChain._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'android/security/KeyChain');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyChain$NullableType();
-  static const type = $KeyChain$Type();
+  static const jni$_.JType<KeyChain> type = $KeyChain$Type$();
   static final _id_ACTION_KEYCHAIN_CHANGED = _class.staticFieldId(
     r'ACTION_KEYCHAIN_CHANGED',
     r'Ljava/lang/String;',
@@ -25449,8 +20637,8 @@
   /// from: `static public final java.lang.String ACTION_KEYCHAIN_CHANGED`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JString? get ACTION_KEYCHAIN_CHANGED =>
-      _id_ACTION_KEYCHAIN_CHANGED.get(
-          _class, const jni$_.JStringNullableType());
+      _id_ACTION_KEYCHAIN_CHANGED.getNullable(_class, jni$_.JString.type)
+          as jni$_.JString?;
 
   static final _id_ACTION_KEY_ACCESS_CHANGED = _class.staticFieldId(
     r'ACTION_KEY_ACCESS_CHANGED',
@@ -25460,8 +20648,8 @@
   /// from: `static public final java.lang.String ACTION_KEY_ACCESS_CHANGED`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JString? get ACTION_KEY_ACCESS_CHANGED =>
-      _id_ACTION_KEY_ACCESS_CHANGED.get(
-          _class, const jni$_.JStringNullableType());
+      _id_ACTION_KEY_ACCESS_CHANGED.getNullable(_class, jni$_.JString.type)
+          as jni$_.JString?;
 
   static final _id_ACTION_STORAGE_CHANGED = _class.staticFieldId(
     r'ACTION_STORAGE_CHANGED',
@@ -25471,7 +20659,8 @@
   /// from: `static public final java.lang.String ACTION_STORAGE_CHANGED`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JString? get ACTION_STORAGE_CHANGED =>
-      _id_ACTION_STORAGE_CHANGED.get(_class, const jni$_.JStringNullableType());
+      _id_ACTION_STORAGE_CHANGED.getNullable(_class, jni$_.JString.type)
+          as jni$_.JString?;
 
   static final _id_ACTION_TRUST_STORE_CHANGED = _class.staticFieldId(
     r'ACTION_TRUST_STORE_CHANGED',
@@ -25481,8 +20670,8 @@
   /// from: `static public final java.lang.String ACTION_TRUST_STORE_CHANGED`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JString? get ACTION_TRUST_STORE_CHANGED =>
-      _id_ACTION_TRUST_STORE_CHANGED.get(
-          _class, const jni$_.JStringNullableType());
+      _id_ACTION_TRUST_STORE_CHANGED.getNullable(_class, jni$_.JString.type)
+          as jni$_.JString?;
 
   static final _id_EXTRA_CERTIFICATE = _class.staticFieldId(
     r'EXTRA_CERTIFICATE',
@@ -25492,7 +20681,8 @@
   /// from: `static public final java.lang.String EXTRA_CERTIFICATE`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JString? get EXTRA_CERTIFICATE =>
-      _id_EXTRA_CERTIFICATE.get(_class, const jni$_.JStringNullableType());
+      _id_EXTRA_CERTIFICATE.getNullable(_class, jni$_.JString.type)
+          as jni$_.JString?;
 
   static final _id_EXTRA_KEY_ACCESSIBLE = _class.staticFieldId(
     r'EXTRA_KEY_ACCESSIBLE',
@@ -25502,7 +20692,8 @@
   /// from: `static public final java.lang.String EXTRA_KEY_ACCESSIBLE`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JString? get EXTRA_KEY_ACCESSIBLE =>
-      _id_EXTRA_KEY_ACCESSIBLE.get(_class, const jni$_.JStringNullableType());
+      _id_EXTRA_KEY_ACCESSIBLE.getNullable(_class, jni$_.JString.type)
+          as jni$_.JString?;
 
   static final _id_EXTRA_KEY_ALIAS = _class.staticFieldId(
     r'EXTRA_KEY_ALIAS',
@@ -25512,7 +20703,8 @@
   /// from: `static public final java.lang.String EXTRA_KEY_ALIAS`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JString? get EXTRA_KEY_ALIAS =>
-      _id_EXTRA_KEY_ALIAS.get(_class, const jni$_.JStringNullableType());
+      _id_EXTRA_KEY_ALIAS.getNullable(_class, jni$_.JString.type)
+          as jni$_.JString?;
 
   static final _id_EXTRA_NAME = _class.staticFieldId(
     r'EXTRA_NAME',
@@ -25522,7 +20714,7 @@
   /// from: `static public final java.lang.String EXTRA_NAME`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JString? get EXTRA_NAME =>
-      _id_EXTRA_NAME.get(_class, const jni$_.JStringNullableType());
+      _id_EXTRA_NAME.getNullable(_class, jni$_.JString.type) as jni$_.JString?;
 
   static final _id_EXTRA_PKCS12 = _class.staticFieldId(
     r'EXTRA_PKCS12',
@@ -25532,7 +20724,8 @@
   /// from: `static public final java.lang.String EXTRA_PKCS12`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JString? get EXTRA_PKCS12 =>
-      _id_EXTRA_PKCS12.get(_class, const jni$_.JStringNullableType());
+      _id_EXTRA_PKCS12.getNullable(_class, jni$_.JString.type)
+          as jni$_.JString?;
 
   static final _id_KEY_ALIAS_SELECTION_DENIED = _class.staticFieldId(
     r'KEY_ALIAS_SELECTION_DENIED',
@@ -25542,8 +20735,8 @@
   /// from: `static public final java.lang.String KEY_ALIAS_SELECTION_DENIED`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JString? get KEY_ALIAS_SELECTION_DENIED =>
-      _id_KEY_ALIAS_SELECTION_DENIED.get(
-          _class, const jni$_.JStringNullableType());
+      _id_KEY_ALIAS_SELECTION_DENIED.getNullable(_class, jni$_.JString.type)
+          as jni$_.JString?;
 
   static final _id_new$ = _class.constructorId(
     r'()V',
@@ -25564,9 +20757,127 @@
   /// from: `public void <init>()`
   /// The returned object must be released after use, by calling the [release] method.
   factory KeyChain() {
-    return KeyChain.fromReference(
-        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
-            .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer).object<KeyChain>();
+  }
+
+  static final _id_choosePrivateKeyAlias = _class.staticMethodId(
+    r'choosePrivateKeyAlias',
+    r'(Landroid/app/Activity;Landroid/security/KeyChainAliasCallback;[Ljava/lang/String;[Ljava/security/Principal;Landroid/net/Uri;Ljava/lang/String;)V',
+  );
+
+  static final _choosePrivateKeyAlias = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void choosePrivateKeyAlias(android.app.Activity activity, android.security.KeyChainAliasCallback keyChainAliasCallback, java.lang.String[] strings, java.security.Principal[] principals, android.net.Uri uri, java.lang.String string)`
+  static void choosePrivateKeyAlias(
+    jni$_.JObject? activity,
+    KeyChainAliasCallback? keyChainAliasCallback,
+    jni$_.JArray<jni$_.JString?>? strings,
+    jni$_.JArray<jni$_.JObject?>? principals,
+    jni$_.JObject? uri,
+    jni$_.JString? string,
+  ) {
+    final _$activity = activity?.reference ?? jni$_.jNullReference;
+    final _$keyChainAliasCallback =
+        keyChainAliasCallback?.reference ?? jni$_.jNullReference;
+    final _$strings = strings?.reference ?? jni$_.jNullReference;
+    final _$principals = principals?.reference ?? jni$_.jNullReference;
+    final _$uri = uri?.reference ?? jni$_.jNullReference;
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    _choosePrivateKeyAlias(
+            _class.reference.pointer,
+            _id_choosePrivateKeyAlias.pointer,
+            _$activity.pointer,
+            _$keyChainAliasCallback.pointer,
+            _$strings.pointer,
+            _$principals.pointer,
+            _$uri.pointer,
+            _$string.pointer)
+        .check();
+  }
+
+  static final _id_choosePrivateKeyAlias$1 = _class.staticMethodId(
+    r'choosePrivateKeyAlias',
+    r'(Landroid/app/Activity;Landroid/security/KeyChainAliasCallback;[Ljava/lang/String;[Ljava/security/Principal;Ljava/lang/String;ILjava/lang/String;)V',
+  );
+
+  static final _choosePrivateKeyAlias$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void choosePrivateKeyAlias(android.app.Activity activity, android.security.KeyChainAliasCallback keyChainAliasCallback, java.lang.String[] strings, java.security.Principal[] principals, java.lang.String string, int i, java.lang.String string1)`
+  static void choosePrivateKeyAlias$1(
+    jni$_.JObject? activity,
+    KeyChainAliasCallback? keyChainAliasCallback,
+    jni$_.JArray<jni$_.JString?>? strings,
+    jni$_.JArray<jni$_.JObject?>? principals,
+    jni$_.JString? string,
+    core$_.int i,
+    jni$_.JString? string1,
+  ) {
+    final _$activity = activity?.reference ?? jni$_.jNullReference;
+    final _$keyChainAliasCallback =
+        keyChainAliasCallback?.reference ?? jni$_.jNullReference;
+    final _$strings = strings?.reference ?? jni$_.jNullReference;
+    final _$principals = principals?.reference ?? jni$_.jNullReference;
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$string1 = string1?.reference ?? jni$_.jNullReference;
+    _choosePrivateKeyAlias$1(
+            _class.reference.pointer,
+            _id_choosePrivateKeyAlias$1.pointer,
+            _$activity.pointer,
+            _$keyChainAliasCallback.pointer,
+            _$strings.pointer,
+            _$principals.pointer,
+            _$string.pointer,
+            i,
+            _$string1.pointer)
+        .check();
   }
 
   static final _id_createInstallIntent = _class.staticMethodId(
@@ -25589,9 +20900,9 @@
   /// from: `static public android.content.Intent createInstallIntent()`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JObject? createInstallIntent() {
-    return _createInstallIntent(_class.reference.pointer,
-            _id_createInstallIntent as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _createInstallIntent(
+            _class.reference.pointer, _id_createInstallIntent.pointer)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_createManageCredentialsIntent = _class.staticMethodId(
@@ -25620,254 +20931,9 @@
         appUriAuthenticationPolicy?.reference ?? jni$_.jNullReference;
     return _createManageCredentialsIntent(
             _class.reference.pointer,
-            _id_createManageCredentialsIntent as jni$_.JMethodIDPtr,
+            _id_createManageCredentialsIntent.pointer,
             _$appUriAuthenticationPolicy.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_choosePrivateKeyAlias = _class.staticMethodId(
-    r'choosePrivateKeyAlias',
-    r'(Landroid/app/Activity;Landroid/security/KeyChainAliasCallback;[Ljava/lang/String;[Ljava/security/Principal;Ljava/lang/String;ILjava/lang/String;)V',
-  );
-
-  static final _choosePrivateKeyAlias = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void choosePrivateKeyAlias(android.app.Activity activity, android.security.KeyChainAliasCallback keyChainAliasCallback, java.lang.String[] strings, java.security.Principal[] principals, java.lang.String string, int i, java.lang.String string1)`
-  static void choosePrivateKeyAlias(
-    jni$_.JObject? activity,
-    KeyChainAliasCallback? keyChainAliasCallback,
-    jni$_.JArray<jni$_.JString?>? strings,
-    jni$_.JArray<jni$_.JObject?>? principals,
-    jni$_.JString? string,
-    int i,
-    jni$_.JString? string1,
-  ) {
-    final _$activity = activity?.reference ?? jni$_.jNullReference;
-    final _$keyChainAliasCallback =
-        keyChainAliasCallback?.reference ?? jni$_.jNullReference;
-    final _$strings = strings?.reference ?? jni$_.jNullReference;
-    final _$principals = principals?.reference ?? jni$_.jNullReference;
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    final _$string1 = string1?.reference ?? jni$_.jNullReference;
-    _choosePrivateKeyAlias(
-            _class.reference.pointer,
-            _id_choosePrivateKeyAlias as jni$_.JMethodIDPtr,
-            _$activity.pointer,
-            _$keyChainAliasCallback.pointer,
-            _$strings.pointer,
-            _$principals.pointer,
-            _$string.pointer,
-            i,
-            _$string1.pointer)
-        .check();
-  }
-
-  static final _id_choosePrivateKeyAlias$1 = _class.staticMethodId(
-    r'choosePrivateKeyAlias',
-    r'(Landroid/app/Activity;Landroid/security/KeyChainAliasCallback;[Ljava/lang/String;[Ljava/security/Principal;Landroid/net/Uri;Ljava/lang/String;)V',
-  );
-
-  static final _choosePrivateKeyAlias$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void choosePrivateKeyAlias(android.app.Activity activity, android.security.KeyChainAliasCallback keyChainAliasCallback, java.lang.String[] strings, java.security.Principal[] principals, android.net.Uri uri, java.lang.String string)`
-  static void choosePrivateKeyAlias$1(
-    jni$_.JObject? activity,
-    KeyChainAliasCallback? keyChainAliasCallback,
-    jni$_.JArray<jni$_.JString?>? strings,
-    jni$_.JArray<jni$_.JObject?>? principals,
-    jni$_.JObject? uri,
-    jni$_.JString? string,
-  ) {
-    final _$activity = activity?.reference ?? jni$_.jNullReference;
-    final _$keyChainAliasCallback =
-        keyChainAliasCallback?.reference ?? jni$_.jNullReference;
-    final _$strings = strings?.reference ?? jni$_.jNullReference;
-    final _$principals = principals?.reference ?? jni$_.jNullReference;
-    final _$uri = uri?.reference ?? jni$_.jNullReference;
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    _choosePrivateKeyAlias$1(
-            _class.reference.pointer,
-            _id_choosePrivateKeyAlias$1 as jni$_.JMethodIDPtr,
-            _$activity.pointer,
-            _$keyChainAliasCallback.pointer,
-            _$strings.pointer,
-            _$principals.pointer,
-            _$uri.pointer,
-            _$string.pointer)
-        .check();
-  }
-
-  static final _id_isCredentialManagementApp = _class.staticMethodId(
-    r'isCredentialManagementApp',
-    r'(Landroid/content/Context;)Z',
-  );
-
-  static final _isCredentialManagementApp = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public boolean isCredentialManagementApp(android.content.Context context)`
-  static bool isCredentialManagementApp(
-    jni$_.JObject? context,
-  ) {
-    final _$context = context?.reference ?? jni$_.jNullReference;
-    return _isCredentialManagementApp(
-            _class.reference.pointer,
-            _id_isCredentialManagementApp as jni$_.JMethodIDPtr,
-            _$context.pointer)
-        .boolean;
-  }
-
-  static final _id_getCredentialManagementAppPolicy = _class.staticMethodId(
-    r'getCredentialManagementAppPolicy',
-    r'(Landroid/content/Context;)Landroid/security/AppUriAuthenticationPolicy;',
-  );
-
-  static final _getCredentialManagementAppPolicy =
-      jni$_.ProtectedJniExtensions.lookup<
-                  jni$_.NativeFunction<
-                      jni$_.JniResult Function(
-                          jni$_.Pointer<jni$_.Void>,
-                          jni$_.JMethodIDPtr,
-                          jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-              'globalEnv_CallStaticObjectMethod')
-          .asFunction<
-              jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public android.security.AppUriAuthenticationPolicy getCredentialManagementAppPolicy(android.content.Context context)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JObject? getCredentialManagementAppPolicy(
-    jni$_.JObject? context,
-  ) {
-    final _$context = context?.reference ?? jni$_.jNullReference;
-    return _getCredentialManagementAppPolicy(
-            _class.reference.pointer,
-            _id_getCredentialManagementAppPolicy as jni$_.JMethodIDPtr,
-            _$context.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_removeCredentialManagementApp = _class.staticMethodId(
-    r'removeCredentialManagementApp',
-    r'(Landroid/content/Context;)Z',
-  );
-
-  static final _removeCredentialManagementApp =
-      jni$_.ProtectedJniExtensions.lookup<
-                  jni$_.NativeFunction<
-                      jni$_.JniResult Function(
-                          jni$_.Pointer<jni$_.Void>,
-                          jni$_.JMethodIDPtr,
-                          jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-              'globalEnv_CallStaticBooleanMethod')
-          .asFunction<
-              jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public boolean removeCredentialManagementApp(android.content.Context context)`
-  static bool removeCredentialManagementApp(
-    jni$_.JObject? context,
-  ) {
-    final _$context = context?.reference ?? jni$_.jNullReference;
-    return _removeCredentialManagementApp(
-            _class.reference.pointer,
-            _id_removeCredentialManagementApp as jni$_.JMethodIDPtr,
-            _$context.pointer)
-        .boolean;
-  }
-
-  static final _id_getPrivateKey = _class.staticMethodId(
-    r'getPrivateKey',
-    r'(Landroid/content/Context;Ljava/lang/String;)Ljava/security/PrivateKey;',
-  );
-
-  static final _getPrivateKey = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public java.security.PrivateKey getPrivateKey(android.content.Context context, java.lang.String string)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static PrivateKey? getPrivateKey(
-    jni$_.JObject? context,
-    jni$_.JString? string,
-  ) {
-    final _$context = context?.reference ?? jni$_.jNullReference;
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getPrivateKey(
-            _class.reference.pointer,
-            _id_getPrivateKey as jni$_.JMethodIDPtr,
-            _$context.pointer,
-            _$string.pointer)
-        .object<PrivateKey?>(const $PrivateKey$NullableType());
+        .object<jni$_.JObject?>();
   }
 
   static final _id_getCertificateChain = _class.staticMethodId(
@@ -25902,38 +20968,73 @@
     final _$string = string?.reference ?? jni$_.jNullReference;
     return _getCertificateChain(
             _class.reference.pointer,
-            _id_getCertificateChain as jni$_.JMethodIDPtr,
+            _id_getCertificateChain.pointer,
             _$context.pointer,
             _$string.pointer)
-        .object<jni$_.JArray<X509Certificate?>?>(
-            const jni$_.JArrayNullableType<X509Certificate?>(
-                $X509Certificate$NullableType()));
+        .object<jni$_.JArray<X509Certificate?>?>();
   }
 
-  static final _id_isKeyAlgorithmSupported = _class.staticMethodId(
-    r'isKeyAlgorithmSupported',
-    r'(Ljava/lang/String;)Z',
+  static final _id_getCredentialManagementAppPolicy = _class.staticMethodId(
+    r'getCredentialManagementAppPolicy',
+    r'(Landroid/content/Context;)Landroid/security/AppUriAuthenticationPolicy;',
   );
 
-  static final _isKeyAlgorithmSupported = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+  static final _getCredentialManagementAppPolicy =
+      jni$_.ProtectedJniExtensions.lookup<
+                  jni$_.NativeFunction<
+                      jni$_.JniResult Function(
+                          jni$_.Pointer<jni$_.Void>,
+                          jni$_.JMethodIDPtr,
+                          jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+              'globalEnv_CallStaticObjectMethod')
+          .asFunction<
+              jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public boolean isKeyAlgorithmSupported(java.lang.String string)`
-  static bool isKeyAlgorithmSupported(
+  /// from: `static public android.security.AppUriAuthenticationPolicy getCredentialManagementAppPolicy(android.content.Context context)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JObject? getCredentialManagementAppPolicy(
+    jni$_.JObject? context,
+  ) {
+    final _$context = context?.reference ?? jni$_.jNullReference;
+    return _getCredentialManagementAppPolicy(_class.reference.pointer,
+            _id_getCredentialManagementAppPolicy.pointer, _$context.pointer)
+        .object<jni$_.JObject?>();
+  }
+
+  static final _id_getPrivateKey = _class.staticMethodId(
+    r'getPrivateKey',
+    r'(Landroid/content/Context;Ljava/lang/String;)Ljava/security/PrivateKey;',
+  );
+
+  static final _getPrivateKey = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public java.security.PrivateKey getPrivateKey(android.content.Context context, java.lang.String string)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static PrivateKey? getPrivateKey(
+    jni$_.JObject? context,
     jni$_.JString? string,
   ) {
+    final _$context = context?.reference ?? jni$_.jNullReference;
     final _$string = string?.reference ?? jni$_.jNullReference;
-    return _isKeyAlgorithmSupported(_class.reference.pointer,
-            _id_isKeyAlgorithmSupported as jni$_.JMethodIDPtr, _$string.pointer)
-        .boolean;
+    return _getPrivateKey(_class.reference.pointer, _id_getPrivateKey.pointer,
+            _$context.pointer, _$string.pointer)
+        .object<PrivateKey?>();
   }
 
   static final _id_isBoundKeyAlgorithm = _class.staticMethodId(
@@ -25953,134 +21054,118 @@
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
   /// from: `static public boolean isBoundKeyAlgorithm(java.lang.String string)`
-  static bool isBoundKeyAlgorithm(
+  static core$_.bool isBoundKeyAlgorithm(
     jni$_.JString? string,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     return _isBoundKeyAlgorithm(_class.reference.pointer,
-            _id_isBoundKeyAlgorithm as jni$_.JMethodIDPtr, _$string.pointer)
+            _id_isBoundKeyAlgorithm.pointer, _$string.pointer)
+        .boolean;
+  }
+
+  static final _id_isCredentialManagementApp = _class.staticMethodId(
+    r'isCredentialManagementApp',
+    r'(Landroid/content/Context;)Z',
+  );
+
+  static final _isCredentialManagementApp = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean isCredentialManagementApp(android.content.Context context)`
+  static core$_.bool isCredentialManagementApp(
+    jni$_.JObject? context,
+  ) {
+    final _$context = context?.reference ?? jni$_.jNullReference;
+    return _isCredentialManagementApp(_class.reference.pointer,
+            _id_isCredentialManagementApp.pointer, _$context.pointer)
+        .boolean;
+  }
+
+  static final _id_isKeyAlgorithmSupported = _class.staticMethodId(
+    r'isKeyAlgorithmSupported',
+    r'(Ljava/lang/String;)Z',
+  );
+
+  static final _isKeyAlgorithmSupported = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean isKeyAlgorithmSupported(java.lang.String string)`
+  static core$_.bool isKeyAlgorithmSupported(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return _isKeyAlgorithmSupported(_class.reference.pointer,
+            _id_isKeyAlgorithmSupported.pointer, _$string.pointer)
+        .boolean;
+  }
+
+  static final _id_removeCredentialManagementApp = _class.staticMethodId(
+    r'removeCredentialManagementApp',
+    r'(Landroid/content/Context;)Z',
+  );
+
+  static final _removeCredentialManagementApp =
+      jni$_.ProtectedJniExtensions.lookup<
+                  jni$_.NativeFunction<
+                      jni$_.JniResult Function(
+                          jni$_.Pointer<jni$_.Void>,
+                          jni$_.JMethodIDPtr,
+                          jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+              'globalEnv_CallStaticBooleanMethod')
+          .asFunction<
+              jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean removeCredentialManagementApp(android.content.Context context)`
+  static core$_.bool removeCredentialManagementApp(
+    jni$_.JObject? context,
+  ) {
+    final _$context = context?.reference ?? jni$_.jNullReference;
+    return _removeCredentialManagementApp(_class.reference.pointer,
+            _id_removeCredentialManagementApp.pointer, _$context.pointer)
         .boolean;
   }
 }
 
-final class $KeyChain$NullableType extends jni$_.JObjType<KeyChain?> {
+final class $KeyChain$Type$ extends jni$_.JType<KeyChain> {
   @jni$_.internal
-  const $KeyChain$NullableType();
+  const $KeyChain$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Landroid/security/KeyChain;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyChain? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : KeyChain.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyChain?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyChain$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyChain$NullableType) &&
-        other is $KeyChain$NullableType;
-  }
-}
-
-final class $KeyChain$Type extends jni$_.JObjType<KeyChain> {
-  @jni$_.internal
-  const $KeyChain$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Landroid/security/KeyChain;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyChain fromReference(jni$_.JReference reference) => KeyChain.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyChain?> get nullableType => const $KeyChain$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyChain$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyChain$Type) && other is $KeyChain$Type;
-  }
 }
 
 /// from: `android.security.KeyChainAliasCallback`
-class KeyChainAliasCallback extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyChainAliasCallback> $type;
-
-  @jni$_.internal
-  KeyChainAliasCallback.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyChainAliasCallback._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class =
       jni$_.JClass.forName(r'android/security/KeyChainAliasCallback');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyChainAliasCallback$NullableType();
-  static const type = $KeyChainAliasCallback$Type();
-  static final _id_alias = _class.instanceMethodId(
-    r'alias',
-    r'(Ljava/lang/String;)V',
-  );
-
-  static final _alias = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public abstract void alias(java.lang.String string)`
-  void alias(
-    jni$_.JString? string,
-  ) {
-    final _$string = string?.reference ?? jni$_.jNullReference;
-    _alias(reference.pointer, _id_alias as jni$_.JMethodIDPtr, _$string.pointer)
-        .check();
-  }
+  static const jni$_.JType<KeyChainAliasCallback> type =
+      $KeyChainAliasCallback$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $KeyChainAliasCallback> _$impls = {};
+  static final core$_.Map<core$_.int, $KeyChainAliasCallback> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -26101,7 +21186,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -26109,7 +21194,7 @@
       final $a = $i.args;
       if ($d == r'alias(Ljava/lang/String;)V') {
         _$impls[$p]!.alias(
-          $a![0]?.as(const jni$_.JStringType(), releaseOriginal: true),
+          ($a![0] as jni$_.JString?),
         );
         return jni$_.nullptr;
       }
@@ -26151,20 +21236,44 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return KeyChainAliasCallback.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<KeyChainAliasCallback>();
+  }
+}
+
+extension KeyChainAliasCallback$$Methods on KeyChainAliasCallback {
+  static final _id_alias = KeyChainAliasCallback._class.instanceMethodId(
+    r'alias',
+    r'(Ljava/lang/String;)V',
+  );
+
+  static final _alias = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public abstract void alias(java.lang.String string)`
+  void alias(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    _alias(reference.pointer, _id_alias.pointer, _$string.pointer).check();
   }
 }
 
 abstract base mixin class $KeyChainAliasCallback {
   factory $KeyChainAliasCallback({
     required void Function(jni$_.JString? string) alias,
-    bool alias$async,
+    core$_.bool alias$async,
   }) = _$KeyChainAliasCallback;
 
   void alias(jni$_.JString? string);
-  bool get alias$async => false;
+  core$_.bool get alias$async => false;
 }
 
 final class _$KeyChainAliasCallback with $KeyChainAliasCallback {
@@ -26174,115 +21283,38 @@
   }) : _alias = alias;
 
   final void Function(jni$_.JString? string) _alias;
-  final bool alias$async;
+  final core$_.bool alias$async;
 
   void alias(jni$_.JString? string) {
     return _alias(string);
   }
 }
 
-final class $KeyChainAliasCallback$NullableType
-    extends jni$_.JObjType<KeyChainAliasCallback?> {
+final class $KeyChainAliasCallback$Type$
+    extends jni$_.JType<KeyChainAliasCallback> {
   @jni$_.internal
-  const $KeyChainAliasCallback$NullableType();
+  const $KeyChainAliasCallback$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Landroid/security/KeyChainAliasCallback;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyChainAliasCallback? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyChainAliasCallback.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyChainAliasCallback?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyChainAliasCallback$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyChainAliasCallback$NullableType) &&
-        other is $KeyChainAliasCallback$NullableType;
-  }
-}
-
-final class $KeyChainAliasCallback$Type
-    extends jni$_.JObjType<KeyChainAliasCallback> {
-  @jni$_.internal
-  const $KeyChainAliasCallback$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Landroid/security/KeyChainAliasCallback;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyChainAliasCallback fromReference(jni$_.JReference reference) =>
-      KeyChainAliasCallback.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyChainAliasCallback?> get nullableType =>
-      const $KeyChainAliasCallback$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyChainAliasCallback$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyChainAliasCallback$Type) &&
-        other is $KeyChainAliasCallback$Type;
-  }
 }
 
 /// from: `java.security.PrivateKey`
-class PrivateKey extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<PrivateKey> $type;
-
-  @jni$_.internal
-  PrivateKey.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type PrivateKey._(jni$_.JObject _$this)
+    implements jni$_.JObject, Key {
   static final _class = jni$_.JClass.forName(r'java/security/PrivateKey');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $PrivateKey$NullableType();
-  static const type = $PrivateKey$Type();
+  static const jni$_.JType<PrivateKey> type = $PrivateKey$Type$();
 
   /// from: `static public final long serialVersionUID`
   static const serialVersionUID = 6034044314589513430;
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $PrivateKey> _$impls = {};
+  static final core$_.Map<core$_.int, $PrivateKey> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -26303,12 +21335,36 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
       final $d = $i.methodDescriptor.toDartString(releaseOriginal: true);
       final $a = $i.args;
+      if ($d == r'getAlgorithm()Ljava/lang/String;') {
+        final $r = _$impls[$p]!.getAlgorithm();
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
+      if ($d == r'getEncoded()[B') {
+        final $r = _$impls[$p]!.getEncoded();
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
+      if ($d == r'getFormat()Ljava/lang/String;') {
+        final $r = _$impls[$p]!.getFormat();
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
     } catch (e) {
       return jni$_.ProtectedJniExtensions.newDartException(e);
     }
@@ -26345,114 +21401,12 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return PrivateKey.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<PrivateKey>();
   }
 }
 
-abstract base mixin class $PrivateKey {
-  factory $PrivateKey() = _$PrivateKey;
-}
-
-final class _$PrivateKey with $PrivateKey {
-  _$PrivateKey();
-}
-
-final class $PrivateKey$NullableType extends jni$_.JObjType<PrivateKey?> {
-  @jni$_.internal
-  const $PrivateKey$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/PrivateKey;';
-
-  @jni$_.internal
-  @core$_.override
-  PrivateKey? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : PrivateKey.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<PrivateKey?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($PrivateKey$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($PrivateKey$NullableType) &&
-        other is $PrivateKey$NullableType;
-  }
-}
-
-final class $PrivateKey$Type extends jni$_.JObjType<PrivateKey> {
-  @jni$_.internal
-  const $PrivateKey$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/PrivateKey;';
-
-  @jni$_.internal
-  @core$_.override
-  PrivateKey fromReference(jni$_.JReference reference) =>
-      PrivateKey.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<PrivateKey?> get nullableType =>
-      const $PrivateKey$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($PrivateKey$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($PrivateKey$Type) && other is $PrivateKey$Type;
-  }
-}
-
-/// from: `java.security.Key`
-class Key extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Key> $type;
-
-  @jni$_.internal
-  Key.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
-  static final _class = jni$_.JClass.forName(r'java/security/Key');
-
-  /// The type which includes information such as the signature of this class.
-  static const nullableType = $Key$NullableType();
-  static const type = $Key$Type();
-
-  /// from: `static public final long serialVersionUID`
-  static const serialVersionUID = 6603384152749567654;
-  static final _id_getAlgorithm = _class.instanceMethodId(
+extension PrivateKey$$Methods on PrivateKey {
+  static final _id_getAlgorithm = PrivateKey._class.instanceMethodId(
     r'getAlgorithm',
     r'()Ljava/lang/String;',
   );
@@ -26472,36 +21426,11 @@
   /// from: `public abstract java.lang.String getAlgorithm()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString? getAlgorithm() {
-    return _getAlgorithm(
-            reference.pointer, _id_getAlgorithm as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+    return _getAlgorithm(reference.pointer, _id_getAlgorithm.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_getFormat = _class.instanceMethodId(
-    r'getFormat',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _getFormat = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.lang.String getFormat()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getFormat() {
-    return _getFormat(reference.pointer, _id_getFormat as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getEncoded = _class.instanceMethodId(
+  static final _id_getEncoded = PrivateKey._class.instanceMethodId(
     r'getEncoded',
     r'()[B',
   );
@@ -26521,14 +21450,96 @@
   /// from: `public abstract byte[] getEncoded()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JByteArray? getEncoded() {
-    return _getEncoded(reference.pointer, _id_getEncoded as jni$_.JMethodIDPtr)
-        .object<jni$_.JByteArray?>(const jni$_.JByteArrayNullableType());
+    return _getEncoded(reference.pointer, _id_getEncoded.pointer)
+        .object<jni$_.JByteArray?>();
   }
 
+  static final _id_getFormat = PrivateKey._class.instanceMethodId(
+    r'getFormat',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _getFormat = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.lang.String getFormat()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? getFormat() {
+    return _getFormat(reference.pointer, _id_getFormat.pointer)
+        .object<jni$_.JString?>();
+  }
+}
+
+abstract base mixin class $PrivateKey {
+  factory $PrivateKey({
+    required jni$_.JString? Function() getAlgorithm,
+    required jni$_.JByteArray? Function() getEncoded,
+    required jni$_.JString? Function() getFormat,
+  }) = _$PrivateKey;
+
+  jni$_.JString? getAlgorithm();
+  jni$_.JByteArray? getEncoded();
+  jni$_.JString? getFormat();
+}
+
+final class _$PrivateKey with $PrivateKey {
+  _$PrivateKey({
+    required jni$_.JString? Function() getAlgorithm,
+    required jni$_.JByteArray? Function() getEncoded,
+    required jni$_.JString? Function() getFormat,
+  })  : _getAlgorithm = getAlgorithm,
+        _getEncoded = getEncoded,
+        _getFormat = getFormat;
+
+  final jni$_.JString? Function() _getAlgorithm;
+  final jni$_.JByteArray? Function() _getEncoded;
+  final jni$_.JString? Function() _getFormat;
+
+  jni$_.JString? getAlgorithm() {
+    return _getAlgorithm();
+  }
+
+  jni$_.JByteArray? getEncoded() {
+    return _getEncoded();
+  }
+
+  jni$_.JString? getFormat() {
+    return _getFormat();
+  }
+}
+
+final class $PrivateKey$Type$ extends jni$_.JType<PrivateKey> {
+  @jni$_.internal
+  const $PrivateKey$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Ljava/security/PrivateKey;';
+}
+
+/// from: `java.security.Key`
+extension type Key._(jni$_.JObject _$this) implements jni$_.JObject {
+  static final _class = jni$_.JClass.forName(r'java/security/Key');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<Key> type = $Key$Type$();
+
+  /// from: `static public final long serialVersionUID`
+  static const serialVersionUID = 6603384152749567654;
+
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $Key> _$impls = {};
+  static final core$_.Map<core$_.int, $Key> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -26549,7 +21560,7 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
@@ -26558,15 +21569,7 @@
       if ($d == r'getAlgorithm()Ljava/lang/String;') {
         final $r = _$impls[$p]!.getAlgorithm();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
-                .reference
-                .toPointer() ??
-            jni$_.nullptr;
-      }
-      if ($d == r'getFormat()Ljava/lang/String;') {
-        final $r = _$impls[$p]!.getFormat();
-        return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -26574,7 +21577,15 @@
       if ($d == r'getEncoded()[B') {
         final $r = _$impls[$p]!.getEncoded();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
+      if ($d == r'getFormat()Ljava/lang/String;') {
+        final $r = _$impls[$p]!.getFormat();
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -26615,165 +21626,12 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return Key.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<Key>();
   }
 }
 
-abstract base mixin class $Key {
-  factory $Key({
-    required jni$_.JString? Function() getAlgorithm,
-    required jni$_.JString? Function() getFormat,
-    required jni$_.JByteArray? Function() getEncoded,
-  }) = _$Key;
-
-  jni$_.JString? getAlgorithm();
-  jni$_.JString? getFormat();
-  jni$_.JByteArray? getEncoded();
-}
-
-final class _$Key with $Key {
-  _$Key({
-    required jni$_.JString? Function() getAlgorithm,
-    required jni$_.JString? Function() getFormat,
-    required jni$_.JByteArray? Function() getEncoded,
-  })  : _getAlgorithm = getAlgorithm,
-        _getFormat = getFormat,
-        _getEncoded = getEncoded;
-
-  final jni$_.JString? Function() _getAlgorithm;
-  final jni$_.JString? Function() _getFormat;
-  final jni$_.JByteArray? Function() _getEncoded;
-
-  jni$_.JString? getAlgorithm() {
-    return _getAlgorithm();
-  }
-
-  jni$_.JString? getFormat() {
-    return _getFormat();
-  }
-
-  jni$_.JByteArray? getEncoded() {
-    return _getEncoded();
-  }
-}
-
-final class $Key$NullableType extends jni$_.JObjType<Key?> {
-  @jni$_.internal
-  const $Key$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/Key;';
-
-  @jni$_.internal
-  @core$_.override
-  Key? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Key.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Key?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Key$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Key$NullableType) &&
-        other is $Key$NullableType;
-  }
-}
-
-final class $Key$Type extends jni$_.JObjType<Key> {
-  @jni$_.internal
-  const $Key$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/Key;';
-
-  @jni$_.internal
-  @core$_.override
-  Key fromReference(jni$_.JReference reference) => Key.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Key?> get nullableType => const $Key$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Key$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Key$Type) && other is $Key$Type;
-  }
-}
-
-/// from: `javax.net.ssl.KeyManagerFactory`
-class KeyManagerFactory extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyManagerFactory> $type;
-
-  @jni$_.internal
-  KeyManagerFactory.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
-  static final _class =
-      jni$_.JClass.forName(r'javax/net/ssl/KeyManagerFactory');
-
-  /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyManagerFactory$NullableType();
-  static const type = $KeyManagerFactory$Type();
-  static final _id_getDefaultAlgorithm = _class.staticMethodId(
-    r'getDefaultAlgorithm',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _getDefaultAlgorithm = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `static public final java.lang.String getDefaultAlgorithm()`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? getDefaultAlgorithm() {
-    return _getDefaultAlgorithm(_class.reference.pointer,
-            _id_getDefaultAlgorithm as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getAlgorithm = _class.instanceMethodId(
+extension Key$$Methods on Key {
+  static final _id_getAlgorithm = Key._class.instanceMethodId(
     r'getAlgorithm',
     r'()Ljava/lang/String;',
   );
@@ -26790,12 +21648,140 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public final java.lang.String getAlgorithm()`
+  /// from: `public abstract java.lang.String getAlgorithm()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JString? getAlgorithm() {
-    return _getAlgorithm(
-            reference.pointer, _id_getAlgorithm as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+    return _getAlgorithm(reference.pointer, _id_getAlgorithm.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_getEncoded = Key._class.instanceMethodId(
+    r'getEncoded',
+    r'()[B',
+  );
+
+  static final _getEncoded = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract byte[] getEncoded()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JByteArray? getEncoded() {
+    return _getEncoded(reference.pointer, _id_getEncoded.pointer)
+        .object<jni$_.JByteArray?>();
+  }
+
+  static final _id_getFormat = Key._class.instanceMethodId(
+    r'getFormat',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _getFormat = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.lang.String getFormat()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? getFormat() {
+    return _getFormat(reference.pointer, _id_getFormat.pointer)
+        .object<jni$_.JString?>();
+  }
+}
+
+abstract base mixin class $Key {
+  factory $Key({
+    required jni$_.JString? Function() getAlgorithm,
+    required jni$_.JByteArray? Function() getEncoded,
+    required jni$_.JString? Function() getFormat,
+  }) = _$Key;
+
+  jni$_.JString? getAlgorithm();
+  jni$_.JByteArray? getEncoded();
+  jni$_.JString? getFormat();
+}
+
+final class _$Key with $Key {
+  _$Key({
+    required jni$_.JString? Function() getAlgorithm,
+    required jni$_.JByteArray? Function() getEncoded,
+    required jni$_.JString? Function() getFormat,
+  })  : _getAlgorithm = getAlgorithm,
+        _getEncoded = getEncoded,
+        _getFormat = getFormat;
+
+  final jni$_.JString? Function() _getAlgorithm;
+  final jni$_.JByteArray? Function() _getEncoded;
+  final jni$_.JString? Function() _getFormat;
+
+  jni$_.JString? getAlgorithm() {
+    return _getAlgorithm();
+  }
+
+  jni$_.JByteArray? getEncoded() {
+    return _getEncoded();
+  }
+
+  jni$_.JString? getFormat() {
+    return _getFormat();
+  }
+}
+
+final class $Key$Type$ extends jni$_.JType<Key> {
+  @jni$_.internal
+  const $Key$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Ljava/security/Key;';
+}
+
+/// from: `javax.net.ssl.KeyManagerFactory`
+extension type KeyManagerFactory._(jni$_.JObject _$this)
+    implements jni$_.JObject {
+  static final _class =
+      jni$_.JClass.forName(r'javax/net/ssl/KeyManagerFactory');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<KeyManagerFactory> type = $KeyManagerFactory$Type$();
+  static final _id_get$defaultAlgorithm = _class.staticMethodId(
+    r'getDefaultAlgorithm',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _get$defaultAlgorithm = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `static public final java.lang.String getDefaultAlgorithm()`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JString? get defaultAlgorithm {
+    return _get$defaultAlgorithm(
+            _class.reference.pointer, _id_get$defaultAlgorithm.pointer)
+        .object<jni$_.JString?>();
   }
 
   static final _id_getInstance = _class.staticMethodId(
@@ -26820,9 +21806,9 @@
     jni$_.JString? string,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getInstance(_class.reference.pointer,
-            _id_getInstance as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<KeyManagerFactory?>(const $KeyManagerFactory$NullableType());
+    return _getInstance(
+            _class.reference.pointer, _id_getInstance.pointer, _$string.pointer)
+        .object<KeyManagerFactory?>();
   }
 
   static final _id_getInstance$1 = _class.staticMethodId(
@@ -26855,12 +21841,9 @@
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$string1 = string1?.reference ?? jni$_.jNullReference;
-    return _getInstance$1(
-            _class.reference.pointer,
-            _id_getInstance$1 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$string1.pointer)
-        .object<KeyManagerFactory?>(const $KeyManagerFactory$NullableType());
+    return _getInstance$1(_class.reference.pointer, _id_getInstance$1.pointer,
+            _$string.pointer, _$string1.pointer)
+        .object<KeyManagerFactory?>();
   }
 
   static final _id_getInstance$2 = _class.staticMethodId(
@@ -26893,20 +21876,67 @@
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$provider = provider?.reference ?? jni$_.jNullReference;
-    return _getInstance$2(
-            _class.reference.pointer,
-            _id_getInstance$2 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$provider.pointer)
-        .object<KeyManagerFactory?>(const $KeyManagerFactory$NullableType());
+    return _getInstance$2(_class.reference.pointer, _id_getInstance$2.pointer,
+            _$string.pointer, _$provider.pointer)
+        .object<KeyManagerFactory?>();
+  }
+}
+
+extension KeyManagerFactory$$Methods on KeyManagerFactory {
+  static final _id_get$algorithm = KeyManagerFactory._class.instanceMethodId(
+    r'getAlgorithm',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _get$algorithm = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.lang.String getAlgorithm()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? get algorithm {
+    return _get$algorithm(reference.pointer, _id_get$algorithm.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_getProvider = _class.instanceMethodId(
+  static final _id_get$keyManagers = KeyManagerFactory._class.instanceMethodId(
+    r'getKeyManagers',
+    r'()[Ljavax/net/ssl/KeyManager;',
+  );
+
+  static final _get$keyManagers = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final javax.net.ssl.KeyManager[] getKeyManagers()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<KeyManager?>? get keyManagers {
+    return _get$keyManagers(reference.pointer, _id_get$keyManagers.pointer)
+        .object<jni$_.JArray<KeyManager?>?>();
+  }
+
+  static final _id_get$provider = KeyManagerFactory._class.instanceMethodId(
     r'getProvider',
     r'()Ljava/security/Provider;',
   );
 
-  static final _getProvider = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$provider = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -26920,13 +21950,12 @@
 
   /// from: `public final java.security.Provider getProvider()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getProvider() {
-    return _getProvider(
-            reference.pointer, _id_getProvider as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  jni$_.JObject? get provider {
+    return _get$provider(reference.pointer, _id_get$provider.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_init = _class.instanceMethodId(
+  static final _id_init = KeyManagerFactory._class.instanceMethodId(
     r'init',
     r'(Ljava/security/KeyStore;[C)V',
   );
@@ -26955,12 +21984,11 @@
   ) {
     final _$keyStore = keyStore?.reference ?? jni$_.jNullReference;
     final _$cs = cs?.reference ?? jni$_.jNullReference;
-    _init(reference.pointer, _id_init as jni$_.JMethodIDPtr, _$keyStore.pointer,
-            _$cs.pointer)
+    _init(reference.pointer, _id_init.pointer, _$keyStore.pointer, _$cs.pointer)
         .check();
   }
 
-  static final _id_init$1 = _class.instanceMethodId(
+  static final _id_init$1 = KeyManagerFactory._class.instanceMethodId(
     r'init',
     r'(Ljavax/net/ssl/ManagerFactoryParameters;)V',
   );
@@ -26982,157 +22010,28 @@
   ) {
     final _$managerFactoryParameters =
         managerFactoryParameters?.reference ?? jni$_.jNullReference;
-    _init$1(reference.pointer, _id_init$1 as jni$_.JMethodIDPtr,
+    _init$1(reference.pointer, _id_init$1.pointer,
             _$managerFactoryParameters.pointer)
         .check();
   }
-
-  static final _id_getKeyManagers = _class.instanceMethodId(
-    r'getKeyManagers',
-    r'()[Ljavax/net/ssl/KeyManager;',
-  );
-
-  static final _getKeyManagers = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final javax.net.ssl.KeyManager[] getKeyManagers()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JArray<KeyManager?>? getKeyManagers() {
-    return _getKeyManagers(
-            reference.pointer, _id_getKeyManagers as jni$_.JMethodIDPtr)
-        .object<jni$_.JArray<KeyManager?>?>(
-            const jni$_.JArrayNullableType<KeyManager?>(
-                $KeyManager$NullableType()));
-  }
 }
 
-final class $KeyManagerFactory$NullableType
-    extends jni$_.JObjType<KeyManagerFactory?> {
+final class $KeyManagerFactory$Type$ extends jni$_.JType<KeyManagerFactory> {
   @jni$_.internal
-  const $KeyManagerFactory$NullableType();
+  const $KeyManagerFactory$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljavax/net/ssl/KeyManagerFactory;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyManagerFactory? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyManagerFactory.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyManagerFactory?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyManagerFactory$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyManagerFactory$NullableType) &&
-        other is $KeyManagerFactory$NullableType;
-  }
-}
-
-final class $KeyManagerFactory$Type extends jni$_.JObjType<KeyManagerFactory> {
-  @jni$_.internal
-  const $KeyManagerFactory$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljavax/net/ssl/KeyManagerFactory;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyManagerFactory fromReference(jni$_.JReference reference) =>
-      KeyManagerFactory.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyManagerFactory?> get nullableType =>
-      const $KeyManagerFactory$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyManagerFactory$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyManagerFactory$Type) &&
-        other is $KeyManagerFactory$Type;
-  }
 }
 
 /// from: `java.security.KeyPairGenerator`
-class KeyPairGenerator extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyPairGenerator> $type;
-
-  @jni$_.internal
-  KeyPairGenerator.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyPairGenerator._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'java/security/KeyPairGenerator');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyPairGenerator$NullableType();
-  static const type = $KeyPairGenerator$Type();
-  static final _id_getAlgorithm = _class.instanceMethodId(
-    r'getAlgorithm',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _getAlgorithm = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.lang.String getAlgorithm()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getAlgorithm() {
-    return _getAlgorithm(
-            reference.pointer, _id_getAlgorithm as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
+  static const jni$_.JType<KeyPairGenerator> type = $KeyPairGenerator$Type$();
   static final _id_getInstance = _class.staticMethodId(
     r'getInstance',
     r'(Ljava/lang/String;)Ljava/security/KeyPairGenerator;',
@@ -27155,9 +22054,9 @@
     jni$_.JString? string,
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
-    return _getInstance(_class.reference.pointer,
-            _id_getInstance as jni$_.JMethodIDPtr, _$string.pointer)
-        .object<KeyPairGenerator?>(const $KeyPairGenerator$NullableType());
+    return _getInstance(
+            _class.reference.pointer, _id_getInstance.pointer, _$string.pointer)
+        .object<KeyPairGenerator?>();
   }
 
   static final _id_getInstance$1 = _class.staticMethodId(
@@ -27190,12 +22089,9 @@
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$string1 = string1?.reference ?? jni$_.jNullReference;
-    return _getInstance$1(
-            _class.reference.pointer,
-            _id_getInstance$1 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$string1.pointer)
-        .object<KeyPairGenerator?>(const $KeyPairGenerator$NullableType());
+    return _getInstance$1(_class.reference.pointer, _id_getInstance$1.pointer,
+            _$string.pointer, _$string1.pointer)
+        .object<KeyPairGenerator?>();
   }
 
   static final _id_getInstance$2 = _class.staticMethodId(
@@ -27228,20 +22124,91 @@
   ) {
     final _$string = string?.reference ?? jni$_.jNullReference;
     final _$provider = provider?.reference ?? jni$_.jNullReference;
-    return _getInstance$2(
-            _class.reference.pointer,
-            _id_getInstance$2 as jni$_.JMethodIDPtr,
-            _$string.pointer,
-            _$provider.pointer)
-        .object<KeyPairGenerator?>(const $KeyPairGenerator$NullableType());
+    return _getInstance$2(_class.reference.pointer, _id_getInstance$2.pointer,
+            _$string.pointer, _$provider.pointer)
+        .object<KeyPairGenerator?>();
+  }
+}
+
+extension KeyPairGenerator$$Methods on KeyPairGenerator {
+  static final _id_genKeyPair = KeyPairGenerator._class.instanceMethodId(
+    r'genKeyPair',
+    r'()Ljava/security/KeyPair;',
+  );
+
+  static final _genKeyPair = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.security.KeyPair genKeyPair()`
+  /// The returned object must be released after use, by calling the [release] method.
+  KeyPair? genKeyPair() {
+    return _genKeyPair(reference.pointer, _id_genKeyPair.pointer)
+        .object<KeyPair?>();
   }
 
-  static final _id_getProvider = _class.instanceMethodId(
+  static final _id_generateKeyPair = KeyPairGenerator._class.instanceMethodId(
+    r'generateKeyPair',
+    r'()Ljava/security/KeyPair;',
+  );
+
+  static final _generateKeyPair = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.security.KeyPair generateKeyPair()`
+  /// The returned object must be released after use, by calling the [release] method.
+  KeyPair? generateKeyPair() {
+    return _generateKeyPair(reference.pointer, _id_generateKeyPair.pointer)
+        .object<KeyPair?>();
+  }
+
+  static final _id_get$algorithm = KeyPairGenerator._class.instanceMethodId(
+    r'getAlgorithm',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _get$algorithm = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.lang.String getAlgorithm()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? get algorithm {
+    return _get$algorithm(reference.pointer, _id_get$algorithm.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_get$provider = KeyPairGenerator._class.instanceMethodId(
     r'getProvider',
     r'()Ljava/security/Provider;',
   );
 
-  static final _getProvider = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$provider = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -27255,13 +22222,12 @@
 
   /// from: `public final java.security.Provider getProvider()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JObject? getProvider() {
-    return _getProvider(
-            reference.pointer, _id_getProvider as jni$_.JMethodIDPtr)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  jni$_.JObject? get provider {
+    return _get$provider(reference.pointer, _id_get$provider.pointer)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_initialize = _class.instanceMethodId(
+  static final _id_initialize = KeyPairGenerator._class.instanceMethodId(
     r'initialize',
     r'(I)V',
   );
@@ -27274,17 +22240,16 @@
                   jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod')
       .asFunction<
           jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
 
   /// from: `public void initialize(int i)`
   void initialize(
-    int i,
+    core$_.int i,
   ) {
-    _initialize(reference.pointer, _id_initialize as jni$_.JMethodIDPtr, i)
-        .check();
+    _initialize(reference.pointer, _id_initialize.pointer, i).check();
   }
 
-  static final _id_initialize$1 = _class.instanceMethodId(
+  static final _id_initialize$1 = KeyPairGenerator._class.instanceMethodId(
     r'initialize',
     r'(ILjava/security/SecureRandom;)V',
   );
@@ -27299,20 +22264,20 @@
           'globalEnv_CallVoidMethod')
       .asFunction<
           jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, int, jni$_.Pointer<jni$_.Void>)>();
+              jni$_.JMethodIDPtr, core$_.int, jni$_.Pointer<jni$_.Void>)>();
 
   /// from: `public void initialize(int i, java.security.SecureRandom secureRandom)`
   void initialize$1(
-    int i,
+    core$_.int i,
     SecureRandom? secureRandom,
   ) {
     final _$secureRandom = secureRandom?.reference ?? jni$_.jNullReference;
-    _initialize$1(reference.pointer, _id_initialize$1 as jni$_.JMethodIDPtr, i,
+    _initialize$1(reference.pointer, _id_initialize$1.pointer, i,
             _$secureRandom.pointer)
         .check();
   }
 
-  static final _id_initialize$2 = _class.instanceMethodId(
+  static final _id_initialize$2 = KeyPairGenerator._class.instanceMethodId(
     r'initialize',
     r'(Ljava/security/spec/AlgorithmParameterSpec;)V',
   );
@@ -27334,12 +22299,12 @@
   ) {
     final _$algorithmParameterSpec =
         algorithmParameterSpec?.reference ?? jni$_.jNullReference;
-    _initialize$2(reference.pointer, _id_initialize$2 as jni$_.JMethodIDPtr,
+    _initialize$2(reference.pointer, _id_initialize$2.pointer,
             _$algorithmParameterSpec.pointer)
         .check();
   }
 
-  static final _id_initialize$3 = _class.instanceMethodId(
+  static final _id_initialize$3 = KeyPairGenerator._class.instanceMethodId(
     r'initialize',
     r'(Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)V',
   );
@@ -27369,154 +22334,27 @@
     final _$algorithmParameterSpec =
         algorithmParameterSpec?.reference ?? jni$_.jNullReference;
     final _$secureRandom = secureRandom?.reference ?? jni$_.jNullReference;
-    _initialize$3(reference.pointer, _id_initialize$3 as jni$_.JMethodIDPtr,
+    _initialize$3(reference.pointer, _id_initialize$3.pointer,
             _$algorithmParameterSpec.pointer, _$secureRandom.pointer)
         .check();
   }
-
-  static final _id_genKeyPair = _class.instanceMethodId(
-    r'genKeyPair',
-    r'()Ljava/security/KeyPair;',
-  );
-
-  static final _genKeyPair = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.security.KeyPair genKeyPair()`
-  /// The returned object must be released after use, by calling the [release] method.
-  KeyPair? genKeyPair() {
-    return _genKeyPair(reference.pointer, _id_genKeyPair as jni$_.JMethodIDPtr)
-        .object<KeyPair?>(const $KeyPair$NullableType());
-  }
-
-  static final _id_generateKeyPair = _class.instanceMethodId(
-    r'generateKeyPair',
-    r'()Ljava/security/KeyPair;',
-  );
-
-  static final _generateKeyPair = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.security.KeyPair generateKeyPair()`
-  /// The returned object must be released after use, by calling the [release] method.
-  KeyPair? generateKeyPair() {
-    return _generateKeyPair(
-            reference.pointer, _id_generateKeyPair as jni$_.JMethodIDPtr)
-        .object<KeyPair?>(const $KeyPair$NullableType());
-  }
 }
 
-final class $KeyPairGenerator$NullableType
-    extends jni$_.JObjType<KeyPairGenerator?> {
+final class $KeyPairGenerator$Type$ extends jni$_.JType<KeyPairGenerator> {
   @jni$_.internal
-  const $KeyPairGenerator$NullableType();
+  const $KeyPairGenerator$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyPairGenerator;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyPairGenerator? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : KeyPairGenerator.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyPairGenerator?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyPairGenerator$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyPairGenerator$NullableType) &&
-        other is $KeyPairGenerator$NullableType;
-  }
-}
-
-final class $KeyPairGenerator$Type extends jni$_.JObjType<KeyPairGenerator> {
-  @jni$_.internal
-  const $KeyPairGenerator$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyPairGenerator;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyPairGenerator fromReference(jni$_.JReference reference) =>
-      KeyPairGenerator.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyPairGenerator?> get nullableType =>
-      const $KeyPairGenerator$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyPairGenerator$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyPairGenerator$Type) &&
-        other is $KeyPairGenerator$Type;
-  }
 }
 
 /// from: `java.security.KeyPair`
-class KeyPair extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<KeyPair> $type;
-
-  @jni$_.internal
-  KeyPair.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type KeyPair._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'java/security/KeyPair');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $KeyPair$NullableType();
-  static const type = $KeyPair$Type();
+  static const jni$_.JType<KeyPair> type = $KeyPair$Type$();
   static final _id_new$ = _class.constructorId(
     r'(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V',
   );
@@ -27546,44 +22384,19 @@
   ) {
     final _$publicKey = publicKey?.reference ?? jni$_.jNullReference;
     final _$privateKey = privateKey?.reference ?? jni$_.jNullReference;
-    return KeyPair.fromReference(_new$(
-            _class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr,
-            _$publicKey.pointer,
-            _$privateKey.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer,
+            _$publicKey.pointer, _$privateKey.pointer)
+        .object<KeyPair>();
   }
+}
 
-  static final _id_getPublic = _class.instanceMethodId(
-    r'getPublic',
-    r'()Ljava/security/PublicKey;',
-  );
-
-  static final _getPublic = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.security.PublicKey getPublic()`
-  /// The returned object must be released after use, by calling the [release] method.
-  PublicKey? getPublic() {
-    return _getPublic(reference.pointer, _id_getPublic as jni$_.JMethodIDPtr)
-        .object<PublicKey?>(const $PublicKey$NullableType());
-  }
-
-  static final _id_getPrivate = _class.instanceMethodId(
+extension KeyPair$$Methods on KeyPair {
+  static final _id_get$private = KeyPair._class.instanceMethodId(
     r'getPrivate',
     r'()Ljava/security/PrivateKey;',
   );
 
-  static final _getPrivate = jni$_.ProtectedJniExtensions.lookup<
+  static final _get$private = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -27597,108 +22410,59 @@
 
   /// from: `public java.security.PrivateKey getPrivate()`
   /// The returned object must be released after use, by calling the [release] method.
-  PrivateKey? getPrivate() {
-    return _getPrivate(reference.pointer, _id_getPrivate as jni$_.JMethodIDPtr)
-        .object<PrivateKey?>(const $PrivateKey$NullableType());
+  PrivateKey? get private {
+    return _get$private(reference.pointer, _id_get$private.pointer)
+        .object<PrivateKey?>();
+  }
+
+  static final _id_get$public = KeyPair._class.instanceMethodId(
+    r'getPublic',
+    r'()Ljava/security/PublicKey;',
+  );
+
+  static final _get$public = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.security.PublicKey getPublic()`
+  /// The returned object must be released after use, by calling the [release] method.
+  PublicKey? get public {
+    return _get$public(reference.pointer, _id_get$public.pointer)
+        .object<PublicKey?>();
   }
 }
 
-final class $KeyPair$NullableType extends jni$_.JObjType<KeyPair?> {
+final class $KeyPair$Type$ extends jni$_.JType<KeyPair> {
   @jni$_.internal
-  const $KeyPair$NullableType();
+  const $KeyPair$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/KeyPair;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyPair? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : KeyPair.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyPair?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyPair$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyPair$NullableType) &&
-        other is $KeyPair$NullableType;
-  }
-}
-
-final class $KeyPair$Type extends jni$_.JObjType<KeyPair> {
-  @jni$_.internal
-  const $KeyPair$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/KeyPair;';
-
-  @jni$_.internal
-  @core$_.override
-  KeyPair fromReference(jni$_.JReference reference) => KeyPair.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<KeyPair?> get nullableType => const $KeyPair$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($KeyPair$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($KeyPair$Type) && other is $KeyPair$Type;
-  }
 }
 
 /// from: `java.security.PublicKey`
-class PublicKey extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<PublicKey> $type;
-
-  @jni$_.internal
-  PublicKey.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type PublicKey._(jni$_.JObject _$this) implements jni$_.JObject, Key {
   static final _class = jni$_.JClass.forName(r'java/security/PublicKey');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $PublicKey$NullableType();
-  static const type = $PublicKey$Type();
+  static const jni$_.JType<PublicKey> type = $PublicKey$Type$();
 
   /// from: `static public final long serialVersionUID`
   static const serialVersionUID = 7187392471159151072;
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $PublicKey> _$impls = {};
+  static final core$_.Map<core$_.int, $PublicKey> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -27719,12 +22483,36 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
       final $d = $i.methodDescriptor.toDartString(releaseOriginal: true);
       final $a = $i.args;
+      if ($d == r'getAlgorithm()Ljava/lang/String;') {
+        final $r = _$impls[$p]!.getAlgorithm();
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
+      if ($d == r'getEncoded()[B') {
+        final $r = _$impls[$p]!.getEncoded();
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
+      if ($d == r'getFormat()Ljava/lang/String;') {
+        final $r = _$impls[$p]!.getFormat();
+        return ($r as jni$_.JObject?)
+                ?.as(const jni$_.$JObject$Type$())
+                .reference
+                .toPointer() ??
+            jni$_.nullptr;
+      }
     } catch (e) {
       return jni$_.ProtectedJniExtensions.newDartException(e);
     }
@@ -27761,110 +22549,139 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return PublicKey.fromReference(
-      $i.implementReference(),
-    );
+    return $i.implement<PublicKey>();
+  }
+}
+
+extension PublicKey$$Methods on PublicKey {
+  static final _id_getAlgorithm = PublicKey._class.instanceMethodId(
+    r'getAlgorithm',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _getAlgorithm = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.lang.String getAlgorithm()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? getAlgorithm() {
+    return _getAlgorithm(reference.pointer, _id_getAlgorithm.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_getEncoded = PublicKey._class.instanceMethodId(
+    r'getEncoded',
+    r'()[B',
+  );
+
+  static final _getEncoded = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract byte[] getEncoded()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JByteArray? getEncoded() {
+    return _getEncoded(reference.pointer, _id_getEncoded.pointer)
+        .object<jni$_.JByteArray?>();
+  }
+
+  static final _id_getFormat = PublicKey._class.instanceMethodId(
+    r'getFormat',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _getFormat = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.lang.String getFormat()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? getFormat() {
+    return _getFormat(reference.pointer, _id_getFormat.pointer)
+        .object<jni$_.JString?>();
   }
 }
 
 abstract base mixin class $PublicKey {
-  factory $PublicKey() = _$PublicKey;
+  factory $PublicKey({
+    required jni$_.JString? Function() getAlgorithm,
+    required jni$_.JByteArray? Function() getEncoded,
+    required jni$_.JString? Function() getFormat,
+  }) = _$PublicKey;
+
+  jni$_.JString? getAlgorithm();
+  jni$_.JByteArray? getEncoded();
+  jni$_.JString? getFormat();
 }
 
 final class _$PublicKey with $PublicKey {
-  _$PublicKey();
+  _$PublicKey({
+    required jni$_.JString? Function() getAlgorithm,
+    required jni$_.JByteArray? Function() getEncoded,
+    required jni$_.JString? Function() getFormat,
+  })  : _getAlgorithm = getAlgorithm,
+        _getEncoded = getEncoded,
+        _getFormat = getFormat;
+
+  final jni$_.JString? Function() _getAlgorithm;
+  final jni$_.JByteArray? Function() _getEncoded;
+  final jni$_.JString? Function() _getFormat;
+
+  jni$_.JString? getAlgorithm() {
+    return _getAlgorithm();
+  }
+
+  jni$_.JByteArray? getEncoded() {
+    return _getEncoded();
+  }
+
+  jni$_.JString? getFormat() {
+    return _getFormat();
+  }
 }
 
-final class $PublicKey$NullableType extends jni$_.JObjType<PublicKey?> {
+final class $PublicKey$Type$ extends jni$_.JType<PublicKey> {
   @jni$_.internal
-  const $PublicKey$NullableType();
+  const $PublicKey$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/PublicKey;';
-
-  @jni$_.internal
-  @core$_.override
-  PublicKey? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : PublicKey.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<PublicKey?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($PublicKey$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($PublicKey$NullableType) &&
-        other is $PublicKey$NullableType;
-  }
-}
-
-final class $PublicKey$Type extends jni$_.JObjType<PublicKey> {
-  @jni$_.internal
-  const $PublicKey$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/PublicKey;';
-
-  @jni$_.internal
-  @core$_.override
-  PublicKey fromReference(jni$_.JReference reference) =>
-      PublicKey.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<PublicKey?> get nullableType =>
-      const $PublicKey$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($PublicKey$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($PublicKey$Type) && other is $PublicKey$Type;
-  }
 }
 
 /// from: `java.io.ByteArrayInputStream`
-class ByteArrayInputStream extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<ByteArrayInputStream> $type;
-
-  @jni$_.internal
-  ByteArrayInputStream.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type ByteArrayInputStream._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'java/io/ByteArrayInputStream');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $ByteArrayInputStream$NullableType();
-  static const type = $ByteArrayInputStream$Type();
+  static const jni$_.JType<ByteArrayInputStream> type =
+      $ByteArrayInputStream$Type$();
   static final _id_new$ = _class.constructorId(
     r'([B)V',
   );
@@ -27886,9 +22703,8 @@
     jni$_.JByteArray? bs,
   ) {
     final _$bs = bs?.reference ?? jni$_.jNullReference;
-    return ByteArrayInputStream.fromReference(_new$(_class.reference.pointer,
-            _id_new$ as jni$_.JMethodIDPtr, _$bs.pointer)
-        .reference);
+    return _new$(_class.reference.pointer, _id_new$.pointer, _$bs.pointer)
+        .object<ByteArrayInputStream>();
   }
 
   static final _id_new$1 = _class.constructorId(
@@ -27907,23 +22723,117 @@
                         jni$_.Int32
                       )>)>>('globalEnv_NewObject')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
   /// from: `public void <init>(byte[] bs, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
   factory ByteArrayInputStream.new$1(
     jni$_.JByteArray? bs,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$bs = bs?.reference ?? jni$_.jNullReference;
-    return ByteArrayInputStream.fromReference(_new$1(_class.reference.pointer,
-            _id_new$1 as jni$_.JMethodIDPtr, _$bs.pointer, i, i1)
-        .reference);
+    return _new$1(
+            _class.reference.pointer, _id_new$1.pointer, _$bs.pointer, i, i1)
+        .object<ByteArrayInputStream>();
+  }
+}
+
+extension ByteArrayInputStream$$Methods on ByteArrayInputStream {
+  static final _id_available = ByteArrayInputStream._class.instanceMethodId(
+    r'available',
+    r'()I',
+  );
+
+  static final _available = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public int available()`
+  core$_.int available() {
+    return _available(reference.pointer, _id_available.pointer).integer;
   }
 
-  static final _id_read = _class.instanceMethodId(
+  static final _id_close = ByteArrayInputStream._class.instanceMethodId(
+    r'close',
+    r'()V',
+  );
+
+  static final _close = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public void close()`
+  void close() {
+    _close(reference.pointer, _id_close.pointer).check();
+  }
+
+  static final _id_mark = ByteArrayInputStream._class.instanceMethodId(
+    r'mark',
+    r'(I)V',
+  );
+
+  static final _mark = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
+
+  /// from: `public void mark(int i)`
+  void mark(
+    core$_.int i,
+  ) {
+    _mark(reference.pointer, _id_mark.pointer, i).check();
+  }
+
+  static final _id_markSupported = ByteArrayInputStream._class.instanceMethodId(
+    r'markSupported',
+    r'()Z',
+  );
+
+  static final _markSupported = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public boolean markSupported()`
+  core$_.bool markSupported() {
+    return _markSupported(reference.pointer, _id_markSupported.pointer).boolean;
+  }
+
+  static final _id_read = ByteArrayInputStream._class.instanceMethodId(
     r'read',
     r'()I',
   );
@@ -27941,11 +22851,11 @@
           )>();
 
   /// from: `public int read()`
-  int read() {
-    return _read(reference.pointer, _id_read as jni$_.JMethodIDPtr).integer;
+  core$_.int read() {
+    return _read(reference.pointer, _id_read.pointer).integer;
   }
 
-  static final _id_read$1 = _class.instanceMethodId(
+  static final _id_read$1 = ByteArrayInputStream._class.instanceMethodId(
     r'read',
     r'([BII)I',
   );
@@ -27962,22 +22872,25 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallIntMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
   /// from: `public int read(byte[] bs, int i, int i1)`
-  int read$1(
+  core$_.int read$1(
     jni$_.JByteArray? bs,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$bs = bs?.reference ?? jni$_.jNullReference;
-    return _read$1(reference.pointer, _id_read$1 as jni$_.JMethodIDPtr,
-            _$bs.pointer, i, i1)
+    return _read$1(reference.pointer, _id_read$1.pointer, _$bs.pointer, i, i1)
         .integer;
   }
 
-  static final _id_readAllBytes = _class.instanceMethodId(
+  static final _id_readAllBytes = ByteArrayInputStream._class.instanceMethodId(
     r'readAllBytes',
     r'()[B',
   );
@@ -27997,12 +22910,11 @@
   /// from: `public byte[] readAllBytes()`
   /// The returned object must be released after use, by calling the [release] method.
   jni$_.JByteArray? readAllBytes() {
-    return _readAllBytes(
-            reference.pointer, _id_readAllBytes as jni$_.JMethodIDPtr)
-        .object<jni$_.JByteArray?>(const jni$_.JByteArrayNullableType());
+    return _readAllBytes(reference.pointer, _id_readAllBytes.pointer)
+        .object<jni$_.JByteArray?>();
   }
 
-  static final _id_readNBytes = _class.instanceMethodId(
+  static final _id_readNBytes = ByteArrayInputStream._class.instanceMethodId(
     r'readNBytes',
     r'([BII)I',
   );
@@ -28019,139 +22931,26 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallIntMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
   /// from: `public int readNBytes(byte[] bs, int i, int i1)`
-  int readNBytes(
+  core$_.int readNBytes(
     jni$_.JByteArray? bs,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$bs = bs?.reference ?? jni$_.jNullReference;
-    return _readNBytes(reference.pointer, _id_readNBytes as jni$_.JMethodIDPtr,
-            _$bs.pointer, i, i1)
+    return _readNBytes(
+            reference.pointer, _id_readNBytes.pointer, _$bs.pointer, i, i1)
         .integer;
   }
 
-  static final _id_transferTo = _class.instanceMethodId(
-    r'transferTo',
-    r'(Ljava/io/OutputStream;)J',
-  );
-
-  static final _transferTo = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `public long transferTo(java.io.OutputStream outputStream)`
-  int transferTo(
-    jni$_.JObject? outputStream,
-  ) {
-    final _$outputStream = outputStream?.reference ?? jni$_.jNullReference;
-    return _transferTo(reference.pointer, _id_transferTo as jni$_.JMethodIDPtr,
-            _$outputStream.pointer)
-        .long;
-  }
-
-  static final _id_skip = _class.instanceMethodId(
-    r'skip',
-    r'(J)J',
-  );
-
-  static final _skip = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public long skip(long j)`
-  int skip(
-    int j,
-  ) {
-    return _skip(reference.pointer, _id_skip as jni$_.JMethodIDPtr, j).long;
-  }
-
-  static final _id_available = _class.instanceMethodId(
-    r'available',
-    r'()I',
-  );
-
-  static final _available = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public int available()`
-  int available() {
-    return _available(reference.pointer, _id_available as jni$_.JMethodIDPtr)
-        .integer;
-  }
-
-  static final _id_markSupported = _class.instanceMethodId(
-    r'markSupported',
-    r'()Z',
-  );
-
-  static final _markSupported = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public boolean markSupported()`
-  bool markSupported() {
-    return _markSupported(
-            reference.pointer, _id_markSupported as jni$_.JMethodIDPtr)
-        .boolean;
-  }
-
-  static final _id_mark = _class.instanceMethodId(
-    r'mark',
-    r'(I)V',
-  );
-
-  static final _mark = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<(jni$_.Int32,)>)>>('globalEnv_CallVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, int)>();
-
-  /// from: `public void mark(int i)`
-  void mark(
-    int i,
-  ) {
-    _mark(reference.pointer, _id_mark as jni$_.JMethodIDPtr, i).check();
-  }
-
-  static final _id_reset = _class.instanceMethodId(
+  static final _id_reset = ByteArrayInputStream._class.instanceMethodId(
     r'reset',
     r'()V',
   );
@@ -28170,222 +22969,80 @@
 
   /// from: `public void reset()`
   void reset() {
-    _reset(reference.pointer, _id_reset as jni$_.JMethodIDPtr).check();
+    _reset(reference.pointer, _id_reset.pointer).check();
   }
 
-  static final _id_close = _class.instanceMethodId(
-    r'close',
-    r'()V',
+  static final _id_skip = ByteArrayInputStream._class.instanceMethodId(
+    r'skip',
+    r'(J)J',
   );
 
-  static final _close = jni$_.ProtectedJniExtensions.lookup<
+  static final _skip = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallVoidMethod')
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<(jni$_.Int64,)>)>>('globalEnv_CallLongMethod')
       .asFunction<
-          jni$_.JThrowablePtr Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>, jni$_.JMethodIDPtr, core$_.int)>();
 
-  /// from: `public void close()`
-  void close() {
-    _close(reference.pointer, _id_close as jni$_.JMethodIDPtr).check();
+  /// from: `public long skip(long j)`
+  core$_.int skip(
+    core$_.int j,
+  ) {
+    return _skip(reference.pointer, _id_skip.pointer, j).long;
+  }
+
+  static final _id_transferTo = ByteArrayInputStream._class.instanceMethodId(
+    r'transferTo',
+    r'(Ljava/io/OutputStream;)J',
+  );
+
+  static final _transferTo = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallLongMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public long transferTo(java.io.OutputStream outputStream)`
+  core$_.int transferTo(
+    jni$_.JObject? outputStream,
+  ) {
+    final _$outputStream = outputStream?.reference ?? jni$_.jNullReference;
+    return _transferTo(
+            reference.pointer, _id_transferTo.pointer, _$outputStream.pointer)
+        .long;
   }
 }
 
-final class $ByteArrayInputStream$NullableType
-    extends jni$_.JObjType<ByteArrayInputStream?> {
+final class $ByteArrayInputStream$Type$
+    extends jni$_.JType<ByteArrayInputStream> {
   @jni$_.internal
-  const $ByteArrayInputStream$NullableType();
+  const $ByteArrayInputStream$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/io/ByteArrayInputStream;';
-
-  @jni$_.internal
-  @core$_.override
-  ByteArrayInputStream? fromReference(jni$_.JReference reference) =>
-      reference.isNull
-          ? null
-          : ByteArrayInputStream.fromReference(
-              reference,
-            );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ByteArrayInputStream?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ByteArrayInputStream$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ByteArrayInputStream$NullableType) &&
-        other is $ByteArrayInputStream$NullableType;
-  }
-}
-
-final class $ByteArrayInputStream$Type
-    extends jni$_.JObjType<ByteArrayInputStream> {
-  @jni$_.internal
-  const $ByteArrayInputStream$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/io/ByteArrayInputStream;';
-
-  @jni$_.internal
-  @core$_.override
-  ByteArrayInputStream fromReference(jni$_.JReference reference) =>
-      ByteArrayInputStream.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<ByteArrayInputStream?> get nullableType =>
-      const $ByteArrayInputStream$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($ByteArrayInputStream$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($ByteArrayInputStream$Type) &&
-        other is $ByteArrayInputStream$Type;
-  }
 }
 
 /// from: `java.util.Enumeration`
-class Enumeration<$E extends jni$_.JObject?> extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Enumeration<$E>> $type;
-
-  @jni$_.internal
-  final jni$_.JObjType<$E> E;
-
-  @jni$_.internal
-  Enumeration.fromReference(
-    this.E,
-    jni$_.JReference reference,
-  )   : $type = type<$E>(E),
-        super.fromReference(reference);
-
+extension type Enumeration<$E extends jni$_.JObject?>._(jni$_.JObject _$this)
+    implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'java/util/Enumeration');
 
   /// The type which includes information such as the signature of this class.
-  static $Enumeration$NullableType<$E> nullableType<$E extends jni$_.JObject?>(
-    jni$_.JObjType<$E> E,
-  ) {
-    return $Enumeration$NullableType<$E>(
-      E,
-    );
-  }
-
-  static $Enumeration$Type<$E> type<$E extends jni$_.JObject?>(
-    jni$_.JObjType<$E> E,
-  ) {
-    return $Enumeration$Type<$E>(
-      E,
-    );
-  }
-
-  static final _id_hasMoreElements = _class.instanceMethodId(
-    r'hasMoreElements',
-    r'()Z',
-  );
-
-  static final _hasMoreElements = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract boolean hasMoreElements()`
-  bool hasMoreElements() {
-    return _hasMoreElements(
-            reference.pointer, _id_hasMoreElements as jni$_.JMethodIDPtr)
-        .boolean;
-  }
-
-  static final _id_nextElement = _class.instanceMethodId(
-    r'nextElement',
-    r'()Ljava/lang/Object;',
-  );
-
-  static final _nextElement = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract E nextElement()`
-  /// The returned object must be released after use, by calling the [release] method.
-  $E? nextElement() {
-    return _nextElement(
-            reference.pointer, _id_nextElement as jni$_.JMethodIDPtr)
-        .object<$E?>(E.nullableType);
-  }
-
-  static final _id_asIterator = _class.instanceMethodId(
-    r'asIterator',
-    r'()Ljava/util/Iterator;',
-  );
-
-  static final _asIterator = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public java.util.Iterator asIterator()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JIterator<$E?>? asIterator() {
-    return _asIterator(reference.pointer, _id_asIterator as jni$_.JMethodIDPtr)
-        .object<jni$_.JIterator<$E?>?>(
-            jni$_.JIteratorNullableType<$E?>(E.nullableType));
-  }
+  static const jni$_.JType<Enumeration> type = $Enumeration$Type$();
 
   /// Maps a specific port to the implemented interface.
-  static final core$_.Map<int, $Enumeration> _$impls = {};
+  static final core$_.Map<core$_.int, $Enumeration> _$impls = {};
   static jni$_.JObjectPtr _$invoke(
-    int port,
+    core$_.int port,
     jni$_.JObjectPtr descriptor,
     jni$_.JObjectPtr args,
   ) {
@@ -28406,28 +23063,28 @@
       _$invokePointer = jni$_.Pointer.fromFunction(_$invoke);
 
   static jni$_.Pointer<jni$_.Void> _$invokeMethod(
-    int $p,
+    core$_.int $p,
     jni$_.MethodInvocation $i,
   ) {
     try {
       final $d = $i.methodDescriptor.toDartString(releaseOriginal: true);
       final $a = $i.args;
-      if ($d == r'hasMoreElements()Z') {
-        final $r = _$impls[$p]!.hasMoreElements();
-        return jni$_.JBoolean($r).reference.toPointer();
-      }
-      if ($d == r'nextElement()Ljava/lang/Object;') {
-        final $r = _$impls[$p]!.nextElement();
+      if ($d == r'asIterator()Ljava/util/Iterator;') {
+        final $r = _$impls[$p]!.asIterator();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
       }
-      if ($d == r'asIterator()Ljava/util/Iterator;') {
-        final $r = _$impls[$p]!.asIterator();
+      if ($d == r'hasMoreElements()Z') {
+        final $r = _$impls[$p]!.hasMoreElements();
+        return $r.toJBoolean().reference.toPointer();
+      }
+      if ($d == r'nextElement()Ljava/lang/Object;') {
+        final $r = _$impls[$p]!.nextElement();
         return ($r as jni$_.JObject?)
-                ?.as(const jni$_.JObjectType())
+                ?.as(const jni$_.$JObject$Type$())
                 .reference
                 .toPointer() ??
             jni$_.nullptr;
@@ -28468,1598 +23125,166 @@
   ) {
     final $i = jni$_.JImplementer();
     implementIn($i, $impl);
-    return Enumeration<$E>.fromReference(
-      $impl.E,
-      $i.implementReference(),
-    );
+    return $i.implement<Enumeration<$E>>();
+  }
+}
+
+extension Enumeration$$Methods<$E extends jni$_.JObject?> on Enumeration<$E> {
+  static final _id_asIterator = Enumeration._class.instanceMethodId(
+    r'asIterator',
+    r'()Ljava/util/Iterator;',
+  );
+
+  static final _asIterator = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.util.Iterator<E> asIterator()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JIterator<$E?>? asIterator() {
+    return _asIterator(reference.pointer, _id_asIterator.pointer)
+        .object<jni$_.JIterator<$E?>?>();
+  }
+
+  static final _id_hasMoreElements = Enumeration._class.instanceMethodId(
+    r'hasMoreElements',
+    r'()Z',
+  );
+
+  static final _hasMoreElements = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract boolean hasMoreElements()`
+  core$_.bool hasMoreElements() {
+    return _hasMoreElements(reference.pointer, _id_hasMoreElements.pointer)
+        .boolean;
+  }
+
+  static final _id_nextElement = Enumeration._class.instanceMethodId(
+    r'nextElement',
+    r'()Ljava/lang/Object;',
+  );
+
+  static final _nextElement = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract E nextElement()`
+  /// The returned object must be released after use, by calling the [release] method.
+  $E? nextElement() {
+    return _nextElement(reference.pointer, _id_nextElement.pointer)
+        .object<$E?>();
   }
 }
 
 abstract base mixin class $Enumeration<$E extends jni$_.JObject?> {
   factory $Enumeration({
-    required jni$_.JObjType<$E> E,
-    required bool Function() hasMoreElements,
-    required $E? Function() nextElement,
     required jni$_.JIterator<jni$_.JObject?>? Function() asIterator,
+    required core$_.bool Function() hasMoreElements,
+    required $E? Function() nextElement,
   }) = _$Enumeration<$E>;
 
-  jni$_.JObjType<$E> get E;
-
-  bool hasMoreElements();
-  $E? nextElement();
   jni$_.JIterator<jni$_.JObject?>? asIterator();
+  core$_.bool hasMoreElements();
+  $E? nextElement();
 }
 
 final class _$Enumeration<$E extends jni$_.JObject?> with $Enumeration<$E> {
   _$Enumeration({
-    required this.E,
-    required bool Function() hasMoreElements,
-    required $E? Function() nextElement,
     required jni$_.JIterator<jni$_.JObject?>? Function() asIterator,
-  })  : _hasMoreElements = hasMoreElements,
-        _nextElement = nextElement,
-        _asIterator = asIterator;
+    required core$_.bool Function() hasMoreElements,
+    required $E? Function() nextElement,
+  })  : _asIterator = asIterator,
+        _hasMoreElements = hasMoreElements,
+        _nextElement = nextElement;
 
-  @core$_.override
-  final jni$_.JObjType<$E> E;
-
-  final bool Function() _hasMoreElements;
-  final $E? Function() _nextElement;
   final jni$_.JIterator<jni$_.JObject?>? Function() _asIterator;
+  final core$_.bool Function() _hasMoreElements;
+  final $E? Function() _nextElement;
 
-  bool hasMoreElements() {
+  jni$_.JIterator<jni$_.JObject?>? asIterator() {
+    return _asIterator();
+  }
+
+  core$_.bool hasMoreElements() {
     return _hasMoreElements();
   }
 
   $E? nextElement() {
     return _nextElement();
   }
-
-  jni$_.JIterator<jni$_.JObject?>? asIterator() {
-    return _asIterator();
-  }
 }
 
-final class $Enumeration$NullableType<$E extends jni$_.JObject?>
-    extends jni$_.JObjType<Enumeration<$E>?> {
+final class $Enumeration$Type$ extends jni$_.JType<Enumeration> {
   @jni$_.internal
-  final jni$_.JObjType<$E> E;
-
-  @jni$_.internal
-  const $Enumeration$NullableType(
-    this.E,
-  );
+  const $Enumeration$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/util/Enumeration;';
-
-  @jni$_.internal
-  @core$_.override
-  Enumeration<$E>? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Enumeration<$E>.fromReference(
-          E,
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Enumeration<$E>?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => Object.hash($Enumeration$NullableType, E);
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Enumeration$NullableType<$E>) &&
-        other is $Enumeration$NullableType<$E> &&
-        E == other.E;
-  }
-}
-
-final class $Enumeration$Type<$E extends jni$_.JObject?>
-    extends jni$_.JObjType<Enumeration<$E>> {
-  @jni$_.internal
-  final jni$_.JObjType<$E> E;
-
-  @jni$_.internal
-  const $Enumeration$Type(
-    this.E,
-  );
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/util/Enumeration;';
-
-  @jni$_.internal
-  @core$_.override
-  Enumeration<$E> fromReference(jni$_.JReference reference) =>
-      Enumeration<$E>.fromReference(
-        E,
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Enumeration<$E>?> get nullableType =>
-      $Enumeration$NullableType<$E>(E);
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => Object.hash($Enumeration$Type, E);
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Enumeration$Type<$E>) &&
-        other is $Enumeration$Type<$E> &&
-        E == other.E;
-  }
 }
 
 /// from: `java.util.Arrays`
-class Arrays extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Arrays> $type;
-
-  @jni$_.internal
-  Arrays.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Arrays._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'java/util/Arrays');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Arrays$NullableType();
-  static const type = $Arrays$Type();
-  static final _id_sort = _class.staticMethodId(
-    r'sort',
-    r'([I)V',
+  static const jni$_.JType<Arrays> type = $Arrays$Type$();
+  static final _id_asList = _class.staticMethodId(
+    r'asList',
+    r'([Ljava/lang/Object;)Ljava/util/List;',
   );
 
-  static final _sort = jni$_.ProtectedJniExtensions.lookup<
+  static final _asList = jni$_.ProtectedJniExtensions.lookup<
               jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
+                  jni$_.JniResult Function(
                       jni$_.Pointer<jni$_.Void>,
                       jni$_.JMethodIDPtr,
                       jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
+          'globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public void sort(int[] is)`
-  static void sort(
-    jni$_.JIntArray? is$,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    _sort(_class.reference.pointer, _id_sort as jni$_.JMethodIDPtr,
-            _$is$.pointer)
-        .check();
-  }
-
-  static final _id_sort$1 = _class.staticMethodId(
-    r'sort',
-    r'([III)V',
-  );
-
-  static final _sort$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void sort(int[] is, int i, int i1)`
-  static void sort$1(
-    jni$_.JIntArray? is$,
-    int i,
-    int i1,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    _sort$1(_class.reference.pointer, _id_sort$1 as jni$_.JMethodIDPtr,
-            _$is$.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_sort$2 = _class.staticMethodId(
-    r'sort',
-    r'([J)V',
-  );
-
-  static final _sort$2 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void sort(long[] js)`
-  static void sort$2(
-    jni$_.JLongArray? js,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    _sort$2(_class.reference.pointer, _id_sort$2 as jni$_.JMethodIDPtr,
-            _$js.pointer)
-        .check();
-  }
-
-  static final _id_sort$3 = _class.staticMethodId(
-    r'sort',
-    r'([JII)V',
-  );
-
-  static final _sort$3 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void sort(long[] js, int i, int i1)`
-  static void sort$3(
-    jni$_.JLongArray? js,
-    int i,
-    int i1,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    _sort$3(_class.reference.pointer, _id_sort$3 as jni$_.JMethodIDPtr,
-            _$js.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_sort$4 = _class.staticMethodId(
-    r'sort',
-    r'([S)V',
-  );
-
-  static final _sort$4 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void sort(short[] ss)`
-  static void sort$4(
-    jni$_.JShortArray? ss,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    _sort$4(_class.reference.pointer, _id_sort$4 as jni$_.JMethodIDPtr,
-            _$ss.pointer)
-        .check();
-  }
-
-  static final _id_sort$5 = _class.staticMethodId(
-    r'sort',
-    r'([SII)V',
-  );
-
-  static final _sort$5 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void sort(short[] ss, int i, int i1)`
-  static void sort$5(
-    jni$_.JShortArray? ss,
-    int i,
-    int i1,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    _sort$5(_class.reference.pointer, _id_sort$5 as jni$_.JMethodIDPtr,
-            _$ss.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_sort$6 = _class.staticMethodId(
-    r'sort',
-    r'([C)V',
-  );
-
-  static final _sort$6 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void sort(char[] cs)`
-  static void sort$6(
-    jni$_.JCharArray? cs,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    _sort$6(_class.reference.pointer, _id_sort$6 as jni$_.JMethodIDPtr,
-            _$cs.pointer)
-        .check();
-  }
-
-  static final _id_sort$7 = _class.staticMethodId(
-    r'sort',
-    r'([CII)V',
-  );
-
-  static final _sort$7 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void sort(char[] cs, int i, int i1)`
-  static void sort$7(
-    jni$_.JCharArray? cs,
-    int i,
-    int i1,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    _sort$7(_class.reference.pointer, _id_sort$7 as jni$_.JMethodIDPtr,
-            _$cs.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_sort$8 = _class.staticMethodId(
-    r'sort',
-    r'([B)V',
-  );
-
-  static final _sort$8 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void sort(byte[] bs)`
-  static void sort$8(
-    jni$_.JByteArray? bs,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    _sort$8(_class.reference.pointer, _id_sort$8 as jni$_.JMethodIDPtr,
-            _$bs.pointer)
-        .check();
-  }
-
-  static final _id_sort$9 = _class.staticMethodId(
-    r'sort',
-    r'([BII)V',
-  );
-
-  static final _sort$9 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void sort(byte[] bs, int i, int i1)`
-  static void sort$9(
-    jni$_.JByteArray? bs,
-    int i,
-    int i1,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    _sort$9(_class.reference.pointer, _id_sort$9 as jni$_.JMethodIDPtr,
-            _$bs.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_sort$10 = _class.staticMethodId(
-    r'sort',
-    r'([F)V',
-  );
-
-  static final _sort$10 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void sort(float[] fs)`
-  static void sort$10(
-    jni$_.JFloatArray? fs,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    _sort$10(_class.reference.pointer, _id_sort$10 as jni$_.JMethodIDPtr,
-            _$fs.pointer)
-        .check();
-  }
-
-  static final _id_sort$11 = _class.staticMethodId(
-    r'sort',
-    r'([FII)V',
-  );
-
-  static final _sort$11 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void sort(float[] fs, int i, int i1)`
-  static void sort$11(
-    jni$_.JFloatArray? fs,
-    int i,
-    int i1,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    _sort$11(_class.reference.pointer, _id_sort$11 as jni$_.JMethodIDPtr,
-            _$fs.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_sort$12 = _class.staticMethodId(
-    r'sort',
-    r'([D)V',
-  );
-
-  static final _sort$12 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void sort(double[] ds)`
-  static void sort$12(
-    jni$_.JDoubleArray? ds,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    _sort$12(_class.reference.pointer, _id_sort$12 as jni$_.JMethodIDPtr,
-            _$ds.pointer)
-        .check();
-  }
-
-  static final _id_sort$13 = _class.staticMethodId(
-    r'sort',
-    r'([DII)V',
-  );
-
-  static final _sort$13 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void sort(double[] ds, int i, int i1)`
-  static void sort$13(
-    jni$_.JDoubleArray? ds,
-    int i,
-    int i1,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    _sort$13(_class.reference.pointer, _id_sort$13 as jni$_.JMethodIDPtr,
-            _$ds.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_parallelSort = _class.staticMethodId(
-    r'parallelSort',
-    r'([B)V',
-  );
-
-  static final _parallelSort = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelSort(byte[] bs)`
-  static void parallelSort(
-    jni$_.JByteArray? bs,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    _parallelSort(_class.reference.pointer,
-            _id_parallelSort as jni$_.JMethodIDPtr, _$bs.pointer)
-        .check();
-  }
-
-  static final _id_parallelSort$1 = _class.staticMethodId(
-    r'parallelSort',
-    r'([BII)V',
-  );
-
-  static final _parallelSort$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void parallelSort(byte[] bs, int i, int i1)`
-  static void parallelSort$1(
-    jni$_.JByteArray? bs,
-    int i,
-    int i1,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    _parallelSort$1(_class.reference.pointer,
-            _id_parallelSort$1 as jni$_.JMethodIDPtr, _$bs.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_parallelSort$2 = _class.staticMethodId(
-    r'parallelSort',
-    r'([C)V',
-  );
-
-  static final _parallelSort$2 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelSort(char[] cs)`
-  static void parallelSort$2(
-    jni$_.JCharArray? cs,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    _parallelSort$2(_class.reference.pointer,
-            _id_parallelSort$2 as jni$_.JMethodIDPtr, _$cs.pointer)
-        .check();
-  }
-
-  static final _id_parallelSort$3 = _class.staticMethodId(
-    r'parallelSort',
-    r'([CII)V',
-  );
-
-  static final _parallelSort$3 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void parallelSort(char[] cs, int i, int i1)`
-  static void parallelSort$3(
-    jni$_.JCharArray? cs,
-    int i,
-    int i1,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    _parallelSort$3(_class.reference.pointer,
-            _id_parallelSort$3 as jni$_.JMethodIDPtr, _$cs.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_parallelSort$4 = _class.staticMethodId(
-    r'parallelSort',
-    r'([S)V',
-  );
-
-  static final _parallelSort$4 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelSort(short[] ss)`
-  static void parallelSort$4(
-    jni$_.JShortArray? ss,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    _parallelSort$4(_class.reference.pointer,
-            _id_parallelSort$4 as jni$_.JMethodIDPtr, _$ss.pointer)
-        .check();
-  }
-
-  static final _id_parallelSort$5 = _class.staticMethodId(
-    r'parallelSort',
-    r'([SII)V',
-  );
-
-  static final _parallelSort$5 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void parallelSort(short[] ss, int i, int i1)`
-  static void parallelSort$5(
-    jni$_.JShortArray? ss,
-    int i,
-    int i1,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    _parallelSort$5(_class.reference.pointer,
-            _id_parallelSort$5 as jni$_.JMethodIDPtr, _$ss.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_parallelSort$6 = _class.staticMethodId(
-    r'parallelSort',
-    r'([I)V',
-  );
-
-  static final _parallelSort$6 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelSort(int[] is)`
-  static void parallelSort$6(
-    jni$_.JIntArray? is$,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    _parallelSort$6(_class.reference.pointer,
-            _id_parallelSort$6 as jni$_.JMethodIDPtr, _$is$.pointer)
-        .check();
-  }
-
-  static final _id_parallelSort$7 = _class.staticMethodId(
-    r'parallelSort',
-    r'([III)V',
-  );
-
-  static final _parallelSort$7 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void parallelSort(int[] is, int i, int i1)`
-  static void parallelSort$7(
-    jni$_.JIntArray? is$,
-    int i,
-    int i1,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    _parallelSort$7(_class.reference.pointer,
-            _id_parallelSort$7 as jni$_.JMethodIDPtr, _$is$.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_parallelSort$8 = _class.staticMethodId(
-    r'parallelSort',
-    r'([J)V',
-  );
-
-  static final _parallelSort$8 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelSort(long[] js)`
-  static void parallelSort$8(
-    jni$_.JLongArray? js,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    _parallelSort$8(_class.reference.pointer,
-            _id_parallelSort$8 as jni$_.JMethodIDPtr, _$js.pointer)
-        .check();
-  }
-
-  static final _id_parallelSort$9 = _class.staticMethodId(
-    r'parallelSort',
-    r'([JII)V',
-  );
-
-  static final _parallelSort$9 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void parallelSort(long[] js, int i, int i1)`
-  static void parallelSort$9(
-    jni$_.JLongArray? js,
-    int i,
-    int i1,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    _parallelSort$9(_class.reference.pointer,
-            _id_parallelSort$9 as jni$_.JMethodIDPtr, _$js.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_parallelSort$10 = _class.staticMethodId(
-    r'parallelSort',
-    r'([F)V',
-  );
-
-  static final _parallelSort$10 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelSort(float[] fs)`
-  static void parallelSort$10(
-    jni$_.JFloatArray? fs,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    _parallelSort$10(_class.reference.pointer,
-            _id_parallelSort$10 as jni$_.JMethodIDPtr, _$fs.pointer)
-        .check();
-  }
-
-  static final _id_parallelSort$11 = _class.staticMethodId(
-    r'parallelSort',
-    r'([FII)V',
-  );
-
-  static final _parallelSort$11 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void parallelSort(float[] fs, int i, int i1)`
-  static void parallelSort$11(
-    jni$_.JFloatArray? fs,
-    int i,
-    int i1,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    _parallelSort$11(_class.reference.pointer,
-            _id_parallelSort$11 as jni$_.JMethodIDPtr, _$fs.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_parallelSort$12 = _class.staticMethodId(
-    r'parallelSort',
-    r'([D)V',
-  );
-
-  static final _parallelSort$12 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelSort(double[] ds)`
-  static void parallelSort$12(
-    jni$_.JDoubleArray? ds,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    _parallelSort$12(_class.reference.pointer,
-            _id_parallelSort$12 as jni$_.JMethodIDPtr, _$ds.pointer)
-        .check();
-  }
-
-  static final _id_parallelSort$13 = _class.staticMethodId(
-    r'parallelSort',
-    r'([DII)V',
-  );
-
-  static final _parallelSort$13 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void parallelSort(double[] ds, int i, int i1)`
-  static void parallelSort$13(
-    jni$_.JDoubleArray? ds,
-    int i,
-    int i1,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    _parallelSort$13(_class.reference.pointer,
-            _id_parallelSort$13 as jni$_.JMethodIDPtr, _$ds.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_parallelSort$14 = _class.staticMethodId(
-    r'parallelSort',
-    r'([Ljava/lang/Comparable;)V',
-  );
-
-  static final _parallelSort$14 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelSort(java.lang.Object[] comparables)`
-  static void parallelSort$14<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? comparables, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$comparables = comparables?.reference ?? jni$_.jNullReference;
-    _parallelSort$14(_class.reference.pointer,
-            _id_parallelSort$14 as jni$_.JMethodIDPtr, _$comparables.pointer)
-        .check();
-  }
-
-  static final _id_parallelSort$15 = _class.staticMethodId(
-    r'parallelSort',
-    r'([Ljava/lang/Comparable;II)V',
-  );
-
-  static final _parallelSort$15 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void parallelSort(java.lang.Object[] comparables, int i, int i1)`
-  static void parallelSort$15<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? comparables,
-    int i,
-    int i1, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$comparables = comparables?.reference ?? jni$_.jNullReference;
-    _parallelSort$15(
-            _class.reference.pointer,
-            _id_parallelSort$15 as jni$_.JMethodIDPtr,
-            _$comparables.pointer,
-            i,
-            i1)
-        .check();
-  }
-
-  static final _id_parallelSort$16 = _class.staticMethodId(
-    r'parallelSort',
-    r'([Ljava/lang/Object;Ljava/util/Comparator;)V',
-  );
-
-  static final _parallelSort$16 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelSort(java.lang.Object[] objects, java.util.Comparator comparator)`
-  static void parallelSort$16<$T extends jni$_.JObject?>(
+  /// from: `static public java.util.List<T> asList(T[] objects)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JList<$T?>? asList<$T extends jni$_.JObject?>(
     jni$_.JArray<$T?>? objects,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
-    _parallelSort$16(
-            _class.reference.pointer,
-            _id_parallelSort$16 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            _$comparator.pointer)
-        .check();
-  }
-
-  static final _id_parallelSort$17 = _class.staticMethodId(
-    r'parallelSort',
-    r'([Ljava/lang/Object;IILjava/util/Comparator;)V',
-  );
-
-  static final _parallelSort$17 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelSort(java.lang.Object[] objects, int i, int i1, java.util.Comparator comparator)`
-  static void parallelSort$17<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    int i,
-    int i1,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
-    _parallelSort$17(
-            _class.reference.pointer,
-            _id_parallelSort$17 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            i,
-            i1,
-            _$comparator.pointer)
-        .check();
-  }
-
-  static final _id_sort$14 = _class.staticMethodId(
-    r'sort',
-    r'([Ljava/lang/Object;)V',
-  );
-
-  static final _sort$14 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void sort(java.lang.Object[] objects)`
-  static void sort$14(
-    jni$_.JArray<jni$_.JObject?>? objects,
   ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
-    _sort$14(_class.reference.pointer, _id_sort$14 as jni$_.JMethodIDPtr,
-            _$objects.pointer)
-        .check();
-  }
-
-  static final _id_sort$15 = _class.staticMethodId(
-    r'sort',
-    r'([Ljava/lang/Object;II)V',
-  );
-
-  static final _sort$15 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public void sort(java.lang.Object[] objects, int i, int i1)`
-  static void sort$15(
-    jni$_.JArray<jni$_.JObject?>? objects,
-    int i,
-    int i1,
-  ) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    _sort$15(_class.reference.pointer, _id_sort$15 as jni$_.JMethodIDPtr,
-            _$objects.pointer, i, i1)
-        .check();
-  }
-
-  static final _id_sort$16 = _class.staticMethodId(
-    r'sort',
-    r'([Ljava/lang/Object;Ljava/util/Comparator;)V',
-  );
-
-  static final _sort$16 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void sort(java.lang.Object[] objects, java.util.Comparator comparator)`
-  static void sort$16<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
-    _sort$16(_class.reference.pointer, _id_sort$16 as jni$_.JMethodIDPtr,
-            _$objects.pointer, _$comparator.pointer)
-        .check();
-  }
-
-  static final _id_sort$17 = _class.staticMethodId(
-    r'sort',
-    r'([Ljava/lang/Object;IILjava/util/Comparator;)V',
-  );
-
-  static final _sort$17 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void sort(java.lang.Object[] objects, int i, int i1, java.util.Comparator comparator)`
-  static void sort$17<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    int i,
-    int i1,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
-    _sort$17(_class.reference.pointer, _id_sort$17 as jni$_.JMethodIDPtr,
-            _$objects.pointer, i, i1, _$comparator.pointer)
-        .check();
-  }
-
-  static final _id_parallelPrefix = _class.staticMethodId(
-    r'parallelPrefix',
-    r'([Ljava/lang/Object;Ljava/util/function/BinaryOperator;)V',
-  );
-
-  static final _parallelPrefix = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelPrefix(java.lang.Object[] objects, java.util.function.BinaryOperator binaryOperator)`
-  static void parallelPrefix<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    jni$_.JObject? binaryOperator, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$binaryOperator = binaryOperator?.reference ?? jni$_.jNullReference;
-    _parallelPrefix(
-            _class.reference.pointer,
-            _id_parallelPrefix as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            _$binaryOperator.pointer)
-        .check();
-  }
-
-  static final _id_parallelPrefix$1 = _class.staticMethodId(
-    r'parallelPrefix',
-    r'([Ljava/lang/Object;IILjava/util/function/BinaryOperator;)V',
-  );
-
-  static final _parallelPrefix$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelPrefix(java.lang.Object[] objects, int i, int i1, java.util.function.BinaryOperator binaryOperator)`
-  static void parallelPrefix$1<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    int i,
-    int i1,
-    jni$_.JObject? binaryOperator, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$binaryOperator = binaryOperator?.reference ?? jni$_.jNullReference;
-    _parallelPrefix$1(
-            _class.reference.pointer,
-            _id_parallelPrefix$1 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            i,
-            i1,
-            _$binaryOperator.pointer)
-        .check();
-  }
-
-  static final _id_parallelPrefix$2 = _class.staticMethodId(
-    r'parallelPrefix',
-    r'([JLjava/util/function/LongBinaryOperator;)V',
-  );
-
-  static final _parallelPrefix$2 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelPrefix(long[] js, java.util.function.LongBinaryOperator longBinaryOperator)`
-  static void parallelPrefix$2(
-    jni$_.JLongArray? js,
-    jni$_.JObject? longBinaryOperator,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    final _$longBinaryOperator =
-        longBinaryOperator?.reference ?? jni$_.jNullReference;
-    _parallelPrefix$2(
-            _class.reference.pointer,
-            _id_parallelPrefix$2 as jni$_.JMethodIDPtr,
-            _$js.pointer,
-            _$longBinaryOperator.pointer)
-        .check();
-  }
-
-  static final _id_parallelPrefix$3 = _class.staticMethodId(
-    r'parallelPrefix',
-    r'([JIILjava/util/function/LongBinaryOperator;)V',
-  );
-
-  static final _parallelPrefix$3 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelPrefix(long[] js, int i, int i1, java.util.function.LongBinaryOperator longBinaryOperator)`
-  static void parallelPrefix$3(
-    jni$_.JLongArray? js,
-    int i,
-    int i1,
-    jni$_.JObject? longBinaryOperator,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    final _$longBinaryOperator =
-        longBinaryOperator?.reference ?? jni$_.jNullReference;
-    _parallelPrefix$3(
-            _class.reference.pointer,
-            _id_parallelPrefix$3 as jni$_.JMethodIDPtr,
-            _$js.pointer,
-            i,
-            i1,
-            _$longBinaryOperator.pointer)
-        .check();
-  }
-
-  static final _id_parallelPrefix$4 = _class.staticMethodId(
-    r'parallelPrefix',
-    r'([DLjava/util/function/DoubleBinaryOperator;)V',
-  );
-
-  static final _parallelPrefix$4 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelPrefix(double[] ds, java.util.function.DoubleBinaryOperator doubleBinaryOperator)`
-  static void parallelPrefix$4(
-    jni$_.JDoubleArray? ds,
-    jni$_.JObject? doubleBinaryOperator,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    final _$doubleBinaryOperator =
-        doubleBinaryOperator?.reference ?? jni$_.jNullReference;
-    _parallelPrefix$4(
-            _class.reference.pointer,
-            _id_parallelPrefix$4 as jni$_.JMethodIDPtr,
-            _$ds.pointer,
-            _$doubleBinaryOperator.pointer)
-        .check();
-  }
-
-  static final _id_parallelPrefix$5 = _class.staticMethodId(
-    r'parallelPrefix',
-    r'([DIILjava/util/function/DoubleBinaryOperator;)V',
-  );
-
-  static final _parallelPrefix$5 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelPrefix(double[] ds, int i, int i1, java.util.function.DoubleBinaryOperator doubleBinaryOperator)`
-  static void parallelPrefix$5(
-    jni$_.JDoubleArray? ds,
-    int i,
-    int i1,
-    jni$_.JObject? doubleBinaryOperator,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    final _$doubleBinaryOperator =
-        doubleBinaryOperator?.reference ?? jni$_.jNullReference;
-    _parallelPrefix$5(
-            _class.reference.pointer,
-            _id_parallelPrefix$5 as jni$_.JMethodIDPtr,
-            _$ds.pointer,
-            i,
-            i1,
-            _$doubleBinaryOperator.pointer)
-        .check();
-  }
-
-  static final _id_parallelPrefix$6 = _class.staticMethodId(
-    r'parallelPrefix',
-    r'([ILjava/util/function/IntBinaryOperator;)V',
-  );
-
-  static final _parallelPrefix$6 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelPrefix(int[] is, java.util.function.IntBinaryOperator intBinaryOperator)`
-  static void parallelPrefix$6(
-    jni$_.JIntArray? is$,
-    jni$_.JObject? intBinaryOperator,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    final _$intBinaryOperator =
-        intBinaryOperator?.reference ?? jni$_.jNullReference;
-    _parallelPrefix$6(
-            _class.reference.pointer,
-            _id_parallelPrefix$6 as jni$_.JMethodIDPtr,
-            _$is$.pointer,
-            _$intBinaryOperator.pointer)
-        .check();
-  }
-
-  static final _id_parallelPrefix$7 = _class.staticMethodId(
-    r'parallelPrefix',
-    r'([IIILjava/util/function/IntBinaryOperator;)V',
-  );
-
-  static final _parallelPrefix$7 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelPrefix(int[] is, int i, int i1, java.util.function.IntBinaryOperator intBinaryOperator)`
-  static void parallelPrefix$7(
-    jni$_.JIntArray? is$,
-    int i,
-    int i1,
-    jni$_.JObject? intBinaryOperator,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    final _$intBinaryOperator =
-        intBinaryOperator?.reference ?? jni$_.jNullReference;
-    _parallelPrefix$7(
-            _class.reference.pointer,
-            _id_parallelPrefix$7 as jni$_.JMethodIDPtr,
-            _$is$.pointer,
-            i,
-            i1,
-            _$intBinaryOperator.pointer)
-        .check();
+    return _asList(
+            _class.reference.pointer, _id_asList.pointer, _$objects.pointer)
+        .object<jni$_.JList<$T?>?>();
   }
 
   static final _id_binarySearch = _class.staticMethodId(
     r'binarySearch',
-    r'([JJ)I',
+    r'([BB)I',
   );
 
   static final _binarySearch = jni$_.ProtectedJniExtensions.lookup<
@@ -30068,26 +23293,26 @@
                       jni$_.Pointer<jni$_.Void>,
                       jni$_.JMethodIDPtr,
                       jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int64)>)>>(
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
           'globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
 
-  /// from: `static public int binarySearch(long[] js, long j)`
-  static int binarySearch(
-    jni$_.JLongArray? js,
-    int j,
+  /// from: `static public int binarySearch(byte[] bs, byte b)`
+  static core$_.int binarySearch(
+    jni$_.JByteArray? bs,
+    core$_.int b,
   ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    return _binarySearch(_class.reference.pointer,
-            _id_binarySearch as jni$_.JMethodIDPtr, _$js.pointer, j)
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    return _binarySearch(
+            _class.reference.pointer, _id_binarySearch.pointer, _$bs.pointer, b)
         .integer;
   }
 
   static final _id_binarySearch$1 = _class.staticMethodId(
     r'binarySearch',
-    r'([JIIJ)I',
+    r'([BIIB)I',
   );
 
   static final _binarySearch$1 = jni$_.ProtectedJniExtensions.lookup<
@@ -30100,28 +23325,33 @@
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Int32,
                         jni$_.Int32,
-                        jni$_.Int64
+                        jni$_.Int32
                       )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `static public int binarySearch(long[] js, int i, int i1, long j)`
-  static int binarySearch$1(
-    jni$_.JLongArray? js,
-    int i,
-    int i1,
-    int j,
+  /// from: `static public int binarySearch(byte[] bs, int i, int i1, byte b)`
+  static core$_.int binarySearch$1(
+    jni$_.JByteArray? bs,
+    core$_.int i,
+    core$_.int i1,
+    core$_.int b,
   ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    return _binarySearch$1(_class.reference.pointer,
-            _id_binarySearch$1 as jni$_.JMethodIDPtr, _$js.pointer, i, i1, j)
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    return _binarySearch$1(_class.reference.pointer, _id_binarySearch$1.pointer,
+            _$bs.pointer, i, i1, b)
         .integer;
   }
 
   static final _id_binarySearch$2 = _class.staticMethodId(
     r'binarySearch',
-    r'([II)I',
+    r'([CC)I',
   );
 
   static final _binarySearch$2 = jni$_.ProtectedJniExtensions.lookup<
@@ -30134,22 +23364,22 @@
           'globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
 
-  /// from: `static public int binarySearch(int[] is, int i)`
-  static int binarySearch$2(
-    jni$_.JIntArray? is$,
-    int i,
+  /// from: `static public int binarySearch(char[] cs, char c)`
+  static core$_.int binarySearch$2(
+    jni$_.JCharArray? cs,
+    core$_.int c,
   ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    return _binarySearch$2(_class.reference.pointer,
-            _id_binarySearch$2 as jni$_.JMethodIDPtr, _$is$.pointer, i)
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    return _binarySearch$2(_class.reference.pointer, _id_binarySearch$2.pointer,
+            _$cs.pointer, c)
         .integer;
   }
 
   static final _id_binarySearch$3 = _class.staticMethodId(
     r'binarySearch',
-    r'([IIII)I',
+    r'([CIIC)I',
   );
 
   static final _binarySearch$3 = jni$_.ProtectedJniExtensions.lookup<
@@ -30165,53 +23395,60 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `static public int binarySearch(int[] is, int i, int i1, int i2)`
-  static int binarySearch$3(
-    jni$_.JIntArray? is$,
-    int i,
-    int i1,
-    int i2,
+  /// from: `static public int binarySearch(char[] cs, int i, int i1, char c)`
+  static core$_.int binarySearch$3(
+    jni$_.JCharArray? cs,
+    core$_.int i,
+    core$_.int i1,
+    core$_.int c,
   ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    return _binarySearch$3(_class.reference.pointer,
-            _id_binarySearch$3 as jni$_.JMethodIDPtr, _$is$.pointer, i, i1, i2)
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    return _binarySearch$3(_class.reference.pointer, _id_binarySearch$3.pointer,
+            _$cs.pointer, i, i1, c)
         .integer;
   }
 
   static final _id_binarySearch$4 = _class.staticMethodId(
     r'binarySearch',
-    r'([SS)I',
+    r'([DD)I',
   );
 
   static final _binarySearch$4 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticIntMethod')
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Double
+                      )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.double)>();
 
-  /// from: `static public int binarySearch(short[] ss, short s)`
-  static int binarySearch$4(
-    jni$_.JShortArray? ss,
-    int s,
+  /// from: `static public int binarySearch(double[] ds, double d)`
+  static core$_.int binarySearch$4(
+    jni$_.JDoubleArray? ds,
+    core$_.double d,
   ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    return _binarySearch$4(_class.reference.pointer,
-            _id_binarySearch$4 as jni$_.JMethodIDPtr, _$ss.pointer, s)
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    return _binarySearch$4(_class.reference.pointer, _id_binarySearch$4.pointer,
+            _$ds.pointer, d)
         .integer;
   }
 
   static final _id_binarySearch$5 = _class.staticMethodId(
     r'binarySearch',
-    r'([SIIS)I',
+    r'([DIID)I',
   );
 
   static final _binarySearch$5 = jni$_.ProtectedJniExtensions.lookup<
@@ -30224,56 +23461,63 @@
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Int32,
                         jni$_.Int32,
-                        jni$_.Int32
+                        jni$_.Double
                       )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.double)>();
 
-  /// from: `static public int binarySearch(short[] ss, int i, int i1, short s)`
-  static int binarySearch$5(
-    jni$_.JShortArray? ss,
-    int i,
-    int i1,
-    int s,
+  /// from: `static public int binarySearch(double[] ds, int i, int i1, double d)`
+  static core$_.int binarySearch$5(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+    core$_.int i1,
+    core$_.double d,
   ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    return _binarySearch$5(_class.reference.pointer,
-            _id_binarySearch$5 as jni$_.JMethodIDPtr, _$ss.pointer, i, i1, s)
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    return _binarySearch$5(_class.reference.pointer, _id_binarySearch$5.pointer,
+            _$ds.pointer, i, i1, d)
         .integer;
   }
 
   static final _id_binarySearch$6 = _class.staticMethodId(
     r'binarySearch',
-    r'([CC)I',
+    r'([FF)I',
   );
 
   static final _binarySearch$6 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticIntMethod')
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Double
+                      )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.double)>();
 
-  /// from: `static public int binarySearch(char[] cs, char c)`
-  static int binarySearch$6(
-    jni$_.JCharArray? cs,
-    int c,
+  /// from: `static public int binarySearch(float[] fs, float f)`
+  static core$_.int binarySearch$6(
+    jni$_.JFloatArray? fs,
+    core$_.double f,
   ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    return _binarySearch$6(_class.reference.pointer,
-            _id_binarySearch$6 as jni$_.JMethodIDPtr, _$cs.pointer, c)
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    return _binarySearch$6(_class.reference.pointer, _id_binarySearch$6.pointer,
+            _$fs.pointer, f)
         .integer;
   }
 
   static final _id_binarySearch$7 = _class.staticMethodId(
     r'binarySearch',
-    r'([CIIC)I',
+    r'([FIIF)I',
   );
 
   static final _binarySearch$7 = jni$_.ProtectedJniExtensions.lookup<
@@ -30286,28 +23530,33 @@
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Int32,
                         jni$_.Int32,
-                        jni$_.Int32
+                        jni$_.Double
                       )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.double)>();
 
-  /// from: `static public int binarySearch(char[] cs, int i, int i1, char c)`
-  static int binarySearch$7(
-    jni$_.JCharArray? cs,
-    int i,
-    int i1,
-    int c,
+  /// from: `static public int binarySearch(float[] fs, int i, int i1, float f)`
+  static core$_.int binarySearch$7(
+    jni$_.JFloatArray? fs,
+    core$_.int i,
+    core$_.int i1,
+    core$_.double f,
   ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    return _binarySearch$7(_class.reference.pointer,
-            _id_binarySearch$7 as jni$_.JMethodIDPtr, _$cs.pointer, i, i1, c)
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    return _binarySearch$7(_class.reference.pointer, _id_binarySearch$7.pointer,
+            _$fs.pointer, i, i1, f)
         .integer;
   }
 
   static final _id_binarySearch$8 = _class.staticMethodId(
     r'binarySearch',
-    r'([BB)I',
+    r'([II)I',
   );
 
   static final _binarySearch$8 = jni$_.ProtectedJniExtensions.lookup<
@@ -30320,22 +23569,22 @@
           'globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
 
-  /// from: `static public int binarySearch(byte[] bs, byte b)`
-  static int binarySearch$8(
-    jni$_.JByteArray? bs,
-    int b,
+  /// from: `static public int binarySearch(int[] is, int i)`
+  static core$_.int binarySearch$8(
+    jni$_.JIntArray? is$,
+    core$_.int i,
   ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    return _binarySearch$8(_class.reference.pointer,
-            _id_binarySearch$8 as jni$_.JMethodIDPtr, _$bs.pointer, b)
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    return _binarySearch$8(_class.reference.pointer, _id_binarySearch$8.pointer,
+            _$is$.pointer, i)
         .integer;
   }
 
   static final _id_binarySearch$9 = _class.staticMethodId(
     r'binarySearch',
-    r'([BIIB)I',
+    r'([IIII)I',
   );
 
   static final _binarySearch$9 = jni$_.ProtectedJniExtensions.lookup<
@@ -30351,25 +23600,30 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `static public int binarySearch(byte[] bs, int i, int i1, byte b)`
-  static int binarySearch$9(
-    jni$_.JByteArray? bs,
-    int i,
-    int i1,
-    int b,
+  /// from: `static public int binarySearch(int[] is, int i, int i1, int i2)`
+  static core$_.int binarySearch$9(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+    core$_.int i1,
+    core$_.int i2,
   ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    return _binarySearch$9(_class.reference.pointer,
-            _id_binarySearch$9 as jni$_.JMethodIDPtr, _$bs.pointer, i, i1, b)
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    return _binarySearch$9(_class.reference.pointer, _id_binarySearch$9.pointer,
+            _$is$.pointer, i, i1, i2)
         .integer;
   }
 
   static final _id_binarySearch$10 = _class.staticMethodId(
     r'binarySearch',
-    r'([DD)I',
+    r'([Ljava/lang/Object;IILjava/lang/Object;)I',
   );
 
   static final _binarySearch$10 = jni$_.ProtectedJniExtensions.lookup<
@@ -30380,137 +23634,44 @@
                   jni$_.VarArgs<
                       (
                         jni$_.Pointer<jni$_.Void>,
-                        jni$_.Double
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
                       )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, double)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public int binarySearch(double[] ds, double d)`
-  static int binarySearch$10(
-    jni$_.JDoubleArray? ds,
-    double d,
+  /// from: `static public int binarySearch(java.lang.Object[] objects, int i, int i1, java.lang.Object object)`
+  static core$_.int binarySearch$10(
+    jni$_.JArray<jni$_.JObject?>? objects,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JObject? object,
   ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    return _binarySearch$10(_class.reference.pointer,
-            _id_binarySearch$10 as jni$_.JMethodIDPtr, _$ds.pointer, d)
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$object = object?.reference ?? jni$_.jNullReference;
+    return _binarySearch$10(
+            _class.reference.pointer,
+            _id_binarySearch$10.pointer,
+            _$objects.pointer,
+            i,
+            i1,
+            _$object.pointer)
         .integer;
   }
 
   static final _id_binarySearch$11 = _class.staticMethodId(
     r'binarySearch',
-    r'([DIID)I',
-  );
-
-  static final _binarySearch$11 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Double
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              double)>();
-
-  /// from: `static public int binarySearch(double[] ds, int i, int i1, double d)`
-  static int binarySearch$11(
-    jni$_.JDoubleArray? ds,
-    int i,
-    int i1,
-    double d,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    return _binarySearch$11(_class.reference.pointer,
-            _id_binarySearch$11 as jni$_.JMethodIDPtr, _$ds.pointer, i, i1, d)
-        .integer;
-  }
-
-  static final _id_binarySearch$12 = _class.staticMethodId(
-    r'binarySearch',
-    r'([FF)I',
-  );
-
-  static final _binarySearch$12 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Double
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, double)>();
-
-  /// from: `static public int binarySearch(float[] fs, float f)`
-  static int binarySearch$12(
-    jni$_.JFloatArray? fs,
-    double f,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    return _binarySearch$12(_class.reference.pointer,
-            _id_binarySearch$12 as jni$_.JMethodIDPtr, _$fs.pointer, f)
-        .integer;
-  }
-
-  static final _id_binarySearch$13 = _class.staticMethodId(
-    r'binarySearch',
-    r'([FIIF)I',
-  );
-
-  static final _binarySearch$13 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Double
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              double)>();
-
-  /// from: `static public int binarySearch(float[] fs, int i, int i1, float f)`
-  static int binarySearch$13(
-    jni$_.JFloatArray? fs,
-    int i,
-    int i1,
-    double f,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    return _binarySearch$13(_class.reference.pointer,
-            _id_binarySearch$13 as jni$_.JMethodIDPtr, _$fs.pointer, i, i1, f)
-        .integer;
-  }
-
-  static final _id_binarySearch$14 = _class.staticMethodId(
-    r'binarySearch',
     r'([Ljava/lang/Object;Ljava/lang/Object;)I',
   );
 
-  static final _binarySearch$14 = jni$_.ProtectedJniExtensions.lookup<
+  static final _binarySearch$11 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -30528,26 +23689,23 @@
               jni$_.Pointer<jni$_.Void>)>();
 
   /// from: `static public int binarySearch(java.lang.Object[] objects, java.lang.Object object)`
-  static int binarySearch$14(
+  static core$_.int binarySearch$11(
     jni$_.JArray<jni$_.JObject?>? objects,
     jni$_.JObject? object,
   ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
     final _$object = object?.reference ?? jni$_.jNullReference;
-    return _binarySearch$14(
-            _class.reference.pointer,
-            _id_binarySearch$14 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            _$object.pointer)
+    return _binarySearch$11(_class.reference.pointer,
+            _id_binarySearch$11.pointer, _$objects.pointer, _$object.pointer)
         .integer;
   }
 
-  static final _id_binarySearch$15 = _class.staticMethodId(
+  static final _id_binarySearch$12 = _class.staticMethodId(
     r'binarySearch',
-    r'([Ljava/lang/Object;IILjava/lang/Object;)I',
+    r'([JIIJ)I',
   );
 
-  static final _binarySearch$15 = jni$_.ProtectedJniExtensions.lookup<
+  static final _binarySearch$12 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -30557,39 +23715,128 @@
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Int32,
                         jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
+                        jni$_.Int64
                       )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
+              core$_.int,
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `static public int binarySearch(java.lang.Object[] objects, int i, int i1, java.lang.Object object)`
-  static int binarySearch$15(
-    jni$_.JArray<jni$_.JObject?>? objects,
-    int i,
-    int i1,
-    jni$_.JObject? object,
+  /// from: `static public int binarySearch(long[] js, int i, int i1, long j)`
+  static core$_.int binarySearch$12(
+    jni$_.JLongArray? js,
+    core$_.int i,
+    core$_.int i1,
+    core$_.int j,
   ) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$object = object?.reference ?? jni$_.jNullReference;
-    return _binarySearch$15(
-            _class.reference.pointer,
-            _id_binarySearch$15 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            i,
-            i1,
-            _$object.pointer)
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    return _binarySearch$12(_class.reference.pointer,
+            _id_binarySearch$12.pointer, _$js.pointer, i, i1, j)
+        .integer;
+  }
+
+  static final _id_binarySearch$13 = _class.staticMethodId(
+    r'binarySearch',
+    r'([JJ)I',
+  );
+
+  static final _binarySearch$13 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int64)>)>>(
+          'globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public int binarySearch(long[] js, long j)`
+  static core$_.int binarySearch$13(
+    jni$_.JLongArray? js,
+    core$_.int j,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    return _binarySearch$13(_class.reference.pointer,
+            _id_binarySearch$13.pointer, _$js.pointer, j)
+        .integer;
+  }
+
+  static final _id_binarySearch$14 = _class.staticMethodId(
+    r'binarySearch',
+    r'([SIIS)I',
+  );
+
+  static final _binarySearch$14 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int binarySearch(short[] ss, int i, int i1, short s)`
+  static core$_.int binarySearch$14(
+    jni$_.JShortArray? ss,
+    core$_.int i,
+    core$_.int i1,
+    core$_.int s,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    return _binarySearch$14(_class.reference.pointer,
+            _id_binarySearch$14.pointer, _$ss.pointer, i, i1, s)
+        .integer;
+  }
+
+  static final _id_binarySearch$15 = _class.staticMethodId(
+    r'binarySearch',
+    r'([SS)I',
+  );
+
+  static final _binarySearch$15 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public int binarySearch(short[] ss, short s)`
+  static core$_.int binarySearch$15(
+    jni$_.JShortArray? ss,
+    core$_.int s,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    return _binarySearch$15(_class.reference.pointer,
+            _id_binarySearch$15.pointer, _$ss.pointer, s)
         .integer;
   }
 
   static final _id_binarySearch$16 = _class.staticMethodId(
     r'binarySearch',
-    r'([Ljava/lang/Object;Ljava/lang/Object;Ljava/util/Comparator;)I',
+    r'([Ljava/lang/Object;IILjava/lang/Object;Ljava/util/Comparator;)I',
   );
 
   static final _binarySearch$16 = jni$_.ProtectedJniExtensions.lookup<
@@ -30600,6 +23847,8 @@
                   jni$_.VarArgs<
                       (
                         jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Pointer<jni$_.Void>
                       )>)>>('globalEnv_CallStaticIntMethod')
@@ -30608,23 +23857,28 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public int binarySearch(java.lang.Object[] objects, T object, java.util.Comparator comparator)`
-  static int binarySearch$16<$T extends jni$_.JObject?>(
+  /// from: `static public int binarySearch(T[] objects, int i, int i1, T object, java.util.Comparator<? super T> comparator)`
+  static core$_.int binarySearch$16<$T extends jni$_.JObject?>(
     jni$_.JArray<$T?>? objects,
+    core$_.int i,
+    core$_.int i1,
     $T? object,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
+    jni$_.JObject? comparator,
+  ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
     final _$object = object?.reference ?? jni$_.jNullReference;
     final _$comparator = comparator?.reference ?? jni$_.jNullReference;
     return _binarySearch$16(
             _class.reference.pointer,
-            _id_binarySearch$16 as jni$_.JMethodIDPtr,
+            _id_binarySearch$16.pointer,
             _$objects.pointer,
+            i,
+            i1,
             _$object.pointer,
             _$comparator.pointer)
         .integer;
@@ -30632,7 +23886,7 @@
 
   static final _id_binarySearch$17 = _class.staticMethodId(
     r'binarySearch',
-    r'([Ljava/lang/Object;IILjava/lang/Object;Ljava/util/Comparator;)I',
+    r'([Ljava/lang/Object;Ljava/lang/Object;Ljava/util/Comparator;)I',
   );
 
   static final _binarySearch$17 = jni$_.ProtectedJniExtensions.lookup<
@@ -30643,8 +23897,6 @@
                   jni$_.VarArgs<
                       (
                         jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Pointer<jni$_.Void>
                       )>)>>('globalEnv_CallStaticIntMethod')
@@ -30653,40 +23905,33 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public int binarySearch(java.lang.Object[] objects, int i, int i1, T object, java.util.Comparator comparator)`
-  static int binarySearch$17<$T extends jni$_.JObject?>(
+  /// from: `static public int binarySearch(T[] objects, T object, java.util.Comparator<? super T> comparator)`
+  static core$_.int binarySearch$17<$T extends jni$_.JObject?>(
     jni$_.JArray<$T?>? objects,
-    int i,
-    int i1,
     $T? object,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
+    jni$_.JObject? comparator,
+  ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
     final _$object = object?.reference ?? jni$_.jNullReference;
     final _$comparator = comparator?.reference ?? jni$_.jNullReference;
     return _binarySearch$17(
             _class.reference.pointer,
-            _id_binarySearch$17 as jni$_.JMethodIDPtr,
+            _id_binarySearch$17.pointer,
             _$objects.pointer,
-            i,
-            i1,
             _$object.pointer,
             _$comparator.pointer)
         .integer;
   }
 
-  static final _id_equals = _class.staticMethodId(
-    r'equals',
-    r'([J[J)Z',
+  static final _id_compare = _class.staticMethodId(
+    r'compare',
+    r'([Z[Z)I',
   );
 
-  static final _equals = jni$_.ProtectedJniExtensions.lookup<
+  static final _compare = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -30695,7 +23940,7 @@
                       (
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
+                      )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(
               jni$_.Pointer<jni$_.Void>,
@@ -30703,24 +23948,550 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public boolean equals(long[] js, long[] js1)`
-  static bool equals(
+  /// from: `static public int compare(boolean[] zs, boolean[] zs1)`
+  static core$_.int compare(
+    jni$_.JBooleanArray? zs,
+    jni$_.JBooleanArray? zs1,
+  ) {
+    final _$zs = zs?.reference ?? jni$_.jNullReference;
+    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
+    return _compare(_class.reference.pointer, _id_compare.pointer, _$zs.pointer,
+            _$zs1.pointer)
+        .integer;
+  }
+
+  static final _id_compare$1 = _class.staticMethodId(
+    r'compare',
+    r'([ZII[ZII)I',
+  );
+
+  static final _compare$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int compare(boolean[] zs, int i, int i1, boolean[] zs1, int i2, int i3)`
+  static core$_.int compare$1(
+    jni$_.JBooleanArray? zs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JBooleanArray? zs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$zs = zs?.reference ?? jni$_.jNullReference;
+    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
+    return _compare$1(_class.reference.pointer, _id_compare$1.pointer,
+            _$zs.pointer, i, i1, _$zs1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_compare$2 = _class.staticMethodId(
+    r'compare',
+    r'([B[B)I',
+  );
+
+  static final _compare$2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int compare(byte[] bs, byte[] bs1)`
+  static core$_.int compare$2(
+    jni$_.JByteArray? bs,
+    jni$_.JByteArray? bs1,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
+    return _compare$2(_class.reference.pointer, _id_compare$2.pointer,
+            _$bs.pointer, _$bs1.pointer)
+        .integer;
+  }
+
+  static final _id_compare$3 = _class.staticMethodId(
+    r'compare',
+    r'([BII[BII)I',
+  );
+
+  static final _compare$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int compare(byte[] bs, int i, int i1, byte[] bs1, int i2, int i3)`
+  static core$_.int compare$3(
+    jni$_.JByteArray? bs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JByteArray? bs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
+    return _compare$3(_class.reference.pointer, _id_compare$3.pointer,
+            _$bs.pointer, i, i1, _$bs1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_compare$4 = _class.staticMethodId(
+    r'compare',
+    r'([C[C)I',
+  );
+
+  static final _compare$4 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int compare(char[] cs, char[] cs1)`
+  static core$_.int compare$4(
+    jni$_.JCharArray? cs,
+    jni$_.JCharArray? cs1,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
+    return _compare$4(_class.reference.pointer, _id_compare$4.pointer,
+            _$cs.pointer, _$cs1.pointer)
+        .integer;
+  }
+
+  static final _id_compare$5 = _class.staticMethodId(
+    r'compare',
+    r'([CII[CII)I',
+  );
+
+  static final _compare$5 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int compare(char[] cs, int i, int i1, char[] cs1, int i2, int i3)`
+  static core$_.int compare$5(
+    jni$_.JCharArray? cs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JCharArray? cs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
+    return _compare$5(_class.reference.pointer, _id_compare$5.pointer,
+            _$cs.pointer, i, i1, _$cs1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_compare$6 = _class.staticMethodId(
+    r'compare',
+    r'([D[D)I',
+  );
+
+  static final _compare$6 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int compare(double[] ds, double[] ds1)`
+  static core$_.int compare$6(
+    jni$_.JDoubleArray? ds,
+    jni$_.JDoubleArray? ds1,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
+    return _compare$6(_class.reference.pointer, _id_compare$6.pointer,
+            _$ds.pointer, _$ds1.pointer)
+        .integer;
+  }
+
+  static final _id_compare$7 = _class.staticMethodId(
+    r'compare',
+    r'([DII[DII)I',
+  );
+
+  static final _compare$7 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int compare(double[] ds, int i, int i1, double[] ds1, int i2, int i3)`
+  static core$_.int compare$7(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JDoubleArray? ds1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
+    return _compare$7(_class.reference.pointer, _id_compare$7.pointer,
+            _$ds.pointer, i, i1, _$ds1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_compare$8 = _class.staticMethodId(
+    r'compare',
+    r'([F[F)I',
+  );
+
+  static final _compare$8 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int compare(float[] fs, float[] fs1)`
+  static core$_.int compare$8(
+    jni$_.JFloatArray? fs,
+    jni$_.JFloatArray? fs1,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
+    return _compare$8(_class.reference.pointer, _id_compare$8.pointer,
+            _$fs.pointer, _$fs1.pointer)
+        .integer;
+  }
+
+  static final _id_compare$9 = _class.staticMethodId(
+    r'compare',
+    r'([FII[FII)I',
+  );
+
+  static final _compare$9 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int compare(float[] fs, int i, int i1, float[] fs1, int i2, int i3)`
+  static core$_.int compare$9(
+    jni$_.JFloatArray? fs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JFloatArray? fs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
+    return _compare$9(_class.reference.pointer, _id_compare$9.pointer,
+            _$fs.pointer, i, i1, _$fs1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_compare$10 = _class.staticMethodId(
+    r'compare',
+    r'([III[III)I',
+  );
+
+  static final _compare$10 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int compare(int[] is, int i, int i1, int[] is1, int i2, int i3)`
+  static core$_.int compare$10(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JIntArray? is1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    final _$is1 = is1?.reference ?? jni$_.jNullReference;
+    return _compare$10(_class.reference.pointer, _id_compare$10.pointer,
+            _$is$.pointer, i, i1, _$is1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_compare$11 = _class.staticMethodId(
+    r'compare',
+    r'([I[I)I',
+  );
+
+  static final _compare$11 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int compare(int[] is, int[] is1)`
+  static core$_.int compare$11(
+    jni$_.JIntArray? is$,
+    jni$_.JIntArray? is1,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    final _$is1 = is1?.reference ?? jni$_.jNullReference;
+    return _compare$11(_class.reference.pointer, _id_compare$11.pointer,
+            _$is$.pointer, _$is1.pointer)
+        .integer;
+  }
+
+  static final _id_compare$12 = _class.staticMethodId(
+    r'compare',
+    r'([JII[JII)I',
+  );
+
+  static final _compare$12 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int compare(long[] js, int i, int i1, long[] js1, int i2, int i3)`
+  static core$_.int compare$12(
+    jni$_.JLongArray? js,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JLongArray? js1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    final _$js1 = js1?.reference ?? jni$_.jNullReference;
+    return _compare$12(_class.reference.pointer, _id_compare$12.pointer,
+            _$js.pointer, i, i1, _$js1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_compare$13 = _class.staticMethodId(
+    r'compare',
+    r'([J[J)I',
+  );
+
+  static final _compare$13 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int compare(long[] js, long[] js1)`
+  static core$_.int compare$13(
     jni$_.JLongArray? js,
     jni$_.JLongArray? js1,
   ) {
     final _$js = js?.reference ?? jni$_.jNullReference;
     final _$js1 = js1?.reference ?? jni$_.jNullReference;
-    return _equals(_class.reference.pointer, _id_equals as jni$_.JMethodIDPtr,
+    return _compare$13(_class.reference.pointer, _id_compare$13.pointer,
             _$js.pointer, _$js1.pointer)
-        .boolean;
+        .integer;
   }
 
-  static final _id_equals$1 = _class.staticMethodId(
-    r'equals',
-    r'([JII[JII)Z',
+  static final _id_compare$14 = _class.staticMethodId(
+    r'compare',
+    r'([SII[SII)I',
   );
 
-  static final _equals$1 = jni$_.ProtectedJniExtensions.lookup<
+  static final _compare$14 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -30733,47 +24504,40 @@
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Int32,
                         jni$_.Int32
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
+                      )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
+              core$_.int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `static public boolean equals(long[] js, int i, int i1, long[] js1, int i2, int i3)`
-  static bool equals$1(
-    jni$_.JLongArray? js,
-    int i,
-    int i1,
-    jni$_.JLongArray? js1,
-    int i2,
-    int i3,
+  /// from: `static public int compare(short[] ss, int i, int i1, short[] ss1, int i2, int i3)`
+  static core$_.int compare$14(
+    jni$_.JShortArray? ss,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JShortArray? ss1,
+    core$_.int i2,
+    core$_.int i3,
   ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    final _$js1 = js1?.reference ?? jni$_.jNullReference;
-    return _equals$1(
-            _class.reference.pointer,
-            _id_equals$1 as jni$_.JMethodIDPtr,
-            _$js.pointer,
-            i,
-            i1,
-            _$js1.pointer,
-            i2,
-            i3)
-        .boolean;
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
+    return _compare$14(_class.reference.pointer, _id_compare$14.pointer,
+            _$ss.pointer, i, i1, _$ss1.pointer, i2, i3)
+        .integer;
   }
 
-  static final _id_equals$2 = _class.staticMethodId(
-    r'equals',
-    r'([I[I)Z',
+  static final _id_compare$15 = _class.staticMethodId(
+    r'compare',
+    r'([S[S)I',
   );
 
-  static final _equals$2 = jni$_.ProtectedJniExtensions.lookup<
+  static final _compare$15 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -30782,7 +24546,7 @@
                       (
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
+                      )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(
               jni$_.Pointer<jni$_.Void>,
@@ -30790,111 +24554,24 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public boolean equals(int[] is, int[] is1)`
-  static bool equals$2(
-    jni$_.JIntArray? is$,
-    jni$_.JIntArray? is1,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    final _$is1 = is1?.reference ?? jni$_.jNullReference;
-    return _equals$2(_class.reference.pointer,
-            _id_equals$2 as jni$_.JMethodIDPtr, _$is$.pointer, _$is1.pointer)
-        .boolean;
-  }
-
-  static final _id_equals$3 = _class.staticMethodId(
-    r'equals',
-    r'([III[III)Z',
-  );
-
-  static final _equals$3 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public boolean equals(int[] is, int i, int i1, int[] is1, int i2, int i3)`
-  static bool equals$3(
-    jni$_.JIntArray? is$,
-    int i,
-    int i1,
-    jni$_.JIntArray? is1,
-    int i2,
-    int i3,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    final _$is1 = is1?.reference ?? jni$_.jNullReference;
-    return _equals$3(
-            _class.reference.pointer,
-            _id_equals$3 as jni$_.JMethodIDPtr,
-            _$is$.pointer,
-            i,
-            i1,
-            _$is1.pointer,
-            i2,
-            i3)
-        .boolean;
-  }
-
-  static final _id_equals$4 = _class.staticMethodId(
-    r'equals',
-    r'([S[S)Z',
-  );
-
-  static final _equals$4 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public boolean equals(short[] ss, short[] ss1)`
-  static bool equals$4(
+  /// from: `static public int compare(short[] ss, short[] ss1)`
+  static core$_.int compare$15(
     jni$_.JShortArray? ss,
     jni$_.JShortArray? ss1,
   ) {
     final _$ss = ss?.reference ?? jni$_.jNullReference;
     final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
-    return _equals$4(_class.reference.pointer,
-            _id_equals$4 as jni$_.JMethodIDPtr, _$ss.pointer, _$ss1.pointer)
-        .boolean;
+    return _compare$15(_class.reference.pointer, _id_compare$15.pointer,
+            _$ss.pointer, _$ss1.pointer)
+        .integer;
   }
 
-  static final _id_equals$5 = _class.staticMethodId(
-    r'equals',
-    r'([SII[SII)Z',
+  static final _id_compare$16 = _class.staticMethodId(
+    r'compare',
+    r'([Ljava/lang/Comparable;II[Ljava/lang/Comparable;II)I',
   );
 
-  static final _equals$5 = jni$_.ProtectedJniExtensions.lookup<
+  static final _compare$16 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -30907,47 +24584,40 @@
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Int32,
                         jni$_.Int32
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
+                      )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
+              core$_.int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `static public boolean equals(short[] ss, int i, int i1, short[] ss1, int i2, int i3)`
-  static bool equals$5(
-    jni$_.JShortArray? ss,
-    int i,
-    int i1,
-    jni$_.JShortArray? ss1,
-    int i2,
-    int i3,
+  /// from: `static public int compare(T[] comparables, int i, int i1, T[] comparables1, int i2, int i3)`
+  static core$_.int compare$16<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? comparables,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JArray<$T?>? comparables1,
+    core$_.int i2,
+    core$_.int i3,
   ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
-    return _equals$5(
-            _class.reference.pointer,
-            _id_equals$5 as jni$_.JMethodIDPtr,
-            _$ss.pointer,
-            i,
-            i1,
-            _$ss1.pointer,
-            i2,
-            i3)
-        .boolean;
+    final _$comparables = comparables?.reference ?? jni$_.jNullReference;
+    final _$comparables1 = comparables1?.reference ?? jni$_.jNullReference;
+    return _compare$16(_class.reference.pointer, _id_compare$16.pointer,
+            _$comparables.pointer, i, i1, _$comparables1.pointer, i2, i3)
+        .integer;
   }
 
-  static final _id_equals$6 = _class.staticMethodId(
-    r'equals',
-    r'([C[C)Z',
+  static final _id_compare$17 = _class.staticMethodId(
+    r'compare',
+    r'([Ljava/lang/Object;II[Ljava/lang/Object;IILjava/util/Comparator;)I',
   );
 
-  static final _equals$6 = jni$_.ProtectedJniExtensions.lookup<
+  static final _compare$17 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -30955,610 +24625,41 @@
                   jni$_.VarArgs<
                       (
                         jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
                         jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
+                      )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public boolean equals(char[] cs, char[] cs1)`
-  static bool equals$6(
-    jni$_.JCharArray? cs,
-    jni$_.JCharArray? cs1,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
-    return _equals$6(_class.reference.pointer,
-            _id_equals$6 as jni$_.JMethodIDPtr, _$cs.pointer, _$cs1.pointer)
-        .boolean;
-  }
-
-  static final _id_equals$7 = _class.staticMethodId(
-    r'equals',
-    r'([CII[CII)Z',
-  );
-
-  static final _equals$7 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public boolean equals(char[] cs, int i, int i1, char[] cs1, int i2, int i3)`
-  static bool equals$7(
-    jni$_.JCharArray? cs,
-    int i,
-    int i1,
-    jni$_.JCharArray? cs1,
-    int i2,
-    int i3,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
-    return _equals$7(
-            _class.reference.pointer,
-            _id_equals$7 as jni$_.JMethodIDPtr,
-            _$cs.pointer,
-            i,
-            i1,
-            _$cs1.pointer,
-            i2,
-            i3)
-        .boolean;
-  }
-
-  static final _id_equals$8 = _class.staticMethodId(
-    r'equals',
-    r'([B[B)Z',
-  );
-
-  static final _equals$8 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public boolean equals(byte[] bs, byte[] bs1)`
-  static bool equals$8(
-    jni$_.JByteArray? bs,
-    jni$_.JByteArray? bs1,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
-    return _equals$8(_class.reference.pointer,
-            _id_equals$8 as jni$_.JMethodIDPtr, _$bs.pointer, _$bs1.pointer)
-        .boolean;
-  }
-
-  static final _id_equals$9 = _class.staticMethodId(
-    r'equals',
-    r'([BII[BII)Z',
-  );
-
-  static final _equals$9 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public boolean equals(byte[] bs, int i, int i1, byte[] bs1, int i2, int i3)`
-  static bool equals$9(
-    jni$_.JByteArray? bs,
-    int i,
-    int i1,
-    jni$_.JByteArray? bs1,
-    int i2,
-    int i3,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
-    return _equals$9(
-            _class.reference.pointer,
-            _id_equals$9 as jni$_.JMethodIDPtr,
-            _$bs.pointer,
-            i,
-            i1,
-            _$bs1.pointer,
-            i2,
-            i3)
-        .boolean;
-  }
-
-  static final _id_equals$10 = _class.staticMethodId(
-    r'equals',
-    r'([Z[Z)Z',
-  );
-
-  static final _equals$10 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public boolean equals(boolean[] zs, boolean[] zs1)`
-  static bool equals$10(
-    jni$_.JBooleanArray? zs,
-    jni$_.JBooleanArray? zs1,
-  ) {
-    final _$zs = zs?.reference ?? jni$_.jNullReference;
-    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
-    return _equals$10(_class.reference.pointer,
-            _id_equals$10 as jni$_.JMethodIDPtr, _$zs.pointer, _$zs1.pointer)
-        .boolean;
-  }
-
-  static final _id_equals$11 = _class.staticMethodId(
-    r'equals',
-    r'([ZII[ZII)Z',
-  );
-
-  static final _equals$11 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public boolean equals(boolean[] zs, int i, int i1, boolean[] zs1, int i2, int i3)`
-  static bool equals$11(
-    jni$_.JBooleanArray? zs,
-    int i,
-    int i1,
-    jni$_.JBooleanArray? zs1,
-    int i2,
-    int i3,
-  ) {
-    final _$zs = zs?.reference ?? jni$_.jNullReference;
-    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
-    return _equals$11(
-            _class.reference.pointer,
-            _id_equals$11 as jni$_.JMethodIDPtr,
-            _$zs.pointer,
-            i,
-            i1,
-            _$zs1.pointer,
-            i2,
-            i3)
-        .boolean;
-  }
-
-  static final _id_equals$12 = _class.staticMethodId(
-    r'equals',
-    r'([D[D)Z',
-  );
-
-  static final _equals$12 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public boolean equals(double[] ds, double[] ds1)`
-  static bool equals$12(
-    jni$_.JDoubleArray? ds,
-    jni$_.JDoubleArray? ds1,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
-    return _equals$12(_class.reference.pointer,
-            _id_equals$12 as jni$_.JMethodIDPtr, _$ds.pointer, _$ds1.pointer)
-        .boolean;
-  }
-
-  static final _id_equals$13 = _class.staticMethodId(
-    r'equals',
-    r'([DII[DII)Z',
-  );
-
-  static final _equals$13 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public boolean equals(double[] ds, int i, int i1, double[] ds1, int i2, int i3)`
-  static bool equals$13(
-    jni$_.JDoubleArray? ds,
-    int i,
-    int i1,
-    jni$_.JDoubleArray? ds1,
-    int i2,
-    int i3,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
-    return _equals$13(
-            _class.reference.pointer,
-            _id_equals$13 as jni$_.JMethodIDPtr,
-            _$ds.pointer,
-            i,
-            i1,
-            _$ds1.pointer,
-            i2,
-            i3)
-        .boolean;
-  }
-
-  static final _id_equals$14 = _class.staticMethodId(
-    r'equals',
-    r'([F[F)Z',
-  );
-
-  static final _equals$14 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public boolean equals(float[] fs, float[] fs1)`
-  static bool equals$14(
-    jni$_.JFloatArray? fs,
-    jni$_.JFloatArray? fs1,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
-    return _equals$14(_class.reference.pointer,
-            _id_equals$14 as jni$_.JMethodIDPtr, _$fs.pointer, _$fs1.pointer)
-        .boolean;
-  }
-
-  static final _id_equals$15 = _class.staticMethodId(
-    r'equals',
-    r'([FII[FII)Z',
-  );
-
-  static final _equals$15 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public boolean equals(float[] fs, int i, int i1, float[] fs1, int i2, int i3)`
-  static bool equals$15(
-    jni$_.JFloatArray? fs,
-    int i,
-    int i1,
-    jni$_.JFloatArray? fs1,
-    int i2,
-    int i3,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
-    return _equals$15(
-            _class.reference.pointer,
-            _id_equals$15 as jni$_.JMethodIDPtr,
-            _$fs.pointer,
-            i,
-            i1,
-            _$fs1.pointer,
-            i2,
-            i3)
-        .boolean;
-  }
-
-  static final _id_equals$16 = _class.staticMethodId(
-    r'equals',
-    r'([Ljava/lang/Object;[Ljava/lang/Object;)Z',
-  );
-
-  static final _equals$16 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public boolean equals(java.lang.Object[] objects, java.lang.Object[] objects1)`
-  static bool equals$16(
-    jni$_.JArray<jni$_.JObject?>? objects,
-    jni$_.JArray<jni$_.JObject?>? objects1,
-  ) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
-    return _equals$16(
-            _class.reference.pointer,
-            _id_equals$16 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            _$objects1.pointer)
-        .boolean;
-  }
-
-  static final _id_equals$17 = _class.staticMethodId(
-    r'equals',
-    r'([Ljava/lang/Object;II[Ljava/lang/Object;II)Z',
-  );
-
-  static final _equals$17 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public boolean equals(java.lang.Object[] objects, int i, int i1, java.lang.Object[] objects1, int i2, int i3)`
-  static bool equals$17(
-    jni$_.JArray<jni$_.JObject?>? objects,
-    int i,
-    int i1,
-    jni$_.JArray<jni$_.JObject?>? objects1,
-    int i2,
-    int i3,
-  ) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
-    return _equals$17(
-            _class.reference.pointer,
-            _id_equals$17 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            i,
-            i1,
-            _$objects1.pointer,
-            i2,
-            i3)
-        .boolean;
-  }
-
-  static final _id_equals$18 = _class.staticMethodId(
-    r'equals',
-    r'([Ljava/lang/Object;[Ljava/lang/Object;Ljava/util/Comparator;)Z',
-  );
-
-  static final _equals$18 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public boolean equals(java.lang.Object[] objects, java.lang.Object[] objects1, java.util.Comparator comparator)`
-  static bool equals$18<$T extends jni$_.JObject?>(
+  /// from: `static public int compare(T[] objects, int i, int i1, T[] objects1, int i2, int i3, java.util.Comparator<? super T> comparator)`
+  static core$_.int compare$17<$T extends jni$_.JObject?>(
     jni$_.JArray<$T?>? objects,
+    core$_.int i,
+    core$_.int i1,
     jni$_.JArray<$T?>? objects1,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
+    core$_.int i2,
+    core$_.int i3,
+    jni$_.JObject? comparator,
+  ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
     final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
     final _$comparator = comparator?.reference ?? jni$_.jNullReference;
-    return _equals$18(
+    return _compare$17(
             _class.reference.pointer,
-            _id_equals$18 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            _$objects1.pointer,
-            _$comparator.pointer)
-        .boolean;
-  }
-
-  static final _id_equals$19 = _class.staticMethodId(
-    r'equals',
-    r'([Ljava/lang/Object;II[Ljava/lang/Object;IILjava/util/Comparator;)Z',
-  );
-
-  static final _equals$19 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticBooleanMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public boolean equals(java.lang.Object[] objects, int i, int i1, java.lang.Object[] objects1, int i2, int i3, java.util.Comparator comparator)`
-  static bool equals$19<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    int i,
-    int i1,
-    jni$_.JArray<$T?>? objects1,
-    int i2,
-    int i3,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
-    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
-    return _equals$19(
-            _class.reference.pointer,
-            _id_equals$19 as jni$_.JMethodIDPtr,
+            _id_compare$17.pointer,
             _$objects.pointer,
             i,
             i1,
@@ -31566,561 +24667,123 @@
             i2,
             i3,
             _$comparator.pointer)
-        .boolean;
+        .integer;
   }
 
-  static final _id_fill = _class.staticMethodId(
-    r'fill',
-    r'([JJ)V',
+  static final _id_compare$18 = _class.staticMethodId(
+    r'compare',
+    r'([Ljava/lang/Comparable;[Ljava/lang/Comparable;)I',
   );
 
-  static final _fill = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int64)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public void fill(long[] js, long j)`
-  static void fill(
-    jni$_.JLongArray? js,
-    int j,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    _fill(_class.reference.pointer, _id_fill as jni$_.JMethodIDPtr,
-            _$js.pointer, j)
-        .check();
-  }
-
-  static final _id_fill$1 = _class.staticMethodId(
-    r'fill',
-    r'([JIIJ)V',
-  );
-
-  static final _fill$1 = jni$_.ProtectedJniExtensions.lookup<
+  static final _compare$18 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Int64
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int, int)>();
-
-  /// from: `static public void fill(long[] js, int i, int i1, long j)`
-  static void fill$1(
-    jni$_.JLongArray? js,
-    int i,
-    int i1,
-    int j,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    _fill$1(_class.reference.pointer, _id_fill$1 as jni$_.JMethodIDPtr,
-            _$js.pointer, i, i1, j)
-        .check();
-  }
-
-  static final _id_fill$2 = _class.staticMethodId(
-    r'fill',
-    r'([II)V',
-  );
-
-  static final _fill$2 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public void fill(int[] is, int i)`
-  static void fill$2(
-    jni$_.JIntArray? is$,
-    int i,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    _fill$2(_class.reference.pointer, _id_fill$2 as jni$_.JMethodIDPtr,
-            _$is$.pointer, i)
-        .check();
-  }
-
-  static final _id_fill$3 = _class.staticMethodId(
-    r'fill',
-    r'([IIII)V',
-  );
-
-  static final _fill$3 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int, int)>();
-
-  /// from: `static public void fill(int[] is, int i, int i1, int i2)`
-  static void fill$3(
-    jni$_.JIntArray? is$,
-    int i,
-    int i1,
-    int i2,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    _fill$3(_class.reference.pointer, _id_fill$3 as jni$_.JMethodIDPtr,
-            _$is$.pointer, i, i1, i2)
-        .check();
-  }
-
-  static final _id_fill$4 = _class.staticMethodId(
-    r'fill',
-    r'([SS)V',
-  );
-
-  static final _fill$4 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public void fill(short[] ss, short s)`
-  static void fill$4(
-    jni$_.JShortArray? ss,
-    int s,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    _fill$4(_class.reference.pointer, _id_fill$4 as jni$_.JMethodIDPtr,
-            _$ss.pointer, s)
-        .check();
-  }
-
-  static final _id_fill$5 = _class.staticMethodId(
-    r'fill',
-    r'([SIIS)V',
-  );
-
-  static final _fill$5 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int, int)>();
-
-  /// from: `static public void fill(short[] ss, int i, int i1, short s)`
-  static void fill$5(
-    jni$_.JShortArray? ss,
-    int i,
-    int i1,
-    int s,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    _fill$5(_class.reference.pointer, _id_fill$5 as jni$_.JMethodIDPtr,
-            _$ss.pointer, i, i1, s)
-        .check();
-  }
-
-  static final _id_fill$6 = _class.staticMethodId(
-    r'fill',
-    r'([CC)V',
-  );
-
-  static final _fill$6 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public void fill(char[] cs, char c)`
-  static void fill$6(
-    jni$_.JCharArray? cs,
-    int c,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    _fill$6(_class.reference.pointer, _id_fill$6 as jni$_.JMethodIDPtr,
-            _$cs.pointer, c)
-        .check();
-  }
-
-  static final _id_fill$7 = _class.staticMethodId(
-    r'fill',
-    r'([CIIC)V',
-  );
-
-  static final _fill$7 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int, int)>();
-
-  /// from: `static public void fill(char[] cs, int i, int i1, char c)`
-  static void fill$7(
-    jni$_.JCharArray? cs,
-    int i,
-    int i1,
-    int c,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    _fill$7(_class.reference.pointer, _id_fill$7 as jni$_.JMethodIDPtr,
-            _$cs.pointer, i, i1, c)
-        .check();
-  }
-
-  static final _id_fill$8 = _class.staticMethodId(
-    r'fill',
-    r'([BB)V',
-  );
-
-  static final _fill$8 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public void fill(byte[] bs, byte b)`
-  static void fill$8(
-    jni$_.JByteArray? bs,
-    int b,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    _fill$8(_class.reference.pointer, _id_fill$8 as jni$_.JMethodIDPtr,
-            _$bs.pointer, b)
-        .check();
-  }
-
-  static final _id_fill$9 = _class.staticMethodId(
-    r'fill',
-    r'([BIIB)V',
-  );
-
-  static final _fill$9 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int, int)>();
-
-  /// from: `static public void fill(byte[] bs, int i, int i1, byte b)`
-  static void fill$9(
-    jni$_.JByteArray? bs,
-    int i,
-    int i1,
-    int b,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    _fill$9(_class.reference.pointer, _id_fill$9 as jni$_.JMethodIDPtr,
-            _$bs.pointer, i, i1, b)
-        .check();
-  }
-
-  static final _id_fill$10 = _class.staticMethodId(
-    r'fill',
-    r'([ZZ)V',
-  );
-
-  static final _fill$10 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JThrowablePtr Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public void fill(boolean[] zs, boolean z)`
-  static void fill$10(
-    jni$_.JBooleanArray? zs,
-    bool z,
-  ) {
-    final _$zs = zs?.reference ?? jni$_.jNullReference;
-    _fill$10(_class.reference.pointer, _id_fill$10 as jni$_.JMethodIDPtr,
-            _$zs.pointer, z ? 1 : 0)
-        .check();
-  }
-
-  static final _id_fill$11 = _class.staticMethodId(
-    r'fill',
-    r'([ZIIZ)V',
-  );
-
-  static final _fill$11 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int, int)>();
-
-  /// from: `static public void fill(boolean[] zs, int i, int i1, boolean z)`
-  static void fill$11(
-    jni$_.JBooleanArray? zs,
-    int i,
-    int i1,
-    bool z,
-  ) {
-    final _$zs = zs?.reference ?? jni$_.jNullReference;
-    _fill$11(_class.reference.pointer, _id_fill$11 as jni$_.JMethodIDPtr,
-            _$zs.pointer, i, i1, z ? 1 : 0)
-        .check();
-  }
-
-  static final _id_fill$12 = _class.staticMethodId(
-    r'fill',
-    r'([DD)V',
-  );
-
-  static final _fill$12 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Double
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, double)>();
-
-  /// from: `static public void fill(double[] ds, double d)`
-  static void fill$12(
-    jni$_.JDoubleArray? ds,
-    double d,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    _fill$12(_class.reference.pointer, _id_fill$12 as jni$_.JMethodIDPtr,
-            _$ds.pointer, d)
-        .check();
-  }
-
-  static final _id_fill$13 = _class.staticMethodId(
-    r'fill',
-    r'([DIID)V',
-  );
-
-  static final _fill$13 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Double
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              double)>();
-
-  /// from: `static public void fill(double[] ds, int i, int i1, double d)`
-  static void fill$13(
-    jni$_.JDoubleArray? ds,
-    int i,
-    int i1,
-    double d,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    _fill$13(_class.reference.pointer, _id_fill$13 as jni$_.JMethodIDPtr,
-            _$ds.pointer, i, i1, d)
-        .check();
-  }
-
-  static final _id_fill$14 = _class.staticMethodId(
-    r'fill',
-    r'([FF)V',
-  );
-
-  static final _fill$14 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Double
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, double)>();
-
-  /// from: `static public void fill(float[] fs, float f)`
-  static void fill$14(
-    jni$_.JFloatArray? fs,
-    double f,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    _fill$14(_class.reference.pointer, _id_fill$14 as jni$_.JMethodIDPtr,
-            _$fs.pointer, f)
-        .check();
-  }
-
-  static final _id_fill$15 = _class.staticMethodId(
-    r'fill',
-    r'([FIIF)V',
-  );
-
-  static final _fill$15 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Double
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              double)>();
-
-  /// from: `static public void fill(float[] fs, int i, int i1, float f)`
-  static void fill$15(
-    jni$_.JFloatArray? fs,
-    int i,
-    int i1,
-    double f,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    _fill$15(_class.reference.pointer, _id_fill$15 as jni$_.JMethodIDPtr,
-            _$fs.pointer, i, i1, f)
-        .check();
-  }
-
-  static final _id_fill$16 = _class.staticMethodId(
-    r'fill',
-    r'([Ljava/lang/Object;Ljava/lang/Object;)V',
-  );
-
-  static final _fill$16 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
+              jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
                   jni$_.JMethodIDPtr,
                   jni$_.VarArgs<
                       (
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
+                      )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
-          jni$_.JThrowablePtr Function(
+          jni$_.JniResult Function(
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public void fill(java.lang.Object[] objects, java.lang.Object object)`
-  static void fill$16(
-    jni$_.JArray<jni$_.JObject?>? objects,
-    jni$_.JObject? object,
+  /// from: `static public int compare(T[] comparables, T[] comparables1)`
+  static core$_.int compare$18<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? comparables,
+    jni$_.JArray<$T?>? comparables1,
   ) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$object = object?.reference ?? jni$_.jNullReference;
-    _fill$16(_class.reference.pointer, _id_fill$16 as jni$_.JMethodIDPtr,
-            _$objects.pointer, _$object.pointer)
-        .check();
+    final _$comparables = comparables?.reference ?? jni$_.jNullReference;
+    final _$comparables1 = comparables1?.reference ?? jni$_.jNullReference;
+    return _compare$18(_class.reference.pointer, _id_compare$18.pointer,
+            _$comparables.pointer, _$comparables1.pointer)
+        .integer;
   }
 
-  static final _id_fill$17 = _class.staticMethodId(
-    r'fill',
-    r'([Ljava/lang/Object;IILjava/lang/Object;)V',
+  static final _id_compare$19 = _class.staticMethodId(
+    r'compare',
+    r'([Ljava/lang/Object;[Ljava/lang/Object;Ljava/util/Comparator;)I',
   );
 
-  static final _fill$17 = jni$_.ProtectedJniExtensions.lookup<
+  static final _compare$19 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int compare(T[] objects, T[] objects1, java.util.Comparator<? super T> comparator)`
+  static core$_.int compare$19<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    jni$_.JArray<$T?>? objects1,
+    jni$_.JObject? comparator,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
+    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
+    return _compare$19(_class.reference.pointer, _id_compare$19.pointer,
+            _$objects.pointer, _$objects1.pointer, _$comparator.pointer)
+        .integer;
+  }
+
+  static final _id_compareUnsigned = _class.staticMethodId(
+    r'compareUnsigned',
+    r'([B[B)I',
+  );
+
+  static final _compareUnsigned = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int compareUnsigned(byte[] bs, byte[] bs1)`
+  static core$_.int compareUnsigned(
+    jni$_.JByteArray? bs,
+    jni$_.JByteArray? bs1,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
+    return _compareUnsigned(_class.reference.pointer,
+            _id_compareUnsigned.pointer, _$bs.pointer, _$bs1.pointer)
+        .integer;
+  }
+
+  static final _id_compareUnsigned$1 = _class.staticMethodId(
+    r'compareUnsigned',
+    r'([BII[BII)I',
+  );
+
+  static final _compareUnsigned$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
                   jni$_.JMethodIDPtr,
                   jni$_.VarArgs<
@@ -32128,34 +24791,308 @@
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Int32,
                         jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
       .asFunction<
-          jni$_.JThrowablePtr Function(
+          jni$_.JniResult Function(
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int compareUnsigned(byte[] bs, int i, int i1, byte[] bs1, int i2, int i3)`
+  static core$_.int compareUnsigned$1(
+    jni$_.JByteArray? bs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JByteArray? bs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
+    return _compareUnsigned$1(
+            _class.reference.pointer,
+            _id_compareUnsigned$1.pointer,
+            _$bs.pointer,
+            i,
+            i1,
+            _$bs1.pointer,
+            i2,
+            i3)
+        .integer;
+  }
+
+  static final _id_compareUnsigned$2 = _class.staticMethodId(
+    r'compareUnsigned',
+    r'([III[III)I',
+  );
+
+  static final _compareUnsigned$2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int compareUnsigned(int[] is, int i, int i1, int[] is1, int i2, int i3)`
+  static core$_.int compareUnsigned$2(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JIntArray? is1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    final _$is1 = is1?.reference ?? jni$_.jNullReference;
+    return _compareUnsigned$2(
+            _class.reference.pointer,
+            _id_compareUnsigned$2.pointer,
+            _$is$.pointer,
+            i,
+            i1,
+            _$is1.pointer,
+            i2,
+            i3)
+        .integer;
+  }
+
+  static final _id_compareUnsigned$3 = _class.staticMethodId(
+    r'compareUnsigned',
+    r'([I[I)I',
+  );
+
+  static final _compareUnsigned$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public void fill(java.lang.Object[] objects, int i, int i1, java.lang.Object object)`
-  static void fill$17(
-    jni$_.JArray<jni$_.JObject?>? objects,
-    int i,
-    int i1,
-    jni$_.JObject? object,
+  /// from: `static public int compareUnsigned(int[] is, int[] is1)`
+  static core$_.int compareUnsigned$3(
+    jni$_.JIntArray? is$,
+    jni$_.JIntArray? is1,
   ) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$object = object?.reference ?? jni$_.jNullReference;
-    _fill$17(_class.reference.pointer, _id_fill$17 as jni$_.JMethodIDPtr,
-            _$objects.pointer, i, i1, _$object.pointer)
-        .check();
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    final _$is1 = is1?.reference ?? jni$_.jNullReference;
+    return _compareUnsigned$3(_class.reference.pointer,
+            _id_compareUnsigned$3.pointer, _$is$.pointer, _$is1.pointer)
+        .integer;
+  }
+
+  static final _id_compareUnsigned$4 = _class.staticMethodId(
+    r'compareUnsigned',
+    r'([JII[JII)I',
+  );
+
+  static final _compareUnsigned$4 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int compareUnsigned(long[] js, int i, int i1, long[] js1, int i2, int i3)`
+  static core$_.int compareUnsigned$4(
+    jni$_.JLongArray? js,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JLongArray? js1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    final _$js1 = js1?.reference ?? jni$_.jNullReference;
+    return _compareUnsigned$4(
+            _class.reference.pointer,
+            _id_compareUnsigned$4.pointer,
+            _$js.pointer,
+            i,
+            i1,
+            _$js1.pointer,
+            i2,
+            i3)
+        .integer;
+  }
+
+  static final _id_compareUnsigned$5 = _class.staticMethodId(
+    r'compareUnsigned',
+    r'([J[J)I',
+  );
+
+  static final _compareUnsigned$5 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int compareUnsigned(long[] js, long[] js1)`
+  static core$_.int compareUnsigned$5(
+    jni$_.JLongArray? js,
+    jni$_.JLongArray? js1,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    final _$js1 = js1?.reference ?? jni$_.jNullReference;
+    return _compareUnsigned$5(_class.reference.pointer,
+            _id_compareUnsigned$5.pointer, _$js.pointer, _$js1.pointer)
+        .integer;
+  }
+
+  static final _id_compareUnsigned$6 = _class.staticMethodId(
+    r'compareUnsigned',
+    r'([SII[SII)I',
+  );
+
+  static final _compareUnsigned$6 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int compareUnsigned(short[] ss, int i, int i1, short[] ss1, int i2, int i3)`
+  static core$_.int compareUnsigned$6(
+    jni$_.JShortArray? ss,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JShortArray? ss1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
+    return _compareUnsigned$6(
+            _class.reference.pointer,
+            _id_compareUnsigned$6.pointer,
+            _$ss.pointer,
+            i,
+            i1,
+            _$ss1.pointer,
+            i2,
+            i3)
+        .integer;
+  }
+
+  static final _id_compareUnsigned$7 = _class.staticMethodId(
+    r'compareUnsigned',
+    r'([S[S)I',
+  );
+
+  static final _compareUnsigned$7 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int compareUnsigned(short[] ss, short[] ss1)`
+  static core$_.int compareUnsigned$7(
+    jni$_.JShortArray? ss,
+    jni$_.JShortArray? ss1,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
+    return _compareUnsigned$7(_class.reference.pointer,
+            _id_compareUnsigned$7.pointer, _$ss.pointer, _$ss1.pointer)
+        .integer;
   }
 
   static final _id_copyOf = _class.staticMethodId(
     r'copyOf',
-    r'([Ljava/lang/Object;I)[Ljava/lang/Object;',
+    r'([ZI)[Z',
   );
 
   static final _copyOf = jni$_.ProtectedJniExtensions.lookup<
@@ -32168,28 +25105,258 @@
           'globalEnv_CallStaticObjectMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
 
-  /// from: `static public java.lang.Object[] copyOf(java.lang.Object[] objects, int i)`
+  /// from: `static public boolean[] copyOf(boolean[] zs, int i)`
   /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JArray<$T?>? copyOf<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    int i, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    return _copyOf(_class.reference.pointer, _id_copyOf as jni$_.JMethodIDPtr,
-            _$objects.pointer, i)
-        .object<jni$_.JArray<$T?>?>(
-            jni$_.JArrayNullableType<$T?>(T.nullableType));
+  static jni$_.JBooleanArray? copyOf(
+    jni$_.JBooleanArray? zs,
+    core$_.int i,
+  ) {
+    final _$zs = zs?.reference ?? jni$_.jNullReference;
+    return _copyOf(
+            _class.reference.pointer, _id_copyOf.pointer, _$zs.pointer, i)
+        .object<jni$_.JBooleanArray?>();
   }
 
   static final _id_copyOf$1 = _class.staticMethodId(
     r'copyOf',
-    r'([Ljava/lang/Object;ILjava/lang/Class;)[Ljava/lang/Object;',
+    r'([BI)[B',
   );
 
   static final _copyOf$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public byte[] copyOf(byte[] bs, int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JByteArray? copyOf$1(
+    jni$_.JByteArray? bs,
+    core$_.int i,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    return _copyOf$1(
+            _class.reference.pointer, _id_copyOf$1.pointer, _$bs.pointer, i)
+        .object<jni$_.JByteArray?>();
+  }
+
+  static final _id_copyOf$2 = _class.staticMethodId(
+    r'copyOf',
+    r'([CI)[C',
+  );
+
+  static final _copyOf$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public char[] copyOf(char[] cs, int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JCharArray? copyOf$2(
+    jni$_.JCharArray? cs,
+    core$_.int i,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    return _copyOf$2(
+            _class.reference.pointer, _id_copyOf$2.pointer, _$cs.pointer, i)
+        .object<jni$_.JCharArray?>();
+  }
+
+  static final _id_copyOf$3 = _class.staticMethodId(
+    r'copyOf',
+    r'([DI)[D',
+  );
+
+  static final _copyOf$3 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public double[] copyOf(double[] ds, int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JDoubleArray? copyOf$3(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    return _copyOf$3(
+            _class.reference.pointer, _id_copyOf$3.pointer, _$ds.pointer, i)
+        .object<jni$_.JDoubleArray?>();
+  }
+
+  static final _id_copyOf$4 = _class.staticMethodId(
+    r'copyOf',
+    r'([FI)[F',
+  );
+
+  static final _copyOf$4 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public float[] copyOf(float[] fs, int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JFloatArray? copyOf$4(
+    jni$_.JFloatArray? fs,
+    core$_.int i,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    return _copyOf$4(
+            _class.reference.pointer, _id_copyOf$4.pointer, _$fs.pointer, i)
+        .object<jni$_.JFloatArray?>();
+  }
+
+  static final _id_copyOf$5 = _class.staticMethodId(
+    r'copyOf',
+    r'([II)[I',
+  );
+
+  static final _copyOf$5 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public int[] copyOf(int[] is, int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JIntArray? copyOf$5(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    return _copyOf$5(
+            _class.reference.pointer, _id_copyOf$5.pointer, _$is$.pointer, i)
+        .object<jni$_.JIntArray?>();
+  }
+
+  static final _id_copyOf$6 = _class.staticMethodId(
+    r'copyOf',
+    r'([JI)[J',
+  );
+
+  static final _copyOf$6 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public long[] copyOf(long[] js, int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JLongArray? copyOf$6(
+    jni$_.JLongArray? js,
+    core$_.int i,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    return _copyOf$6(
+            _class.reference.pointer, _id_copyOf$6.pointer, _$js.pointer, i)
+        .object<jni$_.JLongArray?>();
+  }
+
+  static final _id_copyOf$7 = _class.staticMethodId(
+    r'copyOf',
+    r'([SI)[S',
+  );
+
+  static final _copyOf$7 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public short[] copyOf(short[] ss, int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JShortArray? copyOf$7(
+    jni$_.JShortArray? ss,
+    core$_.int i,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    return _copyOf$7(
+            _class.reference.pointer, _id_copyOf$7.pointer, _$ss.pointer, i)
+        .object<jni$_.JShortArray?>();
+  }
+
+  static final _id_copyOf$8 = _class.staticMethodId(
+    r'copyOf',
+    r'([Ljava/lang/Object;I)[Ljava/lang/Object;',
+  );
+
+  static final _copyOf$8 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public T[] copyOf(T[] objects, int i)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JArray<$T?>? copyOf$8<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    core$_.int i,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    return _copyOf$8(_class.reference.pointer, _id_copyOf$8.pointer,
+            _$objects.pointer, i)
+        .object<jni$_.JArray<$T?>?>();
+  }
+
+  static final _id_copyOf$9 = _class.staticMethodId(
+    r'copyOf',
+    r'([Ljava/lang/Object;ILjava/lang/Class;)[Ljava/lang/Object;',
+  );
+
+  static final _copyOf$9 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -32205,266 +25372,27 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public java.lang.Object[] copyOf(java.lang.Object[] objects, int i, java.lang.Class class)`
+  /// from: `static public T[] copyOf(U[] objects, int i, java.lang.Class<? extends T[]> class)`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JArray<$T?>?
-      copyOf$1<$T extends jni$_.JObject?, $U extends jni$_.JObject?>(
+      copyOf$9<$T extends jni$_.JObject?, $U extends jni$_.JObject?>(
     jni$_.JArray<$U?>? objects,
-    int i,
-    jni$_.JObject? class$, {
-    required jni$_.JObjType<$T> T,
-    required jni$_.JObjType<$U> U,
-  }) {
+    core$_.int i,
+    jni$_.JObject? class$,
+  ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
     final _$class$ = class$?.reference ?? jni$_.jNullReference;
-    return _copyOf$1(
-            _class.reference.pointer,
-            _id_copyOf$1 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            i,
-            _$class$.pointer)
-        .object<jni$_.JArray<$T?>?>(
-            jni$_.JArrayNullableType<$T?>(T.nullableType));
-  }
-
-  static final _id_copyOf$2 = _class.staticMethodId(
-    r'copyOf',
-    r'([BI)[B',
-  );
-
-  static final _copyOf$2 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public byte[] copyOf(byte[] bs, int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JByteArray? copyOf$2(
-    jni$_.JByteArray? bs,
-    int i,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    return _copyOf$2(_class.reference.pointer,
-            _id_copyOf$2 as jni$_.JMethodIDPtr, _$bs.pointer, i)
-        .object<jni$_.JByteArray?>(const jni$_.JByteArrayNullableType());
-  }
-
-  static final _id_copyOf$3 = _class.staticMethodId(
-    r'copyOf',
-    r'([SI)[S',
-  );
-
-  static final _copyOf$3 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public short[] copyOf(short[] ss, int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JShortArray? copyOf$3(
-    jni$_.JShortArray? ss,
-    int i,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    return _copyOf$3(_class.reference.pointer,
-            _id_copyOf$3 as jni$_.JMethodIDPtr, _$ss.pointer, i)
-        .object<jni$_.JShortArray?>(const jni$_.JShortArrayNullableType());
-  }
-
-  static final _id_copyOf$4 = _class.staticMethodId(
-    r'copyOf',
-    r'([II)[I',
-  );
-
-  static final _copyOf$4 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public int[] copyOf(int[] is, int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JIntArray? copyOf$4(
-    jni$_.JIntArray? is$,
-    int i,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    return _copyOf$4(_class.reference.pointer,
-            _id_copyOf$4 as jni$_.JMethodIDPtr, _$is$.pointer, i)
-        .object<jni$_.JIntArray?>(const jni$_.JIntArrayNullableType());
-  }
-
-  static final _id_copyOf$5 = _class.staticMethodId(
-    r'copyOf',
-    r'([JI)[J',
-  );
-
-  static final _copyOf$5 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public long[] copyOf(long[] js, int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JLongArray? copyOf$5(
-    jni$_.JLongArray? js,
-    int i,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    return _copyOf$5(_class.reference.pointer,
-            _id_copyOf$5 as jni$_.JMethodIDPtr, _$js.pointer, i)
-        .object<jni$_.JLongArray?>(const jni$_.JLongArrayNullableType());
-  }
-
-  static final _id_copyOf$6 = _class.staticMethodId(
-    r'copyOf',
-    r'([CI)[C',
-  );
-
-  static final _copyOf$6 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public char[] copyOf(char[] cs, int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JCharArray? copyOf$6(
-    jni$_.JCharArray? cs,
-    int i,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    return _copyOf$6(_class.reference.pointer,
-            _id_copyOf$6 as jni$_.JMethodIDPtr, _$cs.pointer, i)
-        .object<jni$_.JCharArray?>(const jni$_.JCharArrayNullableType());
-  }
-
-  static final _id_copyOf$7 = _class.staticMethodId(
-    r'copyOf',
-    r'([FI)[F',
-  );
-
-  static final _copyOf$7 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public float[] copyOf(float[] fs, int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JFloatArray? copyOf$7(
-    jni$_.JFloatArray? fs,
-    int i,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    return _copyOf$7(_class.reference.pointer,
-            _id_copyOf$7 as jni$_.JMethodIDPtr, _$fs.pointer, i)
-        .object<jni$_.JFloatArray?>(const jni$_.JFloatArrayNullableType());
-  }
-
-  static final _id_copyOf$8 = _class.staticMethodId(
-    r'copyOf',
-    r'([DI)[D',
-  );
-
-  static final _copyOf$8 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public double[] copyOf(double[] ds, int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JDoubleArray? copyOf$8(
-    jni$_.JDoubleArray? ds,
-    int i,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    return _copyOf$8(_class.reference.pointer,
-            _id_copyOf$8 as jni$_.JMethodIDPtr, _$ds.pointer, i)
-        .object<jni$_.JDoubleArray?>(const jni$_.JDoubleArrayNullableType());
-  }
-
-  static final _id_copyOf$9 = _class.staticMethodId(
-    r'copyOf',
-    r'([ZI)[Z',
-  );
-
-  static final _copyOf$9 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_
-                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int)>();
-
-  /// from: `static public boolean[] copyOf(boolean[] zs, int i)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JBooleanArray? copyOf$9(
-    jni$_.JBooleanArray? zs,
-    int i,
-  ) {
-    final _$zs = zs?.reference ?? jni$_.jNullReference;
-    return _copyOf$9(_class.reference.pointer,
-            _id_copyOf$9 as jni$_.JMethodIDPtr, _$zs.pointer, i)
-        .object<jni$_.JBooleanArray?>(const jni$_.JBooleanArrayNullableType());
+    return _copyOf$9(_class.reference.pointer, _id_copyOf$9.pointer,
+            _$objects.pointer, i, _$class$.pointer)
+        .object<jni$_.JArray<$T?>?>();
   }
 
   static final _id_copyOfRange = _class.staticMethodId(
     r'copyOfRange',
-    r'([Ljava/lang/Object;II)[Ljava/lang/Object;',
+    r'([ZII)[Z',
   );
 
   static final _copyOfRange = jni$_.ProtectedJniExtensions.lookup<
@@ -32479,27 +25407,29 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `static public java.lang.Object[] copyOfRange(java.lang.Object[] objects, int i, int i1)`
+  /// from: `static public boolean[] copyOfRange(boolean[] zs, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JArray<$T?>? copyOfRange<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    int i,
-    int i1, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    return _copyOfRange(_class.reference.pointer,
-            _id_copyOfRange as jni$_.JMethodIDPtr, _$objects.pointer, i, i1)
-        .object<jni$_.JArray<$T?>?>(
-            jni$_.JArrayNullableType<$T?>(T.nullableType));
+  static jni$_.JBooleanArray? copyOfRange(
+    jni$_.JBooleanArray? zs,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$zs = zs?.reference ?? jni$_.jNullReference;
+    return _copyOfRange(_class.reference.pointer, _id_copyOfRange.pointer,
+            _$zs.pointer, i, i1)
+        .object<jni$_.JBooleanArray?>();
   }
 
   static final _id_copyOfRange$1 = _class.staticMethodId(
     r'copyOfRange',
-    r'([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;',
+    r'([BII)[B',
   );
 
   static final _copyOfRange$1 = jni$_.ProtectedJniExtensions.lookup<
@@ -32511,6 +25441,302 @@
                       (
                         jni$_.Pointer<jni$_.Void>,
                         jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public byte[] copyOfRange(byte[] bs, int i, int i1)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JByteArray? copyOfRange$1(
+    jni$_.JByteArray? bs,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    return _copyOfRange$1(_class.reference.pointer, _id_copyOfRange$1.pointer,
+            _$bs.pointer, i, i1)
+        .object<jni$_.JByteArray?>();
+  }
+
+  static final _id_copyOfRange$2 = _class.staticMethodId(
+    r'copyOfRange',
+    r'([CII)[C',
+  );
+
+  static final _copyOfRange$2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public char[] copyOfRange(char[] cs, int i, int i1)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JCharArray? copyOfRange$2(
+    jni$_.JCharArray? cs,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    return _copyOfRange$2(_class.reference.pointer, _id_copyOfRange$2.pointer,
+            _$cs.pointer, i, i1)
+        .object<jni$_.JCharArray?>();
+  }
+
+  static final _id_copyOfRange$3 = _class.staticMethodId(
+    r'copyOfRange',
+    r'([DII)[D',
+  );
+
+  static final _copyOfRange$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public double[] copyOfRange(double[] ds, int i, int i1)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JDoubleArray? copyOfRange$3(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    return _copyOfRange$3(_class.reference.pointer, _id_copyOfRange$3.pointer,
+            _$ds.pointer, i, i1)
+        .object<jni$_.JDoubleArray?>();
+  }
+
+  static final _id_copyOfRange$4 = _class.staticMethodId(
+    r'copyOfRange',
+    r'([FII)[F',
+  );
+
+  static final _copyOfRange$4 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public float[] copyOfRange(float[] fs, int i, int i1)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JFloatArray? copyOfRange$4(
+    jni$_.JFloatArray? fs,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    return _copyOfRange$4(_class.reference.pointer, _id_copyOfRange$4.pointer,
+            _$fs.pointer, i, i1)
+        .object<jni$_.JFloatArray?>();
+  }
+
+  static final _id_copyOfRange$5 = _class.staticMethodId(
+    r'copyOfRange',
+    r'([III)[I',
+  );
+
+  static final _copyOfRange$5 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int[] copyOfRange(int[] is, int i, int i1)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JIntArray? copyOfRange$5(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    return _copyOfRange$5(_class.reference.pointer, _id_copyOfRange$5.pointer,
+            _$is$.pointer, i, i1)
+        .object<jni$_.JIntArray?>();
+  }
+
+  static final _id_copyOfRange$6 = _class.staticMethodId(
+    r'copyOfRange',
+    r'([JII)[J',
+  );
+
+  static final _copyOfRange$6 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public long[] copyOfRange(long[] js, int i, int i1)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JLongArray? copyOfRange$6(
+    jni$_.JLongArray? js,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    return _copyOfRange$6(_class.reference.pointer, _id_copyOfRange$6.pointer,
+            _$js.pointer, i, i1)
+        .object<jni$_.JLongArray?>();
+  }
+
+  static final _id_copyOfRange$7 = _class.staticMethodId(
+    r'copyOfRange',
+    r'([SII)[S',
+  );
+
+  static final _copyOfRange$7 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public short[] copyOfRange(short[] ss, int i, int i1)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JShortArray? copyOfRange$7(
+    jni$_.JShortArray? ss,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    return _copyOfRange$7(_class.reference.pointer, _id_copyOfRange$7.pointer,
+            _$ss.pointer, i, i1)
+        .object<jni$_.JShortArray?>();
+  }
+
+  static final _id_copyOfRange$8 = _class.staticMethodId(
+    r'copyOfRange',
+    r'([Ljava/lang/Object;II)[Ljava/lang/Object;',
+  );
+
+  static final _copyOfRange$8 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public T[] copyOfRange(T[] objects, int i, int i1)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JArray<$T?>? copyOfRange$8<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    return _copyOfRange$8(_class.reference.pointer, _id_copyOfRange$8.pointer,
+            _$objects.pointer, i, i1)
+        .object<jni$_.JArray<$T?>?>();
+  }
+
+  static final _id_copyOfRange$9 = _class.staticMethodId(
+    r'copyOfRange',
+    r'([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;',
+  );
+
+  static final _copyOfRange$9 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
                         jni$_.Int32,
                         jni$_.Pointer<jni$_.Void>
                       )>)>>('globalEnv_CallStaticObjectMethod')
@@ -32519,585 +25745,24 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr,
               jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
+              core$_.int,
+              core$_.int,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public java.lang.Object[] copyOfRange(java.lang.Object[] objects, int i, int i1, java.lang.Class class)`
+  /// from: `static public T[] copyOfRange(U[] objects, int i, int i1, java.lang.Class<? extends T[]> class)`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JArray<$T?>?
-      copyOfRange$1<$T extends jni$_.JObject?, $U extends jni$_.JObject?>(
+      copyOfRange$9<$T extends jni$_.JObject?, $U extends jni$_.JObject?>(
     jni$_.JArray<$U?>? objects,
-    int i,
-    int i1,
-    jni$_.JObject? class$, {
-    required jni$_.JObjType<$T> T,
-    required jni$_.JObjType<$U> U,
-  }) {
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JObject? class$,
+  ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
     final _$class$ = class$?.reference ?? jni$_.jNullReference;
-    return _copyOfRange$1(
-            _class.reference.pointer,
-            _id_copyOfRange$1 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            i,
-            i1,
-            _$class$.pointer)
-        .object<jni$_.JArray<$T?>?>(
-            jni$_.JArrayNullableType<$T?>(T.nullableType));
-  }
-
-  static final _id_copyOfRange$2 = _class.staticMethodId(
-    r'copyOfRange',
-    r'([BII)[B',
-  );
-
-  static final _copyOfRange$2 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public byte[] copyOfRange(byte[] bs, int i, int i1)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JByteArray? copyOfRange$2(
-    jni$_.JByteArray? bs,
-    int i,
-    int i1,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    return _copyOfRange$2(_class.reference.pointer,
-            _id_copyOfRange$2 as jni$_.JMethodIDPtr, _$bs.pointer, i, i1)
-        .object<jni$_.JByteArray?>(const jni$_.JByteArrayNullableType());
-  }
-
-  static final _id_copyOfRange$3 = _class.staticMethodId(
-    r'copyOfRange',
-    r'([SII)[S',
-  );
-
-  static final _copyOfRange$3 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public short[] copyOfRange(short[] ss, int i, int i1)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JShortArray? copyOfRange$3(
-    jni$_.JShortArray? ss,
-    int i,
-    int i1,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    return _copyOfRange$3(_class.reference.pointer,
-            _id_copyOfRange$3 as jni$_.JMethodIDPtr, _$ss.pointer, i, i1)
-        .object<jni$_.JShortArray?>(const jni$_.JShortArrayNullableType());
-  }
-
-  static final _id_copyOfRange$4 = _class.staticMethodId(
-    r'copyOfRange',
-    r'([III)[I',
-  );
-
-  static final _copyOfRange$4 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public int[] copyOfRange(int[] is, int i, int i1)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JIntArray? copyOfRange$4(
-    jni$_.JIntArray? is$,
-    int i,
-    int i1,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    return _copyOfRange$4(_class.reference.pointer,
-            _id_copyOfRange$4 as jni$_.JMethodIDPtr, _$is$.pointer, i, i1)
-        .object<jni$_.JIntArray?>(const jni$_.JIntArrayNullableType());
-  }
-
-  static final _id_copyOfRange$5 = _class.staticMethodId(
-    r'copyOfRange',
-    r'([JII)[J',
-  );
-
-  static final _copyOfRange$5 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public long[] copyOfRange(long[] js, int i, int i1)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JLongArray? copyOfRange$5(
-    jni$_.JLongArray? js,
-    int i,
-    int i1,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    return _copyOfRange$5(_class.reference.pointer,
-            _id_copyOfRange$5 as jni$_.JMethodIDPtr, _$js.pointer, i, i1)
-        .object<jni$_.JLongArray?>(const jni$_.JLongArrayNullableType());
-  }
-
-  static final _id_copyOfRange$6 = _class.staticMethodId(
-    r'copyOfRange',
-    r'([CII)[C',
-  );
-
-  static final _copyOfRange$6 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public char[] copyOfRange(char[] cs, int i, int i1)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JCharArray? copyOfRange$6(
-    jni$_.JCharArray? cs,
-    int i,
-    int i1,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    return _copyOfRange$6(_class.reference.pointer,
-            _id_copyOfRange$6 as jni$_.JMethodIDPtr, _$cs.pointer, i, i1)
-        .object<jni$_.JCharArray?>(const jni$_.JCharArrayNullableType());
-  }
-
-  static final _id_copyOfRange$7 = _class.staticMethodId(
-    r'copyOfRange',
-    r'([FII)[F',
-  );
-
-  static final _copyOfRange$7 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public float[] copyOfRange(float[] fs, int i, int i1)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JFloatArray? copyOfRange$7(
-    jni$_.JFloatArray? fs,
-    int i,
-    int i1,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    return _copyOfRange$7(_class.reference.pointer,
-            _id_copyOfRange$7 as jni$_.JMethodIDPtr, _$fs.pointer, i, i1)
-        .object<jni$_.JFloatArray?>(const jni$_.JFloatArrayNullableType());
-  }
-
-  static final _id_copyOfRange$8 = _class.staticMethodId(
-    r'copyOfRange',
-    r'([DII)[D',
-  );
-
-  static final _copyOfRange$8 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public double[] copyOfRange(double[] ds, int i, int i1)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JDoubleArray? copyOfRange$8(
-    jni$_.JDoubleArray? ds,
-    int i,
-    int i1,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    return _copyOfRange$8(_class.reference.pointer,
-            _id_copyOfRange$8 as jni$_.JMethodIDPtr, _$ds.pointer, i, i1)
-        .object<jni$_.JDoubleArray?>(const jni$_.JDoubleArrayNullableType());
-  }
-
-  static final _id_copyOfRange$9 = _class.staticMethodId(
-    r'copyOfRange',
-    r'([ZII)[Z',
-  );
-
-  static final _copyOfRange$9 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
-
-  /// from: `static public boolean[] copyOfRange(boolean[] zs, int i, int i1)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JBooleanArray? copyOfRange$9(
-    jni$_.JBooleanArray? zs,
-    int i,
-    int i1,
-  ) {
-    final _$zs = zs?.reference ?? jni$_.jNullReference;
-    return _copyOfRange$9(_class.reference.pointer,
-            _id_copyOfRange$9 as jni$_.JMethodIDPtr, _$zs.pointer, i, i1)
-        .object<jni$_.JBooleanArray?>(const jni$_.JBooleanArrayNullableType());
-  }
-
-  static final _id_asList = _class.staticMethodId(
-    r'asList',
-    r'([Ljava/lang/Object;)Ljava/util/List;',
-  );
-
-  static final _asList = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public java.util.List asList(java.lang.Object[] objects)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JList<$T?>? asList<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    return _asList(_class.reference.pointer, _id_asList as jni$_.JMethodIDPtr,
-            _$objects.pointer)
-        .object<jni$_.JList<$T?>?>(
-            jni$_.JListNullableType<$T?>(T.nullableType));
-  }
-
-  static final _id_hashCode$1 = _class.staticMethodId(
-    r'hashCode',
-    r'([J)I',
-  );
-
-  static final _hashCode$1 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int hashCode(long[] js)`
-  static int hashCode$1(
-    jni$_.JLongArray? js,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    return _hashCode$1(_class.reference.pointer,
-            _id_hashCode$1 as jni$_.JMethodIDPtr, _$js.pointer)
-        .integer;
-  }
-
-  static final _id_hashCode$2 = _class.staticMethodId(
-    r'hashCode',
-    r'([I)I',
-  );
-
-  static final _hashCode$2 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int hashCode(int[] is)`
-  static int hashCode$2(
-    jni$_.JIntArray? is$,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    return _hashCode$2(_class.reference.pointer,
-            _id_hashCode$2 as jni$_.JMethodIDPtr, _$is$.pointer)
-        .integer;
-  }
-
-  static final _id_hashCode$3 = _class.staticMethodId(
-    r'hashCode',
-    r'([S)I',
-  );
-
-  static final _hashCode$3 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int hashCode(short[] ss)`
-  static int hashCode$3(
-    jni$_.JShortArray? ss,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    return _hashCode$3(_class.reference.pointer,
-            _id_hashCode$3 as jni$_.JMethodIDPtr, _$ss.pointer)
-        .integer;
-  }
-
-  static final _id_hashCode$4 = _class.staticMethodId(
-    r'hashCode',
-    r'([C)I',
-  );
-
-  static final _hashCode$4 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int hashCode(char[] cs)`
-  static int hashCode$4(
-    jni$_.JCharArray? cs,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    return _hashCode$4(_class.reference.pointer,
-            _id_hashCode$4 as jni$_.JMethodIDPtr, _$cs.pointer)
-        .integer;
-  }
-
-  static final _id_hashCode$5 = _class.staticMethodId(
-    r'hashCode',
-    r'([B)I',
-  );
-
-  static final _hashCode$5 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int hashCode(byte[] bs)`
-  static int hashCode$5(
-    jni$_.JByteArray? bs,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    return _hashCode$5(_class.reference.pointer,
-            _id_hashCode$5 as jni$_.JMethodIDPtr, _$bs.pointer)
-        .integer;
-  }
-
-  static final _id_hashCode$6 = _class.staticMethodId(
-    r'hashCode',
-    r'([Z)I',
-  );
-
-  static final _hashCode$6 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int hashCode(boolean[] zs)`
-  static int hashCode$6(
-    jni$_.JBooleanArray? zs,
-  ) {
-    final _$zs = zs?.reference ?? jni$_.jNullReference;
-    return _hashCode$6(_class.reference.pointer,
-            _id_hashCode$6 as jni$_.JMethodIDPtr, _$zs.pointer)
-        .integer;
-  }
-
-  static final _id_hashCode$7 = _class.staticMethodId(
-    r'hashCode',
-    r'([F)I',
-  );
-
-  static final _hashCode$7 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int hashCode(float[] fs)`
-  static int hashCode$7(
-    jni$_.JFloatArray? fs,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    return _hashCode$7(_class.reference.pointer,
-            _id_hashCode$7 as jni$_.JMethodIDPtr, _$fs.pointer)
-        .integer;
-  }
-
-  static final _id_hashCode$8 = _class.staticMethodId(
-    r'hashCode',
-    r'([D)I',
-  );
-
-  static final _hashCode$8 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int hashCode(double[] ds)`
-  static int hashCode$8(
-    jni$_.JDoubleArray? ds,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    return _hashCode$8(_class.reference.pointer,
-            _id_hashCode$8 as jni$_.JMethodIDPtr, _$ds.pointer)
-        .integer;
-  }
-
-  static final _id_hashCode$9 = _class.staticMethodId(
-    r'hashCode',
-    r'([Ljava/lang/Object;)I',
-  );
-
-  static final _hashCode$9 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int hashCode(java.lang.Object[] objects)`
-  static int hashCode$9(
-    jni$_.JArray<jni$_.JObject?>? objects,
-  ) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    return _hashCode$9(_class.reference.pointer,
-            _id_hashCode$9 as jni$_.JMethodIDPtr, _$objects.pointer)
-        .integer;
-  }
-
-  static final _id_deepHashCode = _class.staticMethodId(
-    r'deepHashCode',
-    r'([Ljava/lang/Object;)I',
-  );
-
-  static final _deepHashCode = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int deepHashCode(java.lang.Object[] objects)`
-  static int deepHashCode(
-    jni$_.JArray<jni$_.JObject?>? objects,
-  ) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    return _deepHashCode(_class.reference.pointer,
-            _id_deepHashCode as jni$_.JMethodIDPtr, _$objects.pointer)
-        .integer;
+    return _copyOfRange$9(_class.reference.pointer, _id_copyOfRange$9.pointer,
+            _$objects.pointer, i, i1, _$class$.pointer)
+        .object<jni$_.JArray<$T?>?>();
   }
 
   static final _id_deepEquals = _class.staticMethodId(
@@ -33123,261 +25788,41 @@
               jni$_.Pointer<jni$_.Void>)>();
 
   /// from: `static public boolean deepEquals(java.lang.Object[] objects, java.lang.Object[] objects1)`
-  static bool deepEquals(
+  static core$_.bool deepEquals(
     jni$_.JArray<jni$_.JObject?>? objects,
     jni$_.JArray<jni$_.JObject?>? objects1,
   ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
     final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
-    return _deepEquals(
-            _class.reference.pointer,
-            _id_deepEquals as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            _$objects1.pointer)
+    return _deepEquals(_class.reference.pointer, _id_deepEquals.pointer,
+            _$objects.pointer, _$objects1.pointer)
         .boolean;
   }
 
-  static final _id_toString$1 = _class.staticMethodId(
-    r'toString',
-    r'([J)Ljava/lang/String;',
+  static final _id_deepHashCode = _class.staticMethodId(
+    r'deepHashCode',
+    r'([Ljava/lang/Object;)I',
   );
 
-  static final _toString$1 = jni$_.ProtectedJniExtensions.lookup<
+  static final _deepHashCode = jni$_.ProtectedJniExtensions.lookup<
               jni$_.NativeFunction<
                   jni$_.JniResult Function(
                       jni$_.Pointer<jni$_.Void>,
                       jni$_.JMethodIDPtr,
                       jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
+          'globalEnv_CallStaticIntMethod')
       .asFunction<
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public java.lang.String toString(long[] js)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? toString$1(
-    jni$_.JLongArray? js,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    return _toString$1(_class.reference.pointer,
-            _id_toString$1 as jni$_.JMethodIDPtr, _$js.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_toString$2 = _class.staticMethodId(
-    r'toString',
-    r'([I)Ljava/lang/String;',
-  );
-
-  static final _toString$2 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public java.lang.String toString(int[] is)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? toString$2(
-    jni$_.JIntArray? is$,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    return _toString$2(_class.reference.pointer,
-            _id_toString$2 as jni$_.JMethodIDPtr, _$is$.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_toString$3 = _class.staticMethodId(
-    r'toString',
-    r'([S)Ljava/lang/String;',
-  );
-
-  static final _toString$3 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public java.lang.String toString(short[] ss)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? toString$3(
-    jni$_.JShortArray? ss,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    return _toString$3(_class.reference.pointer,
-            _id_toString$3 as jni$_.JMethodIDPtr, _$ss.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_toString$4 = _class.staticMethodId(
-    r'toString',
-    r'([C)Ljava/lang/String;',
-  );
-
-  static final _toString$4 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public java.lang.String toString(char[] cs)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? toString$4(
-    jni$_.JCharArray? cs,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    return _toString$4(_class.reference.pointer,
-            _id_toString$4 as jni$_.JMethodIDPtr, _$cs.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_toString$5 = _class.staticMethodId(
-    r'toString',
-    r'([B)Ljava/lang/String;',
-  );
-
-  static final _toString$5 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public java.lang.String toString(byte[] bs)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? toString$5(
-    jni$_.JByteArray? bs,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    return _toString$5(_class.reference.pointer,
-            _id_toString$5 as jni$_.JMethodIDPtr, _$bs.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_toString$6 = _class.staticMethodId(
-    r'toString',
-    r'([Z)Ljava/lang/String;',
-  );
-
-  static final _toString$6 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public java.lang.String toString(boolean[] zs)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? toString$6(
-    jni$_.JBooleanArray? zs,
-  ) {
-    final _$zs = zs?.reference ?? jni$_.jNullReference;
-    return _toString$6(_class.reference.pointer,
-            _id_toString$6 as jni$_.JMethodIDPtr, _$zs.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_toString$7 = _class.staticMethodId(
-    r'toString',
-    r'([F)Ljava/lang/String;',
-  );
-
-  static final _toString$7 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public java.lang.String toString(float[] fs)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? toString$7(
-    jni$_.JFloatArray? fs,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    return _toString$7(_class.reference.pointer,
-            _id_toString$7 as jni$_.JMethodIDPtr, _$fs.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_toString$8 = _class.staticMethodId(
-    r'toString',
-    r'([D)Ljava/lang/String;',
-  );
-
-  static final _toString$8 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public java.lang.String toString(double[] ds)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? toString$8(
-    jni$_.JDoubleArray? ds,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    return _toString$8(_class.reference.pointer,
-            _id_toString$8 as jni$_.JMethodIDPtr, _$ds.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_toString$9 = _class.staticMethodId(
-    r'toString',
-    r'([Ljava/lang/Object;)Ljava/lang/String;',
-  );
-
-  static final _toString$9 = jni$_.ProtectedJniExtensions.lookup<
-              jni$_.NativeFunction<
-                  jni$_.JniResult Function(
-                      jni$_.Pointer<jni$_.Void>,
-                      jni$_.JMethodIDPtr,
-                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
-          'globalEnv_CallStaticObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public java.lang.String toString(java.lang.Object[] objects)`
-  /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JString? toString$9(
+  /// from: `static public int deepHashCode(java.lang.Object[] objects)`
+  static core$_.int deepHashCode(
     jni$_.JArray<jni$_.JObject?>? objects,
   ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
-    return _toString$9(_class.reference.pointer,
-            _id_toString$9 as jni$_.JMethodIDPtr, _$objects.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+    return _deepHashCode(_class.reference.pointer, _id_deepHashCode.pointer,
+            _$objects.pointer)
+        .integer;
   }
 
   static final _id_deepToString = _class.staticMethodId(
@@ -33402,17 +25847,1273 @@
     jni$_.JArray<jni$_.JObject?>? objects,
   ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
-    return _deepToString(_class.reference.pointer,
-            _id_deepToString as jni$_.JMethodIDPtr, _$objects.pointer)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
+    return _deepToString(_class.reference.pointer, _id_deepToString.pointer,
+            _$objects.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_setAll = _class.staticMethodId(
-    r'setAll',
-    r'([Ljava/lang/Object;Ljava/util/function/IntFunction;)V',
+  static final _id_equals = _class.staticMethodId(
+    r'equals',
+    r'([Z[Z)Z',
   );
 
-  static final _setAll = jni$_.ProtectedJniExtensions.lookup<
+  static final _equals = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean equals(boolean[] zs, boolean[] zs1)`
+  static core$_.bool equals(
+    jni$_.JBooleanArray? zs,
+    jni$_.JBooleanArray? zs1,
+  ) {
+    final _$zs = zs?.reference ?? jni$_.jNullReference;
+    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
+    return _equals(_class.reference.pointer, _id_equals.pointer, _$zs.pointer,
+            _$zs1.pointer)
+        .boolean;
+  }
+
+  static final _id_equals$1 = _class.staticMethodId(
+    r'equals',
+    r'([ZII[ZII)Z',
+  );
+
+  static final _equals$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public boolean equals(boolean[] zs, int i, int i1, boolean[] zs1, int i2, int i3)`
+  static core$_.bool equals$1(
+    jni$_.JBooleanArray? zs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JBooleanArray? zs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$zs = zs?.reference ?? jni$_.jNullReference;
+    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
+    return _equals$1(_class.reference.pointer, _id_equals$1.pointer,
+            _$zs.pointer, i, i1, _$zs1.pointer, i2, i3)
+        .boolean;
+  }
+
+  static final _id_equals$2 = _class.staticMethodId(
+    r'equals',
+    r'([B[B)Z',
+  );
+
+  static final _equals$2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean equals(byte[] bs, byte[] bs1)`
+  static core$_.bool equals$2(
+    jni$_.JByteArray? bs,
+    jni$_.JByteArray? bs1,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
+    return _equals$2(_class.reference.pointer, _id_equals$2.pointer,
+            _$bs.pointer, _$bs1.pointer)
+        .boolean;
+  }
+
+  static final _id_equals$3 = _class.staticMethodId(
+    r'equals',
+    r'([BII[BII)Z',
+  );
+
+  static final _equals$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public boolean equals(byte[] bs, int i, int i1, byte[] bs1, int i2, int i3)`
+  static core$_.bool equals$3(
+    jni$_.JByteArray? bs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JByteArray? bs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
+    return _equals$3(_class.reference.pointer, _id_equals$3.pointer,
+            _$bs.pointer, i, i1, _$bs1.pointer, i2, i3)
+        .boolean;
+  }
+
+  static final _id_equals$4 = _class.staticMethodId(
+    r'equals',
+    r'([C[C)Z',
+  );
+
+  static final _equals$4 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean equals(char[] cs, char[] cs1)`
+  static core$_.bool equals$4(
+    jni$_.JCharArray? cs,
+    jni$_.JCharArray? cs1,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
+    return _equals$4(_class.reference.pointer, _id_equals$4.pointer,
+            _$cs.pointer, _$cs1.pointer)
+        .boolean;
+  }
+
+  static final _id_equals$5 = _class.staticMethodId(
+    r'equals',
+    r'([CII[CII)Z',
+  );
+
+  static final _equals$5 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public boolean equals(char[] cs, int i, int i1, char[] cs1, int i2, int i3)`
+  static core$_.bool equals$5(
+    jni$_.JCharArray? cs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JCharArray? cs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
+    return _equals$5(_class.reference.pointer, _id_equals$5.pointer,
+            _$cs.pointer, i, i1, _$cs1.pointer, i2, i3)
+        .boolean;
+  }
+
+  static final _id_equals$6 = _class.staticMethodId(
+    r'equals',
+    r'([D[D)Z',
+  );
+
+  static final _equals$6 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean equals(double[] ds, double[] ds1)`
+  static core$_.bool equals$6(
+    jni$_.JDoubleArray? ds,
+    jni$_.JDoubleArray? ds1,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
+    return _equals$6(_class.reference.pointer, _id_equals$6.pointer,
+            _$ds.pointer, _$ds1.pointer)
+        .boolean;
+  }
+
+  static final _id_equals$7 = _class.staticMethodId(
+    r'equals',
+    r'([DII[DII)Z',
+  );
+
+  static final _equals$7 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public boolean equals(double[] ds, int i, int i1, double[] ds1, int i2, int i3)`
+  static core$_.bool equals$7(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JDoubleArray? ds1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
+    return _equals$7(_class.reference.pointer, _id_equals$7.pointer,
+            _$ds.pointer, i, i1, _$ds1.pointer, i2, i3)
+        .boolean;
+  }
+
+  static final _id_equals$8 = _class.staticMethodId(
+    r'equals',
+    r'([F[F)Z',
+  );
+
+  static final _equals$8 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean equals(float[] fs, float[] fs1)`
+  static core$_.bool equals$8(
+    jni$_.JFloatArray? fs,
+    jni$_.JFloatArray? fs1,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
+    return _equals$8(_class.reference.pointer, _id_equals$8.pointer,
+            _$fs.pointer, _$fs1.pointer)
+        .boolean;
+  }
+
+  static final _id_equals$9 = _class.staticMethodId(
+    r'equals',
+    r'([FII[FII)Z',
+  );
+
+  static final _equals$9 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public boolean equals(float[] fs, int i, int i1, float[] fs1, int i2, int i3)`
+  static core$_.bool equals$9(
+    jni$_.JFloatArray? fs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JFloatArray? fs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
+    return _equals$9(_class.reference.pointer, _id_equals$9.pointer,
+            _$fs.pointer, i, i1, _$fs1.pointer, i2, i3)
+        .boolean;
+  }
+
+  static final _id_equals$10 = _class.staticMethodId(
+    r'equals',
+    r'([III[III)Z',
+  );
+
+  static final _equals$10 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public boolean equals(int[] is, int i, int i1, int[] is1, int i2, int i3)`
+  static core$_.bool equals$10(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JIntArray? is1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    final _$is1 = is1?.reference ?? jni$_.jNullReference;
+    return _equals$10(_class.reference.pointer, _id_equals$10.pointer,
+            _$is$.pointer, i, i1, _$is1.pointer, i2, i3)
+        .boolean;
+  }
+
+  static final _id_equals$11 = _class.staticMethodId(
+    r'equals',
+    r'([I[I)Z',
+  );
+
+  static final _equals$11 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean equals(int[] is, int[] is1)`
+  static core$_.bool equals$11(
+    jni$_.JIntArray? is$,
+    jni$_.JIntArray? is1,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    final _$is1 = is1?.reference ?? jni$_.jNullReference;
+    return _equals$11(_class.reference.pointer, _id_equals$11.pointer,
+            _$is$.pointer, _$is1.pointer)
+        .boolean;
+  }
+
+  static final _id_equals$12 = _class.staticMethodId(
+    r'equals',
+    r'([Ljava/lang/Object;II[Ljava/lang/Object;II)Z',
+  );
+
+  static final _equals$12 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public boolean equals(java.lang.Object[] objects, int i, int i1, java.lang.Object[] objects1, int i2, int i3)`
+  static core$_.bool equals$12(
+    jni$_.JArray<jni$_.JObject?>? objects,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JArray<jni$_.JObject?>? objects1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
+    return _equals$12(_class.reference.pointer, _id_equals$12.pointer,
+            _$objects.pointer, i, i1, _$objects1.pointer, i2, i3)
+        .boolean;
+  }
+
+  static final _id_equals$13 = _class.staticMethodId(
+    r'equals',
+    r'([Ljava/lang/Object;[Ljava/lang/Object;)Z',
+  );
+
+  static final _equals$13 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean equals(java.lang.Object[] objects, java.lang.Object[] objects1)`
+  static core$_.bool equals$13(
+    jni$_.JArray<jni$_.JObject?>? objects,
+    jni$_.JArray<jni$_.JObject?>? objects1,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
+    return _equals$13(_class.reference.pointer, _id_equals$13.pointer,
+            _$objects.pointer, _$objects1.pointer)
+        .boolean;
+  }
+
+  static final _id_equals$14 = _class.staticMethodId(
+    r'equals',
+    r'([JII[JII)Z',
+  );
+
+  static final _equals$14 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public boolean equals(long[] js, int i, int i1, long[] js1, int i2, int i3)`
+  static core$_.bool equals$14(
+    jni$_.JLongArray? js,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JLongArray? js1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    final _$js1 = js1?.reference ?? jni$_.jNullReference;
+    return _equals$14(_class.reference.pointer, _id_equals$14.pointer,
+            _$js.pointer, i, i1, _$js1.pointer, i2, i3)
+        .boolean;
+  }
+
+  static final _id_equals$15 = _class.staticMethodId(
+    r'equals',
+    r'([J[J)Z',
+  );
+
+  static final _equals$15 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean equals(long[] js, long[] js1)`
+  static core$_.bool equals$15(
+    jni$_.JLongArray? js,
+    jni$_.JLongArray? js1,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    final _$js1 = js1?.reference ?? jni$_.jNullReference;
+    return _equals$15(_class.reference.pointer, _id_equals$15.pointer,
+            _$js.pointer, _$js1.pointer)
+        .boolean;
+  }
+
+  static final _id_equals$16 = _class.staticMethodId(
+    r'equals',
+    r'([SII[SII)Z',
+  );
+
+  static final _equals$16 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public boolean equals(short[] ss, int i, int i1, short[] ss1, int i2, int i3)`
+  static core$_.bool equals$16(
+    jni$_.JShortArray? ss,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JShortArray? ss1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
+    return _equals$16(_class.reference.pointer, _id_equals$16.pointer,
+            _$ss.pointer, i, i1, _$ss1.pointer, i2, i3)
+        .boolean;
+  }
+
+  static final _id_equals$17 = _class.staticMethodId(
+    r'equals',
+    r'([S[S)Z',
+  );
+
+  static final _equals$17 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean equals(short[] ss, short[] ss1)`
+  static core$_.bool equals$17(
+    jni$_.JShortArray? ss,
+    jni$_.JShortArray? ss1,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
+    return _equals$17(_class.reference.pointer, _id_equals$17.pointer,
+            _$ss.pointer, _$ss1.pointer)
+        .boolean;
+  }
+
+  static final _id_equals$18 = _class.staticMethodId(
+    r'equals',
+    r'([Ljava/lang/Object;II[Ljava/lang/Object;IILjava/util/Comparator;)Z',
+  );
+
+  static final _equals$18 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean equals(T[] objects, int i, int i1, T[] objects1, int i2, int i3, java.util.Comparator<? super T> comparator)`
+  static core$_.bool equals$18<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JArray<$T?>? objects1,
+    core$_.int i2,
+    core$_.int i3,
+    jni$_.JObject? comparator,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
+    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
+    return _equals$18(
+            _class.reference.pointer,
+            _id_equals$18.pointer,
+            _$objects.pointer,
+            i,
+            i1,
+            _$objects1.pointer,
+            i2,
+            i3,
+            _$comparator.pointer)
+        .boolean;
+  }
+
+  static final _id_equals$19 = _class.staticMethodId(
+    r'equals',
+    r'([Ljava/lang/Object;[Ljava/lang/Object;Ljava/util/Comparator;)Z',
+  );
+
+  static final _equals$19 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public boolean equals(T[] objects, T[] objects1, java.util.Comparator<? super T> comparator)`
+  static core$_.bool equals$19<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    jni$_.JArray<$T?>? objects1,
+    jni$_.JObject? comparator,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
+    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
+    return _equals$19(_class.reference.pointer, _id_equals$19.pointer,
+            _$objects.pointer, _$objects1.pointer, _$comparator.pointer)
+        .boolean;
+  }
+
+  static final _id_fill = _class.staticMethodId(
+    r'fill',
+    r'([ZZ)V',
+  );
+
+  static final _fill = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public void fill(boolean[] zs, boolean z)`
+  static void fill(
+    jni$_.JBooleanArray? zs,
+    core$_.bool z,
+  ) {
+    final _$zs = zs?.reference ?? jni$_.jNullReference;
+    _fill(_class.reference.pointer, _id_fill.pointer, _$zs.pointer, z ? 1 : 0)
+        .check();
+  }
+
+  static final _id_fill$1 = _class.staticMethodId(
+    r'fill',
+    r'([ZIIZ)V',
+  );
+
+  static final _fill$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void fill(boolean[] zs, int i, int i1, boolean z)`
+  static void fill$1(
+    jni$_.JBooleanArray? zs,
+    core$_.int i,
+    core$_.int i1,
+    core$_.bool z,
+  ) {
+    final _$zs = zs?.reference ?? jni$_.jNullReference;
+    _fill$1(_class.reference.pointer, _id_fill$1.pointer, _$zs.pointer, i, i1,
+            z ? 1 : 0)
+        .check();
+  }
+
+  static final _id_fill$2 = _class.staticMethodId(
+    r'fill',
+    r'([BB)V',
+  );
+
+  static final _fill$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public void fill(byte[] bs, byte b)`
+  static void fill$2(
+    jni$_.JByteArray? bs,
+    core$_.int b,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    _fill$2(_class.reference.pointer, _id_fill$2.pointer, _$bs.pointer, b)
+        .check();
+  }
+
+  static final _id_fill$3 = _class.staticMethodId(
+    r'fill',
+    r'([BIIB)V',
+  );
+
+  static final _fill$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void fill(byte[] bs, int i, int i1, byte b)`
+  static void fill$3(
+    jni$_.JByteArray? bs,
+    core$_.int i,
+    core$_.int i1,
+    core$_.int b,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    _fill$3(_class.reference.pointer, _id_fill$3.pointer, _$bs.pointer, i, i1,
+            b)
+        .check();
+  }
+
+  static final _id_fill$4 = _class.staticMethodId(
+    r'fill',
+    r'([CC)V',
+  );
+
+  static final _fill$4 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public void fill(char[] cs, char c)`
+  static void fill$4(
+    jni$_.JCharArray? cs,
+    core$_.int c,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    _fill$4(_class.reference.pointer, _id_fill$4.pointer, _$cs.pointer, c)
+        .check();
+  }
+
+  static final _id_fill$5 = _class.staticMethodId(
+    r'fill',
+    r'([CIIC)V',
+  );
+
+  static final _fill$5 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void fill(char[] cs, int i, int i1, char c)`
+  static void fill$5(
+    jni$_.JCharArray? cs,
+    core$_.int i,
+    core$_.int i1,
+    core$_.int c,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    _fill$5(_class.reference.pointer, _id_fill$5.pointer, _$cs.pointer, i, i1,
+            c)
+        .check();
+  }
+
+  static final _id_fill$6 = _class.staticMethodId(
+    r'fill',
+    r'([DD)V',
+  );
+
+  static final _fill$6 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Double
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.double)>();
+
+  /// from: `static public void fill(double[] ds, double d)`
+  static void fill$6(
+    jni$_.JDoubleArray? ds,
+    core$_.double d,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    _fill$6(_class.reference.pointer, _id_fill$6.pointer, _$ds.pointer, d)
+        .check();
+  }
+
+  static final _id_fill$7 = _class.staticMethodId(
+    r'fill',
+    r'([DIID)V',
+  );
+
+  static final _fill$7 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Double
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.double)>();
+
+  /// from: `static public void fill(double[] ds, int i, int i1, double d)`
+  static void fill$7(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+    core$_.int i1,
+    core$_.double d,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    _fill$7(_class.reference.pointer, _id_fill$7.pointer, _$ds.pointer, i, i1,
+            d)
+        .check();
+  }
+
+  static final _id_fill$8 = _class.staticMethodId(
+    r'fill',
+    r'([FF)V',
+  );
+
+  static final _fill$8 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Double
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.double)>();
+
+  /// from: `static public void fill(float[] fs, float f)`
+  static void fill$8(
+    jni$_.JFloatArray? fs,
+    core$_.double f,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    _fill$8(_class.reference.pointer, _id_fill$8.pointer, _$fs.pointer, f)
+        .check();
+  }
+
+  static final _id_fill$9 = _class.staticMethodId(
+    r'fill',
+    r'([FIIF)V',
+  );
+
+  static final _fill$9 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Double
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.double)>();
+
+  /// from: `static public void fill(float[] fs, int i, int i1, float f)`
+  static void fill$9(
+    jni$_.JFloatArray? fs,
+    core$_.int i,
+    core$_.int i1,
+    core$_.double f,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    _fill$9(_class.reference.pointer, _id_fill$9.pointer, _$fs.pointer, i, i1,
+            f)
+        .check();
+  }
+
+  static final _id_fill$10 = _class.staticMethodId(
+    r'fill',
+    r'([II)V',
+  );
+
+  static final _fill$10 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public void fill(int[] is, int i)`
+  static void fill$10(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    _fill$10(_class.reference.pointer, _id_fill$10.pointer, _$is$.pointer, i)
+        .check();
+  }
+
+  static final _id_fill$11 = _class.staticMethodId(
+    r'fill',
+    r'([IIII)V',
+  );
+
+  static final _fill$11 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void fill(int[] is, int i, int i1, int i2)`
+  static void fill$11(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+    core$_.int i1,
+    core$_.int i2,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    _fill$11(_class.reference.pointer, _id_fill$11.pointer, _$is$.pointer, i,
+            i1, i2)
+        .check();
+  }
+
+  static final _id_fill$12 = _class.staticMethodId(
+    r'fill',
+    r'([Ljava/lang/Object;IILjava/lang/Object;)V',
+  );
+
+  static final _fill$12 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void fill(java.lang.Object[] objects, int i, int i1, java.lang.Object object)`
+  static void fill$12(
+    jni$_.JArray<jni$_.JObject?>? objects,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JObject? object,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$object = object?.reference ?? jni$_.jNullReference;
+    _fill$12(_class.reference.pointer, _id_fill$12.pointer, _$objects.pointer,
+            i, i1, _$object.pointer)
+        .check();
+  }
+
+  static final _id_fill$13 = _class.staticMethodId(
+    r'fill',
+    r'([Ljava/lang/Object;Ljava/lang/Object;)V',
+  );
+
+  static final _fill$13 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JThrowablePtr Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -33429,22 +27130,1505 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public void setAll(java.lang.Object[] objects, java.util.function.IntFunction intFunction)`
-  static void setAll<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    jni$_.JObject? intFunction, {
-    required jni$_.JObjType<$T> T,
-  }) {
+  /// from: `static public void fill(java.lang.Object[] objects, java.lang.Object object)`
+  static void fill$13(
+    jni$_.JArray<jni$_.JObject?>? objects,
+    jni$_.JObject? object,
+  ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$intFunction = intFunction?.reference ?? jni$_.jNullReference;
-    _setAll(_class.reference.pointer, _id_setAll as jni$_.JMethodIDPtr,
-            _$objects.pointer, _$intFunction.pointer)
+    final _$object = object?.reference ?? jni$_.jNullReference;
+    _fill$13(_class.reference.pointer, _id_fill$13.pointer, _$objects.pointer,
+            _$object.pointer)
+        .check();
+  }
+
+  static final _id_fill$14 = _class.staticMethodId(
+    r'fill',
+    r'([JIIJ)V',
+  );
+
+  static final _fill$14 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Int64
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void fill(long[] js, int i, int i1, long j)`
+  static void fill$14(
+    jni$_.JLongArray? js,
+    core$_.int i,
+    core$_.int i1,
+    core$_.int j,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    _fill$14(_class.reference.pointer, _id_fill$14.pointer, _$js.pointer, i, i1,
+            j)
+        .check();
+  }
+
+  static final _id_fill$15 = _class.staticMethodId(
+    r'fill',
+    r'([JJ)V',
+  );
+
+  static final _fill$15 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int64)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public void fill(long[] js, long j)`
+  static void fill$15(
+    jni$_.JLongArray? js,
+    core$_.int j,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    _fill$15(_class.reference.pointer, _id_fill$15.pointer, _$js.pointer, j)
+        .check();
+  }
+
+  static final _id_fill$16 = _class.staticMethodId(
+    r'fill',
+    r'([SIIS)V',
+  );
+
+  static final _fill$16 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void fill(short[] ss, int i, int i1, short s)`
+  static void fill$16(
+    jni$_.JShortArray? ss,
+    core$_.int i,
+    core$_.int i1,
+    core$_.int s,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    _fill$16(_class.reference.pointer, _id_fill$16.pointer, _$ss.pointer, i, i1,
+            s)
+        .check();
+  }
+
+  static final _id_fill$17 = _class.staticMethodId(
+    r'fill',
+    r'([SS)V',
+  );
+
+  static final _fill$17 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_
+                          .VarArgs<(jni$_.Pointer<jni$_.Void>, jni$_.Int32)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, core$_.int)>();
+
+  /// from: `static public void fill(short[] ss, short s)`
+  static void fill$17(
+    jni$_.JShortArray? ss,
+    core$_.int s,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    _fill$17(_class.reference.pointer, _id_fill$17.pointer, _$ss.pointer, s)
+        .check();
+  }
+
+  static final _id_hashCode$1 = _class.staticMethodId(
+    r'hashCode',
+    r'([Z)I',
+  );
+
+  static final _hashCode$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int hashCode(boolean[] zs)`
+  static core$_.int hashCode$1(
+    jni$_.JBooleanArray? zs,
+  ) {
+    final _$zs = zs?.reference ?? jni$_.jNullReference;
+    return _hashCode$1(
+            _class.reference.pointer, _id_hashCode$1.pointer, _$zs.pointer)
+        .integer;
+  }
+
+  static final _id_hashCode$2 = _class.staticMethodId(
+    r'hashCode',
+    r'([B)I',
+  );
+
+  static final _hashCode$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int hashCode(byte[] bs)`
+  static core$_.int hashCode$2(
+    jni$_.JByteArray? bs,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    return _hashCode$2(
+            _class.reference.pointer, _id_hashCode$2.pointer, _$bs.pointer)
+        .integer;
+  }
+
+  static final _id_hashCode$3 = _class.staticMethodId(
+    r'hashCode',
+    r'([C)I',
+  );
+
+  static final _hashCode$3 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int hashCode(char[] cs)`
+  static core$_.int hashCode$3(
+    jni$_.JCharArray? cs,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    return _hashCode$3(
+            _class.reference.pointer, _id_hashCode$3.pointer, _$cs.pointer)
+        .integer;
+  }
+
+  static final _id_hashCode$4 = _class.staticMethodId(
+    r'hashCode',
+    r'([D)I',
+  );
+
+  static final _hashCode$4 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int hashCode(double[] ds)`
+  static core$_.int hashCode$4(
+    jni$_.JDoubleArray? ds,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    return _hashCode$4(
+            _class.reference.pointer, _id_hashCode$4.pointer, _$ds.pointer)
+        .integer;
+  }
+
+  static final _id_hashCode$5 = _class.staticMethodId(
+    r'hashCode',
+    r'([F)I',
+  );
+
+  static final _hashCode$5 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int hashCode(float[] fs)`
+  static core$_.int hashCode$5(
+    jni$_.JFloatArray? fs,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    return _hashCode$5(
+            _class.reference.pointer, _id_hashCode$5.pointer, _$fs.pointer)
+        .integer;
+  }
+
+  static final _id_hashCode$6 = _class.staticMethodId(
+    r'hashCode',
+    r'([I)I',
+  );
+
+  static final _hashCode$6 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int hashCode(int[] is)`
+  static core$_.int hashCode$6(
+    jni$_.JIntArray? is$,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    return _hashCode$6(
+            _class.reference.pointer, _id_hashCode$6.pointer, _$is$.pointer)
+        .integer;
+  }
+
+  static final _id_hashCode$7 = _class.staticMethodId(
+    r'hashCode',
+    r'([Ljava/lang/Object;)I',
+  );
+
+  static final _hashCode$7 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int hashCode(java.lang.Object[] objects)`
+  static core$_.int hashCode$7(
+    jni$_.JArray<jni$_.JObject?>? objects,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    return _hashCode$7(
+            _class.reference.pointer, _id_hashCode$7.pointer, _$objects.pointer)
+        .integer;
+  }
+
+  static final _id_hashCode$8 = _class.staticMethodId(
+    r'hashCode',
+    r'([J)I',
+  );
+
+  static final _hashCode$8 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int hashCode(long[] js)`
+  static core$_.int hashCode$8(
+    jni$_.JLongArray? js,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    return _hashCode$8(
+            _class.reference.pointer, _id_hashCode$8.pointer, _$js.pointer)
+        .integer;
+  }
+
+  static final _id_hashCode$9 = _class.staticMethodId(
+    r'hashCode',
+    r'([S)I',
+  );
+
+  static final _hashCode$9 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int hashCode(short[] ss)`
+  static core$_.int hashCode$9(
+    jni$_.JShortArray? ss,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    return _hashCode$9(
+            _class.reference.pointer, _id_hashCode$9.pointer, _$ss.pointer)
+        .integer;
+  }
+
+  static final _id_mismatch = _class.staticMethodId(
+    r'mismatch',
+    r'([Z[Z)I',
+  );
+
+  static final _mismatch = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int mismatch(boolean[] zs, boolean[] zs1)`
+  static core$_.int mismatch(
+    jni$_.JBooleanArray? zs,
+    jni$_.JBooleanArray? zs1,
+  ) {
+    final _$zs = zs?.reference ?? jni$_.jNullReference;
+    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
+    return _mismatch(_class.reference.pointer, _id_mismatch.pointer,
+            _$zs.pointer, _$zs1.pointer)
+        .integer;
+  }
+
+  static final _id_mismatch$1 = _class.staticMethodId(
+    r'mismatch',
+    r'([ZII[ZII)I',
+  );
+
+  static final _mismatch$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int mismatch(boolean[] zs, int i, int i1, boolean[] zs1, int i2, int i3)`
+  static core$_.int mismatch$1(
+    jni$_.JBooleanArray? zs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JBooleanArray? zs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$zs = zs?.reference ?? jni$_.jNullReference;
+    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
+    return _mismatch$1(_class.reference.pointer, _id_mismatch$1.pointer,
+            _$zs.pointer, i, i1, _$zs1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_mismatch$2 = _class.staticMethodId(
+    r'mismatch',
+    r'([B[B)I',
+  );
+
+  static final _mismatch$2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int mismatch(byte[] bs, byte[] bs1)`
+  static core$_.int mismatch$2(
+    jni$_.JByteArray? bs,
+    jni$_.JByteArray? bs1,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
+    return _mismatch$2(_class.reference.pointer, _id_mismatch$2.pointer,
+            _$bs.pointer, _$bs1.pointer)
+        .integer;
+  }
+
+  static final _id_mismatch$3 = _class.staticMethodId(
+    r'mismatch',
+    r'([BII[BII)I',
+  );
+
+  static final _mismatch$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int mismatch(byte[] bs, int i, int i1, byte[] bs1, int i2, int i3)`
+  static core$_.int mismatch$3(
+    jni$_.JByteArray? bs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JByteArray? bs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
+    return _mismatch$3(_class.reference.pointer, _id_mismatch$3.pointer,
+            _$bs.pointer, i, i1, _$bs1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_mismatch$4 = _class.staticMethodId(
+    r'mismatch',
+    r'([C[C)I',
+  );
+
+  static final _mismatch$4 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int mismatch(char[] cs, char[] cs1)`
+  static core$_.int mismatch$4(
+    jni$_.JCharArray? cs,
+    jni$_.JCharArray? cs1,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
+    return _mismatch$4(_class.reference.pointer, _id_mismatch$4.pointer,
+            _$cs.pointer, _$cs1.pointer)
+        .integer;
+  }
+
+  static final _id_mismatch$5 = _class.staticMethodId(
+    r'mismatch',
+    r'([CII[CII)I',
+  );
+
+  static final _mismatch$5 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int mismatch(char[] cs, int i, int i1, char[] cs1, int i2, int i3)`
+  static core$_.int mismatch$5(
+    jni$_.JCharArray? cs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JCharArray? cs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
+    return _mismatch$5(_class.reference.pointer, _id_mismatch$5.pointer,
+            _$cs.pointer, i, i1, _$cs1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_mismatch$6 = _class.staticMethodId(
+    r'mismatch',
+    r'([D[D)I',
+  );
+
+  static final _mismatch$6 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int mismatch(double[] ds, double[] ds1)`
+  static core$_.int mismatch$6(
+    jni$_.JDoubleArray? ds,
+    jni$_.JDoubleArray? ds1,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
+    return _mismatch$6(_class.reference.pointer, _id_mismatch$6.pointer,
+            _$ds.pointer, _$ds1.pointer)
+        .integer;
+  }
+
+  static final _id_mismatch$7 = _class.staticMethodId(
+    r'mismatch',
+    r'([DII[DII)I',
+  );
+
+  static final _mismatch$7 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int mismatch(double[] ds, int i, int i1, double[] ds1, int i2, int i3)`
+  static core$_.int mismatch$7(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JDoubleArray? ds1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
+    return _mismatch$7(_class.reference.pointer, _id_mismatch$7.pointer,
+            _$ds.pointer, i, i1, _$ds1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_mismatch$8 = _class.staticMethodId(
+    r'mismatch',
+    r'([F[F)I',
+  );
+
+  static final _mismatch$8 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int mismatch(float[] fs, float[] fs1)`
+  static core$_.int mismatch$8(
+    jni$_.JFloatArray? fs,
+    jni$_.JFloatArray? fs1,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
+    return _mismatch$8(_class.reference.pointer, _id_mismatch$8.pointer,
+            _$fs.pointer, _$fs1.pointer)
+        .integer;
+  }
+
+  static final _id_mismatch$9 = _class.staticMethodId(
+    r'mismatch',
+    r'([FII[FII)I',
+  );
+
+  static final _mismatch$9 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int mismatch(float[] fs, int i, int i1, float[] fs1, int i2, int i3)`
+  static core$_.int mismatch$9(
+    jni$_.JFloatArray? fs,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JFloatArray? fs1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
+    return _mismatch$9(_class.reference.pointer, _id_mismatch$9.pointer,
+            _$fs.pointer, i, i1, _$fs1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_mismatch$10 = _class.staticMethodId(
+    r'mismatch',
+    r'([III[III)I',
+  );
+
+  static final _mismatch$10 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int mismatch(int[] is, int i, int i1, int[] is1, int i2, int i3)`
+  static core$_.int mismatch$10(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JIntArray? is1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    final _$is1 = is1?.reference ?? jni$_.jNullReference;
+    return _mismatch$10(_class.reference.pointer, _id_mismatch$10.pointer,
+            _$is$.pointer, i, i1, _$is1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_mismatch$11 = _class.staticMethodId(
+    r'mismatch',
+    r'([I[I)I',
+  );
+
+  static final _mismatch$11 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int mismatch(int[] is, int[] is1)`
+  static core$_.int mismatch$11(
+    jni$_.JIntArray? is$,
+    jni$_.JIntArray? is1,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    final _$is1 = is1?.reference ?? jni$_.jNullReference;
+    return _mismatch$11(_class.reference.pointer, _id_mismatch$11.pointer,
+            _$is$.pointer, _$is1.pointer)
+        .integer;
+  }
+
+  static final _id_mismatch$12 = _class.staticMethodId(
+    r'mismatch',
+    r'([Ljava/lang/Object;II[Ljava/lang/Object;II)I',
+  );
+
+  static final _mismatch$12 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int mismatch(java.lang.Object[] objects, int i, int i1, java.lang.Object[] objects1, int i2, int i3)`
+  static core$_.int mismatch$12(
+    jni$_.JArray<jni$_.JObject?>? objects,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JArray<jni$_.JObject?>? objects1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
+    return _mismatch$12(_class.reference.pointer, _id_mismatch$12.pointer,
+            _$objects.pointer, i, i1, _$objects1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_mismatch$13 = _class.staticMethodId(
+    r'mismatch',
+    r'([Ljava/lang/Object;[Ljava/lang/Object;)I',
+  );
+
+  static final _mismatch$13 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int mismatch(java.lang.Object[] objects, java.lang.Object[] objects1)`
+  static core$_.int mismatch$13(
+    jni$_.JArray<jni$_.JObject?>? objects,
+    jni$_.JArray<jni$_.JObject?>? objects1,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
+    return _mismatch$13(_class.reference.pointer, _id_mismatch$13.pointer,
+            _$objects.pointer, _$objects1.pointer)
+        .integer;
+  }
+
+  static final _id_mismatch$14 = _class.staticMethodId(
+    r'mismatch',
+    r'([JII[JII)I',
+  );
+
+  static final _mismatch$14 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int mismatch(long[] js, int i, int i1, long[] js1, int i2, int i3)`
+  static core$_.int mismatch$14(
+    jni$_.JLongArray? js,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JLongArray? js1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    final _$js1 = js1?.reference ?? jni$_.jNullReference;
+    return _mismatch$14(_class.reference.pointer, _id_mismatch$14.pointer,
+            _$js.pointer, i, i1, _$js1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_mismatch$15 = _class.staticMethodId(
+    r'mismatch',
+    r'([J[J)I',
+  );
+
+  static final _mismatch$15 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int mismatch(long[] js, long[] js1)`
+  static core$_.int mismatch$15(
+    jni$_.JLongArray? js,
+    jni$_.JLongArray? js1,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    final _$js1 = js1?.reference ?? jni$_.jNullReference;
+    return _mismatch$15(_class.reference.pointer, _id_mismatch$15.pointer,
+            _$js.pointer, _$js1.pointer)
+        .integer;
+  }
+
+  static final _id_mismatch$16 = _class.staticMethodId(
+    r'mismatch',
+    r'([SII[SII)I',
+  );
+
+  static final _mismatch$16 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public int mismatch(short[] ss, int i, int i1, short[] ss1, int i2, int i3)`
+  static core$_.int mismatch$16(
+    jni$_.JShortArray? ss,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JShortArray? ss1,
+    core$_.int i2,
+    core$_.int i3,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
+    return _mismatch$16(_class.reference.pointer, _id_mismatch$16.pointer,
+            _$ss.pointer, i, i1, _$ss1.pointer, i2, i3)
+        .integer;
+  }
+
+  static final _id_mismatch$17 = _class.staticMethodId(
+    r'mismatch',
+    r'([S[S)I',
+  );
+
+  static final _mismatch$17 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int mismatch(short[] ss, short[] ss1)`
+  static core$_.int mismatch$17(
+    jni$_.JShortArray? ss,
+    jni$_.JShortArray? ss1,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
+    return _mismatch$17(_class.reference.pointer, _id_mismatch$17.pointer,
+            _$ss.pointer, _$ss1.pointer)
+        .integer;
+  }
+
+  static final _id_mismatch$18 = _class.staticMethodId(
+    r'mismatch',
+    r'([Ljava/lang/Object;II[Ljava/lang/Object;IILjava/util/Comparator;)I',
+  );
+
+  static final _mismatch$18 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int mismatch(T[] objects, int i, int i1, T[] objects1, int i2, int i3, java.util.Comparator<? super T> comparator)`
+  static core$_.int mismatch$18<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JArray<$T?>? objects1,
+    core$_.int i2,
+    core$_.int i3,
+    jni$_.JObject? comparator,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
+    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
+    return _mismatch$18(
+            _class.reference.pointer,
+            _id_mismatch$18.pointer,
+            _$objects.pointer,
+            i,
+            i1,
+            _$objects1.pointer,
+            i2,
+            i3,
+            _$comparator.pointer)
+        .integer;
+  }
+
+  static final _id_mismatch$19 = _class.staticMethodId(
+    r'mismatch',
+    r'([Ljava/lang/Object;[Ljava/lang/Object;Ljava/util/Comparator;)I',
+  );
+
+  static final _mismatch$19 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public int mismatch(T[] objects, T[] objects1, java.util.Comparator<? super T> comparator)`
+  static core$_.int mismatch$19<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    jni$_.JArray<$T?>? objects1,
+    jni$_.JObject? comparator,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
+    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
+    return _mismatch$19(_class.reference.pointer, _id_mismatch$19.pointer,
+            _$objects.pointer, _$objects1.pointer, _$comparator.pointer)
+        .integer;
+  }
+
+  static final _id_parallelPrefix = _class.staticMethodId(
+    r'parallelPrefix',
+    r'([DIILjava/util/function/DoubleBinaryOperator;)V',
+  );
+
+  static final _parallelPrefix = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelPrefix(double[] ds, int i, int i1, java.util.function.DoubleBinaryOperator doubleBinaryOperator)`
+  static void parallelPrefix(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JObject? doubleBinaryOperator,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    final _$doubleBinaryOperator =
+        doubleBinaryOperator?.reference ?? jni$_.jNullReference;
+    _parallelPrefix(_class.reference.pointer, _id_parallelPrefix.pointer,
+            _$ds.pointer, i, i1, _$doubleBinaryOperator.pointer)
+        .check();
+  }
+
+  static final _id_parallelPrefix$1 = _class.staticMethodId(
+    r'parallelPrefix',
+    r'([DLjava/util/function/DoubleBinaryOperator;)V',
+  );
+
+  static final _parallelPrefix$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelPrefix(double[] ds, java.util.function.DoubleBinaryOperator doubleBinaryOperator)`
+  static void parallelPrefix$1(
+    jni$_.JDoubleArray? ds,
+    jni$_.JObject? doubleBinaryOperator,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    final _$doubleBinaryOperator =
+        doubleBinaryOperator?.reference ?? jni$_.jNullReference;
+    _parallelPrefix$1(_class.reference.pointer, _id_parallelPrefix$1.pointer,
+            _$ds.pointer, _$doubleBinaryOperator.pointer)
+        .check();
+  }
+
+  static final _id_parallelPrefix$2 = _class.staticMethodId(
+    r'parallelPrefix',
+    r'([IIILjava/util/function/IntBinaryOperator;)V',
+  );
+
+  static final _parallelPrefix$2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelPrefix(int[] is, int i, int i1, java.util.function.IntBinaryOperator intBinaryOperator)`
+  static void parallelPrefix$2(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JObject? intBinaryOperator,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    final _$intBinaryOperator =
+        intBinaryOperator?.reference ?? jni$_.jNullReference;
+    _parallelPrefix$2(_class.reference.pointer, _id_parallelPrefix$2.pointer,
+            _$is$.pointer, i, i1, _$intBinaryOperator.pointer)
+        .check();
+  }
+
+  static final _id_parallelPrefix$3 = _class.staticMethodId(
+    r'parallelPrefix',
+    r'([ILjava/util/function/IntBinaryOperator;)V',
+  );
+
+  static final _parallelPrefix$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelPrefix(int[] is, java.util.function.IntBinaryOperator intBinaryOperator)`
+  static void parallelPrefix$3(
+    jni$_.JIntArray? is$,
+    jni$_.JObject? intBinaryOperator,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    final _$intBinaryOperator =
+        intBinaryOperator?.reference ?? jni$_.jNullReference;
+    _parallelPrefix$3(_class.reference.pointer, _id_parallelPrefix$3.pointer,
+            _$is$.pointer, _$intBinaryOperator.pointer)
+        .check();
+  }
+
+  static final _id_parallelPrefix$4 = _class.staticMethodId(
+    r'parallelPrefix',
+    r'([JIILjava/util/function/LongBinaryOperator;)V',
+  );
+
+  static final _parallelPrefix$4 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelPrefix(long[] js, int i, int i1, java.util.function.LongBinaryOperator longBinaryOperator)`
+  static void parallelPrefix$4(
+    jni$_.JLongArray? js,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JObject? longBinaryOperator,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    final _$longBinaryOperator =
+        longBinaryOperator?.reference ?? jni$_.jNullReference;
+    _parallelPrefix$4(_class.reference.pointer, _id_parallelPrefix$4.pointer,
+            _$js.pointer, i, i1, _$longBinaryOperator.pointer)
+        .check();
+  }
+
+  static final _id_parallelPrefix$5 = _class.staticMethodId(
+    r'parallelPrefix',
+    r'([JLjava/util/function/LongBinaryOperator;)V',
+  );
+
+  static final _parallelPrefix$5 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelPrefix(long[] js, java.util.function.LongBinaryOperator longBinaryOperator)`
+  static void parallelPrefix$5(
+    jni$_.JLongArray? js,
+    jni$_.JObject? longBinaryOperator,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    final _$longBinaryOperator =
+        longBinaryOperator?.reference ?? jni$_.jNullReference;
+    _parallelPrefix$5(_class.reference.pointer, _id_parallelPrefix$5.pointer,
+            _$js.pointer, _$longBinaryOperator.pointer)
+        .check();
+  }
+
+  static final _id_parallelPrefix$6 = _class.staticMethodId(
+    r'parallelPrefix',
+    r'([Ljava/lang/Object;IILjava/util/function/BinaryOperator;)V',
+  );
+
+  static final _parallelPrefix$6 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelPrefix(T[] objects, int i, int i1, java.util.function.BinaryOperator<T> binaryOperator)`
+  static void parallelPrefix$6<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JObject? binaryOperator,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$binaryOperator = binaryOperator?.reference ?? jni$_.jNullReference;
+    _parallelPrefix$6(_class.reference.pointer, _id_parallelPrefix$6.pointer,
+            _$objects.pointer, i, i1, _$binaryOperator.pointer)
+        .check();
+  }
+
+  static final _id_parallelPrefix$7 = _class.staticMethodId(
+    r'parallelPrefix',
+    r'([Ljava/lang/Object;Ljava/util/function/BinaryOperator;)V',
+  );
+
+  static final _parallelPrefix$7 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelPrefix(T[] objects, java.util.function.BinaryOperator<T> binaryOperator)`
+  static void parallelPrefix$7<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    jni$_.JObject? binaryOperator,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$binaryOperator = binaryOperator?.reference ?? jni$_.jNullReference;
+    _parallelPrefix$7(_class.reference.pointer, _id_parallelPrefix$7.pointer,
+            _$objects.pointer, _$binaryOperator.pointer)
         .check();
   }
 
   static final _id_parallelSetAll = _class.staticMethodId(
     r'parallelSetAll',
-    r'([Ljava/lang/Object;Ljava/util/function/IntFunction;)V',
+    r'([DLjava/util/function/IntToDoubleFunction;)V',
   );
 
   static final _parallelSetAll = jni$_.ProtectedJniExtensions.lookup<
@@ -33464,54 +28648,16 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public void parallelSetAll(java.lang.Object[] objects, java.util.function.IntFunction intFunction)`
-  static void parallelSetAll<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    jni$_.JObject? intFunction, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$intFunction = intFunction?.reference ?? jni$_.jNullReference;
-    _parallelSetAll(
-            _class.reference.pointer,
-            _id_parallelSetAll as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            _$intFunction.pointer)
-        .check();
-  }
-
-  static final _id_setAll$1 = _class.staticMethodId(
-    r'setAll',
-    r'([ILjava/util/function/IntUnaryOperator;)V',
-  );
-
-  static final _setAll$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void setAll(int[] is, java.util.function.IntUnaryOperator intUnaryOperator)`
-  static void setAll$1(
-    jni$_.JIntArray? is$,
-    jni$_.JObject? intUnaryOperator,
+  /// from: `static public void parallelSetAll(double[] ds, java.util.function.IntToDoubleFunction intToDoubleFunction)`
+  static void parallelSetAll(
+    jni$_.JDoubleArray? ds,
+    jni$_.JObject? intToDoubleFunction,
   ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    final _$intUnaryOperator =
-        intUnaryOperator?.reference ?? jni$_.jNullReference;
-    _setAll$1(_class.reference.pointer, _id_setAll$1 as jni$_.JMethodIDPtr,
-            _$is$.pointer, _$intUnaryOperator.pointer)
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    final _$intToDoubleFunction =
+        intToDoubleFunction?.reference ?? jni$_.jNullReference;
+    _parallelSetAll(_class.reference.pointer, _id_parallelSetAll.pointer,
+            _$ds.pointer, _$intToDoubleFunction.pointer)
         .check();
   }
 
@@ -33545,10 +28691,716 @@
     final _$is$ = is$?.reference ?? jni$_.jNullReference;
     final _$intUnaryOperator =
         intUnaryOperator?.reference ?? jni$_.jNullReference;
-    _parallelSetAll$1(
-            _class.reference.pointer,
-            _id_parallelSetAll$1 as jni$_.JMethodIDPtr,
-            _$is$.pointer,
+    _parallelSetAll$1(_class.reference.pointer, _id_parallelSetAll$1.pointer,
+            _$is$.pointer, _$intUnaryOperator.pointer)
+        .check();
+  }
+
+  static final _id_parallelSetAll$2 = _class.staticMethodId(
+    r'parallelSetAll',
+    r'([JLjava/util/function/IntToLongFunction;)V',
+  );
+
+  static final _parallelSetAll$2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSetAll(long[] js, java.util.function.IntToLongFunction intToLongFunction)`
+  static void parallelSetAll$2(
+    jni$_.JLongArray? js,
+    jni$_.JObject? intToLongFunction,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    final _$intToLongFunction =
+        intToLongFunction?.reference ?? jni$_.jNullReference;
+    _parallelSetAll$2(_class.reference.pointer, _id_parallelSetAll$2.pointer,
+            _$js.pointer, _$intToLongFunction.pointer)
+        .check();
+  }
+
+  static final _id_parallelSetAll$3 = _class.staticMethodId(
+    r'parallelSetAll',
+    r'([Ljava/lang/Object;Ljava/util/function/IntFunction;)V',
+  );
+
+  static final _parallelSetAll$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSetAll(T[] objects, java.util.function.IntFunction<? extends T> intFunction)`
+  static void parallelSetAll$3<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    jni$_.JObject? intFunction,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$intFunction = intFunction?.reference ?? jni$_.jNullReference;
+    _parallelSetAll$3(_class.reference.pointer, _id_parallelSetAll$3.pointer,
+            _$objects.pointer, _$intFunction.pointer)
+        .check();
+  }
+
+  static final _id_parallelSort = _class.staticMethodId(
+    r'parallelSort',
+    r'([B)V',
+  );
+
+  static final _parallelSort = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSort(byte[] bs)`
+  static void parallelSort(
+    jni$_.JByteArray? bs,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    _parallelSort(
+            _class.reference.pointer, _id_parallelSort.pointer, _$bs.pointer)
+        .check();
+  }
+
+  static final _id_parallelSort$1 = _class.staticMethodId(
+    r'parallelSort',
+    r'([BII)V',
+  );
+
+  static final _parallelSort$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void parallelSort(byte[] bs, int i, int i1)`
+  static void parallelSort$1(
+    jni$_.JByteArray? bs,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    _parallelSort$1(_class.reference.pointer, _id_parallelSort$1.pointer,
+            _$bs.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_parallelSort$2 = _class.staticMethodId(
+    r'parallelSort',
+    r'([C)V',
+  );
+
+  static final _parallelSort$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSort(char[] cs)`
+  static void parallelSort$2(
+    jni$_.JCharArray? cs,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    _parallelSort$2(
+            _class.reference.pointer, _id_parallelSort$2.pointer, _$cs.pointer)
+        .check();
+  }
+
+  static final _id_parallelSort$3 = _class.staticMethodId(
+    r'parallelSort',
+    r'([CII)V',
+  );
+
+  static final _parallelSort$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void parallelSort(char[] cs, int i, int i1)`
+  static void parallelSort$3(
+    jni$_.JCharArray? cs,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    _parallelSort$3(_class.reference.pointer, _id_parallelSort$3.pointer,
+            _$cs.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_parallelSort$4 = _class.staticMethodId(
+    r'parallelSort',
+    r'([D)V',
+  );
+
+  static final _parallelSort$4 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSort(double[] ds)`
+  static void parallelSort$4(
+    jni$_.JDoubleArray? ds,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    _parallelSort$4(
+            _class.reference.pointer, _id_parallelSort$4.pointer, _$ds.pointer)
+        .check();
+  }
+
+  static final _id_parallelSort$5 = _class.staticMethodId(
+    r'parallelSort',
+    r'([DII)V',
+  );
+
+  static final _parallelSort$5 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void parallelSort(double[] ds, int i, int i1)`
+  static void parallelSort$5(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    _parallelSort$5(_class.reference.pointer, _id_parallelSort$5.pointer,
+            _$ds.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_parallelSort$6 = _class.staticMethodId(
+    r'parallelSort',
+    r'([F)V',
+  );
+
+  static final _parallelSort$6 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSort(float[] fs)`
+  static void parallelSort$6(
+    jni$_.JFloatArray? fs,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    _parallelSort$6(
+            _class.reference.pointer, _id_parallelSort$6.pointer, _$fs.pointer)
+        .check();
+  }
+
+  static final _id_parallelSort$7 = _class.staticMethodId(
+    r'parallelSort',
+    r'([FII)V',
+  );
+
+  static final _parallelSort$7 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void parallelSort(float[] fs, int i, int i1)`
+  static void parallelSort$7(
+    jni$_.JFloatArray? fs,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    _parallelSort$7(_class.reference.pointer, _id_parallelSort$7.pointer,
+            _$fs.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_parallelSort$8 = _class.staticMethodId(
+    r'parallelSort',
+    r'([I)V',
+  );
+
+  static final _parallelSort$8 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSort(int[] is)`
+  static void parallelSort$8(
+    jni$_.JIntArray? is$,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    _parallelSort$8(
+            _class.reference.pointer, _id_parallelSort$8.pointer, _$is$.pointer)
+        .check();
+  }
+
+  static final _id_parallelSort$9 = _class.staticMethodId(
+    r'parallelSort',
+    r'([III)V',
+  );
+
+  static final _parallelSort$9 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void parallelSort(int[] is, int i, int i1)`
+  static void parallelSort$9(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    _parallelSort$9(_class.reference.pointer, _id_parallelSort$9.pointer,
+            _$is$.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_parallelSort$10 = _class.staticMethodId(
+    r'parallelSort',
+    r'([J)V',
+  );
+
+  static final _parallelSort$10 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSort(long[] js)`
+  static void parallelSort$10(
+    jni$_.JLongArray? js,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    _parallelSort$10(
+            _class.reference.pointer, _id_parallelSort$10.pointer, _$js.pointer)
+        .check();
+  }
+
+  static final _id_parallelSort$11 = _class.staticMethodId(
+    r'parallelSort',
+    r'([JII)V',
+  );
+
+  static final _parallelSort$11 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void parallelSort(long[] js, int i, int i1)`
+  static void parallelSort$11(
+    jni$_.JLongArray? js,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    _parallelSort$11(_class.reference.pointer, _id_parallelSort$11.pointer,
+            _$js.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_parallelSort$12 = _class.staticMethodId(
+    r'parallelSort',
+    r'([S)V',
+  );
+
+  static final _parallelSort$12 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSort(short[] ss)`
+  static void parallelSort$12(
+    jni$_.JShortArray? ss,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    _parallelSort$12(
+            _class.reference.pointer, _id_parallelSort$12.pointer, _$ss.pointer)
+        .check();
+  }
+
+  static final _id_parallelSort$13 = _class.staticMethodId(
+    r'parallelSort',
+    r'([SII)V',
+  );
+
+  static final _parallelSort$13 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void parallelSort(short[] ss, int i, int i1)`
+  static void parallelSort$13(
+    jni$_.JShortArray? ss,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    _parallelSort$13(_class.reference.pointer, _id_parallelSort$13.pointer,
+            _$ss.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_parallelSort$14 = _class.staticMethodId(
+    r'parallelSort',
+    r'([Ljava/lang/Comparable;)V',
+  );
+
+  static final _parallelSort$14 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSort(T[] comparables)`
+  static void parallelSort$14<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? comparables,
+  ) {
+    final _$comparables = comparables?.reference ?? jni$_.jNullReference;
+    _parallelSort$14(_class.reference.pointer, _id_parallelSort$14.pointer,
+            _$comparables.pointer)
+        .check();
+  }
+
+  static final _id_parallelSort$15 = _class.staticMethodId(
+    r'parallelSort',
+    r'([Ljava/lang/Comparable;II)V',
+  );
+
+  static final _parallelSort$15 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void parallelSort(T[] comparables, int i, int i1)`
+  static void parallelSort$15<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? comparables,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$comparables = comparables?.reference ?? jni$_.jNullReference;
+    _parallelSort$15(_class.reference.pointer, _id_parallelSort$15.pointer,
+            _$comparables.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_parallelSort$16 = _class.staticMethodId(
+    r'parallelSort',
+    r'([Ljava/lang/Object;IILjava/util/Comparator;)V',
+  );
+
+  static final _parallelSort$16 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSort(T[] objects, int i, int i1, java.util.Comparator<? super T> comparator)`
+  static void parallelSort$16<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JObject? comparator,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
+    _parallelSort$16(_class.reference.pointer, _id_parallelSort$16.pointer,
+            _$objects.pointer, i, i1, _$comparator.pointer)
+        .check();
+  }
+
+  static final _id_parallelSort$17 = _class.staticMethodId(
+    r'parallelSort',
+    r'([Ljava/lang/Object;Ljava/util/Comparator;)V',
+  );
+
+  static final _parallelSort$17 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void parallelSort(T[] objects, java.util.Comparator<? super T> comparator)`
+  static void parallelSort$17<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    jni$_.JObject? comparator,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
+    _parallelSort$17(_class.reference.pointer, _id_parallelSort$17.pointer,
+            _$objects.pointer, _$comparator.pointer)
+        .check();
+  }
+
+  static final _id_setAll = _class.staticMethodId(
+    r'setAll',
+    r'([DLjava/util/function/IntToDoubleFunction;)V',
+  );
+
+  static final _setAll = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void setAll(double[] ds, java.util.function.IntToDoubleFunction intToDoubleFunction)`
+  static void setAll(
+    jni$_.JDoubleArray? ds,
+    jni$_.JObject? intToDoubleFunction,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    final _$intToDoubleFunction =
+        intToDoubleFunction?.reference ?? jni$_.jNullReference;
+    _setAll(_class.reference.pointer, _id_setAll.pointer, _$ds.pointer,
+            _$intToDoubleFunction.pointer)
+        .check();
+  }
+
+  static final _id_setAll$1 = _class.staticMethodId(
+    r'setAll',
+    r'([ILjava/util/function/IntUnaryOperator;)V',
+  );
+
+  static final _setAll$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void setAll(int[] is, java.util.function.IntUnaryOperator intUnaryOperator)`
+  static void setAll$1(
+    jni$_.JIntArray? is$,
+    jni$_.JObject? intUnaryOperator,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    final _$intUnaryOperator =
+        intUnaryOperator?.reference ?? jni$_.jNullReference;
+    _setAll$1(_class.reference.pointer, _id_setAll$1.pointer, _$is$.pointer,
             _$intUnaryOperator.pointer)
         .check();
   }
@@ -33583,52 +29435,14 @@
     final _$js = js?.reference ?? jni$_.jNullReference;
     final _$intToLongFunction =
         intToLongFunction?.reference ?? jni$_.jNullReference;
-    _setAll$2(_class.reference.pointer, _id_setAll$2 as jni$_.JMethodIDPtr,
-            _$js.pointer, _$intToLongFunction.pointer)
-        .check();
-  }
-
-  static final _id_parallelSetAll$2 = _class.staticMethodId(
-    r'parallelSetAll',
-    r'([JLjava/util/function/IntToLongFunction;)V',
-  );
-
-  static final _parallelSetAll$2 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JThrowablePtr Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticVoidMethod')
-      .asFunction<
-          jni$_.JThrowablePtr Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public void parallelSetAll(long[] js, java.util.function.IntToLongFunction intToLongFunction)`
-  static void parallelSetAll$2(
-    jni$_.JLongArray? js,
-    jni$_.JObject? intToLongFunction,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    final _$intToLongFunction =
-        intToLongFunction?.reference ?? jni$_.jNullReference;
-    _parallelSetAll$2(
-            _class.reference.pointer,
-            _id_parallelSetAll$2 as jni$_.JMethodIDPtr,
-            _$js.pointer,
+    _setAll$2(_class.reference.pointer, _id_setAll$2.pointer, _$js.pointer,
             _$intToLongFunction.pointer)
         .check();
   }
 
   static final _id_setAll$3 = _class.staticMethodId(
     r'setAll',
-    r'([DLjava/util/function/IntToDoubleFunction;)V',
+    r'([Ljava/lang/Object;Ljava/util/function/IntFunction;)V',
   );
 
   static final _setAll$3 = jni$_.ProtectedJniExtensions.lookup<
@@ -33648,25 +29462,541 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public void setAll(double[] ds, java.util.function.IntToDoubleFunction intToDoubleFunction)`
-  static void setAll$3(
-    jni$_.JDoubleArray? ds,
-    jni$_.JObject? intToDoubleFunction,
+  /// from: `static public void setAll(T[] objects, java.util.function.IntFunction<? extends T> intFunction)`
+  static void setAll$3<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    jni$_.JObject? intFunction,
   ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    final _$intToDoubleFunction =
-        intToDoubleFunction?.reference ?? jni$_.jNullReference;
-    _setAll$3(_class.reference.pointer, _id_setAll$3 as jni$_.JMethodIDPtr,
-            _$ds.pointer, _$intToDoubleFunction.pointer)
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$intFunction = intFunction?.reference ?? jni$_.jNullReference;
+    _setAll$3(_class.reference.pointer, _id_setAll$3.pointer, _$objects.pointer,
+            _$intFunction.pointer)
         .check();
   }
 
-  static final _id_parallelSetAll$3 = _class.staticMethodId(
-    r'parallelSetAll',
-    r'([DLjava/util/function/IntToDoubleFunction;)V',
+  static final _id_sort = _class.staticMethodId(
+    r'sort',
+    r'([B)V',
   );
 
-  static final _parallelSetAll$3 = jni$_.ProtectedJniExtensions.lookup<
+  static final _sort = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void sort(byte[] bs)`
+  static void sort(
+    jni$_.JByteArray? bs,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    _sort(_class.reference.pointer, _id_sort.pointer, _$bs.pointer).check();
+  }
+
+  static final _id_sort$1 = _class.staticMethodId(
+    r'sort',
+    r'([BII)V',
+  );
+
+  static final _sort$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void sort(byte[] bs, int i, int i1)`
+  static void sort$1(
+    jni$_.JByteArray? bs,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$bs = bs?.reference ?? jni$_.jNullReference;
+    _sort$1(_class.reference.pointer, _id_sort$1.pointer, _$bs.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_sort$2 = _class.staticMethodId(
+    r'sort',
+    r'([C)V',
+  );
+
+  static final _sort$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void sort(char[] cs)`
+  static void sort$2(
+    jni$_.JCharArray? cs,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    _sort$2(_class.reference.pointer, _id_sort$2.pointer, _$cs.pointer).check();
+  }
+
+  static final _id_sort$3 = _class.staticMethodId(
+    r'sort',
+    r'([CII)V',
+  );
+
+  static final _sort$3 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void sort(char[] cs, int i, int i1)`
+  static void sort$3(
+    jni$_.JCharArray? cs,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$cs = cs?.reference ?? jni$_.jNullReference;
+    _sort$3(_class.reference.pointer, _id_sort$3.pointer, _$cs.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_sort$4 = _class.staticMethodId(
+    r'sort',
+    r'([D)V',
+  );
+
+  static final _sort$4 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void sort(double[] ds)`
+  static void sort$4(
+    jni$_.JDoubleArray? ds,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    _sort$4(_class.reference.pointer, _id_sort$4.pointer, _$ds.pointer).check();
+  }
+
+  static final _id_sort$5 = _class.staticMethodId(
+    r'sort',
+    r'([DII)V',
+  );
+
+  static final _sort$5 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void sort(double[] ds, int i, int i1)`
+  static void sort$5(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    _sort$5(_class.reference.pointer, _id_sort$5.pointer, _$ds.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_sort$6 = _class.staticMethodId(
+    r'sort',
+    r'([F)V',
+  );
+
+  static final _sort$6 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void sort(float[] fs)`
+  static void sort$6(
+    jni$_.JFloatArray? fs,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    _sort$6(_class.reference.pointer, _id_sort$6.pointer, _$fs.pointer).check();
+  }
+
+  static final _id_sort$7 = _class.staticMethodId(
+    r'sort',
+    r'([FII)V',
+  );
+
+  static final _sort$7 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void sort(float[] fs, int i, int i1)`
+  static void sort$7(
+    jni$_.JFloatArray? fs,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    _sort$7(_class.reference.pointer, _id_sort$7.pointer, _$fs.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_sort$8 = _class.staticMethodId(
+    r'sort',
+    r'([I)V',
+  );
+
+  static final _sort$8 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void sort(int[] is)`
+  static void sort$8(
+    jni$_.JIntArray? is$,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    _sort$8(_class.reference.pointer, _id_sort$8.pointer, _$is$.pointer)
+        .check();
+  }
+
+  static final _id_sort$9 = _class.staticMethodId(
+    r'sort',
+    r'([III)V',
+  );
+
+  static final _sort$9 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void sort(int[] is, int i, int i1)`
+  static void sort$9(
+    jni$_.JIntArray? is$,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    _sort$9(_class.reference.pointer, _id_sort$9.pointer, _$is$.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_sort$10 = _class.staticMethodId(
+    r'sort',
+    r'([Ljava/lang/Object;)V',
+  );
+
+  static final _sort$10 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void sort(java.lang.Object[] objects)`
+  static void sort$10(
+    jni$_.JArray<jni$_.JObject?>? objects,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    _sort$10(_class.reference.pointer, _id_sort$10.pointer, _$objects.pointer)
+        .check();
+  }
+
+  static final _id_sort$11 = _class.staticMethodId(
+    r'sort',
+    r'([Ljava/lang/Object;II)V',
+  );
+
+  static final _sort$11 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void sort(java.lang.Object[] objects, int i, int i1)`
+  static void sort$11(
+    jni$_.JArray<jni$_.JObject?>? objects,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    _sort$11(_class.reference.pointer, _id_sort$11.pointer, _$objects.pointer,
+            i, i1)
+        .check();
+  }
+
+  static final _id_sort$12 = _class.staticMethodId(
+    r'sort',
+    r'([J)V',
+  );
+
+  static final _sort$12 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void sort(long[] js)`
+  static void sort$12(
+    jni$_.JLongArray? js,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    _sort$12(_class.reference.pointer, _id_sort$12.pointer, _$js.pointer)
+        .check();
+  }
+
+  static final _id_sort$13 = _class.staticMethodId(
+    r'sort',
+    r'([JII)V',
+  );
+
+  static final _sort$13 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void sort(long[] js, int i, int i1)`
+  static void sort$13(
+    jni$_.JLongArray? js,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    _sort$13(_class.reference.pointer, _id_sort$13.pointer, _$js.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_sort$14 = _class.staticMethodId(
+    r'sort',
+    r'([S)V',
+  );
+
+  static final _sort$14 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void sort(short[] ss)`
+  static void sort$14(
+    jni$_.JShortArray? ss,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    _sort$14(_class.reference.pointer, _id_sort$14.pointer, _$ss.pointer)
+        .check();
+  }
+
+  static final _id_sort$15 = _class.staticMethodId(
+    r'sort',
+    r'([SII)V',
+  );
+
+  static final _sort$15 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
+
+  /// from: `static public void sort(short[] ss, int i, int i1)`
+  static void sort$15(
+    jni$_.JShortArray? ss,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    _sort$15(_class.reference.pointer, _id_sort$15.pointer, _$ss.pointer, i, i1)
+        .check();
+  }
+
+  static final _id_sort$16 = _class.staticMethodId(
+    r'sort',
+    r'([Ljava/lang/Object;IILjava/util/Comparator;)V',
+  );
+
+  static final _sort$16 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Int32,
+                        jni$_.Int32,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_CallStaticVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public void sort(T[] objects, int i, int i1, java.util.Comparator<? super T> comparator)`
+  static void sort$16<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    core$_.int i,
+    core$_.int i1,
+    jni$_.JObject? comparator,
+  ) {
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
+    _sort$16(_class.reference.pointer, _id_sort$16.pointer, _$objects.pointer,
+            i, i1, _$comparator.pointer)
+        .check();
+  }
+
+  static final _id_sort$17 = _class.staticMethodId(
+    r'sort',
+    r'([Ljava/lang/Object;Ljava/util/Comparator;)V',
+  );
+
+  static final _sort$17 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JThrowablePtr Function(
                   jni$_.Pointer<jni$_.Void>,
@@ -33683,25 +30013,21 @@
               jni$_.Pointer<jni$_.Void>,
               jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public void parallelSetAll(double[] ds, java.util.function.IntToDoubleFunction intToDoubleFunction)`
-  static void parallelSetAll$3(
-    jni$_.JDoubleArray? ds,
-    jni$_.JObject? intToDoubleFunction,
+  /// from: `static public void sort(T[] objects, java.util.Comparator<? super T> comparator)`
+  static void sort$17<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    jni$_.JObject? comparator,
   ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    final _$intToDoubleFunction =
-        intToDoubleFunction?.reference ?? jni$_.jNullReference;
-    _parallelSetAll$3(
-            _class.reference.pointer,
-            _id_parallelSetAll$3 as jni$_.JMethodIDPtr,
-            _$ds.pointer,
-            _$intToDoubleFunction.pointer)
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
+    _sort$17(_class.reference.pointer, _id_sort$17.pointer, _$objects.pointer,
+            _$comparator.pointer)
         .check();
   }
 
   static final _id_spliterator = _class.staticMethodId(
     r'spliterator',
-    r'([Ljava/lang/Object;)Ljava/util/Spliterator;',
+    r'([D)Ljava/util/Spliterator$OfDouble;',
   );
 
   static final _spliterator = jni$_.ProtectedJniExtensions.lookup<
@@ -33715,21 +30041,20 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public java.util.Spliterator spliterator(java.lang.Object[] objects)`
+  /// from: `static public java.util.Spliterator$OfDouble spliterator(double[] ds)`
   /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JObject? spliterator<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    return _spliterator(_class.reference.pointer,
-            _id_spliterator as jni$_.JMethodIDPtr, _$objects.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  static jni$_.JObject? spliterator(
+    jni$_.JDoubleArray? ds,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    return _spliterator(
+            _class.reference.pointer, _id_spliterator.pointer, _$ds.pointer)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_spliterator$1 = _class.staticMethodId(
     r'spliterator',
-    r'([Ljava/lang/Object;II)Ljava/util/Spliterator;',
+    r'([DII)Ljava/util/Spliterator$OfDouble;',
   );
 
   static final _spliterator$1 = jni$_.ProtectedJniExtensions.lookup<
@@ -33744,21 +30069,24 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `static public java.util.Spliterator spliterator(java.lang.Object[] objects, int i, int i1)`
+  /// from: `static public java.util.Spliterator$OfDouble spliterator(double[] ds, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JObject? spliterator$1<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    int i,
-    int i1, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    return _spliterator$1(_class.reference.pointer,
-            _id_spliterator$1 as jni$_.JMethodIDPtr, _$objects.pointer, i, i1)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  static jni$_.JObject? spliterator$1(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    return _spliterator$1(_class.reference.pointer, _id_spliterator$1.pointer,
+            _$ds.pointer, i, i1)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_spliterator$2 = _class.staticMethodId(
@@ -33783,9 +30111,9 @@
     jni$_.JIntArray? is$,
   ) {
     final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    return _spliterator$2(_class.reference.pointer,
-            _id_spliterator$2 as jni$_.JMethodIDPtr, _$is$.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _spliterator$2(
+            _class.reference.pointer, _id_spliterator$2.pointer, _$is$.pointer)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_spliterator$3 = _class.staticMethodId(
@@ -33805,20 +30133,24 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
   /// from: `static public java.util.Spliterator$OfInt spliterator(int[] is, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JObject? spliterator$3(
     jni$_.JIntArray? is$,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    return _spliterator$3(_class.reference.pointer,
-            _id_spliterator$3 as jni$_.JMethodIDPtr, _$is$.pointer, i, i1)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _spliterator$3(_class.reference.pointer, _id_spliterator$3.pointer,
+            _$is$.pointer, i, i1)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_spliterator$4 = _class.staticMethodId(
@@ -33843,9 +30175,9 @@
     jni$_.JLongArray? js,
   ) {
     final _$js = js?.reference ?? jni$_.jNullReference;
-    return _spliterator$4(_class.reference.pointer,
-            _id_spliterator$4 as jni$_.JMethodIDPtr, _$js.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _spliterator$4(
+            _class.reference.pointer, _id_spliterator$4.pointer, _$js.pointer)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_spliterator$5 = _class.staticMethodId(
@@ -33865,25 +30197,29 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
   /// from: `static public java.util.Spliterator$OfLong spliterator(long[] js, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JObject? spliterator$5(
     jni$_.JLongArray? js,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$js = js?.reference ?? jni$_.jNullReference;
-    return _spliterator$5(_class.reference.pointer,
-            _id_spliterator$5 as jni$_.JMethodIDPtr, _$js.pointer, i, i1)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _spliterator$5(_class.reference.pointer, _id_spliterator$5.pointer,
+            _$js.pointer, i, i1)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_spliterator$6 = _class.staticMethodId(
     r'spliterator',
-    r'([D)Ljava/util/Spliterator$OfDouble;',
+    r'([Ljava/lang/Object;)Ljava/util/Spliterator;',
   );
 
   static final _spliterator$6 = jni$_.ProtectedJniExtensions.lookup<
@@ -33897,20 +30233,20 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public java.util.Spliterator$OfDouble spliterator(double[] ds)`
+  /// from: `static public java.util.Spliterator<T> spliterator(T[] objects)`
   /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JObject? spliterator$6(
-    jni$_.JDoubleArray? ds,
+  static jni$_.JObject? spliterator$6<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
   ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    return _spliterator$6(_class.reference.pointer,
-            _id_spliterator$6 as jni$_.JMethodIDPtr, _$ds.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    return _spliterator$6(_class.reference.pointer, _id_spliterator$6.pointer,
+            _$objects.pointer)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_spliterator$7 = _class.staticMethodId(
     r'spliterator',
-    r'([DII)Ljava/util/Spliterator$OfDouble;',
+    r'([Ljava/lang/Object;II)Ljava/util/Spliterator;',
   );
 
   static final _spliterator$7 = jni$_.ProtectedJniExtensions.lookup<
@@ -33925,25 +30261,29 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `static public java.util.Spliterator$OfDouble spliterator(double[] ds, int i, int i1)`
+  /// from: `static public java.util.Spliterator<T> spliterator(T[] objects, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JObject? spliterator$7(
-    jni$_.JDoubleArray? ds,
-    int i,
-    int i1,
+  static jni$_.JObject? spliterator$7<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
+    core$_.int i,
+    core$_.int i1,
   ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    return _spliterator$7(_class.reference.pointer,
-            _id_spliterator$7 as jni$_.JMethodIDPtr, _$ds.pointer, i, i1)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    return _spliterator$7(_class.reference.pointer, _id_spliterator$7.pointer,
+            _$objects.pointer, i, i1)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_stream = _class.staticMethodId(
     r'stream',
-    r'([Ljava/lang/Object;)Ljava/util/stream/Stream;',
+    r'([D)Ljava/util/stream/DoubleStream;',
   );
 
   static final _stream = jni$_.ProtectedJniExtensions.lookup<
@@ -33957,21 +30297,19 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public java.util.stream.Stream stream(java.lang.Object[] objects)`
+  /// from: `static public java.util.stream.DoubleStream stream(double[] ds)`
   /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JObject? stream<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    return _stream(_class.reference.pointer, _id_stream as jni$_.JMethodIDPtr,
-            _$objects.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  static jni$_.JObject? stream(
+    jni$_.JDoubleArray? ds,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    return _stream(_class.reference.pointer, _id_stream.pointer, _$ds.pointer)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_stream$1 = _class.staticMethodId(
     r'stream',
-    r'([Ljava/lang/Object;II)Ljava/util/stream/Stream;',
+    r'([DII)Ljava/util/stream/DoubleStream;',
   );
 
   static final _stream$1 = jni$_.ProtectedJniExtensions.lookup<
@@ -33986,21 +30324,24 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `static public java.util.stream.Stream stream(java.lang.Object[] objects, int i, int i1)`
+  /// from: `static public java.util.stream.DoubleStream stream(double[] ds, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JObject? stream$1<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    int i,
-    int i1, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    return _stream$1(_class.reference.pointer,
-            _id_stream$1 as jni$_.JMethodIDPtr, _$objects.pointer, i, i1)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+  static jni$_.JObject? stream$1(
+    jni$_.JDoubleArray? ds,
+    core$_.int i,
+    core$_.int i1,
+  ) {
+    final _$ds = ds?.reference ?? jni$_.jNullReference;
+    return _stream$1(
+            _class.reference.pointer, _id_stream$1.pointer, _$ds.pointer, i, i1)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_stream$2 = _class.staticMethodId(
@@ -34025,9 +30366,9 @@
     jni$_.JIntArray? is$,
   ) {
     final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    return _stream$2(_class.reference.pointer,
-            _id_stream$2 as jni$_.JMethodIDPtr, _$is$.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _stream$2(
+            _class.reference.pointer, _id_stream$2.pointer, _$is$.pointer)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_stream$3 = _class.staticMethodId(
@@ -34047,20 +30388,24 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
   /// from: `static public java.util.stream.IntStream stream(int[] is, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JObject? stream$3(
     jni$_.JIntArray? is$,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    return _stream$3(_class.reference.pointer,
-            _id_stream$3 as jni$_.JMethodIDPtr, _$is$.pointer, i, i1)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _stream$3(_class.reference.pointer, _id_stream$3.pointer,
+            _$is$.pointer, i, i1)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_stream$4 = _class.staticMethodId(
@@ -34085,9 +30430,9 @@
     jni$_.JLongArray? js,
   ) {
     final _$js = js?.reference ?? jni$_.jNullReference;
-    return _stream$4(_class.reference.pointer,
-            _id_stream$4 as jni$_.JMethodIDPtr, _$js.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _stream$4(
+            _class.reference.pointer, _id_stream$4.pointer, _$js.pointer)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_stream$5 = _class.staticMethodId(
@@ -34107,25 +30452,29 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
   /// from: `static public java.util.stream.LongStream stream(long[] js, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
   static jni$_.JObject? stream$5(
     jni$_.JLongArray? js,
-    int i,
-    int i1,
+    core$_.int i,
+    core$_.int i1,
   ) {
     final _$js = js?.reference ?? jni$_.jNullReference;
-    return _stream$5(_class.reference.pointer,
-            _id_stream$5 as jni$_.JMethodIDPtr, _$js.pointer, i, i1)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    return _stream$5(
+            _class.reference.pointer, _id_stream$5.pointer, _$js.pointer, i, i1)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_stream$6 = _class.staticMethodId(
     r'stream',
-    r'([D)Ljava/util/stream/DoubleStream;',
+    r'([Ljava/lang/Object;)Ljava/util/stream/Stream;',
   );
 
   static final _stream$6 = jni$_.ProtectedJniExtensions.lookup<
@@ -34139,20 +30488,20 @@
           jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public java.util.stream.DoubleStream stream(double[] ds)`
+  /// from: `static public java.util.stream.Stream<T> stream(T[] objects)`
   /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JObject? stream$6(
-    jni$_.JDoubleArray? ds,
+  static jni$_.JObject? stream$6<$T extends jni$_.JObject?>(
+    jni$_.JArray<$T?>? objects,
   ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    return _stream$6(_class.reference.pointer,
-            _id_stream$6 as jni$_.JMethodIDPtr, _$ds.pointer)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
+    final _$objects = objects?.reference ?? jni$_.jNullReference;
+    return _stream$6(
+            _class.reference.pointer, _id_stream$6.pointer, _$objects.pointer)
+        .object<jni$_.JObject?>();
   }
 
   static final _id_stream$7 = _class.staticMethodId(
     r'stream',
-    r'([DII)Ljava/util/stream/DoubleStream;',
+    r'([Ljava/lang/Object;II)Ljava/util/stream/Stream;',
   );
 
   static final _stream$7 = jni$_.ProtectedJniExtensions.lookup<
@@ -34167,2274 +30516,289 @@
                         jni$_.Int32
                       )>)>>('globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>, int, int)>();
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              core$_.int,
+              core$_.int)>();
 
-  /// from: `static public java.util.stream.DoubleStream stream(double[] ds, int i, int i1)`
+  /// from: `static public java.util.stream.Stream<T> stream(T[] objects, int i, int i1)`
   /// The returned object must be released after use, by calling the [release] method.
-  static jni$_.JObject? stream$7(
-    jni$_.JDoubleArray? ds,
-    int i,
-    int i1,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    return _stream$7(_class.reference.pointer,
-            _id_stream$7 as jni$_.JMethodIDPtr, _$ds.pointer, i, i1)
-        .object<jni$_.JObject?>(const jni$_.JObjectNullableType());
-  }
-
-  static final _id_compare = _class.staticMethodId(
-    r'compare',
-    r'([Z[Z)I',
-  );
-
-  static final _compare = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compare(boolean[] zs, boolean[] zs1)`
-  static int compare(
-    jni$_.JBooleanArray? zs,
-    jni$_.JBooleanArray? zs1,
-  ) {
-    final _$zs = zs?.reference ?? jni$_.jNullReference;
-    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
-    return _compare(_class.reference.pointer, _id_compare as jni$_.JMethodIDPtr,
-            _$zs.pointer, _$zs1.pointer)
-        .integer;
-  }
-
-  static final _id_compare$1 = _class.staticMethodId(
-    r'compare',
-    r'([ZII[ZII)I',
-  );
-
-  static final _compare$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compare(boolean[] zs, int i, int i1, boolean[] zs1, int i2, int i3)`
-  static int compare$1(
-    jni$_.JBooleanArray? zs,
-    int i,
-    int i1,
-    jni$_.JBooleanArray? zs1,
-    int i2,
-    int i3,
-  ) {
-    final _$zs = zs?.reference ?? jni$_.jNullReference;
-    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
-    return _compare$1(
-            _class.reference.pointer,
-            _id_compare$1 as jni$_.JMethodIDPtr,
-            _$zs.pointer,
-            i,
-            i1,
-            _$zs1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compare$2 = _class.staticMethodId(
-    r'compare',
-    r'([B[B)I',
-  );
-
-  static final _compare$2 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compare(byte[] bs, byte[] bs1)`
-  static int compare$2(
-    jni$_.JByteArray? bs,
-    jni$_.JByteArray? bs1,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
-    return _compare$2(_class.reference.pointer,
-            _id_compare$2 as jni$_.JMethodIDPtr, _$bs.pointer, _$bs1.pointer)
-        .integer;
-  }
-
-  static final _id_compare$3 = _class.staticMethodId(
-    r'compare',
-    r'([BII[BII)I',
-  );
-
-  static final _compare$3 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compare(byte[] bs, int i, int i1, byte[] bs1, int i2, int i3)`
-  static int compare$3(
-    jni$_.JByteArray? bs,
-    int i,
-    int i1,
-    jni$_.JByteArray? bs1,
-    int i2,
-    int i3,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
-    return _compare$3(
-            _class.reference.pointer,
-            _id_compare$3 as jni$_.JMethodIDPtr,
-            _$bs.pointer,
-            i,
-            i1,
-            _$bs1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compareUnsigned = _class.staticMethodId(
-    r'compareUnsigned',
-    r'([B[B)I',
-  );
-
-  static final _compareUnsigned = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compareUnsigned(byte[] bs, byte[] bs1)`
-  static int compareUnsigned(
-    jni$_.JByteArray? bs,
-    jni$_.JByteArray? bs1,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
-    return _compareUnsigned(
-            _class.reference.pointer,
-            _id_compareUnsigned as jni$_.JMethodIDPtr,
-            _$bs.pointer,
-            _$bs1.pointer)
-        .integer;
-  }
-
-  static final _id_compareUnsigned$1 = _class.staticMethodId(
-    r'compareUnsigned',
-    r'([BII[BII)I',
-  );
-
-  static final _compareUnsigned$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compareUnsigned(byte[] bs, int i, int i1, byte[] bs1, int i2, int i3)`
-  static int compareUnsigned$1(
-    jni$_.JByteArray? bs,
-    int i,
-    int i1,
-    jni$_.JByteArray? bs1,
-    int i2,
-    int i3,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
-    return _compareUnsigned$1(
-            _class.reference.pointer,
-            _id_compareUnsigned$1 as jni$_.JMethodIDPtr,
-            _$bs.pointer,
-            i,
-            i1,
-            _$bs1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compare$4 = _class.staticMethodId(
-    r'compare',
-    r'([S[S)I',
-  );
-
-  static final _compare$4 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compare(short[] ss, short[] ss1)`
-  static int compare$4(
-    jni$_.JShortArray? ss,
-    jni$_.JShortArray? ss1,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
-    return _compare$4(_class.reference.pointer,
-            _id_compare$4 as jni$_.JMethodIDPtr, _$ss.pointer, _$ss1.pointer)
-        .integer;
-  }
-
-  static final _id_compare$5 = _class.staticMethodId(
-    r'compare',
-    r'([SII[SII)I',
-  );
-
-  static final _compare$5 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compare(short[] ss, int i, int i1, short[] ss1, int i2, int i3)`
-  static int compare$5(
-    jni$_.JShortArray? ss,
-    int i,
-    int i1,
-    jni$_.JShortArray? ss1,
-    int i2,
-    int i3,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
-    return _compare$5(
-            _class.reference.pointer,
-            _id_compare$5 as jni$_.JMethodIDPtr,
-            _$ss.pointer,
-            i,
-            i1,
-            _$ss1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compareUnsigned$2 = _class.staticMethodId(
-    r'compareUnsigned',
-    r'([S[S)I',
-  );
-
-  static final _compareUnsigned$2 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compareUnsigned(short[] ss, short[] ss1)`
-  static int compareUnsigned$2(
-    jni$_.JShortArray? ss,
-    jni$_.JShortArray? ss1,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
-    return _compareUnsigned$2(
-            _class.reference.pointer,
-            _id_compareUnsigned$2 as jni$_.JMethodIDPtr,
-            _$ss.pointer,
-            _$ss1.pointer)
-        .integer;
-  }
-
-  static final _id_compareUnsigned$3 = _class.staticMethodId(
-    r'compareUnsigned',
-    r'([SII[SII)I',
-  );
-
-  static final _compareUnsigned$3 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compareUnsigned(short[] ss, int i, int i1, short[] ss1, int i2, int i3)`
-  static int compareUnsigned$3(
-    jni$_.JShortArray? ss,
-    int i,
-    int i1,
-    jni$_.JShortArray? ss1,
-    int i2,
-    int i3,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
-    return _compareUnsigned$3(
-            _class.reference.pointer,
-            _id_compareUnsigned$3 as jni$_.JMethodIDPtr,
-            _$ss.pointer,
-            i,
-            i1,
-            _$ss1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compare$6 = _class.staticMethodId(
-    r'compare',
-    r'([C[C)I',
-  );
-
-  static final _compare$6 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compare(char[] cs, char[] cs1)`
-  static int compare$6(
-    jni$_.JCharArray? cs,
-    jni$_.JCharArray? cs1,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
-    return _compare$6(_class.reference.pointer,
-            _id_compare$6 as jni$_.JMethodIDPtr, _$cs.pointer, _$cs1.pointer)
-        .integer;
-  }
-
-  static final _id_compare$7 = _class.staticMethodId(
-    r'compare',
-    r'([CII[CII)I',
-  );
-
-  static final _compare$7 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compare(char[] cs, int i, int i1, char[] cs1, int i2, int i3)`
-  static int compare$7(
-    jni$_.JCharArray? cs,
-    int i,
-    int i1,
-    jni$_.JCharArray? cs1,
-    int i2,
-    int i3,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
-    return _compare$7(
-            _class.reference.pointer,
-            _id_compare$7 as jni$_.JMethodIDPtr,
-            _$cs.pointer,
-            i,
-            i1,
-            _$cs1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compare$8 = _class.staticMethodId(
-    r'compare',
-    r'([I[I)I',
-  );
-
-  static final _compare$8 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compare(int[] is, int[] is1)`
-  static int compare$8(
-    jni$_.JIntArray? is$,
-    jni$_.JIntArray? is1,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    final _$is1 = is1?.reference ?? jni$_.jNullReference;
-    return _compare$8(_class.reference.pointer,
-            _id_compare$8 as jni$_.JMethodIDPtr, _$is$.pointer, _$is1.pointer)
-        .integer;
-  }
-
-  static final _id_compare$9 = _class.staticMethodId(
-    r'compare',
-    r'([III[III)I',
-  );
-
-  static final _compare$9 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compare(int[] is, int i, int i1, int[] is1, int i2, int i3)`
-  static int compare$9(
-    jni$_.JIntArray? is$,
-    int i,
-    int i1,
-    jni$_.JIntArray? is1,
-    int i2,
-    int i3,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    final _$is1 = is1?.reference ?? jni$_.jNullReference;
-    return _compare$9(
-            _class.reference.pointer,
-            _id_compare$9 as jni$_.JMethodIDPtr,
-            _$is$.pointer,
-            i,
-            i1,
-            _$is1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compareUnsigned$4 = _class.staticMethodId(
-    r'compareUnsigned',
-    r'([I[I)I',
-  );
-
-  static final _compareUnsigned$4 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compareUnsigned(int[] is, int[] is1)`
-  static int compareUnsigned$4(
-    jni$_.JIntArray? is$,
-    jni$_.JIntArray? is1,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    final _$is1 = is1?.reference ?? jni$_.jNullReference;
-    return _compareUnsigned$4(
-            _class.reference.pointer,
-            _id_compareUnsigned$4 as jni$_.JMethodIDPtr,
-            _$is$.pointer,
-            _$is1.pointer)
-        .integer;
-  }
-
-  static final _id_compareUnsigned$5 = _class.staticMethodId(
-    r'compareUnsigned',
-    r'([III[III)I',
-  );
-
-  static final _compareUnsigned$5 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compareUnsigned(int[] is, int i, int i1, int[] is1, int i2, int i3)`
-  static int compareUnsigned$5(
-    jni$_.JIntArray? is$,
-    int i,
-    int i1,
-    jni$_.JIntArray? is1,
-    int i2,
-    int i3,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    final _$is1 = is1?.reference ?? jni$_.jNullReference;
-    return _compareUnsigned$5(
-            _class.reference.pointer,
-            _id_compareUnsigned$5 as jni$_.JMethodIDPtr,
-            _$is$.pointer,
-            i,
-            i1,
-            _$is1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compare$10 = _class.staticMethodId(
-    r'compare',
-    r'([J[J)I',
-  );
-
-  static final _compare$10 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compare(long[] js, long[] js1)`
-  static int compare$10(
-    jni$_.JLongArray? js,
-    jni$_.JLongArray? js1,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    final _$js1 = js1?.reference ?? jni$_.jNullReference;
-    return _compare$10(_class.reference.pointer,
-            _id_compare$10 as jni$_.JMethodIDPtr, _$js.pointer, _$js1.pointer)
-        .integer;
-  }
-
-  static final _id_compare$11 = _class.staticMethodId(
-    r'compare',
-    r'([JII[JII)I',
-  );
-
-  static final _compare$11 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compare(long[] js, int i, int i1, long[] js1, int i2, int i3)`
-  static int compare$11(
-    jni$_.JLongArray? js,
-    int i,
-    int i1,
-    jni$_.JLongArray? js1,
-    int i2,
-    int i3,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    final _$js1 = js1?.reference ?? jni$_.jNullReference;
-    return _compare$11(
-            _class.reference.pointer,
-            _id_compare$11 as jni$_.JMethodIDPtr,
-            _$js.pointer,
-            i,
-            i1,
-            _$js1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compareUnsigned$6 = _class.staticMethodId(
-    r'compareUnsigned',
-    r'([J[J)I',
-  );
-
-  static final _compareUnsigned$6 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compareUnsigned(long[] js, long[] js1)`
-  static int compareUnsigned$6(
-    jni$_.JLongArray? js,
-    jni$_.JLongArray? js1,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    final _$js1 = js1?.reference ?? jni$_.jNullReference;
-    return _compareUnsigned$6(
-            _class.reference.pointer,
-            _id_compareUnsigned$6 as jni$_.JMethodIDPtr,
-            _$js.pointer,
-            _$js1.pointer)
-        .integer;
-  }
-
-  static final _id_compareUnsigned$7 = _class.staticMethodId(
-    r'compareUnsigned',
-    r'([JII[JII)I',
-  );
-
-  static final _compareUnsigned$7 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compareUnsigned(long[] js, int i, int i1, long[] js1, int i2, int i3)`
-  static int compareUnsigned$7(
-    jni$_.JLongArray? js,
-    int i,
-    int i1,
-    jni$_.JLongArray? js1,
-    int i2,
-    int i3,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    final _$js1 = js1?.reference ?? jni$_.jNullReference;
-    return _compareUnsigned$7(
-            _class.reference.pointer,
-            _id_compareUnsigned$7 as jni$_.JMethodIDPtr,
-            _$js.pointer,
-            i,
-            i1,
-            _$js1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compare$12 = _class.staticMethodId(
-    r'compare',
-    r'([F[F)I',
-  );
-
-  static final _compare$12 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compare(float[] fs, float[] fs1)`
-  static int compare$12(
-    jni$_.JFloatArray? fs,
-    jni$_.JFloatArray? fs1,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
-    return _compare$12(_class.reference.pointer,
-            _id_compare$12 as jni$_.JMethodIDPtr, _$fs.pointer, _$fs1.pointer)
-        .integer;
-  }
-
-  static final _id_compare$13 = _class.staticMethodId(
-    r'compare',
-    r'([FII[FII)I',
-  );
-
-  static final _compare$13 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compare(float[] fs, int i, int i1, float[] fs1, int i2, int i3)`
-  static int compare$13(
-    jni$_.JFloatArray? fs,
-    int i,
-    int i1,
-    jni$_.JFloatArray? fs1,
-    int i2,
-    int i3,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
-    return _compare$13(
-            _class.reference.pointer,
-            _id_compare$13 as jni$_.JMethodIDPtr,
-            _$fs.pointer,
-            i,
-            i1,
-            _$fs1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compare$14 = _class.staticMethodId(
-    r'compare',
-    r'([D[D)I',
-  );
-
-  static final _compare$14 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compare(double[] ds, double[] ds1)`
-  static int compare$14(
-    jni$_.JDoubleArray? ds,
-    jni$_.JDoubleArray? ds1,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
-    return _compare$14(_class.reference.pointer,
-            _id_compare$14 as jni$_.JMethodIDPtr, _$ds.pointer, _$ds1.pointer)
-        .integer;
-  }
-
-  static final _id_compare$15 = _class.staticMethodId(
-    r'compare',
-    r'([DII[DII)I',
-  );
-
-  static final _compare$15 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compare(double[] ds, int i, int i1, double[] ds1, int i2, int i3)`
-  static int compare$15(
-    jni$_.JDoubleArray? ds,
-    int i,
-    int i1,
-    jni$_.JDoubleArray? ds1,
-    int i2,
-    int i3,
-  ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
-    return _compare$15(
-            _class.reference.pointer,
-            _id_compare$15 as jni$_.JMethodIDPtr,
-            _$ds.pointer,
-            i,
-            i1,
-            _$ds1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compare$16 = _class.staticMethodId(
-    r'compare',
-    r'([Ljava/lang/Comparable;[Ljava/lang/Comparable;)I',
-  );
-
-  static final _compare$16 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compare(java.lang.Object[] comparables, java.lang.Object[] comparables1)`
-  static int compare$16<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? comparables,
-    jni$_.JArray<$T?>? comparables1, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$comparables = comparables?.reference ?? jni$_.jNullReference;
-    final _$comparables1 = comparables1?.reference ?? jni$_.jNullReference;
-    return _compare$16(
-            _class.reference.pointer,
-            _id_compare$16 as jni$_.JMethodIDPtr,
-            _$comparables.pointer,
-            _$comparables1.pointer)
-        .integer;
-  }
-
-  static final _id_compare$17 = _class.staticMethodId(
-    r'compare',
-    r'([Ljava/lang/Comparable;II[Ljava/lang/Comparable;II)I',
-  );
-
-  static final _compare$17 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int compare(java.lang.Object[] comparables, int i, int i1, java.lang.Object[] comparables1, int i2, int i3)`
-  static int compare$17<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? comparables,
-    int i,
-    int i1,
-    jni$_.JArray<$T?>? comparables1,
-    int i2,
-    int i3, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$comparables = comparables?.reference ?? jni$_.jNullReference;
-    final _$comparables1 = comparables1?.reference ?? jni$_.jNullReference;
-    return _compare$17(
-            _class.reference.pointer,
-            _id_compare$17 as jni$_.JMethodIDPtr,
-            _$comparables.pointer,
-            i,
-            i1,
-            _$comparables1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_compare$18 = _class.staticMethodId(
-    r'compare',
-    r'([Ljava/lang/Object;[Ljava/lang/Object;Ljava/util/Comparator;)I',
-  );
-
-  static final _compare$18 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int compare(java.lang.Object[] objects, java.lang.Object[] objects1, java.util.Comparator comparator)`
-  static int compare$18<$T extends jni$_.JObject?>(
+  static jni$_.JObject? stream$7<$T extends jni$_.JObject?>(
     jni$_.JArray<$T?>? objects,
-    jni$_.JArray<$T?>? objects1,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
+    core$_.int i,
+    core$_.int i1,
+  ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
-    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
-    return _compare$18(
-            _class.reference.pointer,
-            _id_compare$18 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            _$objects1.pointer,
-            _$comparator.pointer)
-        .integer;
+    return _stream$7(_class.reference.pointer, _id_stream$7.pointer,
+            _$objects.pointer, i, i1)
+        .object<jni$_.JObject?>();
   }
 
-  static final _id_compare$19 = _class.staticMethodId(
-    r'compare',
-    r'([Ljava/lang/Object;II[Ljava/lang/Object;IILjava/util/Comparator;)I',
+  static final _id_toString$1 = _class.staticMethodId(
+    r'toString',
+    r'([Z)Ljava/lang/String;',
   );
 
-  static final _compare$19 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
+  static final _toString$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public int compare(java.lang.Object[] objects, int i, int i1, java.lang.Object[] objects1, int i2, int i3, java.util.Comparator comparator)`
-  static int compare$19<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    int i,
-    int i1,
-    jni$_.JArray<$T?>? objects1,
-    int i2,
-    int i3,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
-    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
-    return _compare$19(
-            _class.reference.pointer,
-            _id_compare$19 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            i,
-            i1,
-            _$objects1.pointer,
-            i2,
-            i3,
-            _$comparator.pointer)
-        .integer;
-  }
-
-  static final _id_mismatch = _class.staticMethodId(
-    r'mismatch',
-    r'([Z[Z)I',
-  );
-
-  static final _mismatch = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int mismatch(boolean[] zs, boolean[] zs1)`
-  static int mismatch(
+  /// from: `static public java.lang.String toString(boolean[] zs)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JString? toString$1(
     jni$_.JBooleanArray? zs,
-    jni$_.JBooleanArray? zs1,
   ) {
     final _$zs = zs?.reference ?? jni$_.jNullReference;
-    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
-    return _mismatch(_class.reference.pointer,
-            _id_mismatch as jni$_.JMethodIDPtr, _$zs.pointer, _$zs1.pointer)
-        .integer;
+    return _toString$1(
+            _class.reference.pointer, _id_toString$1.pointer, _$zs.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_mismatch$1 = _class.staticMethodId(
-    r'mismatch',
-    r'([ZII[ZII)I',
+  static final _id_toString$2 = _class.staticMethodId(
+    r'toString',
+    r'([B)Ljava/lang/String;',
   );
 
-  static final _mismatch$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
+  static final _toString$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public int mismatch(boolean[] zs, int i, int i1, boolean[] zs1, int i2, int i3)`
-  static int mismatch$1(
-    jni$_.JBooleanArray? zs,
-    int i,
-    int i1,
-    jni$_.JBooleanArray? zs1,
-    int i2,
-    int i3,
-  ) {
-    final _$zs = zs?.reference ?? jni$_.jNullReference;
-    final _$zs1 = zs1?.reference ?? jni$_.jNullReference;
-    return _mismatch$1(
-            _class.reference.pointer,
-            _id_mismatch$1 as jni$_.JMethodIDPtr,
-            _$zs.pointer,
-            i,
-            i1,
-            _$zs1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_mismatch$2 = _class.staticMethodId(
-    r'mismatch',
-    r'([B[B)I',
-  );
-
-  static final _mismatch$2 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int mismatch(byte[] bs, byte[] bs1)`
-  static int mismatch$2(
+  /// from: `static public java.lang.String toString(byte[] bs)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JString? toString$2(
     jni$_.JByteArray? bs,
-    jni$_.JByteArray? bs1,
   ) {
     final _$bs = bs?.reference ?? jni$_.jNullReference;
-    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
-    return _mismatch$2(_class.reference.pointer,
-            _id_mismatch$2 as jni$_.JMethodIDPtr, _$bs.pointer, _$bs1.pointer)
-        .integer;
+    return _toString$2(
+            _class.reference.pointer, _id_toString$2.pointer, _$bs.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_mismatch$3 = _class.staticMethodId(
-    r'mismatch',
-    r'([BII[BII)I',
+  static final _id_toString$3 = _class.staticMethodId(
+    r'toString',
+    r'([C)Ljava/lang/String;',
   );
 
-  static final _mismatch$3 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
+  static final _toString$3 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public int mismatch(byte[] bs, int i, int i1, byte[] bs1, int i2, int i3)`
-  static int mismatch$3(
-    jni$_.JByteArray? bs,
-    int i,
-    int i1,
-    jni$_.JByteArray? bs1,
-    int i2,
-    int i3,
-  ) {
-    final _$bs = bs?.reference ?? jni$_.jNullReference;
-    final _$bs1 = bs1?.reference ?? jni$_.jNullReference;
-    return _mismatch$3(
-            _class.reference.pointer,
-            _id_mismatch$3 as jni$_.JMethodIDPtr,
-            _$bs.pointer,
-            i,
-            i1,
-            _$bs1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_mismatch$4 = _class.staticMethodId(
-    r'mismatch',
-    r'([C[C)I',
-  );
-
-  static final _mismatch$4 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int mismatch(char[] cs, char[] cs1)`
-  static int mismatch$4(
+  /// from: `static public java.lang.String toString(char[] cs)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JString? toString$3(
     jni$_.JCharArray? cs,
-    jni$_.JCharArray? cs1,
   ) {
     final _$cs = cs?.reference ?? jni$_.jNullReference;
-    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
-    return _mismatch$4(_class.reference.pointer,
-            _id_mismatch$4 as jni$_.JMethodIDPtr, _$cs.pointer, _$cs1.pointer)
-        .integer;
+    return _toString$3(
+            _class.reference.pointer, _id_toString$3.pointer, _$cs.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_mismatch$5 = _class.staticMethodId(
-    r'mismatch',
-    r'([CII[CII)I',
+  static final _id_toString$4 = _class.staticMethodId(
+    r'toString',
+    r'([D)Ljava/lang/String;',
   );
 
-  static final _mismatch$5 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
+  static final _toString$4 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public int mismatch(char[] cs, int i, int i1, char[] cs1, int i2, int i3)`
-  static int mismatch$5(
-    jni$_.JCharArray? cs,
-    int i,
-    int i1,
-    jni$_.JCharArray? cs1,
-    int i2,
-    int i3,
-  ) {
-    final _$cs = cs?.reference ?? jni$_.jNullReference;
-    final _$cs1 = cs1?.reference ?? jni$_.jNullReference;
-    return _mismatch$5(
-            _class.reference.pointer,
-            _id_mismatch$5 as jni$_.JMethodIDPtr,
-            _$cs.pointer,
-            i,
-            i1,
-            _$cs1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_mismatch$6 = _class.staticMethodId(
-    r'mismatch',
-    r'([S[S)I',
-  );
-
-  static final _mismatch$6 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int mismatch(short[] ss, short[] ss1)`
-  static int mismatch$6(
-    jni$_.JShortArray? ss,
-    jni$_.JShortArray? ss1,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
-    return _mismatch$6(_class.reference.pointer,
-            _id_mismatch$6 as jni$_.JMethodIDPtr, _$ss.pointer, _$ss1.pointer)
-        .integer;
-  }
-
-  static final _id_mismatch$7 = _class.staticMethodId(
-    r'mismatch',
-    r'([SII[SII)I',
-  );
-
-  static final _mismatch$7 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int mismatch(short[] ss, int i, int i1, short[] ss1, int i2, int i3)`
-  static int mismatch$7(
-    jni$_.JShortArray? ss,
-    int i,
-    int i1,
-    jni$_.JShortArray? ss1,
-    int i2,
-    int i3,
-  ) {
-    final _$ss = ss?.reference ?? jni$_.jNullReference;
-    final _$ss1 = ss1?.reference ?? jni$_.jNullReference;
-    return _mismatch$7(
-            _class.reference.pointer,
-            _id_mismatch$7 as jni$_.JMethodIDPtr,
-            _$ss.pointer,
-            i,
-            i1,
-            _$ss1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_mismatch$8 = _class.staticMethodId(
-    r'mismatch',
-    r'([I[I)I',
-  );
-
-  static final _mismatch$8 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int mismatch(int[] is, int[] is1)`
-  static int mismatch$8(
-    jni$_.JIntArray? is$,
-    jni$_.JIntArray? is1,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    final _$is1 = is1?.reference ?? jni$_.jNullReference;
-    return _mismatch$8(_class.reference.pointer,
-            _id_mismatch$8 as jni$_.JMethodIDPtr, _$is$.pointer, _$is1.pointer)
-        .integer;
-  }
-
-  static final _id_mismatch$9 = _class.staticMethodId(
-    r'mismatch',
-    r'([III[III)I',
-  );
-
-  static final _mismatch$9 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int mismatch(int[] is, int i, int i1, int[] is1, int i2, int i3)`
-  static int mismatch$9(
-    jni$_.JIntArray? is$,
-    int i,
-    int i1,
-    jni$_.JIntArray? is1,
-    int i2,
-    int i3,
-  ) {
-    final _$is$ = is$?.reference ?? jni$_.jNullReference;
-    final _$is1 = is1?.reference ?? jni$_.jNullReference;
-    return _mismatch$9(
-            _class.reference.pointer,
-            _id_mismatch$9 as jni$_.JMethodIDPtr,
-            _$is$.pointer,
-            i,
-            i1,
-            _$is1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_mismatch$10 = _class.staticMethodId(
-    r'mismatch',
-    r'([J[J)I',
-  );
-
-  static final _mismatch$10 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int mismatch(long[] js, long[] js1)`
-  static int mismatch$10(
-    jni$_.JLongArray? js,
-    jni$_.JLongArray? js1,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    final _$js1 = js1?.reference ?? jni$_.jNullReference;
-    return _mismatch$10(_class.reference.pointer,
-            _id_mismatch$10 as jni$_.JMethodIDPtr, _$js.pointer, _$js1.pointer)
-        .integer;
-  }
-
-  static final _id_mismatch$11 = _class.staticMethodId(
-    r'mismatch',
-    r'([JII[JII)I',
-  );
-
-  static final _mismatch$11 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int mismatch(long[] js, int i, int i1, long[] js1, int i2, int i3)`
-  static int mismatch$11(
-    jni$_.JLongArray? js,
-    int i,
-    int i1,
-    jni$_.JLongArray? js1,
-    int i2,
-    int i3,
-  ) {
-    final _$js = js?.reference ?? jni$_.jNullReference;
-    final _$js1 = js1?.reference ?? jni$_.jNullReference;
-    return _mismatch$11(
-            _class.reference.pointer,
-            _id_mismatch$11 as jni$_.JMethodIDPtr,
-            _$js.pointer,
-            i,
-            i1,
-            _$js1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_mismatch$12 = _class.staticMethodId(
-    r'mismatch',
-    r'([F[F)I',
-  );
-
-  static final _mismatch$12 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int mismatch(float[] fs, float[] fs1)`
-  static int mismatch$12(
-    jni$_.JFloatArray? fs,
-    jni$_.JFloatArray? fs1,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
-    return _mismatch$12(_class.reference.pointer,
-            _id_mismatch$12 as jni$_.JMethodIDPtr, _$fs.pointer, _$fs1.pointer)
-        .integer;
-  }
-
-  static final _id_mismatch$13 = _class.staticMethodId(
-    r'mismatch',
-    r'([FII[FII)I',
-  );
-
-  static final _mismatch$13 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
-
-  /// from: `static public int mismatch(float[] fs, int i, int i1, float[] fs1, int i2, int i3)`
-  static int mismatch$13(
-    jni$_.JFloatArray? fs,
-    int i,
-    int i1,
-    jni$_.JFloatArray? fs1,
-    int i2,
-    int i3,
-  ) {
-    final _$fs = fs?.reference ?? jni$_.jNullReference;
-    final _$fs1 = fs1?.reference ?? jni$_.jNullReference;
-    return _mismatch$13(
-            _class.reference.pointer,
-            _id_mismatch$13 as jni$_.JMethodIDPtr,
-            _$fs.pointer,
-            i,
-            i1,
-            _$fs1.pointer,
-            i2,
-            i3)
-        .integer;
-  }
-
-  static final _id_mismatch$14 = _class.staticMethodId(
-    r'mismatch',
-    r'([D[D)I',
-  );
-
-  static final _mismatch$14 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int mismatch(double[] ds, double[] ds1)`
-  static int mismatch$14(
+  /// from: `static public java.lang.String toString(double[] ds)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JString? toString$4(
     jni$_.JDoubleArray? ds,
-    jni$_.JDoubleArray? ds1,
   ) {
     final _$ds = ds?.reference ?? jni$_.jNullReference;
-    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
-    return _mismatch$14(_class.reference.pointer,
-            _id_mismatch$14 as jni$_.JMethodIDPtr, _$ds.pointer, _$ds1.pointer)
-        .integer;
+    return _toString$4(
+            _class.reference.pointer, _id_toString$4.pointer, _$ds.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_mismatch$15 = _class.staticMethodId(
-    r'mismatch',
-    r'([DII[DII)I',
+  static final _id_toString$5 = _class.staticMethodId(
+    r'toString',
+    r'([F)Ljava/lang/String;',
   );
 
-  static final _mismatch$15 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
+  static final _toString$5 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public int mismatch(double[] ds, int i, int i1, double[] ds1, int i2, int i3)`
-  static int mismatch$15(
-    jni$_.JDoubleArray? ds,
-    int i,
-    int i1,
-    jni$_.JDoubleArray? ds1,
-    int i2,
-    int i3,
+  /// from: `static public java.lang.String toString(float[] fs)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JString? toString$5(
+    jni$_.JFloatArray? fs,
   ) {
-    final _$ds = ds?.reference ?? jni$_.jNullReference;
-    final _$ds1 = ds1?.reference ?? jni$_.jNullReference;
-    return _mismatch$15(
-            _class.reference.pointer,
-            _id_mismatch$15 as jni$_.JMethodIDPtr,
-            _$ds.pointer,
-            i,
-            i1,
-            _$ds1.pointer,
-            i2,
-            i3)
-        .integer;
+    final _$fs = fs?.reference ?? jni$_.jNullReference;
+    return _toString$5(
+            _class.reference.pointer, _id_toString$5.pointer, _$fs.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_mismatch$16 = _class.staticMethodId(
-    r'mismatch',
-    r'([Ljava/lang/Object;[Ljava/lang/Object;)I',
+  static final _id_toString$6 = _class.staticMethodId(
+    r'toString',
+    r'([I)Ljava/lang/String;',
   );
 
-  static final _mismatch$16 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
+  static final _toString$6 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public int mismatch(java.lang.Object[] objects, java.lang.Object[] objects1)`
-  static int mismatch$16(
+  /// from: `static public java.lang.String toString(int[] is)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JString? toString$6(
+    jni$_.JIntArray? is$,
+  ) {
+    final _$is$ = is$?.reference ?? jni$_.jNullReference;
+    return _toString$6(
+            _class.reference.pointer, _id_toString$6.pointer, _$is$.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_toString$7 = _class.staticMethodId(
+    r'toString',
+    r'([Ljava/lang/Object;)Ljava/lang/String;',
+  );
+
+  static final _toString$7 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `static public java.lang.String toString(java.lang.Object[] objects)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JString? toString$7(
     jni$_.JArray<jni$_.JObject?>? objects,
-    jni$_.JArray<jni$_.JObject?>? objects1,
   ) {
     final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
-    return _mismatch$16(
-            _class.reference.pointer,
-            _id_mismatch$16 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            _$objects1.pointer)
-        .integer;
+    return _toString$7(
+            _class.reference.pointer, _id_toString$7.pointer, _$objects.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_mismatch$17 = _class.staticMethodId(
-    r'mismatch',
-    r'([Ljava/lang/Object;II[Ljava/lang/Object;II)I',
+  static final _id_toString$8 = _class.staticMethodId(
+    r'toString',
+    r'([J)Ljava/lang/String;',
   );
 
-  static final _mismatch$17 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32
-                      )>)>>('globalEnv_CallStaticIntMethod')
+  static final _toString$8 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int)>();
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public int mismatch(java.lang.Object[] objects, int i, int i1, java.lang.Object[] objects1, int i2, int i3)`
-  static int mismatch$17(
-    jni$_.JArray<jni$_.JObject?>? objects,
-    int i,
-    int i1,
-    jni$_.JArray<jni$_.JObject?>? objects1,
-    int i2,
-    int i3,
+  /// from: `static public java.lang.String toString(long[] js)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JString? toString$8(
+    jni$_.JLongArray? js,
   ) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
-    return _mismatch$17(
-            _class.reference.pointer,
-            _id_mismatch$17 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            i,
-            i1,
-            _$objects1.pointer,
-            i2,
-            i3)
-        .integer;
+    final _$js = js?.reference ?? jni$_.jNullReference;
+    return _toString$8(
+            _class.reference.pointer, _id_toString$8.pointer, _$js.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_mismatch$18 = _class.staticMethodId(
-    r'mismatch',
-    r'([Ljava/lang/Object;[Ljava/lang/Object;Ljava/util/Comparator;)I',
+  static final _id_toString$9 = _class.staticMethodId(
+    r'toString',
+    r'([S)Ljava/lang/String;',
   );
 
-  static final _mismatch$18 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
+  static final _toString$9 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallStaticObjectMethod')
       .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.Pointer<jni$_.Void>)>();
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
-  /// from: `static public int mismatch(java.lang.Object[] objects, java.lang.Object[] objects1, java.util.Comparator comparator)`
-  static int mismatch$18<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    jni$_.JArray<$T?>? objects1,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
-    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
-    return _mismatch$18(
-            _class.reference.pointer,
-            _id_mismatch$18 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            _$objects1.pointer,
-            _$comparator.pointer)
-        .integer;
-  }
-
-  static final _id_mismatch$19 = _class.staticMethodId(
-    r'mismatch',
-    r'([Ljava/lang/Object;II[Ljava/lang/Object;IILjava/util/Comparator;)I',
-  );
-
-  static final _mismatch$19 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                  jni$_.Pointer<jni$_.Void>,
-                  jni$_.JMethodIDPtr,
-                  jni$_.VarArgs<
-                      (
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>,
-                        jni$_.Int32,
-                        jni$_.Int32,
-                        jni$_.Pointer<jni$_.Void>
-                      )>)>>('globalEnv_CallStaticIntMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-              jni$_.Pointer<jni$_.Void>,
-              jni$_.JMethodIDPtr,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>,
-              int,
-              int,
-              jni$_.Pointer<jni$_.Void>)>();
-
-  /// from: `static public int mismatch(java.lang.Object[] objects, int i, int i1, java.lang.Object[] objects1, int i2, int i3, java.util.Comparator comparator)`
-  static int mismatch$19<$T extends jni$_.JObject?>(
-    jni$_.JArray<$T?>? objects,
-    int i,
-    int i1,
-    jni$_.JArray<$T?>? objects1,
-    int i2,
-    int i3,
-    jni$_.JObject? comparator, {
-    required jni$_.JObjType<$T> T,
-  }) {
-    final _$objects = objects?.reference ?? jni$_.jNullReference;
-    final _$objects1 = objects1?.reference ?? jni$_.jNullReference;
-    final _$comparator = comparator?.reference ?? jni$_.jNullReference;
-    return _mismatch$19(
-            _class.reference.pointer,
-            _id_mismatch$19 as jni$_.JMethodIDPtr,
-            _$objects.pointer,
-            i,
-            i1,
-            _$objects1.pointer,
-            i2,
-            i3,
-            _$comparator.pointer)
-        .integer;
+  /// from: `static public java.lang.String toString(short[] ss)`
+  /// The returned object must be released after use, by calling the [release] method.
+  static jni$_.JString? toString$9(
+    jni$_.JShortArray? ss,
+  ) {
+    final _$ss = ss?.reference ?? jni$_.jNullReference;
+    return _toString$9(
+            _class.reference.pointer, _id_toString$9.pointer, _$ss.pointer)
+        .object<jni$_.JString?>();
   }
 }
 
-final class $Arrays$NullableType extends jni$_.JObjType<Arrays?> {
+final class $Arrays$Type$ extends jni$_.JType<Arrays> {
   @jni$_.internal
-  const $Arrays$NullableType();
+  const $Arrays$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/util/Arrays;';
-
-  @jni$_.internal
-  @core$_.override
-  Arrays? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Arrays.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Arrays?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Arrays$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Arrays$NullableType) &&
-        other is $Arrays$NullableType;
-  }
-}
-
-final class $Arrays$Type extends jni$_.JObjType<Arrays> {
-  @jni$_.internal
-  const $Arrays$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/util/Arrays;';
-
-  @jni$_.internal
-  @core$_.override
-  Arrays fromReference(jni$_.JReference reference) => Arrays.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Arrays?> get nullableType => const $Arrays$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Arrays$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Arrays$Type) && other is $Arrays$Type;
-  }
 }
 
 /// from: `java.security.cert.Certificate`
-class Certificate extends jni$_.JObject {
-  @jni$_.internal
-  @core$_.override
-  final jni$_.JObjType<Certificate> $type;
-
-  @jni$_.internal
-  Certificate.fromReference(
-    jni$_.JReference reference,
-  )   : $type = type,
-        super.fromReference(reference);
-
+extension type Certificate._(jni$_.JObject _$this) implements jni$_.JObject {
   static final _class = jni$_.JClass.forName(r'java/security/cert/Certificate');
 
   /// The type which includes information such as the signature of this class.
-  static const nullableType = $Certificate$NullableType();
-  static const type = $Certificate$Type();
-  static final _id_getType = _class.instanceMethodId(
-    r'getType',
-    r'()Ljava/lang/String;',
-  );
+  static const jni$_.JType<Certificate> type = $Certificate$Type$();
+}
 
-  static final _getType = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public final java.lang.String getType()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? getType() {
-    return _getType(reference.pointer, _id_getType as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_equals = _class.instanceMethodId(
+extension Certificate$$Methods on Certificate {
+  static final _id_equals = Certificate._class.instanceMethodId(
     r'equals',
     r'(Ljava/lang/Object;)Z',
   );
@@ -36451,16 +30815,87 @@
               jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
 
   /// from: `public boolean equals(java.lang.Object object)`
-  bool equals(
+  core$_.bool equals(
     jni$_.JObject? object,
   ) {
     final _$object = object?.reference ?? jni$_.jNullReference;
-    return _equals(reference.pointer, _id_equals as jni$_.JMethodIDPtr,
-            _$object.pointer)
+    return _equals(reference.pointer, _id_equals.pointer, _$object.pointer)
         .boolean;
   }
 
-  static final _id_hashCode$1 = _class.instanceMethodId(
+  static final _id_get$encoded = Certificate._class.instanceMethodId(
+    r'getEncoded',
+    r'()[B',
+  );
+
+  static final _get$encoded = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract byte[] getEncoded()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JByteArray? get encoded {
+    return _get$encoded(reference.pointer, _id_get$encoded.pointer)
+        .object<jni$_.JByteArray?>();
+  }
+
+  static final _id_get$publicKey = Certificate._class.instanceMethodId(
+    r'getPublicKey',
+    r'()Ljava/security/PublicKey;',
+  );
+
+  static final _get$publicKey = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract java.security.PublicKey getPublicKey()`
+  /// The returned object must be released after use, by calling the [release] method.
+  PublicKey? get publicKey {
+    return _get$publicKey(reference.pointer, _id_get$publicKey.pointer)
+        .object<PublicKey?>();
+  }
+
+  static final _id_get$type$1 = Certificate._class.instanceMethodId(
+    r'getType',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _get$type$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.lang.String getType()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? get type$1 {
+    return _get$type$1(reference.pointer, _id_get$type$1.pointer)
+        .object<jni$_.JString?>();
+  }
+
+  static final _id_hashCode$1 = Certificate._class.instanceMethodId(
     r'hashCode',
     r'()I',
   );
@@ -36478,17 +30913,16 @@
           )>();
 
   /// from: `public int hashCode()`
-  int hashCode$1() {
-    return _hashCode$1(reference.pointer, _id_hashCode$1 as jni$_.JMethodIDPtr)
-        .integer;
+  core$_.int hashCode$1() {
+    return _hashCode$1(reference.pointer, _id_hashCode$1.pointer).integer;
   }
 
-  static final _id_getEncoded = _class.instanceMethodId(
-    r'getEncoded',
-    r'()[B',
+  static final _id_toString$1 = Certificate._class.instanceMethodId(
+    r'toString',
+    r'()Ljava/lang/String;',
   );
 
-  static final _getEncoded = jni$_.ProtectedJniExtensions.lookup<
+  static final _toString$1 = jni$_.ProtectedJniExtensions.lookup<
           jni$_.NativeFunction<
               jni$_.JniResult Function(
                 jni$_.Pointer<jni$_.Void>,
@@ -36500,14 +30934,14 @@
             jni$_.JMethodIDPtr,
           )>();
 
-  /// from: `public abstract byte[] getEncoded()`
+  /// from: `public abstract java.lang.String toString()`
   /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JByteArray? getEncoded() {
-    return _getEncoded(reference.pointer, _id_getEncoded as jni$_.JMethodIDPtr)
-        .object<jni$_.JByteArray?>(const jni$_.JByteArrayNullableType());
+  jni$_.JString? toString$1() {
+    return _toString$1(reference.pointer, _id_toString$1.pointer)
+        .object<jni$_.JString?>();
   }
 
-  static final _id_verify = _class.instanceMethodId(
+  static final _id_verify = Certificate._class.instanceMethodId(
     r'verify',
     r'(Ljava/security/PublicKey;)V',
   );
@@ -36528,12 +30962,10 @@
     PublicKey? publicKey,
   ) {
     final _$publicKey = publicKey?.reference ?? jni$_.jNullReference;
-    _verify(reference.pointer, _id_verify as jni$_.JMethodIDPtr,
-            _$publicKey.pointer)
-        .check();
+    _verify(reference.pointer, _id_verify.pointer, _$publicKey.pointer).check();
   }
 
-  static final _id_verify$1 = _class.instanceMethodId(
+  static final _id_verify$1 = Certificate._class.instanceMethodId(
     r'verify',
     r'(Ljava/security/PublicKey;Ljava/lang/String;)V',
   );
@@ -36562,12 +30994,12 @@
   ) {
     final _$publicKey = publicKey?.reference ?? jni$_.jNullReference;
     final _$string = string?.reference ?? jni$_.jNullReference;
-    _verify$1(reference.pointer, _id_verify$1 as jni$_.JMethodIDPtr,
-            _$publicKey.pointer, _$string.pointer)
+    _verify$1(reference.pointer, _id_verify$1.pointer, _$publicKey.pointer,
+            _$string.pointer)
         .check();
   }
 
-  static final _id_verify$2 = _class.instanceMethodId(
+  static final _id_verify$2 = Certificate._class.instanceMethodId(
     r'verify',
     r'(Ljava/security/PublicKey;Ljava/security/Provider;)V',
   );
@@ -36596,131 +31028,17 @@
   ) {
     final _$publicKey = publicKey?.reference ?? jni$_.jNullReference;
     final _$provider = provider?.reference ?? jni$_.jNullReference;
-    _verify$2(reference.pointer, _id_verify$2 as jni$_.JMethodIDPtr,
-            _$publicKey.pointer, _$provider.pointer)
+    _verify$2(reference.pointer, _id_verify$2.pointer, _$publicKey.pointer,
+            _$provider.pointer)
         .check();
   }
-
-  static final _id_toString$1 = _class.instanceMethodId(
-    r'toString',
-    r'()Ljava/lang/String;',
-  );
-
-  static final _toString$1 = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.lang.String toString()`
-  /// The returned object must be released after use, by calling the [release] method.
-  jni$_.JString? toString$1() {
-    return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr)
-        .object<jni$_.JString?>(const jni$_.JStringNullableType());
-  }
-
-  static final _id_getPublicKey = _class.instanceMethodId(
-    r'getPublicKey',
-    r'()Ljava/security/PublicKey;',
-  );
-
-  static final _getPublicKey = jni$_.ProtectedJniExtensions.lookup<
-          jni$_.NativeFunction<
-              jni$_.JniResult Function(
-                jni$_.Pointer<jni$_.Void>,
-                jni$_.JMethodIDPtr,
-              )>>('globalEnv_CallObjectMethod')
-      .asFunction<
-          jni$_.JniResult Function(
-            jni$_.Pointer<jni$_.Void>,
-            jni$_.JMethodIDPtr,
-          )>();
-
-  /// from: `public abstract java.security.PublicKey getPublicKey()`
-  /// The returned object must be released after use, by calling the [release] method.
-  PublicKey? getPublicKey() {
-    return _getPublicKey(
-            reference.pointer, _id_getPublicKey as jni$_.JMethodIDPtr)
-        .object<PublicKey?>(const $PublicKey$NullableType());
-  }
 }
 
-final class $Certificate$NullableType extends jni$_.JObjType<Certificate?> {
+final class $Certificate$Type$ extends jni$_.JType<Certificate> {
   @jni$_.internal
-  const $Certificate$NullableType();
+  const $Certificate$Type$();
 
   @jni$_.internal
   @core$_.override
   String get signature => r'Ljava/security/cert/Certificate;';
-
-  @jni$_.internal
-  @core$_.override
-  Certificate? fromReference(jni$_.JReference reference) => reference.isNull
-      ? null
-      : Certificate.fromReference(
-          reference,
-        );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Certificate?> get nullableType => this;
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Certificate$NullableType).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Certificate$NullableType) &&
-        other is $Certificate$NullableType;
-  }
-}
-
-final class $Certificate$Type extends jni$_.JObjType<Certificate> {
-  @jni$_.internal
-  const $Certificate$Type();
-
-  @jni$_.internal
-  @core$_.override
-  String get signature => r'Ljava/security/cert/Certificate;';
-
-  @jni$_.internal
-  @core$_.override
-  Certificate fromReference(jni$_.JReference reference) =>
-      Certificate.fromReference(
-        reference,
-      );
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType get superType => const jni$_.JObjectNullableType();
-
-  @jni$_.internal
-  @core$_.override
-  jni$_.JObjType<Certificate?> get nullableType =>
-      const $Certificate$NullableType();
-
-  @jni$_.internal
-  @core$_.override
-  final superCount = 1;
-
-  @core$_.override
-  int get hashCode => ($Certificate$Type).hashCode;
-
-  @core$_.override
-  bool operator ==(Object other) {
-    return other.runtimeType == ($Certificate$Type) &&
-        other is $Certificate$Type;
-  }
 }
diff --git a/pkgs/ok_http/lib/src/ok_http_client.dart b/pkgs/ok_http/lib/src/ok_http_client.dart
index e9114b4..d500ac3 100644
--- a/pkgs/ok_http/lib/src/ok_http_client.dart
+++ b/pkgs/ok_http/lib/src/ok_http_client.dart
@@ -16,16 +16,18 @@
 import 'dart:io';
 import 'dart:typed_data';
 
+import 'package:flutter/foundation.dart' show PlatformDispatcher;
 import 'package:http/http.dart';
 import 'package:http_profile/http_profile.dart';
 import 'package:jni/jni.dart';
+import 'package:jni_flutter/jni_flutter.dart';
 
 import 'jni/bindings.dart' as bindings;
 import 'jni/bindings.dart' show PrivateKey, X509Certificate;
 
 class _JavaIOException extends IOException {
   final String _message;
-  _JavaIOException(JniException e) : _message = e.message;
+  _JavaIOException(JThrowable e) : _message = e.message;
 
   @override
   String toString() => _message;
@@ -38,9 +40,9 @@
         checkServerTrusted: (chain, authType) {},
         getAcceptedIssuers: () {
           final factory = bindings.TrustManagerFactory.getInstance(
-              bindings.TrustManagerFactory.getDefaultAlgorithm());
+              bindings.TrustManagerFactory.defaultAlgorithm);
           factory!.init(null);
-          return JArray(bindings.X509Certificate.nullableType, 0);
+          return JArray.withLength(bindings.X509Certificate.type, 0);
         })).as(bindings.TrustManager.type);
 
 /// Configurations for the [OkHttpClient].
@@ -111,8 +113,8 @@
   JObject? activity,
 }) async {
   final c = Completer<String?>();
-  activity ??= JObject.fromReference(Jni.getCurrentActivity());
-  bindings.KeyChain.choosePrivateKeyAlias(activity,
+  activity ??= androidActivity(PlatformDispatcher.instance.engineId!);
+  bindings.KeyChain.choosePrivateKeyAlias$1(activity,
       bindings.KeyChainAliasCallback.implement(
           bindings.$KeyChainAliasCallback(alias: (alias) {
     c.complete(alias?.toDartString());
@@ -126,12 +128,12 @@
 (PrivateKey, List<X509Certificate>) loadPrivateKeyAndCertificateChainFromAlias(
     String alias,
     {JObject? context}) {
-  context ??= JObject.fromReference(Jni.getCachedApplicationContext());
+  context ??= androidApplicationContext;
   final jAlias = alias.toJString();
   final pk = bindings.KeyChain.getPrivateKey(context, jAlias)!;
   final chain = bindings.KeyChain.getCertificateChain(context, jAlias)!;
 
-  return (pk, chain.toList().cast<X509Certificate>());
+  return (pk, chain.asDart().cast<X509Certificate>());
 }
 
 /// Load a [PrivateKey] and certificate chain from a PKCS 12 archive.
@@ -141,8 +143,8 @@
 (PrivateKey, List<X509Certificate>) loadPrivateKeyAndCertificateChainFromPKCS12(
     Uint8List pkcs12Data, String password,
     {JObject? context}) {
-  context ??= JObject.fromReference(Jni.getCachedApplicationContext());
-  var keyStore = bindings.KeyStore.getInstance('PKCS12'.toJString())!;
+  context ??= androidApplicationContext;
+  var keyStore = bindings.KeyStore.getInstance$2('PKCS12'.toJString())!;
 
   final jPassword = JCharArray(password.length);
   for (var i = 0; i < password.length; ++i) {
@@ -150,8 +152,8 @@
   }
   try {
     keyStore.load(
-        bindings.ByteArrayInputStream(JByteArray.from(pkcs12Data)), jPassword);
-  } on JniException catch (e) {
+        bindings.ByteArrayInputStream(JByteArray.of(pkcs12Data)), jPassword);
+  } on JThrowable catch (e) {
     if (e.message.contains('java.io.IOException')) {
       throw _JavaIOException(e);
     }
@@ -181,7 +183,7 @@
     throw ArgumentError('certificate key is not a PrivateKey', 'pkcs12Data');
   }
 
-  final certificates = jCertificates.map((c) {
+  final certificates = jCertificates.asDart().map((c) {
     if (c == null || !c.isA(X509Certificate.type)) {
       throw ArgumentError(
           'certificate chain contains non-X509 certificates', 'pkcs12Data');
@@ -246,7 +248,7 @@
         clientCertificateChain != null ||
         !configuration.validateServerCertificates) {
       JArray<bindings.KeyManager>? keyManagers;
-      final trustManagers = JArray(bindings.TrustManager.nullableType, 1);
+      final trustManagers = JArray.withLength(bindings.TrustManager.type, 1);
 
       if (clientPrivateKey != null && clientCertificateChain != null) {
         final chain =
@@ -254,16 +256,16 @@
         final keyManager = bindings.FixedResponseX509ExtendedKeyManager(
             chain, clientPrivateKey, 'DUMMY'.toJString());
         keyManagers = JArray.filled(1, keyManager.as(bindings.KeyManager.type),
-            E: bindings.KeyManager.type);
+            elementType: bindings.KeyManager.type);
       }
 
       if (!configuration.validateServerCertificates) {
         trustManagers[0] = _allAllTrustManager;
       } else {
         final tmf = bindings.TrustManagerFactory.getInstance(
-            bindings.TrustManagerFactory.getDefaultAlgorithm())!
+            bindings.TrustManagerFactory.defaultAlgorithm)!
           ..init(null);
-        final tms = tmf.getTrustManagers()!;
+        final tms = tmf.trustManagers!;
         if (tms.length != 1) {
           throw StateError('unexpected XXX');
         }
@@ -272,7 +274,7 @@
 
       final sslContext = bindings.SSLContext.getInstance('TLS'.toJString())!
         ..init(keyManagers, trustManagers, null);
-      builder.sslSocketFactory$1(sslContext.getSocketFactory()!,
+      builder.sslSocketFactory$1(sslContext.socketFactory!,
           trustManagers[0]!.as(bindings.X509TrustManager.type));
     }
     _client = builder.build();
@@ -363,7 +365,7 @@
     // So, we need to handle this case separately.
     bindings.RequestBody? okReqBody;
     if (requestMethod != 'GET' && requestMethod != 'HEAD') {
-      okReqBody = bindings.RequestBody.create$10(JByteArray.from(requestBody));
+      okReqBody = bindings.RequestBody.create$10(JByteArray.of(requestBody));
     }
 
     reqBuilder.method(
@@ -417,9 +419,9 @@
 
             var responseHeaders = <String, String>{};
 
-            response.headers().toMultimap().forEach((key, value) {
+            response.headers().toMultimap().asDart().forEach((key, value) {
               responseHeaders[key.toDartString(releaseOriginal: true)] =
-                  value.join(',');
+                  value.asDart().join(',');
             });
 
             int? contentLength;
@@ -441,7 +443,7 @@
                 bindings.DataCallback.implement(
                   bindings.$DataCallback(
                     onDataRead: (bytesRead) {
-                      var data = bytesRead.toList(growable: false);
+                      var data = bytesRead.asDart().toList(growable: false);
 
                       respBodyStreamController.sink.add(data);
                       profile?.responseData.bodySink.add(data);
@@ -476,14 +478,14 @@
               headers: responseHeaders,
               request: request,
               contentLength: contentLength,
-              isRedirect: response.isRedirect(),
+              isRedirect: response.isRedirect,
             ));
 
             profile?.requestData.close();
             profile?.responseData
               ?..contentLength = contentLength
               ..headersCommaValues = responseHeaders
-              ..isRedirect = response.isRedirect()
+              ..isRedirect = response.isRedirect
               ..reasonPhrase =
                   response.message().toDartString(releaseOriginal: true)
               ..startTime = DateTime.now()
diff --git a/pkgs/ok_http/lib/src/ok_http_web_socket.dart b/pkgs/ok_http/lib/src/ok_http_web_socket.dart
index f9c1d3a..db12061 100644
--- a/pkgs/ok_http/lib/src/ok_http_web_socket.dart
+++ b/pkgs/ok_http/lib/src/ok_http_web_socket.dart
@@ -126,7 +126,7 @@
               (bindings.WebSocket webSocket, bindings.ByteString byteString) {
             if (_events.isClosed) return;
             _events.add(BinaryDataReceived(
-                Uint8List.fromList(byteString.toByteArray().toList())));
+                Uint8List.fromList(byteString.toByteArray().asDart())));
           },
           onClosing:
               (bindings.WebSocket webSocket, int i, JString string) async {
diff --git a/pkgs/ok_http/pubspec.yaml b/pkgs/ok_http/pubspec.yaml
index b412de2..740c6c4 100644
--- a/pkgs/ok_http/pubspec.yaml
+++ b/pkgs/ok_http/pubspec.yaml
@@ -13,13 +13,14 @@
     sdk: flutter
   http: ^1.2.1
   http_profile: ^0.1.0
-  jni: ^0.14.0
+  jni: ^1.0.0
+  jni_flutter: ^1.0.0
   plugin_platform_interface: ^2.0.2
   web_socket: '>=0.1.5 <2.0.0'
 
 dev_dependencies:
   dart_flutter_team_lints: ^3.0.0
-  jnigen: ^0.14.0
+  jnigen: ^0.16.0
 
 flutter:
   plugin:
