diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..1036ca72e
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,4 @@
+# These are supported funding model platforms
+
+github: [k163377, cowtowncoder]
+tidelift: maven/com.fasterxml.jackson.module:jackson-module-kotlin
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml
index c5f764037..c93e89e1d 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yaml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yaml
@@ -10,14 +10,17 @@ body:
       label: Search before asking
       description: |-
         Please search [issues](https://github.com/FasterXML/jackson-module-kotlin/issues) to check if your issue has already been reported.
+        Check [all value class labeled issues](https://github.com/FasterXML/jackson-module-kotlin/issues?q=is%3Aopen+is%3Aissue+label%3A%22value+class%22), especially if the problem is related to a value class.
         Also, KotlinModule is only an extension of databind, so it is not an appropriate place to report problems with databind or other modules.
         Please try to ensure that the problem occurs only in Kotlin, and not regular Java objects.
       options:
         - label: "I searched in the [issues](https://github.com/FasterXML/jackson-module-kotlin/issues) and found nothing similar."
           required: true
+        - label: "I have confirmed that the same problem is not reproduced if I exclude the KotlinModule."
+          required: true
         - label: "I searched in the [issues of databind](https://github.com/FasterXML/jackson-databind/issues) and other modules used and found nothing similar."
           required: false
-        - label: "I have confirmed that the problem only occurs when using Kotlin."
+        - label: "I have confirmed that the problem does not reproduce in Java and only occurs when using Kotlin and KotlinModule."
           required: false
   - type: textarea
     id: bug-description
diff --git a/.github/workflows/dep_build_v2.yml b/.github/workflows/dep_build_v2.yml
index 48ef8416a..0598f8435 100644
--- a/.github/workflows/dep_build_v2.yml
+++ b/.github/workflows/dep_build_v2.yml
@@ -10,21 +10,21 @@ permissions:
 
 jobs:
   build:
-    runs-on: 'ubuntu-22.04'
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
-        java_version: ['8', '17', '21', '23']
+        java_version: ['8', '17', '21', '24']
         # Versions need to align with ones in 'main.yml' workflow
-        # kotlin-reflect 1.8.2x has a bug and some tests fail, so we are downgrading to 1.8.10.
-        # https://youtrack.jetbrains.com/issue/KT-65156
-        kotlin_version: ['1.8.10', '1.9.24', '2.0.21', '2.1.0']
+        kotlin_version: ['1.9.24', '2.0.21', '2.1.20']
     env:
       JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+    - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+      with:
+        ref: 2.x
     - name: Set up JDK
-      uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
+      uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
       with:
         distribution: 'temurin'
         java-version: ${{ matrix.java_version }}
diff --git a/.github/workflows/dep_build_v3.yml b/.github/workflows/dep_build_v3.yml
index 2379d3230..da61ee1f9 100644
--- a/.github/workflows/dep_build_v3.yml
+++ b/.github/workflows/dep_build_v3.yml
@@ -2,36 +2,30 @@ name: Re-build on jackson-databind v3 push
 on:
   repository_dispatch:
     types: [jackson-databind-pushed-v3]
-  # just for testing
-  workflow_dispatch:
 
 permissions:
   contents: read
 
 jobs:
   build:
-    runs-on: 'ubuntu-22.04'
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
-        java_version: ['8', '17', '21', '23']
+        java_version: ['17', '21', '24']
         # Versions need to align with ones in 'main.yml' workflow
-        # kotlin-reflect 1.8.2x has a bug and some tests fail, so we are downgrading to 1.8.10.
-        # https://youtrack.jetbrains.com/issue/KT-65156
-        kotlin_version: ['1.8.10', '1.9.24', '2.0.21', '2.1.0']
+        kotlin_version: ['1.9.24', '2.0.21', '2.1.20']
     env:
       JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
     steps:
-    - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+    - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
       with:
-        ref: master
+        ref: 3.x
     - name: Set up JDK
-      uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
+      uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
       with:
         distribution: 'temurin'
         java-version: ${{ matrix.java_version }}
         cache: 'maven'
     - name: Build and test
       run: ./mvnw -B -ff -ntp -Dversion.kotlin=${{ matrix.kotlin_version }} clean verify
-
-# No recursive rebuild (yet?)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 1f6a54084..439688735 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -15,25 +15,23 @@ permissions:
 
 jobs:
   build:
-    runs-on: 'ubuntu-latest'
+    runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       max-parallel: 5
       matrix:
-        java_version: ['8', '11', '17', '21', '23']
-        # kotlin-reflect 1.8.2x has a bug and some tests fail, so we are downgrading to 1.8.10.
-        # https://youtrack.jetbrains.com/issue/KT-65156
-        kotlin_version: ['1.8.10', '1.9.24', '2.0.21', '2.1.0']
+        java_version: ['8', '11', '17', '21', '24']
+        kotlin_version: ['1.9.25', '2.0.21', '2.1.20']
         include:
           - java_version: '8'
-            kotlin_version: '1.8.10'
+            kotlin_version: '1.9.25'
             release_build: 'R'
     env:
       JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
     steps:
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
     - name: Set up JDK
-      uses: actions/setup-java@v4
+      uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
       with:
         distribution: 'temurin'
         java-version: ${{ matrix.java_version }}
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index ca5ab4bab..b9b1153ae 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -14,5 +14,5 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar
diff --git a/README.md b/README.md
index b0f58245d..ce791cbf7 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,7 @@
-[](https://kotlinlang.org) [](https://slack.kotlinlang.org/)
+[](https://mvnrepository.com/artifact/com.fasterxml.jackson.module/jackson-module-kotlin)
+[](./release-notes/VERSION-2.x)
+[](https://tidelift.com/subscription/pkg/maven-com-fasterxml-jackson-module-jackson-module-kotlin?utm_source=maven-com-fasterxml-jackson-module-jackson-module-kotlin&utm_medium=referral&utm_campaign=readme)
+[](https://slack.kotlinlang.org/)
 
 # Overview
 
@@ -10,17 +13,15 @@ and those with secondary constructors or static factories are also supported.
 
 # Status
 
-* release `2.18.2` (for Jackson `2.18.x`) [](https://github.com/FasterXML/jackson-module-kotlin/actions?query=branch%3A2.18)
+* release `2.19.0` (for Jackson `2.19.0`) [](https://github.com/FasterXML/jackson-module-kotlin/actions?query=branch%3A2.19)
+* release `2.18.3` (for Jackson `2.18.x`) [](https://github.com/FasterXML/jackson-module-kotlin/actions?query=branch%3A2.18)
 * release `2.17.3` (for Jackson `2.17.x`) [](https://github.com/FasterXML/jackson-module-kotlin/actions?query=branch%3A2.17)
-* release `2.16.2` (for Jackson `2.16.x`) [](https://github.com/FasterXML/jackson-module-kotlin/actions?query=branch%3A2.16)
-* release `2.15.4` (for Jackson `2.15.x`) [](https://github.com/FasterXML/jackson-module-kotlin/actions?query=branch%3A2.15)
-* release `2.14.3` (for Jackson `2.14.x`) [](https://github.com/FasterXML/jackson-module-kotlin/actions?query=branch%3A2.14)
 
 Releases require that you have included Kotlin stdlib and reflect libraries already.
 
 Gradle:
 ```
-implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.18.+"
+implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.19.+"
 ```
 
 Maven:
@@ -28,7 +29,7 @@ Maven:
 
     com.fasterxml.jackson.module
     jackson-module-kotlin
-    2.18.2
+    2.19.0
 
 ```
 
@@ -111,12 +112,9 @@ println(arrayNode.toString()) // ["foo",true,1,1.0,"YmFy"]
 Different `kotlin-core` versions are supported by different Jackson Kotlin module minor versions.
 Here is an incomplete list of supported versions:
 
+* Jackson 2.19.x: Kotlin-core 1.9 - 2.1
 * Jackson 2.18.x: Kotlin-core 1.8 - 2.1
 * Jackson 2.17.x: Kotlin-core 1.7 - 2.0
-* Jackson 2.16.x: Kotlin-core 1.6 - 1.9
-* Jackson 2.15.x: Kotlin-core 1.5 - 1.8
-* Jackson 2.14.x: Kotlin-core 1.4 - 1.8
-* Jackson 2.13.x: Kotlin-core 1.4 - 1.7
 
 Please note that the versions supported by 2.17 are tentative and may change depending on the release date.
 
@@ -193,7 +191,7 @@ when(root){
 # Configuration
 
 The Kotlin module may be given a few configuration parameters at construction time;
-see the [inline documentation](https://github.com/FasterXML/jackson-module-kotlin/blob/master/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModule.kt)
+see the [inline documentation](https://github.com/FasterXML/jackson-module-kotlin/blob/2.19/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModule.kt)
 for details on what options are available and what they do.
 
 ```kotlin
@@ -256,9 +254,9 @@ See the [main Jackson contribution guidelines](https://github.com/FasterXML/jack
 
 If you are going to write code, choose the appropriate base branch:
 
-- `2.17` for bugfixes against the current stable version
-- `2.18` for additive functionality & features or [minor](https://semver.org), backwards compatible changes to existing behavior to be included in the next minor version release
-- `master` for significant changes to existing behavior, which will be part of Jackson 3.0
+- `2.18` for bugfixes against the current stable version
+- `2.19` for additive functionality & features or [minor](https://semver.org), backwards compatible changes to existing behavior to be included in the next minor version release
+- `3.x` for significant changes to existing behavior, which will be part of Jackson 3.0
 
 ### Failing tests
 
diff --git a/pom.xml b/pom.xml
index 97026cb13..a26e15816 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,12 +8,12 @@
     
         com.fasterxml.jackson
         jackson-base
-        2.18.5-SNAPSHOT
+        2.19.1-SNAPSHOT
     
     com.fasterxml.jackson.module
     jackson-module-kotlin
     jackson-module-kotlin
-    2.18.5-SNAPSHOT
+    2.19.1-SNAPSHOT
     bundle
     Add-on module for Jackson (https://github.com/FasterXML/jackson/) to support
         Kotlin language, specifically introspection of method/constructor parameter names,
@@ -62,9 +62,7 @@
         1.8
         1.8
 
-        
-        
-        1.8.10
+        1.9.25
 
         
         com/fasterxml/jackson/module/kotlin
@@ -111,15 +109,11 @@
             compile
         
 
-        
-        
-            junit
-            junit
-            test
-        
+        
+
         
             org.jetbrains.kotlin
-            kotlin-test-junit
+            kotlin-test-junit5
             ${version.kotlin}
             test
         
@@ -128,6 +122,11 @@
             jackson-dataformat-xml
             test
         
+        
+            com.fasterxml.jackson.dataformat
+            jackson-dataformat-csv
+            test
+        
         
             
             com.fasterxml.jackson.datatype
@@ -215,7 +214,7 @@
 
             
             
-                de.jjohannes
+                org.gradlex
                 gradle-module-metadata-maven-plugin
             
 
@@ -233,7 +232,7 @@
                             -->
                             
-                            2.17.0
+                            2.18.0
                             jar
                         
                     
@@ -249,43 +248,16 @@
                             
                             
                             
-                                com.fasterxml.jackson.module.kotlin.KotlinModule#KotlinModule(int,boolean,boolean,boolean,com.fasterxml.jackson.module.kotlin.SingletonSupport,boolean,boolean,boolean)
-                            
-                            com.fasterxml.jackson.module.kotlin.KotlinModule$Builder#getNullIsSameAsDefault()
-                            
-                            
-                                com.fasterxml.jackson.module.kotlin.KotlinModule$Builder#nullIsSameAsDefault(boolean)
-                            
-                            
-                                com.fasterxml.jackson.module.kotlin.KotlinModule$Builder#getNullToEmptyCollection()
-                            
-                            
-                                com.fasterxml.jackson.module.kotlin.KotlinModule$Builder#nullToEmptyCollection(boolean)
-                            
-                            com.fasterxml.jackson.module.kotlin.KotlinModule$Builder#getNullToEmptyMap()
-                            
-                            com.fasterxml.jackson.module.kotlin.KotlinModule$Builder#nullToEmptyMap(boolean)
-                            
-                            com.fasterxml.jackson.module.kotlin.KotlinModule$Builder#getSingletonSupport()
-                            
-                            
-                                com.fasterxml.jackson.module.kotlin.KotlinModule$Builder#singletonSupport(com.fasterxml.jackson.module.kotlin.SingletonSupport)
-                            
-                            com.fasterxml.jackson.module.kotlin.KotlinModule$Builder#getStrictNullChecks()
-                            
-                            
-                                com.fasterxml.jackson.module.kotlin.KotlinModule$Builder#strictNullChecks(boolean)
-                            
-                            com.fasterxml.jackson.module.kotlin.KotlinModule$Builder#reflectionCacheSize(int)
+                                com.fasterxml.jackson.module.kotlin.KotlinModule#getUseKotlinPropertyNameForGetter()
                             
+                            com.fasterxml.jackson.module.kotlin.KotlinModule#getSingletonSupport()
+                            com.fasterxml.jackson.module.kotlin.SingletonSupport
                             
                             
-                                com.fasterxml.jackson.module.kotlin.KotlinNamesAnnotationIntrospector#KotlinNamesAnnotationIntrospector(com.fasterxml.jackson.module.kotlin.ReflectionCache,java.util.Set,boolean)
+                                com.fasterxml.jackson.module.kotlin.KotlinNamesAnnotationIntrospector#KotlinNamesAnnotationIntrospector(com.fasterxml.jackson.module.kotlin.ReflectionCache,boolean)
                             
-                            
-                                com.fasterxml.jackson.module.kotlin.ReflectionCache#checkConstructorIsCreatorAnnotated(com.fasterxml.jackson.databind.introspect.AnnotatedConstructor,kotlin.jvm.functions.Function1)
-                            
-
+                            com.fasterxml.jackson.module.kotlin.KotlinKeyDeserializers#INSTANCE
+                            com.fasterxml.jackson.module.kotlin.ReflectionCache$BooleanTriState
                         
                     
                 
diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x
index 920e4df73..d56cae886 100644
--- a/release-notes/CREDITS-2.x
+++ b/release-notes/CREDITS-2.x
@@ -15,6 +15,34 @@ Authors:
 
 Contributors:
 
+# 2.19.1 (not yet released)
+
+# 2.19.0 (24-Apr-2025)
+
+WrongWrong (@k163377)
+* #959: Add extensions for configOverride
+* #954: Replace BooleanTriState with OptBoolean
+* #944: Fixed to use common util for Member accessibility override
+* #937: Added type match check to read functions
+
+Tatu Saloranta (@cowtowncoder)
+* #889: Upgrade kotlin dep to 1.9.25 (from 1.9.24)
+
+WrongWrong (@k163377)
+* #930: Add tests for #917
+* #929: Bug fixes to hasRequiredMarker and added isRequired considerations
+* #914: Add test case to serialize Nothing? (for #314)
+* #910: Add default KeyDeserializer for value class
+* #885: Performance improvement of strictNullChecks
+* #884: Changed the base class of MissingKotlinParameterException to InvalidNullException
+* #878: Fix for #876
+* #868: Added test case for FAIL_ON_NULL_FOR_PRIMITIVES
+* #866: Upgrade to JUnit5
+* #861: Update Kotlin to 1.9.24
+* #858: Refactor findDefaultCreator
+* #839: Remove useKotlinPropertyNameForGetter and unify with kotlinPropertyNameAsImplicitName
+* #835: Remove old SingletonSupport class and unified with KotlinFeature.SingletonSupport
+
 # 2.18.4 (not yet released)
 
 WrongWrong (@k163377)
@@ -31,6 +59,8 @@ WrongWrong (@k163377)
 # 2.18.0 (26-Sep-2024)
 
 WrongWrong (@k163377)
+* #883: Raise the deprecation level to error for the MissingKotlinParameterException secondary constructor
+* #869: Replaced Enum.values with Enum.entries
 * #818: Optimize the search process for creators
 * #817: Fixed nullability of convertValue function argument
 * #782: Organize deprecated contents
diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x
index 4b25e696f..a20868c41 100644
--- a/release-notes/VERSION-2.x
+++ b/release-notes/VERSION-2.x
@@ -16,6 +16,46 @@ Co-maintainers:
 === Releases ===
 ------------------------------------------------------------------------
 
+2.19.1 (not yet released)
+
+2.19.0 (24-Apr-2025)
+
+#959: Extension functions has been added to simplify `configOverride` calls to `ObjectMapper` and `Module.SetupContext`.
+#954: Replaced `OptBoolean` of internal caching with a common implementation.
+#944: Common util is now used for member accessibility overrides.
+#937: For `readValue` and other shorthands for `ObjectMapper` deserialization methods,
+  type consistency checks have been added.
+  A `RuntimeJsonMappingException` will be thrown in case of inconsistency.
+  This fixes a problem that broke `Kotlin` null safety by reading null as a value even if the type parameter was specified as non-null.
+  It also checks for custom errors in ObjectMapper that cause a different value to be read than the specified type parameter.
+#929: Added consideration of `JsonProperty.isRequired` added in `2.19` in `hasRequiredMarker` processing.
+  Previously `JsonProperty.required` was defined as `Boolean` with default `false`,
+  so `KotlinModule` was forced to override it if the value was `false`.
+  This made it impossible for users to override the parsed result by `KotlinModule`.
+  The new `JsonProperty.isRequired` is defined with three values, including the default,
+  so `KotlinModule` can now respect user specifications.
+#929: Fixed a problem with the `NullToEmptyCollection` and `NullToEmptyMap` options being applied to non-parameters
+  in the `hasRequiredMarker` process.
+  They currently do not work for setters or fields and are not related to serialization,
+  but were being incorrectly applied to their `required` decisions.
+#910: A default `KeyDeserializer` for `value class` has been added.
+ This eliminates the need to have a custom `KeyDeserializer` for each `value class` when using it as a key in a `Map`, if only simple boxing is needed.
+#889: Kotlin has been upgraded to 1.9.25.
+#885: A new `StrictNullChecks` option(KotlinFeature.NewStrictNullChecks) has been added which greatly improves throughput.
+ Benchmarks show a consistent throughput drop of less than 2% when enabled (prior to the improvement, the worst throughput drop was more than 30%).
+ Note that the new backend changes the exception thrown to `InvalidNullException` and with it the error message.
+ Also note that the base class for `MissingKotlinParameterException` was changed to `InvalidNullException` in #884.
+#884: The base class for `MissingKotlinParameterException` has been changed to `InvalidNullException`.
+ If you do not catch this exception or catch `MismatchedInputException`, the behavior is unchanged.
+ If you are catching both `MismatchedKotlinParameterException` and `InvalidNullException`, you must catch `MismatchedKotlinParameterException` first.
+#883: The deprecation level has been raised to error for the `MissingKotlinParameterException` secondary constructor.
+ This is a problematic process that has been marked as deprecated for a very long time and will be removed in 2.20 or later.
+#878: Fixed a problem where settings like `@JsonSetter(nulls = AS_EMPTY)` were not being applied when the input was `undefined`.
+#869: By using Enum.entries in the acquisition of KotlinFeature.defaults, the initialization load was reduced, albeit slightly.
+#858: Minor performance improvement of findDefaultCreator in edge cases.
+#839: Remove useKotlinPropertyNameForGetter and unify with kotlinPropertyNameAsImplicitName.
+#835: Remove old SingletonSupport class and unified with KotlinFeature.SingletonSupport.
+
 2.18.4 (06-May-2025)
 
 #923: Fixed a problem where the result of processing `hasRequiredMarker ` by a `KotlinModule` would also apply to
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Converters.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Converters.kt
index e1416426d..c284fb8c3 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Converters.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Converters.kt
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JavaType
 import com.fasterxml.jackson.databind.deser.std.StdDelegatingDeserializer
 import com.fasterxml.jackson.databind.ser.std.StdDelegatingSerializer
 import com.fasterxml.jackson.databind.type.TypeFactory
+import com.fasterxml.jackson.databind.util.ClassUtil
 import com.fasterxml.jackson.databind.util.StdConverter
 import kotlin.reflect.KClass
 import kotlin.time.toJavaDuration
@@ -51,7 +52,7 @@ internal class ValueClassBoxConverter(
     val boxedClass: KClass
 ) : StdConverter() {
     private val boxMethod = boxedClass.java.getDeclaredMethod("box-impl", unboxedClass).apply {
-        if (!this.isAccessible) this.isAccessible = true
+        ClassUtil.checkAndFixAccess(this, false)
     }
 
     @Suppress("UNCHECKED_CAST")
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Exceptions.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Exceptions.kt
index add73669b..120ad0f08 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Exceptions.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Exceptions.kt
@@ -2,7 +2,7 @@ package com.fasterxml.jackson.module.kotlin
 
 import com.fasterxml.jackson.core.JsonParser
 import com.fasterxml.jackson.databind.JsonMappingException
-import com.fasterxml.jackson.databind.exc.MismatchedInputException
+import com.fasterxml.jackson.databind.exc.InvalidNullException
 import java.io.Closeable
 import kotlin.reflect.KParameter
 
@@ -31,8 +31,12 @@ class MissingKotlinParameterException(
     val parameter: KParameter,
     processor: JsonParser? = null,
     msg: String
-) : MismatchedInputException(processor, msg) {
-    @Deprecated("Use main constructor", ReplaceWith("MissingKotlinParameterException(KParameter, JsonParser?, String)"))
+) : InvalidNullException(processor, msg, null) {
+    @Deprecated(
+        "Use main constructor, ",
+        ReplaceWith("MissingKotlinParameterException(KParameter, JsonParser?, String)"),
+        DeprecationLevel.ERROR,
+    )
     constructor(
             parameter: KParameter,
             processor: Closeable? = null,
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt
index 2a8c3b1a2..dc75e7b26 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt
@@ -7,8 +7,11 @@ import com.fasterxml.jackson.databind.JsonDeserializer
 import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.JsonSerializer
 import com.fasterxml.jackson.databind.MappingIterator
+import com.fasterxml.jackson.databind.Module
 import com.fasterxml.jackson.databind.ObjectMapper
 import com.fasterxml.jackson.databind.ObjectReader
+import com.fasterxml.jackson.databind.RuntimeJsonMappingException
+import com.fasterxml.jackson.databind.cfg.MutableConfigOverride
 import com.fasterxml.jackson.databind.json.JsonMapper
 import com.fasterxml.jackson.databind.module.SimpleModule
 import com.fasterxml.jackson.databind.node.ArrayNode
@@ -50,21 +53,130 @@ fun ObjectMapper.registerKotlinModule(initializer: KotlinModule.Builder.() -> Un
 
 inline fun  jacksonTypeRef(): TypeReference = object: TypeReference() {}
 
+@PublishedApi
+internal inline fun  Any?.checkTypeMismatch(): T {
+    // Basically, this check assumes that T is non-null and the value is null.
+    // Since this can be caused by both input or ObjectMapper implementation errors,
+    // a more abstract RuntimeJsonMappingException is thrown.
+    if (this !is T) {
+        val nullability = if (null is T) "?" else "(non-null)"
+
+        // Since the databind implementation of MappingIterator throws RuntimeJsonMappingException,
+        // JsonMappingException was not used to unify the behavior.
+        throw RuntimeJsonMappingException(
+            "Deserialized value did not match the specified type; " +
+                    "specified ${T::class.qualifiedName}${nullability} but was ${this?.let { it::class.qualifiedName }}"
+        )
+    }
+    return this
+}
+
+/**
+ * Shorthand for [ObjectMapper.readValue].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectMapper].
+ */
 inline fun  ObjectMapper.readValue(jp: JsonParser): T = readValue(jp, jacksonTypeRef())
-inline fun  ObjectMapper.readValues(jp: JsonParser): MappingIterator = readValues(jp, jacksonTypeRef())
+    .checkTypeMismatch()
+/**
+ * Shorthand for [ObjectMapper.readValues].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectMapper].
+ */
+inline fun  ObjectMapper.readValues(jp: JsonParser): MappingIterator {
+    val values = readValues(jp, jacksonTypeRef())
+
+    return object : MappingIterator(values) {
+        override fun nextValue(): T = super.nextValue().checkTypeMismatch()
+    }
+}
 
-inline fun  ObjectMapper.readValue(src: File): T = readValue(src, jacksonTypeRef())
-inline fun  ObjectMapper.readValue(src: URL): T = readValue(src, jacksonTypeRef())
+/**
+ * Shorthand for [ObjectMapper.readValue].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectMapper].
+ */
+inline fun  ObjectMapper.readValue(src: File): T = readValue(src, jacksonTypeRef()).checkTypeMismatch()
+/**
+ * Shorthand for [ObjectMapper.readValue].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectMapper].
+ */
+inline fun  ObjectMapper.readValue(src: URL): T = readValue(src, jacksonTypeRef()).checkTypeMismatch()
+/**
+ * Shorthand for [ObjectMapper.readValue].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectMapper].
+ */
 inline fun  ObjectMapper.readValue(content: String): T = readValue(content, jacksonTypeRef())
-inline fun  ObjectMapper.readValue(src: Reader): T = readValue(src, jacksonTypeRef())
+    .checkTypeMismatch()
+/**
+ * Shorthand for [ObjectMapper.readValue].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectMapper].
+ */
+inline fun  ObjectMapper.readValue(src: Reader): T = readValue(src, jacksonTypeRef()).checkTypeMismatch()
+/**
+ * Shorthand for [ObjectMapper.readValue].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectMapper].
+ */
 inline fun  ObjectMapper.readValue(src: InputStream): T = readValue(src, jacksonTypeRef())
+    .checkTypeMismatch()
+/**
+ * Shorthand for [ObjectMapper.readValue].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectMapper].
+ */
 inline fun  ObjectMapper.readValue(src: ByteArray): T = readValue(src, jacksonTypeRef())
-
+    .checkTypeMismatch()
+
+/**
+ * Shorthand for [ObjectMapper.readValue].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectMapper].
+ */
 inline fun  ObjectMapper.treeToValue(n: TreeNode): T = readValue(this.treeAsTokens(n), jacksonTypeRef())
+    .checkTypeMismatch()
+/**
+ * Shorthand for [ObjectMapper.convertValue].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectMapper].
+ */
 inline fun  ObjectMapper.convertValue(from: Any?): T = convertValue(from, jacksonTypeRef())
-
+    .checkTypeMismatch()
+
+/**
+ * Shorthand for [ObjectReader.readValue].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectReader].
+ */
 inline fun  ObjectReader.readValueTyped(jp: JsonParser): T = readValue(jp, jacksonTypeRef())
-inline fun  ObjectReader.readValuesTyped(jp: JsonParser): Iterator = readValues(jp, jacksonTypeRef())
+    .checkTypeMismatch()
+/**
+ * Shorthand for [ObjectReader.readValues].
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
+ *   Other cases where the read value is of a different type than [T]
+ *   due to an incorrect customization to [ObjectReader].
+ */
+inline fun  ObjectReader.readValuesTyped(jp: JsonParser): Iterator {
+    val values = readValues(jp, jacksonTypeRef())
+
+    return object : Iterator by values {
+        override fun next(): T = values.next().checkTypeMismatch()
+    }
+}
 inline fun  ObjectReader.treeToValue(n: TreeNode): T? = readValue(this.treeAsTokens(n), jacksonTypeRef())
 
 inline fun  ObjectMapper.addMixIn(): ObjectMapper = this.addMixIn(T::class.java, U::class.java)
@@ -114,3 +226,7 @@ fun  SimpleModule.addDeserializer(kClass: KClass, deserializer: Json
     kClass.javaPrimitiveType?.let { addDeserializer(it, deserializer) }
     addDeserializer(kClass.javaObjectType, deserializer)
 }
+
+inline fun  ObjectMapper.configOverride(): MutableConfigOverride = configOverride(T::class.java)
+inline fun  Module.SetupContext.configOverride(): MutableConfigOverride =
+    configOverride(T::class.java)
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt
index 7efb65377..0054b3659 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt
@@ -1,6 +1,7 @@
 package com.fasterxml.jackson.module.kotlin
 
 import com.fasterxml.jackson.annotation.JsonProperty
+import com.fasterxml.jackson.annotation.OptBoolean
 import com.fasterxml.jackson.databind.DeserializationFeature
 import com.fasterxml.jackson.databind.JsonSerializer
 import com.fasterxml.jackson.databind.Module
@@ -36,20 +37,27 @@ internal class KotlinAnnotationIntrospector(
     // TODO: implement nullIsSameAsDefault flag, which represents when TRUE that if something has a default value, it can be passed a null to default it
     //       this likely impacts this class to be accurate about what COULD be considered required
 
+    // If a new isRequired is explicitly specified or the old required is true, those values take precedence.
+    // In other cases, override is done by KotlinModule.
+    private fun JsonProperty.forceRequiredByAnnotation(): Boolean? = when {
+        isRequired != OptBoolean.DEFAULT -> isRequired.asBoolean()
+        required -> true
+        else -> null
+    }
+
+    private fun AccessibleObject.forceRequiredByAnnotation(): Boolean? =
+        getAnnotation(JsonProperty::class.java)?.forceRequiredByAnnotation()
+
     override fun hasRequiredMarker(
         m: AnnotatedMember
     ): Boolean? = m.takeIf { it.member.declaringClass.isKotlinClass() }?.let { _ ->
         cache.javaMemberIsRequired(m) {
             try {
-                when {
-                    nullToEmptyCollection && m.type.isCollectionLikeType -> false
-                    nullToEmptyMap && m.type.isMapLikeType -> false
-                    else -> when (m) {
-                        is AnnotatedField -> m.hasRequiredMarker()
-                        is AnnotatedMethod -> m.hasRequiredMarker()
-                        is AnnotatedParameter -> m.hasRequiredMarker()
-                        else -> null
-                    }
+                when (m) {
+                    is AnnotatedField -> m.hasRequiredMarker()
+                    is AnnotatedMethod -> m.hasRequiredMarker()
+                    is AnnotatedParameter -> m.hasRequiredMarker()
+                    else -> null
                 }
             } catch (_: UnsupportedOperationException) {
                 null
@@ -100,28 +108,9 @@ internal class KotlinAnnotationIntrospector(
         }
 
     private fun AnnotatedField.hasRequiredMarker(): Boolean? {
-        val byAnnotation = (member as Field).isRequiredByAnnotation()
-        val byNullability = (member as Field).kotlinProperty?.returnType?.isRequired()
-
-        return requiredAnnotationOrNullability(byAnnotation, byNullability)
-    }
-
-    private fun AccessibleObject.isRequiredByAnnotation(): Boolean? = annotations
-        .firstOrNull { it.annotationClass == JsonProperty::class }
-        ?.let { it as JsonProperty }
-        ?.required
-
-    private fun requiredAnnotationOrNullability(byAnnotation: Boolean?, byNullability: Boolean?): Boolean? {
-        if (byAnnotation != null && byNullability != null) {
-            return byAnnotation || byNullability
-        } else if (byNullability != null) {
-            return byNullability
-        }
-        return byAnnotation
-    }
-
-    private fun Method.isRequiredByAnnotation(): Boolean? {
-        return (this.annotations.firstOrNull { it.annotationClass.java == JsonProperty::class.java } as? JsonProperty)?.required
+        val field = member as Field
+        return field.forceRequiredByAnnotation()
+            ?: field.kotlinProperty?.returnType?.isRequired()
     }
 
     // Since Kotlin's property has the same Type for each field, getter, and setter,
@@ -136,9 +125,7 @@ internal class KotlinAnnotationIntrospector(
     private fun AnnotatedMethod.getRequiredMarkerFromCorrespondingAccessor(): Boolean? {
         member.declaringClass.kotlin.declaredMemberProperties.forEach { kProperty ->
             if (kProperty.javaGetter == this.member || (kProperty as? KMutableProperty1)?.javaSetter == this.member) {
-                val byAnnotation = this.member.isRequiredByAnnotation()
-                val byNullability = kProperty.isRequiredByNullability()
-                return requiredAnnotationOrNullability(byAnnotation, byNullability)
+                return member.forceRequiredByAnnotation() ?: kProperty.isRequiredByNullability()
             }
         }
         return null
@@ -146,10 +133,11 @@ internal class KotlinAnnotationIntrospector(
 
     // Is the member method a regular method of the data class or
     private fun Method.getRequiredMarkerFromAccessorLikeMethod(): Boolean? = cache.kotlinFromJava(this)?.let { func ->
-        val byAnnotation = this.isRequiredByAnnotation()
-        return when {
-            func.isGetterLike() -> requiredAnnotationOrNullability(byAnnotation, func.returnType.isRequired())
-            func.isSetterLike() -> requiredAnnotationOrNullability(byAnnotation, func.valueParameters[0].isRequired())
+        forceRequiredByAnnotation() ?: when {
+            func.isGetterLike() -> func.returnType.isRequired()
+            // If nullToEmpty could be supported for setters,
+            // a branch similar to AnnotatedParameter.hasRequiredMarker should be added.
+            func.isSetterLike() -> func.valueParameters[0].isRequired()
             else -> null
         }
     }
@@ -157,12 +145,15 @@ internal class KotlinAnnotationIntrospector(
     private fun KFunction<*>.isGetterLike(): Boolean = parameters.size == 1
     private fun KFunction<*>.isSetterLike(): Boolean = parameters.size == 2 && returnType == UNIT_TYPE
 
-    private fun AnnotatedParameter.hasRequiredMarker(): Boolean? {
-        val byAnnotation = this.getAnnotation(JsonProperty::class.java)?.required
-        val byNullability = cache.findKotlinParameter(this)?.isRequired()
-
-        return requiredAnnotationOrNullability(byAnnotation, byNullability)
-    }
+    private fun AnnotatedParameter.hasRequiredMarker(): Boolean? = getAnnotation(JsonProperty::class.java)
+        ?.forceRequiredByAnnotation()
+        ?: run {
+            when {
+                nullToEmptyCollection && type.isCollectionLikeType -> false
+                nullToEmptyMap && type.isMapLikeType -> false
+                else -> cache.findKotlinParameter(this)?.isRequired()
+            }
+        }
 
     private fun AnnotatedMethod.findValueClassReturnType() = cache.findValueClassReturnType(this)
 
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinDeserializers.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinDeserializers.kt
index 4d8057ee6..09dd7e022 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinDeserializers.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinDeserializers.kt
@@ -11,6 +11,7 @@ import com.fasterxml.jackson.databind.JsonDeserializer
 import com.fasterxml.jackson.databind.deser.Deserializers
 import com.fasterxml.jackson.databind.deser.std.StdDeserializer
 import com.fasterxml.jackson.databind.exc.InvalidDefinitionException
+import com.fasterxml.jackson.databind.util.ClassUtil
 import java.lang.reflect.Method
 import java.lang.reflect.Modifier
 import kotlin.reflect.full.primaryConstructor
@@ -106,7 +107,7 @@ internal class WrapsNullableValueClassBoxDeserializer(
     private val inputType: Class<*> = creator.parameterTypes[0]
 
     init {
-        creator.apply { if (!this.isAccessible) this.isAccessible = true }
+        ClassUtil.checkAndFixAccess(creator, false)
     }
 
     // Cache the result of wrapping null, since the result is always expected to be the same.
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinFeature.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinFeature.kt
index f8da63d4a..e7e12d5ba 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinFeature.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinFeature.kt
@@ -1,5 +1,7 @@
 package com.fasterxml.jackson.module.kotlin
 
+import com.fasterxml.jackson.annotation.JsonSetter
+import com.fasterxml.jackson.databind.exc.InvalidNullException
 import java.util.BitSet
 
 /**
@@ -30,7 +32,6 @@ enum class KotlinFeature(internal val enabledByDefault: Boolean) {
      * Deserializing a singleton overwrites the value of the single instance.
      *
      * See [jackson-module-kotlin#225]: keep Kotlin singletons as singletons.
-     * @see com.fasterxml.jackson.module.kotlin.SingletonSupport
      */
     SingletonSupport(enabledByDefault = false),
 
@@ -41,6 +42,11 @@ enum class KotlinFeature(internal val enabledByDefault: Boolean) {
      * may contain null values after deserialization.
      * Enabling it protects against this but has significant performance impact.
      */
+    @Deprecated(
+        level = DeprecationLevel.WARNING,
+        message = "This option will be migrated to the new backend in 2.21.",
+        replaceWith = ReplaceWith("NewStrictNullChecks")
+    )
     StrictNullChecks(enabledByDefault = false),
 
     /**
@@ -67,13 +73,29 @@ enum class KotlinFeature(internal val enabledByDefault: Boolean) {
      * `@JsonFormat` annotations need to be declared either on getter using `@get:JsonFormat` or field using `@field:JsonFormat`.
      * See [jackson-module-kotlin#651] for details.
      */
-    UseJavaDurationConversion(enabledByDefault = false);
+    UseJavaDurationConversion(enabledByDefault = false),
+
+    /**
+     * New [StrictNullChecks] feature with improved throughput.
+     * Internally, it will be the same as if [JsonSetter] (contentNulls = FAIL) had been granted.
+     * Benchmarks show that it can check for illegal nulls with throughput nearly identical to the default (see [jackson-module-kotlin#719]).
+     *
+     * Note that in the new backend, the exception thrown has changed from [MissingKotlinParameterException] to [InvalidNullException].
+     * The message will be changed accordingly.
+     * Since 2.19, the base class of [MissingKotlinParameterException] has also been changed to [InvalidNullException],
+     * so be careful when catching it.
+     *
+     * This is a temporary option for a phased backend migration,
+     * which will eventually be merged into [StrictNullChecks].
+     * Also, specifying both this and [StrictNullChecks] is not permitted.
+     */
+    NewStrictNullChecks(enabledByDefault = false);
 
     internal val bitSet: BitSet = (1 shl ordinal).toBitSet()
 
     companion object {
         internal val defaults
-            get() = values().fold(BitSet(Int.SIZE_BITS)) { acc, cur ->
+            get() = entries.fold(BitSet(Int.SIZE_BITS)) { acc, cur ->
                 acc.apply { if (cur.enabledByDefault) this.or(cur.bitSet) }
             }
     }
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinKeyDeserializers.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinKeyDeserializers.kt
index 70e2e35a6..8658747a8 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinKeyDeserializers.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinKeyDeserializers.kt
@@ -5,6 +5,12 @@ import com.fasterxml.jackson.core.exc.InputCoercionException
 import com.fasterxml.jackson.databind.*
 import com.fasterxml.jackson.databind.deser.std.StdKeyDeserializer
 import com.fasterxml.jackson.databind.deser.std.StdKeyDeserializers
+import com.fasterxml.jackson.databind.exc.InvalidDefinitionException
+import com.fasterxml.jackson.databind.util.ClassUtil
+import java.lang.reflect.Method
+import kotlin.reflect.KClass
+import kotlin.reflect.full.primaryConstructor
+import kotlin.reflect.jvm.javaMethod
 
 // The reason why key is treated as nullable is to match the tentative behavior of StdKeyDeserializer.
 // If StdKeyDeserializer is modified, need to modify this too.
@@ -65,18 +71,68 @@ internal object ULongKeyDeserializer : StdKeyDeserializer(TYPE_LONG, ULong::clas
     }
 }
 
-internal object KotlinKeyDeserializers : StdKeyDeserializers() {
-    private fun readResolve(): Any = KotlinKeyDeserializers
+// The implementation is designed to be compatible with various creators, just in case.
+internal class ValueClassKeyDeserializer(
+    private val creator: Method,
+    private val converter: ValueClassBoxConverter
+) : KeyDeserializer() {
+    private val unboxedClass: Class<*> = creator.parameterTypes[0]
 
+    init {
+        ClassUtil.checkAndFixAccess(creator, false)
+    }
+
+    // Based on databind error
+    // https://github.com/FasterXML/jackson-databind/blob/341f8d360a5f10b5e609d6ee0ea023bf597ce98a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java#L624
+    private fun errorMessage(boxedType: JavaType): String =
+        "Could not find (Map) Key deserializer for types wrapped in $boxedType"
+
+    override fun deserializeKey(key: String?, ctxt: DeserializationContext): Any {
+        val unboxedJavaType = ctxt.constructType(unboxedClass)
+
+        return try {
+            // findKeyDeserializer does not return null, and an exception will be thrown if not found.
+            val value = ctxt.findKeyDeserializer(unboxedJavaType, null).deserializeKey(key, ctxt)
+            @Suppress("UNCHECKED_CAST")
+            converter.convert(creator.invoke(null, value) as S)
+        } catch (e: InvalidDefinitionException) {
+            throw JsonMappingException.from(ctxt, errorMessage(ctxt.constructType(converter.boxedClass.java)), e)
+        }
+    }
+
+    companion object {
+        fun createOrNull(
+            boxedClass: KClass<*>,
+            cache: ReflectionCache
+        ): ValueClassKeyDeserializer<*, *>? {
+            // primaryConstructor.javaMethod for the value class returns constructor-impl
+            // Only primary constructor is allowed as creator, regardless of visibility.
+            // This is because it is based on the WrapsNullableValueClassBoxDeserializer.
+            // Also, as far as I could research, there was no such functionality as JsonKeyCreator,
+            // so it was not taken into account.
+            val creator = boxedClass.primaryConstructor?.javaMethod ?: return null
+            val converter = cache.getValueClassBoxConverter(creator.returnType, boxedClass)
+
+            return ValueClassKeyDeserializer(creator, converter)
+        }
+    }
+}
+
+internal class KotlinKeyDeserializers(private val cache: ReflectionCache) : StdKeyDeserializers() {
     override fun findKeyDeserializer(
         type: JavaType,
         config: DeserializationConfig?,
         beanDesc: BeanDescription?
-    ): KeyDeserializer? = when (type.rawClass) {
-        UByte::class.java -> UByteKeyDeserializer
-        UShort::class.java -> UShortKeyDeserializer
-        UInt::class.java -> UIntKeyDeserializer
-        ULong::class.java -> ULongKeyDeserializer
-        else -> null
+    ): KeyDeserializer? {
+        val rawClass = type.rawClass
+
+        return when {
+            rawClass == UByte::class.java -> UByteKeyDeserializer
+            rawClass == UShort::class.java -> UShortKeyDeserializer
+            rawClass == UInt::class.java -> UIntKeyDeserializer
+            rawClass == ULong::class.java -> ULongKeyDeserializer
+            rawClass.isUnboxableValueClass() -> ValueClassKeyDeserializer.createOrNull(rawClass.kotlin, cache)
+            else -> null
+        }
     }
 }
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModule.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModule.kt
index 0af625ad4..f09b1707a 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModule.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModule.kt
@@ -5,7 +5,9 @@ import com.fasterxml.jackson.databind.module.SimpleModule
 import com.fasterxml.jackson.module.kotlin.KotlinFeature.NullIsSameAsDefault
 import com.fasterxml.jackson.module.kotlin.KotlinFeature.NullToEmptyCollection
 import com.fasterxml.jackson.module.kotlin.KotlinFeature.NullToEmptyMap
+import com.fasterxml.jackson.module.kotlin.KotlinFeature.SingletonSupport
 import com.fasterxml.jackson.module.kotlin.KotlinFeature.StrictNullChecks
+import com.fasterxml.jackson.module.kotlin.KotlinFeature.NewStrictNullChecks
 import com.fasterxml.jackson.module.kotlin.KotlinFeature.KotlinPropertyNameAsImplicitName
 import com.fasterxml.jackson.module.kotlin.KotlinFeature.UseJavaDurationConversion
 import java.util.*
@@ -22,8 +24,8 @@ fun Class<*>.isKotlinClass(): Boolean = this.isAnnotationPresent(Metadata::class
  *  map object.
  * @property nullIsSameAsDefault     Default false.  Whether to treat null values as absent when deserializing, thereby
  *  using the default value provided in Kotlin.
- * @property singletonSupport        Default: DISABLED.  Mode for singleton handling.
- *  See {@link com.fasterxml.jackson.module.kotlin.SingletonSupport label}
+ * @property singletonSupport        Default: false.  Mode for singleton handling.
+ *  See [KotlinFeature.SingletonSupport]
  * @property enabledSingletonSupport Default: false.  A temporary property that is maintained until the return value of `singletonSupport` is changed.
  *  It will be removed in 2.21.
  * @property strictNullChecks        Default: false.  Whether to check deserialized collections.  With this disabled,
@@ -40,31 +42,46 @@ class KotlinModule private constructor(
     val nullToEmptyCollection: Boolean = NullToEmptyCollection.enabledByDefault,
     val nullToEmptyMap: Boolean = NullToEmptyMap.enabledByDefault,
     val nullIsSameAsDefault: Boolean = NullIsSameAsDefault.enabledByDefault,
-    @property:Deprecated(
-        level = DeprecationLevel.ERROR,
-        message = "The return value will be Boolean in 2.19. Until then, use enabledSingletonSupport.",
-        replaceWith = ReplaceWith("enabledSingletonSupport")
-    )
-    @Suppress("DEPRECATION_ERROR")
-    val singletonSupport: SingletonSupport = SingletonSupport.DISABLED,
-    val strictNullChecks: Boolean = StrictNullChecks.enabledByDefault,
-    @Deprecated(
-        level = DeprecationLevel.ERROR,
-        message = "There was a discrepancy between the property name and the Feature name." +
-            " To migrate to the correct property name, it will be ERROR in 2.18 and removed in 2.19.",
-        replaceWith = ReplaceWith("kotlinPropertyNameAsImplicitName")
-    )
-    val useKotlinPropertyNameForGetter: Boolean = KotlinPropertyNameAsImplicitName.enabledByDefault,
+    val singletonSupport: Boolean = SingletonSupport.enabledByDefault,
+    strictNullChecks: Boolean = StrictNullChecks.enabledByDefault,
+    val kotlinPropertyNameAsImplicitName: Boolean = KotlinPropertyNameAsImplicitName.enabledByDefault,
     val useJavaDurationConversion: Boolean = UseJavaDurationConversion.enabledByDefault,
+    private val newStrictNullChecks: Boolean = NewStrictNullChecks.enabledByDefault,
 ) : SimpleModule(KotlinModule::class.java.name, PackageVersion.VERSION) {
-    @Suppress("DEPRECATION_ERROR")
-    val kotlinPropertyNameAsImplicitName: Boolean get() = useKotlinPropertyNameForGetter
-    @Suppress("DEPRECATION_ERROR")
-    val enabledSingletonSupport: Boolean get() = singletonSupport == SingletonSupport.CANONICALIZE
+    /*
+     * Prior to 2.18, an older Enum called SingletonSupport was used to manage feature.
+     * To deprecate it and replace it with singletonSupport: Boolean, the following steps are in progress.
+     *
+     * 1. add enabledSingletonSupport: Boolean property
+     * 2. delete SingletonSupport class and change the property to singletonSupport: Boolean
+     * 3. remove the enabledSingletonSupport property
+     *
+     * Now that 2 is complete, deprecation is in progress for 3.
+     */
+    @Deprecated(
+        level = DeprecationLevel.WARNING,
+        message = "This property is scheduled to be removed in 2.21 or later" +
+                " in order to unify the use of KotlinFeature.",
+        replaceWith = ReplaceWith("singletonSupport")
+    )
+    val enabledSingletonSupport: Boolean get() = singletonSupport
+
+    private val oldStrictNullChecks: Boolean = strictNullChecks
+
+    // To reduce the amount of destructive changes, no properties will be added to the public.
+    val strictNullChecks: Boolean = if (strictNullChecks) {
+        if (newStrictNullChecks) {
+            throw IllegalArgumentException("Enabling both StrictNullChecks and NewStrictNullChecks is not permitted.")
+        }
+
+        true
+    } else {
+        newStrictNullChecks
+    }
 
     companion object {
         // Increment when option is added
-        private const val serialVersionUID = 2L
+        private const val serialVersionUID = 3L
     }
 
     @Deprecated(
@@ -78,14 +95,11 @@ class KotlinModule private constructor(
         builder.isEnabled(NullToEmptyCollection),
         builder.isEnabled(NullToEmptyMap),
         builder.isEnabled(NullIsSameAsDefault),
-        @Suppress("DEPRECATION_ERROR")
-        when {
-            builder.isEnabled(KotlinFeature.SingletonSupport) -> SingletonSupport.CANONICALIZE
-            else -> SingletonSupport.DISABLED
-        },
+        builder.isEnabled(SingletonSupport),
         builder.isEnabled(StrictNullChecks),
         builder.isEnabled(KotlinPropertyNameAsImplicitName),
         builder.isEnabled(UseJavaDurationConversion),
+        builder.isEnabled(NewStrictNullChecks),
     )
 
     override fun setupModule(context: SetupContext) {
@@ -97,9 +111,9 @@ class KotlinModule private constructor(
 
         val cache = ReflectionCache(reflectionCacheSize)
 
-        context.addValueInstantiators(KotlinInstantiators(cache, nullToEmptyCollection, nullToEmptyMap, nullIsSameAsDefault, strictNullChecks))
+        context.addValueInstantiators(KotlinInstantiators(cache, nullToEmptyCollection, nullToEmptyMap, nullIsSameAsDefault, oldStrictNullChecks))
 
-        if (enabledSingletonSupport) {
+        if (singletonSupport) {
             context.addBeanDeserializerModifier(KotlinBeanDeserializerModifier)
         }
 
@@ -111,10 +125,12 @@ class KotlinModule private constructor(
             nullIsSameAsDefault,
             useJavaDurationConversion
         ))
-        context.appendAnnotationIntrospector(KotlinNamesAnnotationIntrospector(cache, kotlinPropertyNameAsImplicitName))
+        context.appendAnnotationIntrospector(
+            KotlinNamesAnnotationIntrospector(cache, newStrictNullChecks, kotlinPropertyNameAsImplicitName)
+        )
 
         context.addDeserializers(KotlinDeserializers(cache, useJavaDurationConversion))
-        context.addKeyDeserializers(KotlinKeyDeserializers)
+        context.addKeyDeserializers(KotlinKeyDeserializers(cache))
         context.addSerializers(KotlinSerializers())
         context.addKeySerializers(KotlinKeySerializers())
 
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinNamesAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinNamesAnnotationIntrospector.kt
index da4ea6849..b082ad855 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinNamesAnnotationIntrospector.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinNamesAnnotationIntrospector.kt
@@ -1,6 +1,8 @@
 package com.fasterxml.jackson.module.kotlin
 
 import com.fasterxml.jackson.annotation.JsonProperty
+import com.fasterxml.jackson.annotation.JsonSetter
+import com.fasterxml.jackson.annotation.Nulls
 import com.fasterxml.jackson.databind.JavaType
 import com.fasterxml.jackson.databind.cfg.MapperConfig
 import com.fasterxml.jackson.databind.introspect.Annotated
@@ -12,8 +14,10 @@ import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector
 import com.fasterxml.jackson.databind.introspect.PotentialCreator
 import java.lang.reflect.Constructor
 import java.util.Locale
+import kotlin.collections.getOrNull
 import kotlin.reflect.KClass
 import kotlin.reflect.KFunction
+import kotlin.reflect.KParameter
 import kotlin.reflect.full.hasAnnotation
 import kotlin.reflect.full.memberProperties
 import kotlin.reflect.full.primaryConstructor
@@ -22,7 +26,8 @@ import kotlin.reflect.jvm.javaType
 
 internal class KotlinNamesAnnotationIntrospector(
     private val cache: ReflectionCache,
-    private val useKotlinPropertyNameForGetter: Boolean
+    private val strictNullChecks: Boolean,
+    private val kotlinPropertyNameAsImplicitName: Boolean
 ) : NopAnnotationIntrospector() {
     private fun getterNameFromJava(member: AnnotatedMethod): String? {
         val name = member.name
@@ -61,7 +66,7 @@ internal class KotlinNamesAnnotationIntrospector(
 
         return when (member) {
             is AnnotatedMethod -> if (member.parameterCount == 0) {
-                if (useKotlinPropertyNameForGetter) {
+                if (kotlinPropertyNameAsImplicitName) {
                     // Fall back to default if it is a getter-like function
                     getterNameFromKotlin(member) ?: getterNameFromJava(member)
                 } else getterNameFromJava(member)
@@ -72,16 +77,26 @@ internal class KotlinNamesAnnotationIntrospector(
     }
 
     override fun refineDeserializationType(config: MapperConfig<*>, a: Annotated, baseType: JavaType): JavaType =
-        (a as? AnnotatedParameter)?.let { _ ->
-            cache.findKotlinParameter(a)?.let { param ->
-                val rawType = a.rawType
-                (param.type.classifier as? KClass<*>)
-                    ?.java
-                    ?.takeIf { it.isUnboxableValueClass() && it != rawType }
-                    ?.let { config.constructType(it) }
-            }
+        findKotlinParameter(a)?.let { param ->
+            val rawType = a.rawType
+            (param.type.classifier as? KClass<*>)
+                ?.java
+                ?.takeIf { it.isUnboxableValueClass() && it != rawType }
+                ?.let { config.constructType(it) }
         } ?: baseType
 
+    override fun findSetterInfo(ann: Annotated): JsonSetter.Value = ann.takeIf { strictNullChecks }
+        ?.let { _ ->
+            findKotlinParameter(ann)?.let { param ->
+                if (param.requireStrictNullCheck(ann.type)) {
+                    JsonSetter.Value.forContentNulls(Nulls.FAIL)
+                } else {
+                    null
+                }
+            }
+        }
+        ?: super.findSetterInfo(ann)
+
     override fun findDefaultCreator(
         config: MapperConfig<*>,
         valueClass: AnnotatedClass,
@@ -90,13 +105,11 @@ internal class KotlinNamesAnnotationIntrospector(
     ): PotentialCreator? {
         val kClass = valueClass.creatableKotlinClass() ?: return null
 
-        val propertyNames = kClass.memberProperties.map { it.name }.toSet()
-
-        val defaultCreator = kClass.let { _ ->
-            // By default, the primary constructor or the only publicly available constructor may be used
-            val ctor = kClass.primaryConstructor ?: kClass.constructors.takeIf { it.size == 1 }?.single()
-            ctor?.takeIf { it.isPossibleCreator(propertyNames) }
-        }
+        val defaultCreator = kClass.primarilyConstructor()
+            ?.takeIf { ctor ->
+                val propertyNames = kClass.memberProperties.map { it.name }.toSet()
+                ctor.isPossibleCreator(propertyNames)
+            }
             ?: return null
 
         return declaredConstructors.find {
@@ -107,13 +120,26 @@ internal class KotlinNamesAnnotationIntrospector(
     }
 
     private fun findKotlinParameterName(param: AnnotatedParameter): String? = cache.findKotlinParameter(param)?.name
+
+    private fun findKotlinParameter(param: Annotated) = (param as? AnnotatedParameter)
+        ?.let { cache.findKotlinParameter(it) }
 }
 
+private fun KParameter.markedNonNullAt(index: Int) = type.arguments.getOrNull(index)?.type?.isMarkedNullable == false
+
+private fun KParameter.requireStrictNullCheck(type: JavaType): Boolean =
+    ((type.isArrayType || type.isCollectionLikeType) && this.markedNonNullAt(0)) ||
+            (type.isMapLikeType && this.markedNonNullAt(1))
+
+
 // If it is not a Kotlin class or an Enum, Creator is not used
 private fun AnnotatedClass.creatableKotlinClass(): KClass<*>? = annotated
     .takeIf { it.isKotlinClass() && !it.isEnum }
     ?.kotlin
 
+// By default, the primary constructor or the only publicly available constructor may be used
+private fun KClass<*>.primarilyConstructor() = primaryConstructor ?: constructors.singleOrNull()
+
 private fun KFunction<*>.isPossibleCreator(propertyNames: Set): Boolean = 0 < parameters.size
     && !isPossibleSingleString(propertyNames)
     && parameters.none { it.name == null }
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt
index 57923a03c..320eb6cfb 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt
@@ -78,8 +78,8 @@ internal class KotlinValueInstantiator(
                     paramType.isMarkedNullable -> null
                     // Primitive types always try to get from a buffer, considering several settings
                     jsonProp.type.isPrimitive -> buffer.getParameter(jsonProp)
-                    // to get suitable "missing" value provided by deserializer
-                    else -> valueDeserializer?.getAbsentValue(ctxt)
+                    // to get suitable "missing" value provided by nullValueProvider
+                    else -> jsonProp.nullValueProvider?.getAbsentValue(ctxt)
                 }
             }
 
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/MethodValueCreator.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/MethodValueCreator.kt
index ed7f68ecf..b6c8dafb9 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/MethodValueCreator.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/MethodValueCreator.kt
@@ -1,5 +1,6 @@
 package com.fasterxml.jackson.module.kotlin
 
+import com.fasterxml.jackson.databind.util.ClassUtil
 import kotlin.reflect.KFunction
 import kotlin.reflect.full.extensionReceiverParameter
 import kotlin.reflect.full.instanceParameter
@@ -39,7 +40,7 @@ internal class MethodValueCreator private constructor(
                 possibleCompanion.java.enclosingClass.declaredFields
                     .firstOrNull { it.type.kotlin.isCompanion }
                     ?.let {
-                        it.isAccessible = true
+                        ClassUtil.checkAndFixAccess(it, false)
 
                         // If the instance of the companion object cannot be obtained, accessibility will always be false
                         it.get(null) to false
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCache.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCache.kt
index b13ae4918..3960deb5e 100644
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCache.kt
+++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCache.kt
@@ -1,5 +1,6 @@
 package com.fasterxml.jackson.module.kotlin
 
+import com.fasterxml.jackson.annotation.OptBoolean
 import com.fasterxml.jackson.databind.introspect.AnnotatedConstructor
 import com.fasterxml.jackson.databind.introspect.AnnotatedMember
 import com.fasterxml.jackson.databind.introspect.AnnotatedMethod
@@ -22,32 +23,12 @@ import kotlin.reflect.jvm.kotlinFunction
 internal class ReflectionCache(reflectionCacheSize: Int) : Serializable {
     companion object {
         // Increment is required when properties that use LRUMap are changed.
-        private const val serialVersionUID = 3L
-    }
-
-    sealed class BooleanTriState(val value: Boolean?) {
-        class True : BooleanTriState(true)
-        class False : BooleanTriState(false)
-        class Empty : BooleanTriState(null)
-
-        companion object {
-            private val TRUE = True()
-            private val FALSE = False()
-            private val EMPTY = Empty()
-
-            fun fromBoolean(value: Boolean?): BooleanTriState {
-                return when (value) {
-                    null -> EMPTY
-                    true -> TRUE
-                    false -> FALSE
-                }
-            }
-        }
+        private const val serialVersionUID = 4L
     }
 
     private val javaExecutableToKotlin = LRUMap>(reflectionCacheSize, reflectionCacheSize)
     private val javaExecutableToValueCreator = LRUMap>(reflectionCacheSize, reflectionCacheSize)
-    private val javaMemberIsRequired = LRUMap(reflectionCacheSize, reflectionCacheSize)
+    private val javaMemberIsRequired = LRUMap(reflectionCacheSize, reflectionCacheSize)
 
     // Initial size is 0 because the value class is not always used
     private val valueClassReturnTypeCache: LRUMap>> =
@@ -102,8 +83,8 @@ internal class ReflectionCache(reflectionCacheSize: Int) : Serializable {
         )
     } // we cannot reflect this method so do the default Java-ish behavior
 
-    fun javaMemberIsRequired(key: AnnotatedMember, calc: (AnnotatedMember) -> Boolean?): Boolean? = javaMemberIsRequired.get(key)?.value
-            ?: calc(key).let { javaMemberIsRequired.putIfAbsent(key, BooleanTriState.fromBoolean(it))?.value ?: it }
+    fun javaMemberIsRequired(key: AnnotatedMember, calc: (AnnotatedMember) -> Boolean?): Boolean? = javaMemberIsRequired.get(key)?.asBoolean()
+            ?: calc(key).let { javaMemberIsRequired.putIfAbsent(key, OptBoolean.fromBoolean(it))?.asBoolean() ?: it }
 
     private fun AnnotatedMethod.getValueClassReturnType(): KClass<*>? {
         val getter = this.member.apply {
diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/SingletonSupport.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/SingletonSupport.kt
deleted file mode 100644
index 7e2d83d9b..000000000
--- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/SingletonSupport.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.fasterxml.jackson.module.kotlin
-
-/**
- * Special handling for singletons.
- */
-@Deprecated(
-    level = DeprecationLevel.ERROR,
-    message = "It will be removed in 2.19 to unify with KotlinFeature.",
-    replaceWith = ReplaceWith("KotlinFeature.SingletonSupport")
-)
-enum class SingletonSupport {
-    // No special handling of singletons (pre-2.10 behavior)
-    //      Each time a Singleton object is deserialized a new instance is created.
-    DISABLED,
-    // Deserialize then canonicalize (was the default in 2.10)
-    //      Deserializing a singleton overwrites the value of the single instance.
-    //     [jackson-module-kotlin#225]: keep Kotlin singletons as singletons
-    CANONICALIZE
-}
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ArgumentBucketTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ArgumentBucketTest.kt
index 20155690f..f011a5ea1 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ArgumentBucketTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ArgumentBucketTest.kt
@@ -1,24 +1,28 @@
 package com.fasterxml.jackson.module.kotlin
 
 import com.fasterxml.jackson.annotation.JsonCreator
-import org.junit.Ignore
-import org.junit.experimental.runners.Enclosed
-import org.junit.runner.RunWith
+import org.junit.jupiter.api.Nested
 import kotlin.reflect.KFunction
 import kotlin.reflect.full.functions
 import kotlin.reflect.full.hasAnnotation
-import kotlin.test.Test
+import org.junit.jupiter.api.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertFalse
 import kotlin.test.assertTrue
 
-
-@RunWith(Enclosed::class)
 class ArgumentBucketTest {
-    class Normal {
-        @Ignore
-        data class Constructor(val foo: String, val bar: String)
+    data class Constructor(val foo: String, val bar: String)
+
+    data class Method(val foo: String, val bar: String) {
+        companion object {
+            @JvmStatic
+            @JsonCreator
+            fun of(foo: String, bar: String): Method = Method(foo, bar)
+        }
+    }
 
+    @Nested
+    inner class Normal {
         @Test
         fun constructorTest() {
             val function: KFunction<*> = ::Constructor
@@ -45,15 +49,6 @@ class ArgumentBucketTest {
             assertEquals("bar", bucket[params[1]])
         }
 
-        @Ignore
-        data class Method(val foo: String, val bar: String) {
-            companion object {
-                @JvmStatic
-                @JsonCreator
-                fun of(foo: String, bar: String): Method = Method(foo, bar)
-            }
-        }
-
         @Test
         fun methodTest() {
             val function: KFunction<*> = Method.Companion::class.functions.first { it.hasAnnotation() }
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/DslTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/DslTest.kt
index e1e00ba22..d448a3eff 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/DslTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/DslTest.kt
@@ -6,9 +6,9 @@ import com.fasterxml.jackson.module.kotlin.KotlinFeature.NullIsSameAsDefault
 import com.fasterxml.jackson.module.kotlin.KotlinFeature.NullToEmptyCollection
 import com.fasterxml.jackson.module.kotlin.KotlinFeature.NullToEmptyMap
 import com.fasterxml.jackson.module.kotlin.KotlinFeature.SingletonSupport
-import com.fasterxml.jackson.module.kotlin.KotlinFeature.StrictNullChecks
-import org.junit.Assert.assertNotNull
-import org.junit.Test
+import com.fasterxml.jackson.module.kotlin.KotlinFeature.NewStrictNullChecks
+import org.junit.jupiter.api.Assertions.assertNotNull
+import org.junit.jupiter.api.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertFalse
 import kotlin.test.assertTrue
@@ -35,7 +35,7 @@ class DslTest {
             enable(NullToEmptyMap)
             enable(NullIsSameAsDefault)
             enable(SingletonSupport)
-            enable(StrictNullChecks)
+            enable(NewStrictNullChecks)
         }
 
         assertNotNull(module)
@@ -43,7 +43,7 @@ class DslTest {
         assertTrue(module.nullToEmptyCollection)
         assertTrue(module.nullToEmptyMap)
         assertTrue(module.nullIsSameAsDefault)
-        assertTrue(module.enabledSingletonSupport)
+        assertTrue(module.singletonSupport)
         assertTrue(module.strictNullChecks)
     }
 
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/JDKSerializabilityTestHelper.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/JDKSerializabilityTestHelper.kt
index a5af1dbdf..0c6493218 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/JDKSerializabilityTestHelper.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/JDKSerializabilityTestHelper.kt
@@ -1,6 +1,6 @@
 package com.fasterxml.jackson.module.kotlin
 
-import junit.framework.TestCase
+import org.junit.jupiter.api.Assertions.fail
 import java.io.ByteArrayInputStream
 import java.io.ByteArrayOutputStream
 import java.io.ObjectInputStream
@@ -14,14 +14,13 @@ fun jdkSerialize(o: Any): ByteArray {
     return bytes.toByteArray()
 }
 
-fun  jdkDeserialize(raw: ByteArray): T? {
+fun  jdkDeserialize(raw: ByteArray): T {
     val objIn = ObjectInputStream(ByteArrayInputStream(raw))
     return try {
         @Suppress("UNCHECKED_CAST")
         objIn.readObject() as T
     } catch (e: ClassNotFoundException) {
-        TestCase.fail("Missing class: " + e.message)
-        null
+        fail("Missing class: " + e.message)
     } finally {
         objIn.close()
     }
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinInstantiatorsTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinInstantiatorsTest.kt
index dad0fc60b..628f5afc8 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinInstantiatorsTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinInstantiatorsTest.kt
@@ -1,8 +1,8 @@
 package com.fasterxml.jackson.module.kotlin
 
 import com.fasterxml.jackson.databind.deser.std.StdValueInstantiator
-import org.junit.Assert.*
-import org.junit.Test
+import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.Test
 
 class KotlinInstantiatorsTest {
     private val mapper = jacksonObjectMapper()
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModuleTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModuleTest.kt
index 5b8fd0aa6..5a7e7de79 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModuleTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModuleTest.kt
@@ -2,13 +2,28 @@ package com.fasterxml.jackson.module.kotlin
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import com.fasterxml.jackson.module.kotlin.KotlinFeature.*
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertTrue
-import org.junit.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertFalse
+import org.junit.jupiter.api.Assertions.assertTrue
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
 import kotlin.test.assertNotNull
 
 class KotlinModuleTest {
+    // After the final migration is complete, this test will be removed.
+    @Test
+    fun strictNullChecksTests() {
+        assertTrue(kotlinModule { enable(StrictNullChecks) }.strictNullChecks)
+        assertTrue(kotlinModule { enable(NewStrictNullChecks) }.strictNullChecks)
+
+        assertThrows {
+            kotlinModule {
+                enable(StrictNullChecks)
+                enable(NewStrictNullChecks)
+            }
+        }
+    }
+
     @Test
     fun builder_Defaults() {
         val module = KotlinModule.Builder().build()
@@ -17,7 +32,7 @@ class KotlinModuleTest {
         assertFalse(module.nullToEmptyCollection)
         assertFalse(module.nullToEmptyMap)
         assertFalse(module.nullIsSameAsDefault)
-        assertFalse(module.enabledSingletonSupport)
+        assertFalse(module.singletonSupport)
         assertFalse(module.strictNullChecks)
         assertFalse(module.kotlinPropertyNameAsImplicitName)
         assertFalse(module.useJavaDurationConversion)
@@ -31,7 +46,7 @@ class KotlinModuleTest {
             enable(NullToEmptyMap)
             enable(NullIsSameAsDefault)
             enable(SingletonSupport)
-            enable(StrictNullChecks)
+            enable(NewStrictNullChecks)
             enable(KotlinPropertyNameAsImplicitName)
             enable(UseJavaDurationConversion)
         }.build()
@@ -40,7 +55,7 @@ class KotlinModuleTest {
         assertTrue(module.nullToEmptyCollection)
         assertTrue(module.nullToEmptyMap)
         assertTrue(module.nullIsSameAsDefault)
-        assertTrue(module.enabledSingletonSupport)
+        assertTrue(module.singletonSupport)
         assertTrue(module.strictNullChecks)
         assertTrue(module.kotlinPropertyNameAsImplicitName)
         assertTrue(module.useJavaDurationConversion)
@@ -79,13 +94,13 @@ class KotlinModuleTest {
             enable(SingletonSupport)
         }.build()
 
-        assertTrue(module.enabledSingletonSupport)
+        assertTrue(module.singletonSupport)
     }
 
     @Test
     fun builder_EnableStrictNullChecks() {
         val module = KotlinModule.Builder().apply {
-            enable(StrictNullChecks)
+            enable(NewStrictNullChecks)
         }.build()
 
         assertTrue(module.strictNullChecks)
@@ -99,7 +114,7 @@ class KotlinModuleTest {
             enable(NullToEmptyMap)
             enable(NullIsSameAsDefault)
             enable(SingletonSupport)
-            enable(StrictNullChecks)
+            enable(NewStrictNullChecks)
         }.build()
 
         val serialized = jdkSerialize(module)
@@ -110,7 +125,7 @@ class KotlinModuleTest {
         assertTrue(deserialized.nullToEmptyCollection)
         assertTrue(deserialized.nullToEmptyMap)
         assertTrue(deserialized.nullIsSameAsDefault)
-        assertTrue(deserialized.enabledSingletonSupport)
+        assertTrue(deserialized.singletonSupport)
         assertTrue(deserialized.strictNullChecks)
     }
 
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/MissingKotlinParameterExceptionTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/MissingKotlinParameterExceptionTest.kt
index 2a15fed5b..713cb6614 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/MissingKotlinParameterExceptionTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/MissingKotlinParameterExceptionTest.kt
@@ -1,6 +1,6 @@
 package com.fasterxml.jackson.module.kotlin
 
-import org.junit.Test
+import org.junit.jupiter.api.Test
 import kotlin.test.assertNotNull
 import kotlin.test.assertNull
 
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReadValueTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReadValueTest.kt
new file mode 100644
index 000000000..66e524c25
--- /dev/null
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReadValueTest.kt
@@ -0,0 +1,89 @@
+package com.fasterxml.jackson.module.kotlin
+
+import com.fasterxml.jackson.databind.RuntimeJsonMappingException
+import com.fasterxml.jackson.databind.node.NullNode
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+import java.io.StringReader
+
+class ReadValueTest {
+    @Nested
+    inner class CheckTypeMismatchTest {
+        @Test
+        fun jsonParser() {
+            val src = defaultMapper.createParser("null")
+            assertThrows {
+                defaultMapper.readValue(src)
+            }
+        }
+
+        @Test
+        fun file() {
+            val src = createTempJson("null")
+            assertThrows {
+                defaultMapper.readValue(src)
+            }
+        }
+
+        // Not implemented because a way to test without mocks was not found
+        // @Test
+        // fun url() {
+        // }
+
+        @Test
+        fun string() {
+            val src = "null"
+            assertThrows {
+                defaultMapper.readValue(src)
+            }
+        }
+
+        @Test
+        fun reader() {
+            val src = StringReader("null")
+            assertThrows {
+                defaultMapper.readValue(src)
+            }
+        }
+
+        @Test
+        fun inputStream() {
+            val src = "null".byteInputStream()
+            assertThrows {
+                defaultMapper.readValue(src)
+            }
+        }
+
+        @Test
+        fun byteArray() {
+            val src = "null".toByteArray()
+            assertThrows {
+                defaultMapper.readValue(src)
+            }
+        }
+
+        @Test
+        fun treeToValueTreeNode() {
+            assertThrows {
+                defaultMapper.treeToValue(NullNode.instance)
+            }
+        }
+
+        @Test
+        fun convertValueAny() {
+            assertThrows {
+                defaultMapper.convertValue(null)
+            }
+        }
+
+        @Test
+        fun readValueTypedJsonParser() {
+            val reader = defaultMapper.reader()
+            val src = reader.createParser("null")
+            assertThrows {
+                reader.readValueTyped(src)
+            }
+        }
+    }
+}
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReadValuesTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReadValuesTest.kt
new file mode 100644
index 000000000..2d2aa10b5
--- /dev/null
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReadValuesTest.kt
@@ -0,0 +1,65 @@
+package com.fasterxml.jackson.module.kotlin
+
+import com.fasterxml.jackson.core.JsonParser
+import com.fasterxml.jackson.databind.DeserializationContext
+import com.fasterxml.jackson.databind.RuntimeJsonMappingException
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer
+import com.fasterxml.jackson.databind.module.SimpleModule
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+import kotlin.test.assertEquals
+
+class ReadValuesTest {
+    class MyStrDeser : StdDeserializer(String::class.java) {
+        override fun deserialize(
+            p: JsonParser,
+            ctxt: DeserializationContext
+        ): String? = p.valueAsString.takeIf { it != "bar" }
+    }
+
+    @Nested
+    inner class CheckTypeMismatchTest {
+        val mapper = jacksonObjectMapper().registerModule(
+            object : SimpleModule() {
+                init {
+                    addDeserializer(String::class.java, MyStrDeser())
+                }
+            }
+        )!!
+
+        @Test
+        fun readValuesJsonParserNext() {
+            val src = mapper.createParser(""""foo"${"\n"}"bar"""")
+            val itr = mapper.readValues(src)
+
+            assertEquals("foo", itr.next())
+            assertThrows {
+                itr.next()
+            }
+        }
+
+        @Test
+        fun readValuesJsonParserNextValue() {
+            val src = mapper.createParser(""""foo"${"\n"}"bar"""")
+            val itr = mapper.readValues(src)
+
+            assertEquals("foo", itr.nextValue())
+            assertThrows {
+                itr.nextValue()
+            }
+        }
+
+        @Test
+        fun readValuesTypedJsonParser() {
+            val reader = mapper.reader()
+            val src = reader.createParser(""""foo"${"\n"}"bar"""")
+            val itr = reader.readValuesTyped(src)
+
+            assertEquals("foo", itr.next())
+            assertThrows {
+                itr.next()
+            }
+        }
+    }
+}
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCacheTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCacheTest.kt
index 7914a402a..1a03a923b 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCacheTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCacheTest.kt
@@ -1,6 +1,6 @@
 package com.fasterxml.jackson.module.kotlin
 
-import org.junit.Test
+import org.junit.jupiter.api.Test
 import kotlin.test.assertNotNull
 
 class ReflectionCacheTest {
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/TestCommons.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/TestCommons.kt
index 3bd3e5bd8..327fc3a55 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/TestCommons.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/TestCommons.kt
@@ -5,6 +5,10 @@ import com.fasterxml.jackson.core.util.DefaultIndenter
 import com.fasterxml.jackson.core.util.DefaultPrettyPrinter
 import com.fasterxml.jackson.databind.ObjectMapper
 import com.fasterxml.jackson.databind.ObjectWriter
+import java.io.File
+import java.io.FileOutputStream
+import java.io.OutputStreamWriter
+import java.nio.charset.StandardCharsets
 import kotlin.reflect.KParameter
 import kotlin.reflect.full.memberProperties
 import kotlin.reflect.full.primaryConstructor
@@ -30,3 +34,16 @@ internal inline fun  assertReflectEquals(expected: T, actual: T
         assertEquals(it.get(expected), it.get(actual))
     }
 }
+
+internal fun createTempJson(json: String): File {
+    val file = File.createTempFile("temp", ".json")
+    file.deleteOnExit()
+    OutputStreamWriter(
+        FileOutputStream(file),
+        StandardCharsets.UTF_8
+    ).use { writer ->
+        writer.write(json)
+        writer.flush()
+    }
+    return file
+}
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/StrictNullChecksTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/StrictNullChecksTest.kt
new file mode 100644
index 000000000..d0d74f09f
--- /dev/null
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/StrictNullChecksTest.kt
@@ -0,0 +1,139 @@
+package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser
+
+import com.fasterxml.jackson.annotation.JsonSetter
+import com.fasterxml.jackson.annotation.Nulls
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.databind.exc.InvalidNullException
+import com.fasterxml.jackson.module.kotlin.KotlinFeature
+import com.fasterxml.jackson.module.kotlin.KotlinModule
+import com.fasterxml.jackson.module.kotlin.readValue
+import org.junit.jupiter.api.Assertions
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+
+class StrictNullChecksTest {
+    val mapper: ObjectMapper = ObjectMapper()
+        .registerModule(
+            KotlinModule.Builder()
+                .enable(KotlinFeature.NewStrictNullChecks)
+                .build()
+        )
+
+    class ArrayWrapper(val value: Array)
+    data class ListWrapper(val value: List)
+    data class MapWrapper(val value: Map)
+
+    @Nested
+    inner class NonNullInput {
+        @Test
+        fun array() {
+            val expected = ArrayWrapper(arrayOf(1))
+            val src = mapper.writeValueAsString(expected)
+            val result = mapper.readValue(src)
+
+            Assertions.assertArrayEquals(expected.value, result.value)
+        }
+
+        @Test
+        fun list() {
+            val expected = ListWrapper(listOf(1))
+            val src = mapper.writeValueAsString(expected)
+            val result = mapper.readValue(src)
+
+            Assertions.assertEquals(expected, result)
+        }
+
+        @Test
+        fun map() {
+            val expected = MapWrapper(mapOf("foo" to 1))
+            val src = mapper.writeValueAsString(expected)
+            val result = mapper.readValue(src)
+
+            Assertions.assertEquals(expected, result)
+        }
+    }
+
+    data class AnyWrapper(val value: Any)
+
+    @Nested
+    inner class NullInput {
+        @Test
+        fun array() {
+            val src = mapper.writeValueAsString(AnyWrapper(arrayOf(null)))
+            assertThrows { mapper.readValue(src) }
+        }
+
+        @Test
+        fun list() {
+            val src = mapper.writeValueAsString(AnyWrapper(arrayOf(null)))
+            assertThrows { mapper.readValue(src) }
+        }
+
+        @Test
+        fun map() {
+            val src = mapper.writeValueAsString(AnyWrapper(mapOf("foo" to null)))
+            assertThrows { mapper.readValue(src) }
+        }
+    }
+
+    class ContentNullsSkipArrayWrapper(@JsonSetter(contentNulls = Nulls.SKIP) val value: Array)
+    data class ContentNullsSkipListWrapper(@JsonSetter(contentNulls = Nulls.SKIP) val value: List)
+    data class ContentNullsSkipMapWrapper(@JsonSetter(contentNulls = Nulls.SKIP) val value: Map)
+
+    @Nested
+    inner class CustomByAnnotationTest {
+        @Test
+        fun array() {
+            val expected = ContentNullsSkipArrayWrapper(emptyArray())
+            val src = mapper.writeValueAsString(AnyWrapper(arrayOf(null)))
+            val result = mapper.readValue(src)
+
+            Assertions.assertArrayEquals(expected.value, result.value)
+        }
+
+        @Test
+        fun list() {
+            val expected = ContentNullsSkipListWrapper(emptyList())
+            val src = mapper.writeValueAsString(AnyWrapper(listOf(null)))
+            val result = mapper.readValue(src)
+
+            Assertions.assertEquals(expected, result)
+        }
+
+        @Test
+        fun map() {
+            val expected = ContentNullsSkipMapWrapper(emptyMap())
+            val src = mapper.writeValueAsString(AnyWrapper(mapOf("foo" to null)))
+            val result = mapper.readValue(src)
+
+            Assertions.assertEquals(expected, result)
+        }
+    }
+
+    class AnnotatedArrayWrapper(@JsonSetter(nulls = Nulls.SKIP) val value: Array = emptyArray())
+    data class AnnotatedListWrapper(@JsonSetter(nulls = Nulls.SKIP) val value: List = emptyList())
+    data class AnnotatedMapWrapper(@JsonSetter(nulls = Nulls.SKIP) val value: Map = emptyMap())
+
+    // If Default is specified by annotation, it is not overridden.
+    @Nested
+    inner class AnnotatedNullInput {
+        @Test
+        fun array() {
+            val src = mapper.writeValueAsString(AnyWrapper(arrayOf(null)))
+            assertThrows { mapper.readValue(src) }
+        }
+
+        @Test
+        fun list() {
+            val src = mapper.writeValueAsString(AnyWrapper(arrayOf(null)))
+            assertThrows { mapper.readValue(src) }
+        }
+
+        @Test
+        fun map() {
+            val src = mapper.writeValueAsString(AnyWrapper(mapOf("foo" to null)))
+            assertThrows { mapper.readValue(src) }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/JacksonInjectTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/JacksonInjectTest.kt
index 73468e6eb..5b8e31013 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/JacksonInjectTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/JacksonInjectTest.kt
@@ -3,9 +3,9 @@ package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass
 import com.fasterxml.jackson.annotation.JacksonInject
 import com.fasterxml.jackson.databind.InjectableValues
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertThrows
-import org.junit.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertThrows
+import org.junit.jupiter.api.Test
 
 class JacksonInjectTest {
     // This is specified as a getter because there is a possibility of problems if it is assigned to a field.
@@ -31,24 +31,28 @@ class JacksonInjectTest {
 
     @Test
     fun test() {
-        val injectables = InjectableValues.Std(
-            mapOf(
-                "pNn" to Primitive(0),
-                "pN" to Primitive(1),
-                "nnoNn" to NonNullObject("nnoNn"),
-                "nnoN" to NonNullObject("nnoN"),
-                "noNnNn" to NullableObject("noNnNn"),
-                "noNnN" to NullableObject(null),
-                "noNNn" to NullableObject("noNNn"),
-                "noNN" to NullableObject(null)
-            )
+        val injectables = mapOf(
+            "pNn" to Primitive(0),
+            "pN" to Primitive(1),
+            "nnoNn" to NonNullObject("nnoNn"),
+            "nnoN" to NonNullObject("nnoN"),
+            "noNnNn" to NullableObject("noNnNn"),
+            "noNnN" to NullableObject(null),
+            "noNNn" to NullableObject("noNNn"),
+            "noNN" to NullableObject(null)
         )
 
         val reader = jacksonObjectMapper()
             .readerFor(Dto::class.java)
-            .with(injectables)
+            .with(InjectableValues.Std(injectables))
+
+        val result = reader.readValue("{}")
+        val expected = ::Dto.let { ctor ->
+            val args = ctor.parameters.associateWith { injectables[it.name] }
+            ctor.callBy(args)
+        }
 
-        println(reader.readValue("{}"))
+        assertEquals(expected, result)
     }
 
     data class DataBind4218FailingDto(
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/NullableObjectEdgeCases.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/NullableObjectEdgeCases.kt
index 66d2d0878..95b44ae6d 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/NullableObjectEdgeCases.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/NullableObjectEdgeCases.kt
@@ -10,9 +10,9 @@ import com.fasterxml.jackson.module.kotlin.WrapsNullableValueClassDeserializer
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.fasterxml.jackson.module.kotlin.readValue
 import kotlin.reflect.jvm.internal.KotlinReflectionInternalError
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertThrows
-import org.junit.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
 
 class NullableObjectEdgeCases {
     @JvmInline
@@ -61,7 +61,7 @@ class NullableObjectEdgeCases {
     // There is a problem with #51, so it is a failing test.
     @Test
     fun `Nulls_SKIP works`() {
-        assertThrows("#761(KT-57357) fixed", KotlinReflectionInternalError::class.java) {
+        assertThrows("#761(KT-57357) fixed") {
             val result = jacksonObjectMapper().readValue("""{"nn":null,"n":null}""")
             assertEquals(NullValue(VC("skip"), VC("skip")), result)
         }
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/ValueClasses.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/ValueClasses.kt
index 5855a6f1c..1bfb3ccd9 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/ValueClasses.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/ValueClasses.kt
@@ -4,12 +4,17 @@ import com.fasterxml.jackson.core.JsonParser
 import com.fasterxml.jackson.databind.DeserializationContext
 import com.fasterxml.jackson.databind.deser.std.StdDeserializer
 import com.fasterxml.jackson.module.kotlin.WrapsNullableValueClassDeserializer
+import com.fasterxml.jackson.databind.KeyDeserializer as JacksonKeyDeserializer
 
 @JvmInline
 value class Primitive(val v: Int) {
     class Deserializer : StdDeserializer(Primitive::class.java) {
         override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Primitive = Primitive(p.intValue + 100)
     }
+
+    class KeyDeserializer : JacksonKeyDeserializer() {
+        override fun deserializeKey(key: String, ctxt: DeserializationContext) = Primitive(key.toInt() + 100)
+    }
 }
 
 @JvmInline
@@ -18,6 +23,10 @@ value class NonNullObject(val v: String) {
         override fun deserialize(p: JsonParser, ctxt: DeserializationContext): NonNullObject =
             NonNullObject(p.valueAsString + "-deser")
     }
+
+    class KeyDeserializer : JacksonKeyDeserializer() {
+        override fun deserializeKey(key: String, ctxt: DeserializationContext) = NonNullObject("$key-deser")
+    }
 }
 
 @JvmInline
@@ -28,4 +37,8 @@ value class NullableObject(val v: String?) {
 
         override fun getBoxedNullValue(): NullableObject = NullableObject("null-value-deser")
     }
+
+    class KeyDeserializer : JacksonKeyDeserializer() {
+        override fun deserializeKey(key: String, ctxt: DeserializationContext) = NullableObject("$key-deser")
+    }
 }
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/WithoutCustomDeserializeMethodTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/WithoutCustomDeserializeMethodTest.kt
index 79c6a3394..ab5709599 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/WithoutCustomDeserializeMethodTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/WithoutCustomDeserializeMethodTest.kt
@@ -3,24 +3,22 @@ package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass
 import com.fasterxml.jackson.module.kotlin.defaultMapper
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.fasterxml.jackson.module.kotlin.readValue
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertThrows
-import org.junit.Assert.assertTrue
-import org.junit.Ignore
-import org.junit.experimental.runners.Enclosed
-import org.junit.runner.RunWith
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertTrue
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.assertThrows
+import org.junit.jupiter.api.Test
 import java.lang.reflect.InvocationTargetException
-import kotlin.test.Test
+import kotlin.test.assertNotEquals
 
-@RunWith(Enclosed::class)
 class WithoutCustomDeserializeMethodTest {
-    @Ignore
     companion object {
         val mapper = jacksonObjectMapper()
         val throwable = IllegalArgumentException("test")
     }
 
-    class DirectDeserializeTest {
+    @Nested
+    inner class DirectDeserializeTest {
         @Test
         fun primitive() {
             val result = defaultMapper.readValue("1")
@@ -34,7 +32,8 @@ class WithoutCustomDeserializeMethodTest {
         }
 
         @Suppress("ClassName")
-        class NullableObject_ {
+        @Nested
+        inner class NullableObject_ {
             @Test
             fun value() {
                 val result = defaultMapper.readValue(""""foo"""")
@@ -44,32 +43,12 @@ class WithoutCustomDeserializeMethodTest {
             // failing
             @Test
             fun nullString() {
-                // #209 has been fixed.
-                assertThrows(NullPointerException::class.java) {
-                    val result = defaultMapper.readValue("null")
-                    assertEquals(NullableObject(null), result)
-                }
+                val result = defaultMapper.readValue("null")
+                assertNotEquals(NullableObject(null), result, "kogera #209 has been fixed.")
             }
         }
-
-        @Ignore
-        @JvmInline
-        value class HasCheckConstructor(val value: Int) {
-            init {
-                if (value < 0) throw throwable
-            }
-        }
-
-        @Test
-        fun callConstructorCheckTest() {
-            val e = assertThrows(InvocationTargetException::class.java) {
-                defaultMapper.readValue("-1")
-            }
-            assertTrue(e.cause === throwable)
-        }
     }
 
-    @Ignore
     data class Dst(
         val pNn: Primitive,
         val pN: Primitive?,
@@ -79,39 +58,50 @@ class WithoutCustomDeserializeMethodTest {
         val noN: NullableObject?
     )
 
-    class InParameterDeserialize {
-        @Test
-        fun withoutNull() {
-            val expected = Dst(
-                Primitive(1),
-                Primitive(2),
-                NonNullObject("foo"),
-                NonNullObject("bar"),
-                NullableObject("baz"),
-                NullableObject("qux")
-            )
-            val src = mapper.writeValueAsString(expected)
-            val result = mapper.readValue(src)
+    @Test
+    fun withoutNull() {
+        val expected = Dst(
+            Primitive(1),
+            Primitive(2),
+            NonNullObject("foo"),
+            NonNullObject("bar"),
+            NullableObject("baz"),
+            NullableObject("qux")
+        )
+        val src = mapper.writeValueAsString(expected)
+        val result = mapper.readValue(src)
 
-            assertEquals(expected, result)
-        }
+        assertEquals(expected, result)
+    }
 
-        @Test
-        fun withNull() {
-            val expected = Dst(
-                Primitive(1),
-                null,
-                NonNullObject("foo"),
-                null,
-                NullableObject(null),
-                null
-            )
-            val src = mapper.writeValueAsString(expected)
-            val result = mapper.readValue(src)
+    @Test
+    fun withNull() {
+        val expected = Dst(
+            Primitive(1),
+            null,
+            NonNullObject("foo"),
+            null,
+            NullableObject(null),
+            null
+        )
+        val src = mapper.writeValueAsString(expected)
+        val result = mapper.readValue(src)
 
-            assertEquals(expected, result)
+        assertEquals(expected, result)
+    }
+
+    @JvmInline
+    value class HasCheckConstructor(val value: Int) {
+        init {
+            if (value < 0) throw throwable
         }
     }
 
+    @Test
+    fun callConstructorCheckTest() {
+        val e = assertThrows { defaultMapper.readValue("-1") }
+        assertTrue(e.cause === throwable)
+    }
+
     // If all JsonCreator tests are OK, no need to check throws from factory functions.
 }
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/NonNullObjectTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/NonNullObjectTest.kt
index c7124cdd0..4d12664c7 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/NonNullObjectTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/NonNullObjectTest.kt
@@ -4,8 +4,8 @@ import com.fasterxml.jackson.annotation.JsonCreator
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NonNullObject
 import com.fasterxml.jackson.module.kotlin.readValue
-import org.junit.Assert.assertEquals
-import org.junit.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
 
 class NonNullObjectTest {
     companion object {
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/NullableObjectTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/NullableObjectTest.kt
index 408f69a95..596a44736 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/NullableObjectTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/NullableObjectTest.kt
@@ -4,9 +4,9 @@ import com.fasterxml.jackson.annotation.JsonCreator
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.fasterxml.jackson.module.kotlin.readValue
 import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NullableObject
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertThrows
-import kotlin.test.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertThrows
+import org.junit.jupiter.api.Test
 
 class NullableObjectTest {
     companion object {
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/PrimitiveTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/PrimitiveTest.kt
index 1d20a229d..a79794605 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/PrimitiveTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/defaultArgument/PrimitiveTest.kt
@@ -4,8 +4,8 @@ import com.fasterxml.jackson.annotation.JsonCreator
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.Primitive
 import com.fasterxml.jackson.module.kotlin.readValue
-import org.junit.Assert.assertEquals
-import org.junit.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
 
 class PrimitiveTest {
     companion object {
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/SpecifiedForObjectMapperTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/SpecifiedForObjectMapperTest.kt
index c56c75c2d..643883a74 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/SpecifiedForObjectMapperTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/SpecifiedForObjectMapperTest.kt
@@ -6,16 +6,12 @@ import com.fasterxml.jackson.module.kotlin.readValue
 import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NonNullObject
 import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NullableObject
 import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.Primitive
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertThrows
-import org.junit.Ignore
-import org.junit.experimental.runners.Enclosed
-import org.junit.runner.RunWith
-import kotlin.test.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
+import kotlin.test.assertNotEquals
 
-@RunWith(Enclosed::class)
 class SpecifiedForObjectMapperTest {
-    @Ignore
     companion object {
         val mapper = jacksonObjectMapper().apply {
             val module = SimpleModule().apply {
@@ -27,7 +23,8 @@ class SpecifiedForObjectMapperTest {
         }
     }
 
-    class DirectDeserialize {
+    @Nested
+    inner class DirectDeserialize {
         @Test
         fun primitive() {
             val result = mapper.readValue("1")
@@ -41,7 +38,8 @@ class SpecifiedForObjectMapperTest {
         }
 
         @Suppress("ClassName")
-        class NullableObject_ {
+        @Nested
+        inner class NullableObject_ {
             @Test
             fun value() {
                 val result = mapper.readValue(""""foo"""")
@@ -51,16 +49,12 @@ class SpecifiedForObjectMapperTest {
             // failing
             @Test
             fun nullString() {
-                // #209 has been fixed.
-                assertThrows(NullPointerException::class.java) {
-                    val result = mapper.readValue("null")
-                    assertEquals(NullableObject("null-value-deser"), result)
-                }
+                val result = mapper.readValue("null")
+                assertNotEquals(NullableObject("null-value-deser"), result, "kogera #209 has been fixed.")
             }
         }
     }
 
-    @Ignore
     data class Dst(
         val pNn: Primitive,
         val pN: Primitive?,
@@ -70,53 +64,51 @@ class SpecifiedForObjectMapperTest {
         val noN: NullableObject?
     )
 
-    class InParameterDeserialize {
-        @Test
-        fun nonNull() {
-            val base = Dst(
-                Primitive(1),
-                Primitive(2),
-                NonNullObject("foo"),
-                NonNullObject("bar"),
-                NullableObject("baz"),
-                NullableObject("qux")
-            )
-            val src = mapper.writeValueAsString(base)
-            val result = mapper.readValue(src)
+    @Test
+    fun nonNull() {
+        val base = Dst(
+            Primitive(1),
+            Primitive(2),
+            NonNullObject("foo"),
+            NonNullObject("bar"),
+            NullableObject("baz"),
+            NullableObject("qux")
+        )
+        val src = mapper.writeValueAsString(base)
+        val result = mapper.readValue(src)
 
-            val expected = Dst(
-                Primitive(101),
-                Primitive(102),
-                NonNullObject("foo-deser"),
-                NonNullObject("bar-deser"),
-                NullableObject("baz-deser"),
-                NullableObject("qux-deser")
-            )
-            assertEquals(expected, result)
-        }
+        val expected = Dst(
+            Primitive(101),
+            Primitive(102),
+            NonNullObject("foo-deser"),
+            NonNullObject("bar-deser"),
+            NullableObject("baz-deser"),
+            NullableObject("qux-deser")
+        )
+        assertEquals(expected, result)
+    }
 
-        @Test
-        fun withNull() {
-            val base = Dst(
-                Primitive(1),
-                null,
-                NonNullObject("foo"),
-                null,
-                NullableObject(null),
-                null
-            )
-            val src = mapper.writeValueAsString(base)
-            val result = mapper.readValue(src)
+    @Test
+    fun withNull() {
+        val base = Dst(
+            Primitive(1),
+            null,
+            NonNullObject("foo"),
+            null,
+            NullableObject(null),
+            null
+        )
+        val src = mapper.writeValueAsString(base)
+        val result = mapper.readValue(src)
 
-            val expected = Dst(
-                Primitive(101),
-                null,
-                NonNullObject("foo-deser"),
-                null,
-                NullableObject("null-value-deser"),
-                null
-            )
-            assertEquals(expected, result)
-        }
+        val expected = Dst(
+            Primitive(101),
+            null,
+            NonNullObject("foo-deser"),
+            null,
+            NullableObject("null-value-deser"),
+            null
+        )
+        assertEquals(expected, result)
     }
 }
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/SpecifiedForClassTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/SpecifiedForClassTest.kt
index 55d42d10b..8b8bcb19f 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/SpecifiedForClassTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/SpecifiedForClassTest.kt
@@ -6,8 +6,8 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import com.fasterxml.jackson.databind.deser.std.StdDeserializer
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.fasterxml.jackson.module.kotlin.readValue
-import org.junit.Assert.assertEquals
-import kotlin.test.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
 
 class SpecifiedForClassTest {
     @JsonDeserialize(using = Value.Deserializer::class)
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/NonNullObjectTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/NonNullObjectTest.kt
index 5cc395415..744de4168 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/NonNullObjectTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/NonNullObjectTest.kt
@@ -4,20 +4,15 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.fasterxml.jackson.module.kotlin.readValue
 import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NonNullObject
-import org.junit.Assert.assertEquals
-import org.junit.Ignore
-import org.junit.experimental.runners.Enclosed
-import org.junit.runner.RunWith
-import kotlin.test.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
 
-@RunWith(Enclosed::class)
 class NonNullObjectTest {
-    @Ignore
     companion object {
         val mapper = jacksonObjectMapper()
     }
 
-    @Ignore
     data class NonNull(
         @get:JsonDeserialize(using = NonNullObject.Deserializer::class)
         val getterAnn: NonNullObject,
@@ -25,22 +20,19 @@ class NonNullObjectTest {
         val fieldAnn: NonNullObject
     )
 
-    class NonNullTest {
-        @Test
-        fun nonNull() {
-            val result = mapper.readValue(
-                """
+    @Test
+    fun nonNull() {
+        val result = mapper.readValue(
+            """
                 {
                   "getterAnn" : "foo",
                   "fieldAnn" : "bar"
                 }
             """.trimIndent()
-            )
-            assertEquals(NonNull(NonNullObject("foo-deser"), NonNullObject("bar-deser")), result)
-        }
+        )
+        assertEquals(NonNull(NonNullObject("foo-deser"), NonNullObject("bar-deser")), result)
     }
 
-    @Ignore
     data class Nullable(
         @get:JsonDeserialize(using = NonNullObject.Deserializer::class)
         val getterAnn: NonNullObject?,
@@ -48,7 +40,8 @@ class NonNullObjectTest {
         val fieldAnn: NonNullObject?
     )
 
-    class NullableTest {
+    @Nested
+    inner class NullableTest {
         @Test
         fun nonNullInput() {
             val result = mapper.readValue(
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/NullableObjectTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/NullableObjectTest.kt
index b9319f938..ad424ad08 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/NullableObjectTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/NullableObjectTest.kt
@@ -4,20 +4,15 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.fasterxml.jackson.module.kotlin.readValue
 import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NullableObject
-import org.junit.Assert.assertEquals
-import org.junit.Ignore
-import org.junit.experimental.runners.Enclosed
-import org.junit.runner.RunWith
-import kotlin.test.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
 
-@RunWith(Enclosed::class)
 class NullableObjectTest {
-    @Ignore
     companion object {
         val mapper = jacksonObjectMapper()
     }
 
-    @Ignore
     data class NonNull(
         @get:JsonDeserialize(using = NullableObject.DeserializerWrapsNullable::class)
         val getterAnn: NullableObject,
@@ -25,22 +20,19 @@ class NullableObjectTest {
         val fieldAnn: NullableObject
     )
 
-    class NonNullTest {
-        @Test
-        fun nonNull() {
-            val result = mapper.readValue(
-                """
+    @Test
+    fun nonNull() {
+        val result = mapper.readValue(
+            """
                 {
                   "getterAnn" : "foo",
                   "fieldAnn" : "bar"
                 }
             """.trimIndent()
-            )
-            assertEquals(NonNull(NullableObject("foo-deser"), NullableObject("bar-deser")), result)
-        }
+        )
+        assertEquals(NonNull(NullableObject("foo-deser"), NullableObject("bar-deser")), result)
     }
 
-    @Ignore
     data class Nullable(
         @get:JsonDeserialize(using = NullableObject.DeserializerWrapsNullable::class)
         val getterAnn: NullableObject?,
@@ -48,7 +40,8 @@ class NullableObjectTest {
         val fieldAnn: NullableObject?
     )
 
-    class NullableTest {
+    @Nested
+    inner class NullableTest {
         @Test
         fun nonNullInput() {
             val result = mapper.readValue(
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/PrimitiveTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/PrimitiveTest.kt
index 7cdc31b8c..521e762f8 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/PrimitiveTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/deserializer/byAnnotation/specifiedForProperty/PrimitiveTest.kt
@@ -4,20 +4,15 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.fasterxml.jackson.module.kotlin.readValue
 import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.Primitive
-import org.junit.Assert.assertEquals
-import org.junit.experimental.runners.Enclosed
-import org.junit.runner.RunWith
-import kotlin.test.Ignore
-import kotlin.test.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
 
-@RunWith(Enclosed::class)
 class PrimitiveTest {
-    @Ignore
     companion object {
         val mapper = jacksonObjectMapper()
     }
 
-    @Ignore
     data class NonNull(
         @get:JsonDeserialize(using = Primitive.Deserializer::class)
         val getterAnn: Primitive,
@@ -25,22 +20,19 @@ class PrimitiveTest {
         val fieldAnn: Primitive
     )
 
-    class NonNullTest {
-        @Test
-        fun nonNull() {
-            val result = mapper.readValue(
-                """
+    @Test
+    fun nonNull() {
+        val result = mapper.readValue(
+            """
                 {
                   "getterAnn" : 1,
                   "fieldAnn" : 2
                 }
             """.trimIndent()
-            )
-            assertEquals(NonNull(Primitive(101), Primitive(102)), result)
-        }
+        )
+        assertEquals(NonNull(Primitive(101), Primitive(102)), result)
     }
 
-    @Ignore
     data class Nullable(
         @get:JsonDeserialize(using = Primitive.Deserializer::class)
         val getterAnn: Primitive?,
@@ -48,7 +40,8 @@ class PrimitiveTest {
         val fieldAnn: Primitive?
     )
 
-    class NullableTest {
+    @Nested
+    inner class NullableTest {
         @Test
         fun nonNullInput() {
             val result = mapper.readValue(
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/HandledByJacksonTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/HandledByJacksonTest.kt
index 047f470e9..effeea18f 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/HandledByJacksonTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/HandledByJacksonTest.kt
@@ -3,8 +3,8 @@ package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.j
 import com.fasterxml.jackson.annotation.JsonCreator
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.fasterxml.jackson.module.kotlin.readValue
-import org.junit.Assert.assertEquals
-import org.junit.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
 
 // Test for Creator that can be handled by the Jackson mechanism.
 class HandledByJacksonTest {
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/HandledByKogeraTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/HandledByKogeraTest.kt
index 147c9889a..bf76a9c2f 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/HandledByKogeraTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/HandledByKogeraTest.kt
@@ -4,9 +4,9 @@ import com.fasterxml.jackson.annotation.JsonCreator
 import com.fasterxml.jackson.databind.exc.InvalidDefinitionException
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import com.fasterxml.jackson.module.kotlin.readValue
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertThrows
-import org.junit.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertThrows
+import org.junit.jupiter.api.Test
 
 // Test on the case of deserialization by ValueClassBoxDeserializer
 class HandledByKogeraTest {
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/InCreatorArgumentTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/InCreatorArgumentTest.kt
index 621a213dd..cd1961622 100644
--- a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/InCreatorArgumentTest.kt
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/jsonCreator/InCreatorArgumentTest.kt
@@ -6,8 +6,8 @@ import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.No
 import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NullableObject
 import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.Primitive
 import com.fasterxml.jackson.module.kotlin.readValue
-import org.junit.Assert.assertEquals
-import org.junit.Test
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
 
 private fun Primitive.modify(): Primitive = Primitive(v + 100)
 private fun NonNullObject.modify(): NonNullObject = NonNullObject("$v-creator")
diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/mapKey/WithoutCustomDeserializeMethodTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/mapKey/WithoutCustomDeserializeMethodTest.kt
new file mode 100644
index 000000000..b80d7375b
--- /dev/null
+++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/kogeraIntegration/deser/valueClass/mapKey/WithoutCustomDeserializeMethodTest.kt
@@ -0,0 +1,117 @@
+package com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.mapKey
+
+import com.fasterxml.jackson.databind.DeserializationContext
+import com.fasterxml.jackson.databind.JsonMappingException
+import com.fasterxml.jackson.databind.exc.InvalidDefinitionException
+import com.fasterxml.jackson.databind.module.SimpleModule
+import com.fasterxml.jackson.module.kotlin.defaultMapper
+import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
+import com.fasterxml.jackson.module.kotlin.readValue
+import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NonNullObject
+import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.NullableObject
+import com.fasterxml.jackson.module.kotlin.kogeraIntegration.deser.valueClass.Primitive
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertTrue
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+import java.lang.reflect.InvocationTargetException
+import com.fasterxml.jackson.databind.KeyDeserializer as JacksonKeyDeserializer
+
+class WithoutCustomDeserializeMethodTest {
+    companion object {
+        val throwable = IllegalArgumentException("test")
+    }
+
+    @Nested
+    inner class DirectDeserialize {
+        @Test
+        fun primitive() {
+            val result = defaultMapper.readValue