FINERACT-2009: Upgrade latest framework libs
diff --git a/.github/workflows/build-docker-mariadb.yml b/.github/workflows/build-docker-mariadb.yml
index dfcbb52..0882613 100644
--- a/.github/workflows/build-docker-mariadb.yml
+++ b/.github/workflows/build-docker-mariadb.yml
@@ -16,17 +16,19 @@
         with:
           fetch-depth: 0
       - name: Set up JDK 17
-        uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
+        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4
         with:
           java-version: '17'
           distribution: 'zulu'
           cache: gradle
       - name: Build the image
-        run: ./gradlew :fineract-provider:clean :fineract-provider:jibDockerBuild -x test
+        run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:build :fineract-provider:jibDockerBuild -x test -x cucumber
       - name: Start the stack
-        run: docker-compose up -d
+        run: docker compose up -d
       - name: Wait for stack to come up
-        run: sleep 300
+        run: sleep 500
+      - name: Check the stack
+        run: docker ps
       - name: Check health
         run: curl -f -k --retry 10 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
       - name: Check info
diff --git a/.github/workflows/build-docker-postgresql.yml b/.github/workflows/build-docker-postgresql.yml
index ab92790..53bb8d3 100644
--- a/.github/workflows/build-docker-postgresql.yml
+++ b/.github/workflows/build-docker-postgresql.yml
@@ -16,17 +16,19 @@
         with:
           fetch-depth: 0
       - name: Set up JDK 17
-        uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
+        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4
         with:
           java-version: '17'
           distribution: 'zulu'
           cache: gradle
       - name: Build the image
-        run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:jibDockerBuild -x test
+        run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:build :fineract-provider:jibDockerBuild -x test -x cucumber
       - name: Start the Standalone Stack
-        run: docker-compose -f docker-compose-postgresql.yml up -d
+        run: docker compose -f docker-compose-postgresql.yml up -d
       - name: Wait for stack to come up
-        run: sleep 300
+        run: sleep 500
+      - name: Check the stack
+        run: docker ps
       - name: Check health
         run: curl -f -k --retry 10 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
       - name: Check info
diff --git a/.github/workflows/build-documentation.yml b/.github/workflows/build-documentation.yml
index 83982fa..eae03a1 100644
--- a/.github/workflows/build-documentation.yml
+++ b/.github/workflows/build-documentation.yml
@@ -15,12 +15,12 @@
         with:
           fetch-depth: 0
       - name: Set up JDK 17
-        uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
+        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4
         with:
           java-version: '17'
           distribution: 'zulu'
           cache: gradle
-      - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4
+      - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4
         with:
           node-version: 16
       - name: Congfigure vega-cli
diff --git a/.github/workflows/build-mariadb.yml b/.github/workflows/build-mariadb.yml
index 0b76cb7..691403b 100644
--- a/.github/workflows/build-mariadb.yml
+++ b/.github/workflows/build-mariadb.yml
@@ -10,7 +10,7 @@
 
     services:
         mariad:
-            image: mariadb:11.1
+            image: mariadb:11.2
             ports:
                 - 3306:3306
             env:
@@ -18,7 +18,7 @@
             options: --health-cmd="healthcheck.sh --su-mysql --connect --innodb_initialized" --health-interval=5s --health-timeout=2s --health-retries=3
 
         mock-oauth2-server:
-          image: ghcr.io/navikt/mock-oauth2-server:2.0.1
+          image: ghcr.io/navikt/mock-oauth2-server:2.1.0
           ports:
             - 9000:9000
           env:
@@ -34,12 +34,12 @@
         with:
           fetch-depth: 0
       - name: Set up JDK 17
-        uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
+        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4
         with:
           java-version: '17'
           distribution: 'zulu'
           cache: gradle
-      - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4
+      - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4
         with:
           node-version: 16
       - name: Congfigure vega-cli
@@ -88,17 +88,18 @@
 
       - name: Archive test results
         if: always()
-        uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # tag=v3
+        uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # tag=v3
         with:
           name: test-results
           path: |
+            build/reports/
             integration-tests/build/reports/
             twofactor-tests/build/reports/
             oauth2-tests/build/reports/
 
       - name: Archive server logs
         if: always()
-        uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # tag=v3
+        uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # tag=v3
         with:
           name: server-logs
           path: |
diff --git a/.github/workflows/build-mysql.yml b/.github/workflows/build-mysql.yml
index 09c5079..683d3e0 100644
--- a/.github/workflows/build-mysql.yml
+++ b/.github/workflows/build-mysql.yml
@@ -18,7 +18,7 @@
             options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
 
         mock-oauth2-server:
-          image: ghcr.io/navikt/mock-oauth2-server:2.0.1
+          image: ghcr.io/navikt/mock-oauth2-server:2.1.0
           ports:
             - 9000:9000
           env:
@@ -34,12 +34,12 @@
         with:
           fetch-depth: 0
       - name: Set up JDK 17
-        uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
+        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4
         with:
           java-version: '17'
           distribution: 'zulu'
           cache: gradle
-      - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4
+      - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4
         with:
           node-version: 16
       - name: Congfigure vega-cli
@@ -88,17 +88,18 @@
 
       - name: Archive test results
         if: always()
-        uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # tag=v3
+        uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # tag=v3
         with:
           name: test-results
           path: |
+            build/reports/
             integration-tests/build/reports/
             twofactor-tests/build/reports/
             oauth2-tests/build/reports/
 
       - name: Archive server logs
         if: always()
-        uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # tag=v3
+        uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # tag=v3
         with:
           name: server-logs
           path: |
diff --git a/.github/workflows/build-postgresql.yml b/.github/workflows/build-postgresql.yml
index bcf577d..f657d9a 100644
--- a/.github/workflows/build-postgresql.yml
+++ b/.github/workflows/build-postgresql.yml
@@ -19,7 +19,7 @@
             options: --health-cmd="pg_isready -q -d postgres -U root" --health-interval=5s --health-timeout=2s --health-retries=3
 
         mock-oauth2-server:
-          image: ghcr.io/navikt/mock-oauth2-server:2.0.1
+          image: ghcr.io/navikt/mock-oauth2-server:2.1.0
           ports:
             - 9000:9000
           env:
@@ -35,12 +35,12 @@
         with:
           fetch-depth: 0
       - name: Set up JDK 17
-        uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
+        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4
         with:
           java-version: '17'
           distribution: 'zulu'
           cache: gradle
-      - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4
+      - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4
         with:
           node-version: 16
       - name: Congfigure vega-cli
@@ -89,17 +89,18 @@
 
       - name: Archive test results
         if: always()
-        uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # tag=v3
+        uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # tag=v3
         with:
           name: test-results
           path: |
+            build/reports/
             integration-tests/build/reports/
             twofactor-tests/build/reports/
             oauth2-tests/build/reports/
 
       - name: Archive server logs
         if: always()
-        uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # tag=v3
+        uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # tag=v3
         with:
           name: server-logs
           path: |
diff --git a/.github/workflows/smoke-activemq.yml b/.github/workflows/smoke-activemq.yml
index 2880403..8f9455f 100644
--- a/.github/workflows/smoke-activemq.yml
+++ b/.github/workflows/smoke-activemq.yml
@@ -16,17 +16,19 @@
         with:
           fetch-depth: 0
       - name: Set up JDK 17
-        uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
+        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4
         with:
           java-version: '17'
           distribution: 'zulu'
           cache: gradle
       - name: Build the image
-        run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:jibDockerBuild -x test
+        run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:build :fineract-provider:jibDockerBuild -x test -x cucumber
       - name: Start the ActiveMQ Stack
-        run: docker-compose -f docker-compose-postgresql-activemq.yml up --scale fineract-worker=1 -d
+        run: docker compose -f docker-compose-postgresql-activemq.yml up --scale fineract-worker=1 -d
       - name: Wait for stack to come up
         run: sleep 500
+      - name: Check the stack
+        run: docker ps
       - name: Check health Manager
         run: curl -f -k --retry 10 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
       - name: Check health Worker1
diff --git a/.github/workflows/smoke-kafka.yml b/.github/workflows/smoke-kafka.yml
index ce8bc91..e614cdc 100644
--- a/.github/workflows/smoke-kafka.yml
+++ b/.github/workflows/smoke-kafka.yml
@@ -16,17 +16,19 @@
         with:
           fetch-depth: 0
       - name: Set up JDK 17
-        uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
+        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4
         with:
           java-version: '17'
           distribution: 'zulu'
           cache: gradle
       - name: Build the image
-        run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:jibDockerBuild -x test
+        run: ./gradlew --no-daemon --console=plain :fineract-provider:clean :fineract-provider:build :fineract-provider:jibDockerBuild -x test -x cucumber
       - name: Start the Kafka Stack
-        run: docker-compose -f docker-compose-postgresql-kafka.yml up --scale fineract-worker=1 -d
+        run: docker compose -f docker-compose-postgresql-kafka.yml up --scale fineract-worker=1 -d
       - name: Wait for stack to come up
         run: sleep 500
+      - name: Check the stack
+        run: docker ps
       - name: Check health Manager
         run: curl -f -k --retry 10 --retry-connrefused --connect-timeout 30 --retry-delay 30 https://localhost:8443/fineract-provider/actuator/health
       - name: Check health Worker1
diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml
index 94f7bb9..f240f1a 100644
--- a/.github/workflows/sonarqube.yml
+++ b/.github/workflows/sonarqube.yml
@@ -24,7 +24,7 @@
         with:
           fetch-depth: 0
       - name: Set up JDK 17
-        uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
+        uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4
         with:
           java-version: '17'
           distribution: 'zulu'
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index ca79a7b..eb30dda 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -15,7 +15,7 @@
       pull-requests: write  # for actions/stale to close stale PRs
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 # v8
+    - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9
       with:
         repo-token: ${{ secrets.GITHUB_TOKEN }}
         # stale-issue-message: 'Stale issue message'
diff --git a/.profileconfig.json b/.profileconfig.json
new file mode 100644
index 0000000..b2f42d9
--- /dev/null
+++ b/.profileconfig.json
@@ -0,0 +1,64 @@
+{
+    "jfrConfig": {
+        "settings": "profile"
+    },
+    "asyncProfilerConfig": {
+        "jfrsync": true,
+        "alloc": true,
+        "event": "wall",
+        "misc": ""
+    },
+    "file": "$PROJECT_DIR/profile.jfr",
+    "conversionConfig": {
+        "nonProjectPackagePrefixes": [
+            "java.",
+            "javax.",
+            "kotlin.",
+            "jdk.",
+            "com.google.",
+            "org.apache.",
+            "org.spring.",
+            "sun.",
+            "scala."
+        ],
+        "enableMarkers": true,
+        "initialVisibleThreads": 10,
+        "initialSelectedThreads": 10,
+        "includeGCThreads": false,
+        "includeInitialSystemProperty": false,
+        "includeInitialEnvironmentVariables": false,
+        "includeSystemProcesses": false,
+        "ignoredEvents": [
+            "jdk.ActiveSetting",
+            "jdk.ActiveRecording",
+            "jdk.BooleanFlag",
+            "jdk.IntFlag",
+            "jdk.DoubleFlag",
+            "jdk.LongFlag",
+            "jdk.NativeLibrary",
+            "jdk.StringFlag",
+            "jdk.UnsignedIntFlag",
+            "jdk.UnsignedLongFlag",
+            "jdk.InitialSystemProperty",
+            "jdk.InitialEnvironmentVariable",
+            "jdk.SystemProcess",
+            "jdk.ModuleExport",
+            "jdk.ModuleRequire"
+        ],
+        "minRequiredItemsPerThread": 3
+    },
+    "additionalGradleTargets": [
+        {
+            "targetPrefix": "quarkus",
+            "optionForVmArgs": "-Djvm.args",
+            "description": "Example quarkus config, adding profiling arguments via -Djvm.args option to the Gradle task run"
+        }
+    ],
+    "additionalMavenTargets": [
+        {
+            "targetPrefix": "quarkus:",
+            "optionForVmArgs": "-Djvm.args",
+            "description": "Example quarkus config, adding profiling arguments via -Djvm.args option to the Maven goal run"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index d715dac..68991bc 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 Apache Fineract: A Platform for Microfinance
 ============
-[![Swagger Validation](https://validator.swagger.io/validator?url=https://demo.fineract.dev/fineract-provider/swagger-ui/fineract.yaml)](https://validator.swagger.io/validator/debug?url=https://demo.fineract.dev/fineract-provider/swagger-ui/fineract.yaml) [![build](https://github.com/apache/fineract/actions/workflows/build.yml/badge.svg)](https://github.com/apache/fineract/actions/workflows/build.yml) [![Docker Hub](https://img.shields.io/docker/pulls/apache/fineract.svg?logo=Docker)](https://hub.docker.com/r/apache/fineract)  [![Docker Build](https://img.shields.io/docker/cloud/build/apache/fineract.svg?logo=Docker)](https://hub.docker.com/r/apache/fineract/builds) [![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=apache_fineract&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=apache_fineract)
+[![Swagger Validation](https://validator.swagger.io/validator?url=https://sandbox.mifos.community/fineract-provider/swagger-ui/fineract.yaml)](https://validator.swagger.io/validator/debug?url=https://sandbox.mifos.community/fineract-provider/swagger-ui/fineract.yaml) [![build](https://github.com/apache/fineract/actions/workflows/build.yml/badge.svg)](https://github.com/apache/fineract/actions/workflows/build.yml) [![Docker Hub](https://img.shields.io/docker/pulls/apache/fineract.svg?logo=Docker)](https://hub.docker.com/r/apache/fineract)  [![Docker Build](https://img.shields.io/docker/cloud/build/apache/fineract.svg?logo=Docker)](https://hub.docker.com/r/apache/fineract/builds) [![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=apache_fineract&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=apache_fineract)
 
 </b>
 
@@ -22,15 +22,15 @@
 REQUIREMENTS
 ============
 * `Java >= 17` (Azul Zulu JVM is tested by our CI on GitHub Actions)
-* MariaDB `10.9`
+* MariaDB `11.2`
 
 You can run the required version of the database server in a container, instead of having to install it, like this:
 
-    docker run --name mariadb-10.9 -p 3306:3306 -e MARIADB_ROOT_PASSWORD=mysql -d mariadb:10.9
+    docker run --name mariadb-11.2 -p 3306:3306 -e MARIADB_ROOT_PASSWORD=mysql -d mariadb:11.2
 
 and stop and destroy it like this:
 
-    docker rm -f mariadb-10.9
+    docker rm -f mariadb-11.2
 
 <br>Beware that this database container database keeps its state inside the container and not on the host filesystem.  It is lost when you destroy (rm) this container.  This is typically fine for development.  See [Caveats: Where to Store Data on the database container documentation](https://hub.docker.com/_/mariadb) re. how to make it persistent instead of ephemeral.<br>
 
@@ -75,7 +75,7 @@
 ============
 1. Clone the repository or download and extract the archive file to your local directory.
 2. Run `./gradlew clean bootJar` to build a modern cloud native fully self contained JAR file which will be created at `fineract-provider/build/libs` directory.
-3. As we are not allowed to include a JDBC driver in the built JAR, download a JDBC driver of your choice. For example: `wget https://downloads.mariadb.com/Connectors/java/connector-java-2.7.5/mariadb-java-client-2.7.5.jar`
+3. As we are not allowed to include a JDBC driver in the built JAR, download a JDBC driver of your choice. For example: `wget https://downloads.mariadb.com/Connectors/java/connector-java-3.3.2/mariadb-java-client-3.3.2.jar`
 4. Start the jar and pass the directory where you have downloaded the JDBC driver as loader.path, for example: `java -Dloader.path=. -jar fineract-provider/build/libs/fineract-provider.jar` (does not require external Tomcat)
 
 NOTE: we cannot upgrade to version 3.0.x of the MariaDB driver just yet; have to wait until 3.0.4 is out for a bug fix.
@@ -207,13 +207,16 @@
 `docker run` time did something similar; this has changed in [FINERACT-773](https://issues.apache.org/jira/browse/FINERACT-773)),
 and the `mysqlserver` environment variable is now no longer supported.)_
 
-If you need the Java Flight Recorder image then copy the file from the running fineract-development container:
+The logfiles and the Java Flight Recorder output are available in `PROJECT_ROOT/build/fineract/logs`. If you use IntelliJ then you can double-click on the `.jfr` file and open it with the IDE. You can also download Azul Mission Control from here https://www.azul.com/products/components/azul-mission-control/ to analyze the Java Flight Recorder file.
+
+NOTE: If you have issues with the file permissions and Docker Compose then you might need to change the variable values for `FINERACT_USER` and `FINERACT_GROUP` in `PROJECT_ROOT/config/docker/env/fineract-common.env`. You can find out what values you need to put there with the following commands:
 
 ```
-docker container cp fineract-development:/tmp/fineract.jfr /tmp
+id -u ${USER}
+id -u ${GROUP}
 ```
 
-NOTE: Download Azul Mission Control from here https://www.azul.com/products/components/azul-mission-control/ to analyze the Java Flight Recorder file.
+Please make sure that you are not checking in your changed values. The defaults should normally work for most people.
 
 Connection pool configuration
 =============================
@@ -399,9 +402,9 @@
 <br><br>APACHE FINERACT PLATFORM API
 ============
 
-The API for Fineract is documented in [apiLive.htm](fineract-provider/src/main/resources/static/api-docs/apiLive.htm), and the [apiLive.htm can be viewed on Fineract.dev](https://fineract.apache.org/legacy-docs/apiLive.htm "API Documentation").  If you have your own Fineract instance running, you can find this documentation under [/fineract-provider/api-docs/apiLive.htm](https://localhost:8443/fineract-provider/api-docs/apiLive.htm).
+The API for Fineract is documented in [apiLive.htm](fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm), and the [apiLive.htm can be viewed on fineract.apache.org](https://fineract.apache.org/docs/legacy/ "API Documentation").  If you have your own Fineract instance running, you can find this documentation under [/fineract-provider/legacy-docs/apiLive.htm](https://localhost:8443/fineract-provider/legacy-docs/apiLive.htm).
 
-The Swagger documentation (work in progress; see [FINERACT-733](https://issues.apache.org/jira/browse/FINERACT-733)) can be accessed under [/fineract-provider/swagger-ui/index.html](https://localhost:8443/fineract-provider/swagger-ui/index.html) and [live Swagger UI here on Fineract.dev](https://demo.fineract.dev/fineract-provider/swagger-ui/index.html).
+The Swagger documentation (work in progress; see [FINERACT-733](https://issues.apache.org/jira/browse/FINERACT-733)) can be accessed under [/fineract-provider/swagger-ui/index.html](https://localhost:8443/fineract-provider/swagger-ui/index.html) and [live Swagger UI here on Fineract.dev](https://sandbox.mifos.community/fineract-provider/swagger-ui/index.html).
 
 Apache Fineract supports client code generation using [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) based on the [OpenAPI Specification](https://swagger.io/specification/).  For more instructions on how to generate the client code, check [docs/developers/swagger/client.md](docs/developers/swagger/client.md).
 
@@ -418,7 +421,7 @@
 <br>ONLINE DEMOS
 ============
 
-* [fineract.dev](https://www.fineract.dev) always runs the latest version of this code
+* [sandbox.mifos.community](https://sandbox.mifos.community) always runs the latest version of this code
 * [demo.mifos.io](https://demo.mifos.io) A demo account is provided for users to experience the functionality of the Community App.  Users can use "mifos" for USERNAME and "password" for PASSWORD (without quotation marks).
 * [Swagger-UI Demo video](https://www.youtube.com/watch?v=FlVd-0YAo6c) This is a demo video for Swagger-UI documentation, more information [here](https://github.com/apache/fineract#swagger-ui-documentation).
 
@@ -443,7 +446,7 @@
 ============
 
 We use Swagger-UI to generate and maintain our API documentation, you can see the demo video [here](https://www.youtube.com/watch?v=FlVd-0YAo6c) or a live version
-[here](https://demo.fineract.dev/fineract-provider/swagger-ui/index.html). If you interested to know more about Swagger-UI you can check their [website](https://swagger.io/).
+[here](https://sandbox.mifos.community/fineract-provider/swagger-ui/index.html). If you interested to know more about Swagger-UI you can check their [website](https://swagger.io/).
 
 <br>GORVENANCE AND POLICIES
 =======================
diff --git a/build.gradle b/build.gradle
index 9b1a179..3ac3d74 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,4 +1,4 @@
-/**
+    /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
  * distributed with this work for additional information
@@ -61,7 +61,7 @@
         classpath 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'
         classpath 'com.google.cloud.tools:jib-layer-filter-extension-gradle:0.3.0'
         classpath 'org.apache.commons:commons-lang3:3.14.0'
-        classpath 'io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.11'
+        classpath 'io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.19'
         classpath 'jakarta.servlet:jakarta.servlet-api:6.0.0'
     }
 }
@@ -70,14 +70,14 @@
     id 'me.qoomon.git-versioning' version '6.4.3'
     id "org.barfuin.gradle.taskinfo" version "2.1.0"
     id 'com.adarshr.test-logger' version '4.0.0'
-    id 'com.diffplug.spotless' version '6.22.0' apply false
+    id 'com.diffplug.spotless' version '6.23.3' apply false
     id 'org.nosphere.apache.rat' version '0.8.1' apply false
     id 'com.github.hierynomus.license' version '0.16.1' apply false
     id 'com.github.jk1.dependency-license-report' version '2.5' apply false
     id 'org.zeroturnaround.gradle.jrebel' version '1.2.0' apply false
-    id 'org.springframework.boot' version '3.1.5' apply false
+    id 'org.springframework.boot' version '3.1.7' apply false
     id 'net.ltgt.errorprone' version '3.1.0' apply false
-    id 'io.swagger.core.v3.swagger-gradle-plugin' version '2.2.11' apply false
+    id 'io.swagger.core.v3.swagger-gradle-plugin' version '2.2.19' apply false
     id 'com.gorylenko.gradle-git-properties' version '2.4.1' apply false
     id 'org.asciidoctor.jvm.convert' version '3.3.2' apply false
     id 'org.asciidoctor.jvm.pdf' version '3.3.2' apply false
@@ -88,9 +88,11 @@
     id 'com.google.cloud.tools.jib' version '3.4.0' apply false
     id 'org.sonarqube' version '4.4.1.3373'
     id 'com.github.andygoossens.modernizer' version '1.9.0' apply false
-    id 'com.github.spotbugs' version '5.0.14' apply false
+    // TODO: upgrade to 6.0.4
+    id 'com.github.spotbugs' version '5.0.15' apply false
     id 'se.thinkcode.cucumber-runner' version '0.0.11' apply false
     id "com.github.davidmc24.gradle.plugin.avro-base" version "1.9.1" apply false
+    id 'org.openapi.generator' version '7.2.0' apply false
 }
 
 apply from: "${rootDir}/buildSrc/src/main/groovy/org.apache.fineract.release.gradle"
@@ -119,7 +121,7 @@
     }
 }
 
-ext['groovy.version'] = '4.0.6'
+ext['groovy.version'] = '4.0.17'
 ext['swaggerFile'] = "$rootDir/fineract-provider/build/classes/java/main/static/fineract.json".toString()
 
 allprojects  {
@@ -143,7 +145,7 @@
     spotless {
         format 'misc', {
             target '**/*.md', '**/*.properties', '**/.gitignore', '**/.openapi-generator-ignore', '**/*.yml', '**/*.xml', '**/**.json', '**/*.sql'
-            targetExclude '**/build/**', '**/bin/**', '**/.settings/**', '**/.idea/**', '**/.gradle/**', '**/gradlew.bat', '**/licenses/**', '**/banner.txt', '.vscode/**'
+            targetExclude '**/build/**', '**/bin/**', '**/.settings/**', '**/.idea/**', '**/.gradle/**', '**/gradlew.bat', '**/licenses/**', '**/banner.txt', '.vscode/**', '.profileconfig.json'
             indentWithSpaces(4)
             endWithNewline()
             trimTrailingWhitespace()
@@ -321,6 +323,15 @@
     sourceSets.main.output.resourcesDir = sourceSets.main.java.classesDirectory
     sourceSets.test.output.resourcesDir = sourceSets.test.java.classesDirectory
 
+    configurations.named('spotbugs').configure {
+        resolutionStrategy.eachDependency {
+            if (it.requested.group == 'org.ow2.asm') {
+                it.useVersion '9.5'
+                it.because "Asm 9.5 is required for JDK 21 support"
+            }
+        }
+    }
+
     configurations {
         implementation.setCanBeResolved(true)
         api.setCanBeResolved(true)
@@ -423,7 +434,7 @@
     // Configuration for the Checkstyle plugin
     // https://docs.gradle.org/current/userguide/checkstyle_plugin.html
     dependencies {
-        checkstyle 'com.puppycrawl.tools:checkstyle:10.12.5'
+        checkstyle 'com.puppycrawl.tools:checkstyle:10.12.7'
         checkstyle 'com.github.sevntu-checkstyle:sevntu-checks:1.44.1'
     }
 
@@ -445,7 +456,7 @@
     // Configuration for the errorprone plugin
     // https://github.com/tbroyer/gradle-errorprone-plugin
     dependencies {
-        errorprone "com.google.errorprone:error_prone_core:2.23.0"
+        errorprone "com.google.errorprone:error_prone_core:2.24.0"
     }
 
     tasks.withType(JavaCompile) {
@@ -600,7 +611,8 @@
 
     // To generate an HTML report instead of XML
     spotbugs {
-        reportLevel = 'high'
+        // reportLevel = 'high'
+        // reportLevel = com.github.spotbugs.snom.Confidence.DEFAULT
         showProgress = false
         excludeFilter = file("$rootDir/config/spotbugs/exclude.xml")
     }
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index 4f609bb..6f413c4 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -58,4 +58,5 @@
     implementation 'com.squareup.retrofit2:retrofit'
     implementation 'com.squareup.retrofit2:converter-jackson'
     implementation 'com.fasterxml.jackson.core:jackson-databind'
+    implementation 'com.squareup.okhttp3:okhttp'
 }
diff --git a/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle b/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle
index 29364ef..d3f7ab3 100644
--- a/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle
+++ b/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle
@@ -22,18 +22,21 @@
 // https://github.com/spring-gradle-plugins/dependency-management-plugin
 dependencyManagement {
     imports {
-        mavenBom 'io.micrometer:micrometer-bom:1.12.0'
-        mavenBom 'org.springframework:spring-framework-bom:6.1.0'
-        mavenBom 'org.springframework.boot:spring-boot-dependencies:3.1.5'
-        mavenBom 'io.awspring.cloud:spring-cloud-aws-dependencies:3.0.3'
-        mavenBom 'io.opentelemetry:opentelemetry-bom:1.32.0'
-        mavenBom 'org.jetbrains.kotlin:kotlin-bom:1.9.20'
+        mavenBom 'com.squareup.okhttp3:okhttp-bom:4.12.0'
+        mavenBom 'org.slf4j:slf4j-bom:2.0.10'
+        mavenBom 'io.micrometer:micrometer-bom:1.12.1'
+        mavenBom 'org.springframework:spring-framework-bom:6.1.2'
+        mavenBom 'org.springframework.boot:spring-boot-dependencies:3.1.7'
+        mavenBom 'io.awspring.cloud:spring-cloud-aws-dependencies:3.0.4'
+        mavenBom 'io.opentelemetry:opentelemetry-bom:1.33.0'
+        mavenBom 'org.jetbrains.kotlin:kotlin-bom:1.9.22'
         mavenBom 'org.junit:junit-bom:5.10.1'
-        mavenBom 'com.fasterxml.jackson:jackson-bom:2.16.0'
-        mavenBom 'io.cucumber:cucumber-bom:7.14.0'
-        mavenBom 'io.netty:netty-bom:4.1.101.Final'
-        mavenBom 'org.mockito:mockito-bom:5.7.0'
-        mavenBom 'software.amazon.awssdk:bom:2.21.28'
+        mavenBom 'com.fasterxml.jackson:jackson-bom:2.16.1'
+        mavenBom 'io.cucumber:cucumber-bom:7.15.0'
+        mavenBom 'io.netty:netty-bom:4.1.104.Final'
+        mavenBom 'org.mockito:mockito-bom:5.8.0'
+        mavenBom 'software.amazon.awssdk:bom:2.22.9'
+        mavenBom 'io.github.resilience4j:resilience4j-bom:2.2.0'
     }
 
     dependencies {
@@ -41,37 +44,31 @@
         // We do not use :+ to get the latest available version available on Maven Central, as that could suddenly break things.
         // We use the Renovate Bot to automatically propose Pull Requests (PRs) when upgrades for all of these versions are available.
 
-        dependency 'org.slf4j:slf4j-api:2.0.9'
-        dependency 'org.slf4j:slf4j-simple:2.0.9'
-        dependency 'org.slf4j:jcl-over-slf4j:2.0.9'
-        dependency 'org.slf4j:jul-to-slf4j:2.0.9'
-        dependency 'org.slf4j:log4j-over-slf4j:2.0.9'
-        dependency 'ch.qos.logback:logback-core:1.4.11'
-        dependency 'ch.qos.logback:logback-classic:1.4.11'
+        dependency 'ch.qos.logback:logback-core:1.4.14'
+        dependency 'ch.qos.logback:logback-classic:1.4.14'
         dependency 'ch.qos.logback.contrib:logback-json-classic:0.1.5'
         dependency 'ch.qos.logback.contrib:logback-jackson:0.1.5'
-        dependency 'org.codehaus.janino:janino:3.1.10'
+        dependency 'org.codehaus.janino:janino:3.1.11'
 
 
         dependency 'org.eclipse.persistence:org.eclipse.persistence.jpa:4.0.0'
         dependency 'com.google.guava:guava:32.0.0-jre'
         dependency 'com.google.code.gson:gson:2.10.1'
-        dependency 'com.google.truth:truth:1.1.5'
-        dependency 'com.google.truth.extensions:truth-java8-extension:1.1.5'
-        dependency 'com.google.googlejavaformat:google-java-format:1.18.1'
-        dependency ('org.apache.commons:commons-email:1.5') {
+        dependency 'com.google.truth:truth:1.2.0'
+        dependency 'com.google.truth.extensions:truth-java8-extension:1.2.0'
+        dependency 'com.google.googlejavaformat:google-java-format:1.19.1'
+        dependency ('org.apache.commons:commons-email:1.6.0') {
             exclude 'com.sun.mail:javax.mail'
             exclude 'javax.activation:activation'
         }
-        dependency 'commons-io:commons-io:2.15.0'
-        dependency 'com.github.librepdf:openpdf:1.3.33'
+        dependency 'commons-io:commons-io:2.15.1'
+        dependency 'com.github.librepdf:openpdf:1.3.35'
         dependency ('org.mnode.ical4j:ical4j:3.2.14') {
             exclude 'com.sun.mail:javax.mail'
             exclude 'org.codehaus.groovy:groovy'
         }
         dependency 'org.apache.commons:commons-csv:1.10.0'
         dependency 'org.quartz-scheduler:quartz:2.3.2'
-        dependency 'software.amazon.awssdk:bom:2.21.28'
         dependency 'org.ehcache:ehcache:3.10.8'
         dependency 'com.github.spullara.mustache.java:compiler:0.9.11'
         dependency 'com.jayway.jsonpath:json-path:2.8.0'
@@ -119,13 +116,14 @@
         dependency 'jakarta.management.j2ee:jakarta.management.j2ee-api:1.1.4'
         dependency 'jakarta.jms:jakarta.jms-api:3.1.0'
         dependency 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'
-        dependency 'org.glassfish.jersey.media:jersey-media-multipart:3.1.3'
+        dependency 'org.glassfish.jersey.media:jersey-media-multipart:3.1.5'
         dependency 'org.glassfish.jaxb:jaxb-runtime:2.3.6' // Swagger needs exactly this version
         dependency 'org.apache.bval:org.apache.bval.bundle:3.0.0'
         dependency 'joda-time:joda-time:2.12.5'
 
         dependency 'io.github.classgraph:classgraph:4.8.165'
         dependency 'org.awaitility:awaitility:4.2.0'
+        // TODO: upgrade to 4.8.3
         dependency 'com.github.spotbugs:spotbugs-annotations:4.7.3'
         dependency 'javax.cache:cache-api:1.1.1'
         dependency 'org.mock-server:mockserver-junit-jupiter:5.15.0'
@@ -148,16 +146,10 @@
         dependency "com.squareup.retrofit2:converter-scalars:2.9.0"
         dependency "com.squareup.retrofit2:converter-gson:2.9.0"
         dependency "com.squareup.retrofit2:converter-protobuf:2.9.0"
+        dependency 'io.reactivex.rxjava2:rxjava:2.2.21'
         dependency "org.apache.oltu.oauth2:org.apache.oltu.oauth2.common:1.0.1"
         dependency "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:1.0.1"
         dependency "org.apache.oltu.oauth2:org.apache.oltu.oauth2.httpclient4:1.0.1"
-        dependency "com.squareup.okhttp3:okhttp:4.12.0"
-        dependency "com.squareup.okhttp3:okcurl:4.12.0"
-        dependency "com.squareup.okhttp3:logging-interceptor:4.12.0"
-        dependency "com.squareup.okhttp3:okhttp-apache:4.9.3"
-        dependency "com.squareup.okhttp3:okhttp-android-support:4.9.3"
-        dependency "com.squareup.okhttp3:okhttp-urlconnection:4.12.0"
-        dependency "com.squareup.okhttp3:okhttp-sse:4.12.0"
         dependency "io.gsonfire:gson-fire:1.9.0"
         dependency "com.google.code.findbugs:jsr305:3.0.2"
         dependency "commons-codec:commons-codec:1.16.0"
@@ -168,44 +160,45 @@
         dependency 'org.bouncycastle:bcprov-jdk15on:1.70'
         dependency 'org.bouncycastle:bcpg-jdk15on:1.70'
 
-        dependency 'org.eclipse.jgit:org.eclipse.jgit:6.7.0.202309050840-r'
-        dependency 'org.eclipse.jgit:org.eclipse.jgit.ssh.apache:6.7.0.202309050840-r'
+        dependency 'org.eclipse.jgit:org.eclipse.jgit:6.8.0.202311291450-r'
+        dependency 'org.eclipse.jgit:org.eclipse.jgit.ssh.apache:6.8.0.202311291450-r'
 
         dependency 'org.tmatesoft.svnkit:svnkit:1.10.11'
         dependency 'com.vdurmont:semver4j:3.1.0'
         dependency 'org.beryx:text-io:3.4.1'
 
-        dependency ('org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0') {
+        dependency ('org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0') {
             exclude 'io.swagger.core.v3:swagger-core'
         }
 
-        dependency 'com.google.cloud.sql:mysql-socket-factory-connector-j-8:1.15.0'
+        dependency 'com.google.cloud.sql:mysql-socket-factory-connector-j-8:1.15.1'
 
-        dependency ('org.apache.activemq:activemq-client:6.0.0') {
+        dependency ('org.apache.activemq:activemq-client:6.0.1') {
             exclude 'javax.annotation:javax.annotation-api'
         }
 
-        dependency 'io.swagger.core.v3:swagger-annotations-jakarta:2.2.11'
-        dependency ('io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.11') {
+        dependency 'io.swagger.core.v3:swagger-annotations-jakarta:2.2.19'
+        dependency ('io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.19') {
             exclude 'jakarta.activation:jakarta.activation-api'
         }
-        dependency ('io.swagger.core.v3:swagger-core-jakarta:2.2.11') {
+        dependency ('io.swagger.core.v3:swagger-core-jakarta:2.2.19') {
             exclude 'jakarta.activation:jakarta.activation-api'
         }
 
-        dependency "jakarta.annotation:jakarta.annotation-api:2.1.1"
+        dependency 'jakarta.annotation:jakarta.annotation-api:2.1.1'
         dependency 'jakarta.activation:jakarta.activation-api:2.1.2'
         dependency ('com.sun.mail:jakarta.mail:2.0.1') {
             // Spring needs this version
             exclude 'com.sun.activation:jakarta.activation'
         }
-        dependency ('jakarta.xml.bind:jakarta.xml.bind-api:4.0.0') {
+        dependency ('jakarta.xml.bind:jakarta.xml.bind-api:4.0.1') {
             exclude 'jakarta.activation:jakarta.activation-api'
         }
 
-        dependency ('org.liquibase:liquibase-core:4.23.0') {
+        dependency ('org.liquibase:liquibase-core:4.25.1') {
             exclude 'javax.xml.bind:jaxb-api'
         }
+        dependency 'org.liquibase.ext:liquibase-postgresql:4.25.1'
 
         dependency ('org.dom4j:dom4j:2.1.4') {
             exclude 'relaxngDatatype:relaxngDatatype' // already in com.sun.xml.bind:jaxb-osgi:2.3.0.1
@@ -214,38 +207,36 @@
             exclude 'pull-parser:pull-parser'
         }
 
-        dependency 'org.owasp.esapi:esapi:2.5.2.0'
+        dependency 'org.owasp.esapi:esapi:2.5.3.1'
         dependency 'org.awaitility:awaitility:4.2.0'
 
-        dependencySet(group: 'org.apache.poi', version: '5.2.4') {
+        dependencySet(group: 'org.apache.poi', version: '5.2.5') {
             entry 'poi'
             entry 'poi-ooxml'
             entry 'poi-ooxml-schemas'
         }
 
-        dependencySet(group: 'io.rest-assured', version: '5.3.2') {
+        dependencySet(group: 'io.rest-assured', version: '5.4.0') {
             entry 'rest-assured'
             entry 'json-path'
             entry 'xml-path'
         }
-        dependency 'org.apache.groovy:groovy-xml:4.0.14'
-        dependency 'org.apache.groovy:groovy-json:4.0.15'
+        dependency 'org.apache.groovy:groovy-xml:4.0.17'
+        dependency 'org.apache.groovy:groovy-json:4.0.17'
 
         dependency 'org.mapstruct:mapstruct:1.5.5.Final'
         dependency 'org.mapstruct:mapstruct-processor:1.5.5.Final'
 
         dependency "org.apache.avro:avro:1.11.3"
 
-        dependency "io.github.resilience4j:resilience4j-spring-boot2:2.1.0"
-
-        dependency ('org.mariadb.jdbc:mariadb-java-client:3.3.0') {
+        dependency ('org.mariadb.jdbc:mariadb-java-client:3.3.2') {
             exclude 'org.slf4j:jcl-over-slf4j'
             exclude 'org.slf4j:slf4j-api'
         }
 
-        dependency 'org.postgresql:postgresql:42.7.0'
+        dependency 'org.postgresql:postgresql:42.7.1'
 
-        dependency 'org.assertj:assertj-core:3.24.2'
+        dependency 'org.assertj:assertj-core:3.25.0'
 
         dependency 'org.apache.commons:commons-math3:3.6.1'
 
diff --git a/config/docker/compose/activemq.yml b/config/docker/compose/activemq.yml
index e60c40f..80c6699 100644
--- a/config/docker/compose/activemq.yml
+++ b/config/docker/compose/activemq.yml
@@ -22,5 +22,5 @@
   activemq:
     image: symptoma/activemq:5.18.3
     ports:
-      - 6161:6161
-      - 61616:61616
+      - "6161:6161"
+      - "61616:61616"
diff --git a/config/docker/compose/fineract-custom.yml b/config/docker/compose/fineract-custom.yml
new file mode 100644
index 0000000..d46ef41
--- /dev/null
+++ b/config/docker/compose/fineract-custom.yml
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+version: "3.8"
+
+services:
+  fineract:
+    # user: "${FINERACT_USER}:${FINERACT_GROUP}"
+    image: fineract-custom:latest
+    volumes:
+      - ${PWD}/config/docker/logback/logback-override.xml:/app/logback-override.xml
+      - ${PWD}/config/docker/aws/etc/credentials:/etc/aws/credentials:ro
+      - ${PWD}/build/fineract/logs:/var/logs/fineract:rw
+    healthcheck:
+      test: ["CMD", 'sh', '-c', 'echo -e "Checking for the availability of Fineract server deployment"; while ! nc -z "localhost" 8443; do sleep 1; printf "-"; done; echo -e " >> Fineract server has started";' ]
+      timeout: 1s
+      retries: 60
diff --git a/config/docker/compose/fineract.yml b/config/docker/compose/fineract.yml
index e4a3be8..ae5323c 100644
--- a/config/docker/compose/fineract.yml
+++ b/config/docker/compose/fineract.yml
@@ -20,12 +20,13 @@
 
 services:
   fineract:
+    # user: "${FINERACT_USER}:${FINERACT_GROUP}"
     image: fineract:latest
     volumes:
-      - ../aws/etc/credentials:/etc/aws/credentials
+      - ${PWD}/config/docker/logback/logback-override.xml:/app/logback-override.xml
+      - ${PWD}/config/docker/aws/etc/credentials:/etc/aws/credentials:ro
+      - ${PWD}/build/fineract/logs:/var/logs/fineract:rw
     healthcheck:
-      test: ["CMD", 'sh', '-c', 'echo -e "Checking for the availability of Fineract server deployment"; while ! nc -z "fineract-server" 8443; do sleep 1; printf "-"; done; echo -e " >> Fineract server has started";' ]
-      timeout: 10s
-      retries: 10
-    env_file:
-      - ../env/fineract-common.env
+      test: ["CMD", 'sh', '-c', 'echo -e "Checking for the availability of Fineract server deployment"; while ! nc -z "localhost" 8443; do sleep 1; printf "-"; done; echo -e " >> Fineract server has started";' ]
+      timeout: 1s
+      retries: 60
diff --git a/config/docker/compose/mariadb.yml b/config/docker/compose/mariadb.yml
index 75a5483..2c56ec1 100644
--- a/config/docker/compose/mariadb.yml
+++ b/config/docker/compose/mariadb.yml
@@ -13,22 +13,20 @@
 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 # KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations
-# under the License.
-#
-
 version: "3.8"
 
 services:
   mariadb:
-    image: mariadb:11.0
+    container_name: mariadb
+    image: mariadb:11.2
     volumes:
-      - ../mysql/conf.d/server_collation.cnf:/etc/mysql/conf.d/server_collation.cnf
-      - ../mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:Z,ro
+      - ${PWD}/config/docker/mysql/conf.d/server_collation.cnf:/etc/mysql/conf.d/server_collation.cnf:ro
+      - ${PWD}/config/docker/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:Z,ro
     restart: always
     env_file:
-      - ../env/mysql.env
+      - ${PWD}/config/docker/env/mysql.env
     healthcheck:
-      test: ["CMD", "healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized"]
+      test: [ "CMD", "healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized" ]
       timeout: 10s
       retries: 10
     ports:
diff --git a/config/docker/compose/observability.yml b/config/docker/compose/observability.yml
index dc1f6d4..de59e18 100644
--- a/config/docker/compose/observability.yml
+++ b/config/docker/compose/observability.yml
@@ -31,31 +31,35 @@
 
 services:
   loki:
+    container_name: loki
     image: grafana/loki:2.9.2
     command: -config.file=/etc/loki/local-config.yaml
     ports:
       - "3100:3100"
 
   prometheus:
+    container_name: prometheus
     image: prom/prometheus:v2.47.2
     command: '--config.file=/etc/prometheus/prometheus.yml'
     ports:
       - "9090:9090"
     volumes:
-      - ../prometheus/etc:/etc/prometheus
+      - ${PWD}/config/docker/prometheus/etc:/etc/prometheus
     logging: *default-logging
 
   grafana:
+    container_name: grafana
     image: grafana/grafana-oss:10.2.0
     ports:
       - "3000:3000"
     volumes:
-      - ../grafana/datasources:/etc/grafana/provisioning/datasources
-      - ../grafana/etc/dashboards.yml:/etc/grafana/provisioning/dashboards/dashboards.yaml
-      - ../grafana/dashboards:/var/lib/grafana/dashboards
+      - ${PWD}/config/docker/grafana/datasources:/etc/grafana/provisioning/datasources
+      - ${PWD}/config/docker/grafana/etc/dashboards.yml:/etc/grafana/provisioning/dashboards/dashboards.yaml
+      - ${PWD}/config/docker/grafana/dashboards:/var/lib/grafana/dashboards
     logging: *default-logging
 
   tempo:
+    container_name: tempo
     image: grafana/tempo:2.2.4
     # command: [ "--target=all", "--storage.trace.backend=local", "--storage.trace.local.path=/tmp/tempo", "--auth.enabled=false" ]
     command: [ "-config.file=/etc/tempo.yml" ]
@@ -67,6 +71,6 @@
       - "4318:4318"   # otlp http
       - "9411:9411"   # zipkin
     volumes:
-      - ../tempo/etc/tempo.yml:/etc/tempo.yml
+      - ${PWD}/config/docker/tempo/etc/tempo.yml:/etc/tempo.yml
       - /tmp/tempo:/tmp/tempo
     logging: *default-logging
diff --git a/config/docker/compose/postgresql.yml b/config/docker/compose/postgresql.yml
index 4c87ba9..878c882 100644
--- a/config/docker/compose/postgresql.yml
+++ b/config/docker/compose/postgresql.yml
@@ -20,12 +20,12 @@
 
 services:
   postgresql:
-    image: postgres:16.0
+    image: postgres:16.1
     volumes:
-      - ../postgresql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d/:Z,ro
+      - ${PWD}/config/docker/postgresql/docker-entrypoint-initdb.d/01-init.sh:/docker-entrypoint-initdb.d/01-init.sh:Z,ro
     restart: always
     env_file:
-      - ../env/postgresql.env
+      - ${PWD}/config/docker/env/postgresql.env
     healthcheck:
       test: [ "CMD", "pg_isready", "-q", "-d", "postgres", "-U", "root" ]
       timeout: 10s
diff --git a/config/docker/env/debug.env b/config/docker/env/debug.env
index fcddc45..34023e5 100644
--- a/config/docker/env/debug.env
+++ b/config/docker/env/debug.env
@@ -18,4 +18,5 @@
 #
 
 # see here for more details related to JFR: https://access.redhat.com/documentation/en-us/red_hat_build_of_openjdk/8/html/using_jdk_flight_recorder_with_red_hat_build_of_openjdk/configure-jfr-options
-JAVA_TOOL_OPTIONS="-Xmx2G -Xms2G -XX:TieredStopAtLevel=1 -XX:+UseContainerSupport -XX:+UseStringDeduplication -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5000 -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:StartFlightRecording=delay=20s,duration=60s,disk=true,name=fineract,dumponexit=true,filename=/tmp/fineract.jfr,settings=profile -Xlog:jfr=info"
+# JAVA_TOOL_OPTIONS="-Xmx2G -Xms2G -Dlogging.config=/app/logback-override.xml -XX:TieredStopAtLevel=1 -XX:+UseContainerSupport -XX:+UseStringDeduplication -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5000 -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:StartFlightRecording=delay=20s,duration=60s,disk=true,name=fineract,path-to-gc-roots=true,dumponexit=true,filename=/var/logs/fineract/fineract.jfr,settings=profile -Xlog:jfr=info"
+JAVA_TOOL_OPTIONS="-Xmx2G -Xms2G -Dlogging.config=/app/logback-override.xml -XX:TieredStopAtLevel=1 -XX:+UseContainerSupport -XX:+UseStringDeduplication -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5000 -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -Xlog:jfr=info"
diff --git a/config/docker/env/fineract-common.env b/config/docker/env/fineract-common.env
index cff6245..fd1f0f2 100644
--- a/config/docker/env/fineract-common.env
+++ b/config/docker/env/fineract-common.env
@@ -18,6 +18,8 @@
 #
 
 # ... following variables are optional; "application.properties" contains reasonable defaults (same as here)
+FINERACT_USER=1000
+FINERACT_GROUP=1000
 FINERACT_HIKARI_MINIMUM_IDLE=3
 FINERACT_HIKARI_MAXIMUM_POOL_SIZE=10
 FINERACT_HIKARI_IDLE_TIMEOUT=60000
@@ -25,6 +27,8 @@
 FINERACT_HIKARI_TEST_QUERY=SELECT 1
 FINERACT_HIKARI_AUTO_COMMIT=true
 FINERACT_SERVER_SSL_ENABLED=true
+FINERACT_HIKARI_USERNAME=root
+FINERACT_HIKARI_PASSWORD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
 FINERACT_HIKARI_DS_PROPERTIES_CACHE_PREP_STMTS=true
 FINERACT_HIKARI_DS_PROPERTIES_PREP_STMT_CACHE_SIZE=250
 FINERACT_HIKARI_DS_PROPERTIES_PREP_STMT_CACHE_SQL_LIMIT=2048
@@ -37,14 +41,19 @@
 FINERACT_HIKARI_DS_PROPERTIES_MAINTAIN_TIME_STATS=false
 FINERACT_HIKARI_DS_PROPERTIES_LOG_SLOW_QUERIES=true
 FINERACT_HIKARI_DS_PROPERTIES_DUMP_QUERIES_IN_EXCEPTION=true
+# NOTE: env vars prefixed "FINERACT_DEFAULT_TENANTDB_*" are used to create the default tenant database
 FINERACT_DEFAULT_TENANTDB_CONN_PARAMS=
 FINERACT_DEFAULT_TENANTDB_TIMEZONE=Asia/Kolkata
 FINERACT_DEFAULT_TENANTDB_IDENTIFIER=default
 FINERACT_DEFAULT_TENANTDB_NAME=fineract_default
 FINERACT_DEFAULT_TENANTDB_DESCRIPTION=Default Demo Tenant
+FINERACT_DEFAULT_TENANTDB_HOSTNAME=db
+FINERACT_DEFAULT_TENANTDB_PWD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
+FINERACT_DEFAULT_MASTER_PASSWORD=fineract
 FINERACT_MANAGEMENT_ENDPOINT_WEB_EXPOSURE_INCLUDE=health,info,prometheus
 FINERACT_MANAGEMENT_METRICS_TAGS_APPLICATION=fineract
 FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=false
+FINERACT_INSECURE_HTTP_CLIENT=true
 SPRING_PROFILES_ACTIVE=test,diagnostics
 OTEL_SERVICE_NAME=fineract
 JAVA_TOOL_OPTIONS="-Xmx1G -XX:TieredStopAtLevel=1 -XX:+UseContainerSupport -XX:+UseStringDeduplication"
diff --git a/config/docker/env/fineract-mariadb.env b/config/docker/env/fineract-mariadb.env
index 6a9bc7d..af84f54 100644
--- a/config/docker/env/fineract-mariadb.env
+++ b/config/docker/env/fineract-mariadb.env
@@ -20,10 +20,6 @@
 # NOTE: env vars prefixed "FINERACT_HIKARI_*" are used to configure the database connection pool
 FINERACT_HIKARI_DRIVER_SOURCE_CLASS_NAME=org.mariadb.jdbc.Driver
 FINERACT_HIKARI_JDBC_URL=jdbc:mariadb://db:3306/fineract_tenants
-FINERACT_HIKARI_USERNAME=root
-FINERACT_HIKARI_PASSWORD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
 # NOTE: env vars prefixed "FINERACT_DEFAULT_TENANTDB_*" are used to create the default tenant database
-FINERACT_DEFAULT_TENANTDB_HOSTNAME=db
 FINERACT_DEFAULT_TENANTDB_PORT=3306
 FINERACT_DEFAULT_TENANTDB_UID=root
-FINERACT_DEFAULT_TENANTDB_PWD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
diff --git a/config/docker/env/fineract-postgresql.env b/config/docker/env/fineract-postgresql.env
index 99c5355..1fb152d 100644
--- a/config/docker/env/fineract-postgresql.env
+++ b/config/docker/env/fineract-postgresql.env
@@ -23,7 +23,5 @@
 FINERACT_HIKARI_USERNAME=postgres
 FINERACT_HIKARI_PASSWORD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
 # NOTE: env vars prefixed "FINERACT_DEFAULT_TENANTDB_*" are used to create the default tenant database
-FINERACT_DEFAULT_TENANTDB_HOSTNAME=db
 FINERACT_DEFAULT_TENANTDB_PORT=5432
 FINERACT_DEFAULT_TENANTDB_UID=postgres
-FINERACT_DEFAULT_TENANTDB_PWD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
diff --git a/config/docker/env/fineract-worker.env b/config/docker/env/fineract-worker.env
index 0245b5a..e7ad855 100644
--- a/config/docker/env/fineract-worker.env
+++ b/config/docker/env/fineract-worker.env
@@ -21,3 +21,4 @@
 FINERACT_MODE_BATCH_MANAGER_ENABLED=false
 FINERACT_MODE_BATCH_WORKER_ENABLED=true
 OTEL_SERVICE_NAME=fineract-worker
+FINERACT_LIQUIBASE_ENABLED=false
\ No newline at end of file
diff --git a/config/docker/logback/logback-override.xml b/config/docker/logback/logback-override.xml
new file mode 100644
index 0000000..4c5871f
--- /dev/null
+++ b/config/docker/logback/logback-override.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements. See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership. The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License. You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied. See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<configuration>
+    <!--
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+    <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
+    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
+    -->
+
+    <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
+        <resetJUL>false</resetJUL>
+    </contextListener>
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <withJansi>false</withJansi>
+        <encoder>
+            <pattern>%green(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%thread] %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>/var/logs/fineract/fineract.log</file>
+        <append>true</append>
+        <prudent>true</prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>/var/logs/fineract/fineract.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <maxHistory>2</maxHistory>
+            <totalSizeCap>100MB</totalSizeCap>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <logger name="org.springframework.transaction" level="INFO" />
+
+    <root level="INFO">
+        <appender-ref ref="STDOUT" />
+        <appender-ref ref="FILE"/>
+    </root>
+</configuration>
diff --git a/config/spotbugs/exclude.xml b/config/spotbugs/exclude.xml
index b5c1ed4..251015b 100644
--- a/config/spotbugs/exclude.xml
+++ b/config/spotbugs/exclude.xml
@@ -26,4 +26,77 @@
     <Match>
         <Package name="~.*\.domain"/>
     </Match>
+    <Match>
+        <Package name="~.*\.data"/>
+    </Match>
+    <Match>
+        <Package name="~org\.apache\.fineract\.integrationtests.*"/>
+    </Match>
+    <Match>
+        <Package name="~.*\.self\..*"/>
+        <Bug pattern="UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD" />
+    </Match>
+    <Match>
+        <Package name="~.*\.api"/>
+        <Bug pattern="UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD" />
+    </Match>
+    <Match>
+        <Package name="~.*\.api"/>
+        <Bug pattern="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD" />
+    </Match>
+    <Match>
+        <Package name="~.*\.api"/>
+        <Bug pattern="UUF_UNUSED_FIELD" />
+    </Match>
+    <Match>
+        <Bug pattern="MS_EXPOSE_REP" />
+    </Match>
+    <Match>
+        <Bug pattern="EI_EXPOSE_REP" />
+    </Match>
+    <Match>
+        <Bug pattern="EI_EXPOSE_REP2" />
+    </Match>
+    <Match>
+        <Bug pattern="NP_LOAD_OF_KNOWN_NULL_VALUE" />
+    </Match>
+    <Match>
+        <Bug pattern="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE" />
+    </Match>
+    <Match>
+        <Bug pattern="NP_NULL_ON_SOME_PATH" />
+    </Match>
+    <Match>
+        <Bug pattern="NP_NULL_PARAM_DEREF" />
+    </Match>
+    <Match>
+        <Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" />
+    </Match>
+    <Match>
+        <Bug pattern="RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE" />
+    </Match>
+    <Match>
+        <Bug pattern="REC_CATCH_EXCEPTION" />
+    </Match>
+    <Match>
+        <Bug pattern="OBL_UNSATISFIED_OBLIGATION" />
+    </Match>
+    <Match>
+        <Bug pattern="OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE" />
+    </Match>
+    <Match>
+        <Bug pattern="MS_MUTABLE_COLLECTION_PKGPROTECT" />
+    </Match>
+    <Match>
+        <Bug pattern="BX_UNBOXING_IMMEDIATELY_REBOXED" />
+    </Match>
+    <Match>
+        <Bug pattern="RV_RETURN_VALUE_IGNORED_BAD_PRACTICE" />
+    </Match>
+    <Match>
+        <Bug pattern="RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT" />
+    </Match>
+    <Match>
+        <Bug pattern="UR_UNINIT_READ" />
+    </Match>
 </FindBugsFilter>
diff --git a/custom/docker/docker-compose.yml b/custom/docker/docker-compose.yml
deleted file mode 100644
index ae5b69d..0000000
--- a/custom/docker/docker-compose.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# You can replace and test a more recent version of docker compose
-version: '3.7'
-services:
-  # Backend service
-  fineractmysql:
-    image: mariadb:11.1
-    volumes:
-      - ../../fineract-db/server_collation.cnf:/etc/mysql/conf.d/server_collation.cnf
-      - ../../fineract-db/docker:/docker-entrypoint-initdb.d:Z,ro
-    restart: always
-    environment:
-      MYSQL_ROOT_PASSWORD: skdcnwauicn2ucnaecasdsajdnizucawencascdca
-    healthcheck:
-      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "--password=skdcnwauicn2ucnaecasdsajdnizucawencascdca" ]
-      timeout: 10s
-      retries: 10
-    ports:
-      - "3306:3306"
-  fineract-server:
-    image: fineract-custom:latest
-    volumes:
-      - ../../fineract-provider/build/data:/data
-    healthcheck:
-      test: ["CMD", 'sh', '-c', 'echo -e "Checking for the availability of Fineract server deployment"; while ! nc -z "fineract-server" 8443; do sleep 1; printf "-"; done; echo -e " >> Fineract server has started";' ]
-      timeout: 10s
-      retries: 10
-    ports:
-      - 8443:8443
-    depends_on:
-      fineractmysql:
-        condition: service_healthy
-    environment:
-      # NOTE: node aware scheduler
-      - FINERACT_NODE_ID=1
-      # NOTE: env vars prefixed "FINERACT_HIKARI_*" are used to configure the database connection pool
-      - FINERACT_HIKARI_DRIVER_SOURCE_CLASS_NAME=org.mariadb.jdbc.Driver
-      - FINERACT_HIKARI_JDBC_URL=jdbc:mariadb://fineractmysql:3306/fineract_tenants
-      - FINERACT_HIKARI_USERNAME=root
-      - FINERACT_HIKARI_PASSWORD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
-      # ... following variables are optional; "application.properties" contains reasonable defaults (same as here)
-      - FINERACT_HIKARI_MINIMUM_IDLE=3
-      - FINERACT_HIKARI_MAXIMUM_POOL_SIZE=10
-      - FINERACT_HIKARI_IDLE_TIMEOUT=60000
-      - FINERACT_HIKARI_CONNECTION_TIMEOUT=20000
-      - FINERACT_HIKARI_TEST_QUERY=SELECT 1
-      - FINERACT_HIKARI_AUTO_COMMIT=true
-      - FINERACT_HIKARI_DS_PROPERTIES_CACHE_PREP_STMTS=true
-      - FINERACT_HIKARI_DS_PROPERTIES_PREP_STMT_CACHE_SIZE=250
-      - FINERACT_HIKARI_DS_PROPERTIES_PREP_STMT_CACHE_SQL_LIMIT=2048
-      - FINERACT_HIKARI_DS_PROPERTIES_USE_SERVER_PREP_STMTS=true
-      - FINERACT_HIKARI_DS_PROPERTIES_USE_LOCAL_SESSION_STATE=true
-      - FINERACT_HIKARI_DS_PROPERTIES_REWRITE_BATCHED_STATEMENTS=true
-      - FINERACT_HIKARI_DS_PROPERTIES_CACHE_RESULT_SET_METADATA=true
-      - FINERACT_HIKARI_DS_PROPERTIES_CACHE_SERVER_CONFIGURATION=true
-      - FINERACT_HIKARI_DS_PROPERTIES_ELIDE_SET_AUTO_COMMITS=true
-      - FINERACT_HIKARI_DS_PROPERTIES_MAINTAIN_TIME_STATS=false
-      - FINERACT_HIKARI_DS_PROPERTIES_LOG_SLOW_QUERIES=true
-      - FINERACT_HIKARI_DS_PROPERTIES_DUMP_QUERIES_IN_EXCEPTION=true
-      # NOTE: env vars prefixed "FINERACT_DEFAULT_TENANTDB_*" are used to create the default tenant database
-      - FINERACT_DEFAULT_TENANTDB_HOSTNAME=fineractmysql
-      - FINERACT_DEFAULT_TENANTDB_PORT=3306
-      - FINERACT_DEFAULT_TENANTDB_UID=root
-      - FINERACT_DEFAULT_TENANTDB_PWD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
-      - FINERACT_DEFAULT_TENANTDB_CONN_PARAMS=
-      - FINERACT_DEFAULT_TENANTDB_TIMEZONE=Asia/Kolkata
-      - FINERACT_DEFAULT_TENANTDB_IDENTIFIER=default
-      - FINERACT_DEFAULT_TENANTDB_NAME=fineract_default
-      - FINERACT_DEFAULT_TENANTDB_DESCRIPTION=Default Demo Tenant
-      - JAVA_TOOL_OPTIONS="-Xmx1G"
diff --git a/docker-compose-custom.yml b/docker-compose-custom.yml
new file mode 100644
index 0000000..ecb2d72
--- /dev/null
+++ b/docker-compose-custom.yml
@@ -0,0 +1,39 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# You can replace and test a more recent version of docker compose
+version: "3.8"
+services:
+  db:
+    extends:
+      file: ./config/docker/compose/mariadb.yml
+      service: mariadb
+
+  fineract:
+    extends:
+      file: ./config/docker/compose/fineract-custom.yml
+      service: fineract
+    ports:
+      - "8443:8443"
+    depends_on:
+      db:
+        condition: service_healthy
+    env_file:
+      - ./config/docker/env/fineract.env
+      - ./config/docker/env/fineract-common.env
+      - ./config/docker/env/fineract-mariadb.env
diff --git a/docker-compose-development.yml b/docker-compose-development.yml
index f089370..ddaf50c 100644
--- a/docker-compose-development.yml
+++ b/docker-compose-development.yml
@@ -79,8 +79,9 @@
         condition: service_started
     env_file:
       - ./config/docker/env/aws.env
-      - ./config/docker/env/fineract-mariadb.env
       - ./config/docker/env/fineract.env
+      - ./config/docker/env/fineract-common.env
+      - ./config/docker/env/fineract-mariadb.env
       - ./config/docker/env/tracing.env
       - ./config/docker/env/oltp.env
       - ./config/docker/env/prometheus.env
diff --git a/docker-compose-postgresql-activemq.yml b/docker-compose-postgresql-activemq.yml
index 2055a54..7e5961f 100644
--- a/docker-compose-postgresql-activemq.yml
+++ b/docker-compose-postgresql-activemq.yml
@@ -39,8 +39,9 @@
       db:
         condition: service_healthy
     env_file:
-      - ./config/docker/env/fineract-postgresql.env
       - ./config/docker/env/fineract-manager.env
+      - ./config/docker/env/fineract-common.env
+      - ./config/docker/env/fineract-postgresql.env
       - ./config/docker/env/activemq.env
 
   fineract-worker:
@@ -53,9 +54,10 @@
     ports:
       - "8444-8445:8443"
     depends_on:
-      db:
+      fineract-manager:
         condition: service_healthy
     env_file:
-      - ./config/docker/env/fineract-postgresql.env
       - ./config/docker/env/fineract-worker.env
+      - ./config/docker/env/fineract-common.env
+      - ./config/docker/env/fineract-postgresql.env
       - ./config/docker/env/activemq.env
diff --git a/docker-compose-postgresql-kafka-msk.yml b/docker-compose-postgresql-kafka-msk.yml
index 3e1cfa0..8ca2cef 100644
--- a/docker-compose-postgresql-kafka-msk.yml
+++ b/docker-compose-postgresql-kafka-msk.yml
@@ -19,7 +19,6 @@
 version: "3.8"
 
 services:
-
   db:
     extends:
       file: ./config/docker/compose/postgresql.yml
@@ -35,8 +34,10 @@
       db:
         condition: service_healthy
     env_file:
-      - ./config/docker/env/aws.env
       - ./config/docker/env/fineract-manager.env
+      - ./config/docker/env/fineract-common.env
+      - ./config/docker/env/fineract-postgresql.env
+      - ./config/docker/env/aws.env
       - ./config/docker/env/kafka-client-msk.env
 
   fineract-worker:
@@ -49,9 +50,11 @@
     ports:
       - "8444-8445:8443"
     depends_on:
-      db:
+      fineract-manager:
         condition: service_healthy
     env_file:
-      - ./config/docker/env/aws.env
       - ./config/docker/env/fineract-worker.env
+      - ./config/docker/env/fineract-common.env
+      - ./config/docker/env/fineract-postgresql.env
+      - ./config/docker/env/aws.env
       - ./config/docker/env/kafka-client-msk.env
diff --git a/docker-compose-postgresql-kafka.yml b/docker-compose-postgresql-kafka.yml
index c0fbb89..92e6cf2 100644
--- a/docker-compose-postgresql-kafka.yml
+++ b/docker-compose-postgresql-kafka.yml
@@ -17,12 +17,12 @@
 #
 
 # You can replace and test a more recent version of docker compose
-version: '3.7'
+version: "3.7"
 services:
   kafka:
-    image: 'bitnami/kafka:3.5.1-debian-11-r7'
+    image: "bitnami/kafka:3.5.1-debian-11-r7"
     ports:
-      - '9092:9092'
+      - "9092:9092"
     env_file:
       - ./config/docker/env/kafka-server.env
 
@@ -40,9 +40,12 @@
     depends_on:
       db:
         condition: service_healthy
+      kafka:
+        condition: service_started
     env_file:
-      - ./config/docker/env/fineract-postgresql.env
       - ./config/docker/env/fineract-manager.env
+      - ./config/docker/env/fineract-common.env
+      - ./config/docker/env/fineract-postgresql.env
       - ./config/docker/env/kafka-client.env
 
   fineract-worker:
@@ -55,9 +58,10 @@
     ports:
       - "8444-8445:8443"
     depends_on:
-      db:
+      fineract-manager:
         condition: service_healthy
     env_file:
-      - ./config/docker/env/fineract-postgresql.env
       - ./config/docker/env/fineract-worker.env
+      - ./config/docker/env/fineract-common.env
+      - ./config/docker/env/fineract-postgresql.env
       - ./config/docker/env/kafka-client.env
diff --git a/docker-compose-postgresql.yml b/docker-compose-postgresql.yml
index e6a5690..181fb6f 100644
--- a/docker-compose-postgresql.yml
+++ b/docker-compose-postgresql.yml
@@ -35,5 +35,6 @@
       db:
         condition: service_healthy
     env_file:
-      - ./config/docker/env/fineract-postgresql.env
       - ./config/docker/env/fineract.env
+      - ./config/docker/env/fineract-common.env
+      - ./config/docker/env/fineract-postgresql.env
diff --git a/docker-compose.yml b/docker-compose.yml
index 17417a6..d675796 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -35,5 +35,6 @@
       db:
         condition: service_healthy
     env_file:
-      - ./config/docker/env/fineract-mariadb.env
       - ./config/docker/env/fineract.env
+      - ./config/docker/env/fineract-common.env
+      - ./config/docker/env/fineract-mariadb.env
diff --git a/fineract-client/build.gradle b/fineract-client/build.gradle
index 5c7bc65..6fd0185 100644
--- a/fineract-client/build.gradle
+++ b/fineract-client/build.gradle
@@ -16,9 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-plugins {
-    id 'org.openapi.generator' version '6.6.0'
-}
+apply plugin: 'org.openapi.generator'
 description = 'Fineract Client'
 
 apply from: 'dependencies.gradle'
diff --git a/fineract-client/dependencies.gradle b/fineract-client/dependencies.gradle
index 62f7b8b..e5bf65e 100644
--- a/fineract-client/dependencies.gradle
+++ b/fineract-client/dependencies.gradle
@@ -21,7 +21,6 @@
     // only handles javax annotations, not jakarta ones
     implementation 'jakarta.annotation:jakarta.annotation-api:1.3.5'
 
-
     implementation(
             'io.swagger.core.v3:swagger-annotations-jakarta',
             'com.squareup.retrofit2:retrofit',
@@ -31,6 +30,8 @@
             'com.squareup.retrofit2:converter-gson',
             'io.gsonfire:gson-fire',
             'com.google.code.findbugs:jsr305',
+            'com.github.spotbugs:spotbugs-annotations',
+            'com.squareup.okhttp3:okhttp',
             'com.squareup.okhttp3:logging-interceptor',
             )
 
diff --git a/fineract-client/src/test/java/org/apache/fineract/client/test/FineractClientDemo.java b/fineract-client/src/test/java/org/apache/fineract/client/test/FineractClientDemo.java
index 316240b..0a3d7ec 100644
--- a/fineract-client/src/test/java/org/apache/fineract/client/test/FineractClientDemo.java
+++ b/fineract-client/src/test/java/org/apache/fineract/client/test/FineractClientDemo.java
@@ -22,6 +22,8 @@
 import org.apache.fineract.client.models.RetrieveOneResponse;
 import org.apache.fineract.client.util.Calls;
 import org.apache.fineract.client.util.FineractClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Demo code which is included in the fineract-doc/src/docs/en/05_client.adoc.
@@ -33,12 +35,15 @@
  */
 public class FineractClientDemo {
 
+    private static final Logger log = LoggerFactory.getLogger(FineractClientDemo.class);
+
     void demoClient() {
         // tag::documentation[]
         FineractClient fineract = FineractClient.builder().baseURL("https://demo.fineract.dev/fineract-provider/api/v1/").tenant("default")
                 .basicAuth("mifos", "password").build();
         List<RetrieveOneResponse> staff = Calls.ok(fineract.staff.retrieveAll16(1L, true, false, "ACTIVE"));
         String name = staff.get(0).getDisplayName();
+        log.info("Display name: {}", name);
         // end::documentation[]
     }
 
diff --git a/fineract-client/src/test/java/org/apache/fineract/client/test/FineractClientTechnicalTest.java b/fineract-client/src/test/java/org/apache/fineract/client/test/FineractClientTechnicalTest.java
index b369bec..f45b371 100644
--- a/fineract-client/src/test/java/org/apache/fineract/client/test/FineractClientTechnicalTest.java
+++ b/fineract-client/src/test/java/org/apache/fineract/client/test/FineractClientTechnicalTest.java
@@ -20,6 +20,7 @@
 
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import org.apache.fineract.client.util.FineractClient;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
@@ -29,6 +30,7 @@
  *
  * @author Michael Vorburger.ch
  */
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class FineractClientTechnicalTest {
 
     @Test
diff --git a/fineract-core/dependencies.gradle b/fineract-core/dependencies.gradle
index 3bbde9d..b7bab1d 100644
--- a/fineract-core/dependencies.gradle
+++ b/fineract-core/dependencies.gradle
@@ -53,7 +53,7 @@
             'org.springdoc:springdoc-openapi-starter-webmvc-ui',
             'org.mapstruct:mapstruct',
 
-            'io.github.resilience4j:resilience4j-spring-boot2',
+            'io.github.resilience4j:resilience4j-spring-boot3',
             'org.apache.httpcomponents:httpcore',
             )
     implementation ('org.springframework.boot:spring-boot-starter-data-jpa') {
diff --git a/fineract-core/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResource.java b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResource.java
index 95c8d4a..e9d2e54 100644
--- a/fineract-core/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResource.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/closure/api/GLClosuresApiResource.java
@@ -70,7 +70,7 @@
             Arrays.asList("id", "officeId", "officeName", "closingDate", "deleted", "createdDate", "lastUpdatedDate", "createdByUserId",
                     "createdByUsername", "lastUpdatedByUserId", "lastUpdatedByUsername"));
 
-    private final String resourceNameForPermission = "GLCLOSURE";
+    private static final String RESOURCE_NAME_FOR_PERMISSION = "GLCLOSURE";
 
     private final PlatformSecurityContext context;
     private final GLClosureReadPlatformService glClosureReadPlatformService;
@@ -88,7 +88,7 @@
     public String retrieveAllClosures(@Context final UriInfo uriInfo,
             @QueryParam("officeId") @Parameter(name = "officeId") final Long officeId) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
         final List<GLClosureData> glClosureDatas = this.glClosureReadPlatformService.retrieveAllGLClosures(officeId);
 
         final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
@@ -106,7 +106,7 @@
     public String retreiveClosure(@PathParam("glClosureId") @Parameter(description = "glClosureId") final Long glClosureId,
             @Context final UriInfo uriInfo) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
 
         final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResource.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResource.java
index e4b51b0..2bbd839 100644
--- a/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResource.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/api/GLAccountsApiResource.java
@@ -85,7 +85,7 @@
             "allowedAssetsTagOptions", "allowedLiabilitiesTagOptions", "allowedEquityTagOptions", "allowedIncomeTagOptions",
             "allowedExpensesTagOptions", "creditAccounts", "debitAccounts"));
 
-    private final String resourceNameForPermission = "GLACCOUNT";
+    private static final String RESOURCE_NAME_FOR_PERMISSION = "GLACCOUNT";
 
     private final PlatformSecurityContext context;
     private final GLAccountReadPlatformService glAccountReadPlatformService;
@@ -111,7 +111,7 @@
     public String retrieveNewAccountDetails(@Context final UriInfo uriInfo,
             @QueryParam("type") @Parameter(description = "type") final Integer type) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
 
         GLAccountData glAccountData = this.glAccountReadPlatformService.retrieveNewGLAccountDetails(type);
         glAccountData = handleTemplate(glAccountData);
@@ -137,7 +137,7 @@
             @QueryParam("disabled") @Parameter(description = "disabled") final Boolean disabled,
             @QueryParam("fetchRunningBalance") @Parameter(description = "fetchRunningBalance") final boolean runningBalance) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
         JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance);
         final List<GLAccountData> glAccountDatas = this.glAccountReadPlatformService.retrieveAllGLAccounts(type, searchParam, usage,
                 manualEntriesAllowed, disabled, associationParametersData);
@@ -159,7 +159,7 @@
             @Context final UriInfo uriInfo,
             @QueryParam("fetchRunningBalance") @Parameter(description = "fetchRunningBalance") final boolean runningBalance) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
 
         final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
         JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(false, runningBalance);
diff --git a/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountType.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountType.java
index 4f86f97..79814b2 100644
--- a/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountType.java
@@ -18,8 +18,6 @@
  */
 package org.apache.fineract.accounting.glaccount.domain;
 
-import java.util.HashMap;
-import java.util.Map;
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 
 public enum GLAccountType {
@@ -43,7 +41,6 @@
         return this.code;
     }
 
-    private static final Map<Integer, GLAccountType> intToEnumMap = new HashMap<>();
     private static int minValue;
     private static int maxValue;
 
@@ -53,7 +50,6 @@
             if (i == 0) {
                 minValue = type.value;
             }
-            intToEnumMap.put(type.value, type);
             if (minValue >= type.value) {
                 minValue = type.value;
             }
@@ -86,9 +82,25 @@
         }
     }
 
-    public static GLAccountType fromInt(final int i) {
-        final GLAccountType type = intToEnumMap.get(Integer.valueOf(i));
-        return type;
+    public static GLAccountType fromInt(final Integer v) {
+        if (v == null) {
+            return null;
+        }
+
+        switch (v) {
+            case 1:
+                return ASSET;
+            case 2:
+                return LIABILITY;
+            case 3:
+                return EQUITY;
+            case 4:
+                return INCOME;
+            case 5:
+                return EXPENSE;
+            default:
+                return null;
+        }
     }
 
     public static int getMinValue() {
diff --git a/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java
index 2393369..cc672fc 100644
--- a/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/service/GLAccountWritePlatformServiceJpaRepositoryImpl.java
@@ -170,8 +170,8 @@
     private void validateForAttachedProduct(Long glAccountId) {
         String sql = "select count(*) from acc_product_mapping acc where acc.gl_account_id = ?";
         try {
-            int count = this.jdbcTemplate.queryForObject(sql, Integer.class, glAccountId);
-            if (count > 0) {
+            Integer count = this.jdbcTemplate.queryForObject(sql, Integer.class, glAccountId);
+            if (count == null || count > 0) {
                 throw new GLAccountDisableException();
             }
         } catch (EmptyResultDataAccessException e) {
diff --git a/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryType.java b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryType.java
index 52f0322..80b9b49 100755
--- a/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryType.java
@@ -18,9 +18,6 @@
  */
 package org.apache.fineract.accounting.journalentry.domain;
 
-import java.util.HashMap;
-import java.util.Map;
-
 public enum JournalEntryType {
 
     CREDIT(1, "journalEntryType.credit"), DEBIT(2, "journalEntrytType.debit");
@@ -41,16 +38,19 @@
         return this.code;
     }
 
-    private static final Map<Integer, JournalEntryType> intToEnumMap = new HashMap<>();
-
-    static {
-        for (final JournalEntryType type : JournalEntryType.values()) {
-            intToEnumMap.put(type.value, type);
+    public static JournalEntryType fromInt(final Integer v) {
+        if (v == null) {
+            return null;
         }
-    }
 
-    public static JournalEntryType fromInt(final int i) {
-        return intToEnumMap.get(i);
+        switch (v) {
+            case 1:
+                return CREDIT;
+            case 2:
+                return DEBIT;
+            default:
+                return null;
+        }
     }
 
     @Override
@@ -59,11 +59,11 @@
     }
 
     public boolean isDebitType() {
-        return this.value.equals(JournalEntryType.DEBIT.getValue());
+        return this.equals(DEBIT);
     }
 
     public boolean isCreditType() {
-        return this.value.equals(JournalEntryType.CREDIT.getValue());
+        return this.equals(CREDIT);
     }
 
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/PortfolioProductType.java b/fineract-core/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/PortfolioProductType.java
index d233e73..0826a4c 100644
--- a/fineract-core/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/PortfolioProductType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/PortfolioProductType.java
@@ -18,9 +18,6 @@
  */
 package org.apache.fineract.accounting.producttoaccountmapping.domain;
 
-import java.util.HashMap;
-import java.util.Map;
-
 public enum PortfolioProductType {
 
     LOAN(1, "productType.loan"), SAVING(2, "productType.saving"), CLIENT(5, "productType.client"), PROVISIONING(3,
@@ -47,33 +44,41 @@
         return this.code;
     }
 
-    private static final Map<Integer, PortfolioProductType> intToEnumMap = new HashMap<>();
+    public static PortfolioProductType fromInt(final Integer v) {
+        if (v == null) {
+            return null;
+        }
 
-    static {
-        for (final PortfolioProductType type : PortfolioProductType.values()) {
-            intToEnumMap.put(type.value, type);
+        switch (v) {
+            case 1:
+                return LOAN;
+            case 2:
+                return SAVING;
+            case 3:
+                return CLIENT;
+            case 4:
+                return PROVISIONING;
+            case 5:
+                return SHARES;
+            default:
+                return null;
         }
     }
 
-    public static PortfolioProductType fromInt(final int i) {
-        final PortfolioProductType type = intToEnumMap.get(Integer.valueOf(i));
-        return type;
-    }
-
     public boolean isSavingProduct() {
-        return this.value.equals(PortfolioProductType.SAVING.getValue());
+        return this.equals(SAVING);
     }
 
     public boolean isLoanProduct() {
-        return this.value.equals(PortfolioProductType.LOAN.getValue());
+        return this.equals(LOAN);
     }
 
     public boolean isClient() {
-        return this.value.equals(PortfolioProductType.CLIENT.getValue());
+        return this.equals(CLIENT);
     }
 
     public boolean isShareProduct() {
-        return this.value.equals(PortfolioProductType.SHARES.getValue());
+        return this.equals(SHARES);
     }
 
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java b/fineract-core/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
index 3ae4965..0e895bb 100644
--- a/fineract-core/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
@@ -26,6 +26,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import lombok.RequiredArgsConstructor;
 import org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForLoan;
@@ -99,7 +100,7 @@
                     throw new ProductToGLAccountMappingNotFoundException(portfolioProductType, productId, accountTypeName);
                 }
             } else {
-                if (!accountMapping.getGlAccount().getId().equals(accountId)) {
+                if (accountMapping.getGlAccount() != null && !Objects.equals(accountMapping.getGlAccount().getId(), accountId)) {
                     final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
                     changes.put(paramName, accountId);
                     accountMapping.setGlAccount(glAccount);
@@ -124,7 +125,7 @@
                 ProductToGLAccountMapping newAccountMapping = new ProductToGLAccountMapping().setGlAccount(glAccount)
                         .setProductId(productId).setProductType(portfolioProductType.getValue()).setFinancialAccountType(accountTypeId);
                 this.accountMappingRepository.saveAndFlush(newAccountMapping);
-            } else if (!accountMapping.getGlAccount().getId().equals(accountId)) {
+            } else if (accountMapping.getGlAccount() != null && !Objects.equals(accountMapping.getGlAccount().getId(), accountId)) {
                 final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
                 changes.put(paramName, accountId);
                 accountMapping.setGlAccount(glAccount);
@@ -272,14 +273,11 @@
                         this.accountMappingRepository.delete(chargeToIncomeAccountMapping);
                     }
                 }
-                // create new mappings
-                final Set<Long> incomingCharges = inputChargeToIncomeAccountMap.keySet();
-                incomingCharges.removeAll(existingCharges);
-                // incomingPaymentTypes now only contains the newly added
-                // payment Type mappings
-                for (final Long newCharge : incomingCharges) {
-                    final Long newGLAccountId = inputChargeToIncomeAccountMap.get(newCharge);
-                    saveChargeToFundSourceMapping(productId, newCharge, newGLAccountId, portfolioProductType, isPenalty);
+
+                // only the newly added
+                for (Map.Entry<Long, Long> entry : inputChargeToIncomeAccountMap.entrySet().stream()
+                        .filter(e -> !existingCharges.contains(e.getKey())).toList()) {
+                    saveChargeToFundSourceMapping(productId, entry.getKey(), entry.getValue(), portfolioProductType, isPenalty);
                 }
             }
         }
@@ -321,7 +319,7 @@
             }
 
             // If input map is empty, delete all existing mappings
-            if (inputPaymentChannelFundSourceMap.size() == 0) {
+            if (inputPaymentChannelFundSourceMap.isEmpty()) {
                 this.accountMappingRepository.deleteAllInBatch(existingPaymentChannelToFundSourceMappings);
             } /**
                * Else, <br/>
@@ -348,14 +346,11 @@
                         this.accountMappingRepository.delete(existingPaymentChannelToFundSourceMapping);
                     }
                 }
-                // create new mappings
-                final Set<Long> incomingPaymentTypes = inputPaymentChannelFundSourceMap.keySet();
-                incomingPaymentTypes.removeAll(existingPaymentTypes);
-                // incomingPaymentTypes now only contains the newly added
-                // payment Type mappings
-                for (final Long newPaymentType : incomingPaymentTypes) {
-                    final Long newGLAccountId = inputPaymentChannelFundSourceMap.get(newPaymentType);
-                    savePaymentChannelToFundSourceMapping(productId, newPaymentType, newGLAccountId, portfolioProductType);
+
+                // only the newly added
+                for (Map.Entry<Long, Long> entry : inputPaymentChannelFundSourceMap.entrySet().stream()
+                        .filter(e -> !existingPaymentTypes.contains(e.getKey())).toList()) {
+                    savePaymentChannelToFundSourceMapping(productId, entry.getKey(), entry.getValue(), portfolioProductType);
                 }
             }
         }
diff --git a/fineract-core/src/main/java/org/apache/fineract/batch/api/BatchApiResource.java b/fineract-core/src/main/java/org/apache/fineract/batch/api/BatchApiResource.java
index 6eb1898..d8cb1b8 100644
--- a/fineract-core/src/main/java/org/apache/fineract/batch/api/BatchApiResource.java
+++ b/fineract-core/src/main/java/org/apache/fineract/batch/api/BatchApiResource.java
@@ -37,7 +37,6 @@
 import jakarta.ws.rs.core.Context;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.UriInfo;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
 import lombok.RequiredArgsConstructor;
@@ -112,7 +111,7 @@
         validateRequestMethodsAllowedOnInstanceType(requestList);
 
         // Gets back the consolidated BatchResponse from BatchApiservice
-        List<BatchResponse> result = new ArrayList<>();
+        List<BatchResponse> result;
 
         // If the request is to be handled as a Transaction. All requests will
         // be rolled back on error
diff --git a/fineract-core/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java
index a7d799a..0339cee 100644
--- a/fineract-core/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java
+++ b/fineract-core/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java
@@ -23,6 +23,7 @@
 
 import com.google.gson.Gson;
 import com.jayway.jsonpath.JsonPathException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.github.resilience4j.core.functions.Either;
 import jakarta.persistence.EntityManager;
 import jakarta.persistence.PersistenceContext;
@@ -380,6 +381,7 @@
         return List.of(buildErrorResponse(requestId, statusCode, body, headers));
     }
 
+    @SuppressFBWarnings(value = "BX_UNBOXING_IMMEDIATELY_REBOXED", justification = "TODO: fix this!")
     private BatchResponse buildErrorResponse(Long requestId, Integer statusCode, String body, Set<Header> headers) {
         return new BatchResponse().setRequestId(requestId).setStatusCode(statusCode == null ? SC_INTERNAL_SERVER_ERROR : statusCode)
                 .setBody(body == null ? "Request with id " + requestId + " was erroneous!" : body).setHeaders(headers);
diff --git a/fineract-core/src/main/java/org/apache/fineract/commands/provider/CommandHandlerProvider.java b/fineract-core/src/main/java/org/apache/fineract/commands/provider/CommandHandlerProvider.java
index a4297f9..38ca3e7 100644
--- a/fineract-core/src/main/java/org/apache/fineract/commands/provider/CommandHandlerProvider.java
+++ b/fineract-core/src/main/java/org/apache/fineract/commands/provider/CommandHandlerProvider.java
@@ -65,7 +65,11 @@
                 log.debug("Register command handler '{}' ...", commandHandlerName);
                 final CommandType commandType = applicationContext.findAnnotationOnBean(commandHandlerName, CommandType.class);
                 try {
-                    registeredHandlers.put(commandType.entity() + "|" + commandType.action(), commandHandlerName);
+                    if (commandType != null) {
+                        registeredHandlers.put(commandType.entity() + "|" + commandType.action(), commandHandlerName);
+                    } else {
+                        log.error("Unable to register command handler '{}'!", commandHandlerName);
+                    }
                 } catch (final Throwable th) {
                     log.error("Unable to register command handler '{}'!", commandHandlerName, th);
                 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java b/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
index 486abf6..8864640 100644
--- a/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
+++ b/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.commands.service;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import org.apache.fineract.commands.domain.CommandWrapper;
 import org.apache.fineract.infrastructure.accountnumberformat.service.AccountNumberFormatConstants;
 import org.apache.fineract.portfolio.client.api.ClientApiConstants;
@@ -47,6 +48,7 @@
     private String jobName;
     private String idempotencyKey;
 
+    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "TODO: fix this!")
     public CommandWrapper build() {
         return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName, this.entityName,
                 this.entityId, this.subentityId, this.href, this.json, this.transactionId, this.productId, this.templateId,
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/service/RuntimeDelegatingCacheManager.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/service/RuntimeDelegatingCacheManager.java
index a15ae01..f2d3b4e 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/service/RuntimeDelegatingCacheManager.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/cache/service/RuntimeDelegatingCacheManager.java
@@ -18,10 +18,12 @@
  */
 package org.apache.fineract.infrastructure.cache.service;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.cache.CacheApiConstants;
@@ -105,7 +107,7 @@
                 }
                 currentCacheManager = ehCacheManager;
 
-                if (currentCacheManager.getCacheNames().size() == 0) {
+                if (currentCacheManager.getCacheNames().isEmpty()) {
                     log.error("No caches configured for activated CacheManager {}", currentCacheManager);
                 }
             }
@@ -115,10 +117,17 @@
         return changes;
     }
 
+    @SuppressFBWarnings(value = "DCN_NULLPOINTER_EXCEPTION", justification = "TODO: fix this!")
     private void clearEhCache() {
         Iterable<String> cacheNames = ehCacheManager.getCacheNames();
         for (String cacheName : cacheNames) {
-            ehCacheManager.getCache(cacheName).clear();
+            try {
+                if (Objects.nonNull(ehCacheManager.getCache(cacheName))) {
+                    Objects.requireNonNull(ehCacheManager.getCache(cacheName)).clear();
+                }
+            } catch (NullPointerException npe) {
+                log.warn(npe.getMessage());
+            }
         }
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
index 5f80f69..0e0b57d 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java
@@ -38,6 +38,8 @@
 
     private String idempotencyKeyHeaderName;
 
+    private Boolean insecureHttpClient;
+
     private FineractTenantProperties tenant;
 
     private FineractModeProperties mode;
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessFailedException.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessFailedException.java
index 0ea52b8..bd0f969 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessFailedException.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/IdempotentCommandProcessFailedException.java
@@ -39,6 +39,6 @@
     @NotNull
     public Integer getStatusCode() {
         // If the database inconsistent we return http 500 instead of null pointer exception
-        return statusCode == null ? SC_INTERNAL_SERVER_ERROR : statusCode;
+        return statusCode == null ? Integer.valueOf(SC_INTERNAL_SERVER_ERROR) : statusCode;
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java
index 0074442..a3cd2bd 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/serialization/JsonParserHelper.java
@@ -736,6 +736,7 @@
     /***
      * TODO: Vishwas move all Locale related code to a separate Utils class
      ***/
+    @SuppressWarnings("StringSplitter")
     public static Locale localeFromString(final String localeAsString) {
 
         if (StringUtils.isBlank(localeAsString)) {
@@ -754,16 +755,16 @@
 
         final String[] localeParts = localeAsString.split("_");
 
-        if (localeParts != null && localeParts.length == 1) {
+        if (localeParts.length == 1) {
             languageCode = localeParts[0];
         }
 
-        if (localeParts != null && localeParts.length == 2) {
+        if (localeParts.length == 2) {
             languageCode = localeParts[0];
             countryCode = localeParts[1];
         }
 
-        if (localeParts != null && localeParts.length == 3) {
+        if (localeParts.length == 3) {
             languageCode = localeParts[0];
             countryCode = localeParts[1];
             variantCode = localeParts[2];
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/Page.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/Page.java
index a7bf95d..76755e4 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/Page.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/Page.java
@@ -23,10 +23,10 @@
 
 public class Page<E> implements Serializable {
 
-    private final int totalFilteredRecords;
+    private final Integer totalFilteredRecords;
     private final List<E> pageItems;
 
-    public Page(final List<E> pageItems, final int totalFilteredRecords) {
+    public Page(final List<E> pageItems, final Integer totalFilteredRecords) {
         this.pageItems = pageItems;
         this.totalFilteredRecords = totalFilteredRecords;
     }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PagedLocalRequest.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PagedLocalRequest.java
index b2c6454..5289850 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PagedLocalRequest.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PagedLocalRequest.java
@@ -19,6 +19,7 @@
 package org.apache.fineract.infrastructure.core.service;
 
 import java.util.Locale;
+import java.util.Objects;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.Setter;
@@ -38,4 +39,25 @@
     public Locale getLocaleObject() {
         return locale == null ? null : JsonParserHelper.localeFromString(locale);
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || !(o instanceof PagedLocalRequest)) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+        PagedLocalRequest<?> that = (PagedLocalRequest<?>) o;
+        return Objects.equals(dateFormat, that.dateFormat) && Objects.equals(dateTimeFormat, that.dateTimeFormat)
+                && Objects.equals(locale, that.locale);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), dateFormat, dateTimeFormat, locale);
+    }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PagedRequest.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PagedRequest.java
index e2becbb..b87e4d3 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PagedRequest.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PagedRequest.java
@@ -37,7 +37,7 @@
     private int page;
     private int size = DEFAULT_PAGE_SIZE;
 
-    private List<SortOrder> sorts = new ArrayList<>();
+    private final List<SortOrder> sorts = new ArrayList<>();
 
     public Optional<T> getRequest() {
         return Optional.ofNullable(request);
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java
index 2787aad..51b394b 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java
@@ -45,7 +45,7 @@
 
         // determine how many rows are available
         final String sqlCountRows = sqlGenerator.countLastExecutedQueryResult(sqlFetchRows);
-        final int totalFilteredRecords;
+        final Integer totalFilteredRecords;
         if (databaseTypeResolver.isMySQL()) {
             totalFilteredRecords = jt.queryForObject(sqlCountRows, Integer.class); // NOSONAR
         } else {
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/JavaType.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/JavaType.java
index 56b31d2..3d1536c 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/JavaType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/JavaType.java
@@ -91,9 +91,7 @@
     OBJECT(Object.class), //
     ;
 
-    public static final JavaType[] VALUES = values();
-
-    private static final Map<Class<?>, JavaType> BY_TYPE = Arrays.stream(VALUES).filter(e -> e.type != null)
+    private static final Map<Class<?>, JavaType> BY_TYPE = Arrays.stream(values()).filter(e -> e.type != null)
             .collect(Collectors.toMap(JavaType::getTypeClass, v -> v));
 
     private final Class<?> type;
@@ -244,9 +242,9 @@
         // have to do this first to catch custom collection and map types;
         // on resolve we figure out if these custom types are
         // persistence-capable
-        for (Class<?> aType : BY_TYPE.keySet()) {
-            if (aType.isAssignableFrom(type)) {
-                return BY_TYPE.get(aType);
+        for (Map.Entry<Class<?>, JavaType> entry : BY_TYPE.entrySet()) {
+            if (entry.getKey().isAssignableFrom(type)) {
+                return entry.getValue();
             }
         }
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/JdbcJavaType.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/JdbcJavaType.java
index aea1339..2eb35d2 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/JdbcJavaType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/JdbcJavaType.java
@@ -136,11 +136,19 @@
         for (JdbcJavaType type : values()) {
             DialectType dialectType = type.getDialectType(dialect);
             if (dialectType.getNameResolved().equals(name)) {
+                // NOTE: make MySQL systems happy aka TINYINT vs BOOLEAN issue!
+                if (type.canBooleanType(dialect)) {
+                    return BOOLEAN;
+                }
                 return type;
             }
             if (dialectType.alterNames != null) {
                 for (String alterName : dialectType.alterNames) {
                     if (alterName.equals(name)) {
+                        // NOTE: make MySQL systems happy aka TINYINT vs BOOLEAN issue!
+                        if (type.canBooleanType(dialect)) {
+                            return BOOLEAN;
+                        }
                         return type;
                     }
                 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java
index 77e2793..ddaec05 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationWritePlatformServiceImpl.java
@@ -48,14 +48,15 @@
         final Map<String, Object> changes = new HashMap<>();
         final Map<String, Boolean> changedConfigurations = new HashMap<>();
         final List<ExternalEventConfiguration> modifiedConfigurations = new ArrayList<>();
-        for (final String eventType : commandConfigurations.keySet()) {
+
+        for (Map.Entry<String, Boolean> entry : commandConfigurations.entrySet()) {
             final ExternalEventConfiguration configuration = repository
-                    .findExternalEventConfigurationByTypeWithNotFoundDetection(eventType);
-            final boolean canEnable = commandConfigurations.get(eventType).booleanValue();
-            configuration.setEnabled(canEnable);
-            changedConfigurations.put(eventType, canEnable);
+                    .findExternalEventConfigurationByTypeWithNotFoundDetection(entry.getKey());
+            configuration.setEnabled(entry.getValue());
+            changedConfigurations.put(entry.getKey(), entry.getValue());
             modifiedConfigurations.add(configuration);
         }
+
         if (!modifiedConfigurations.isEmpty()) {
             this.repository.saveAll(modifiedConfigurations);
         }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/ColumnValidator.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/ColumnValidator.java
index f3c63de..cf5c2ee 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/ColumnValidator.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/security/utils/ColumnValidator.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.infrastructure.security.utils;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
@@ -28,6 +29,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -48,17 +50,18 @@
         this.jdbcTemplate = jdbcTemplate;
     }
 
+    @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "TODO: fix this!")
     private void validateColumn(Map<String, Set<String>> tableColumnMap) {
         Connection connection = null;
+
         try {
-            connection = this.jdbcTemplate.getDataSource().getConnection();
+            connection = Objects.requireNonNull(this.jdbcTemplate.getDataSource()).getConnection();
             DatabaseMetaData dbMetaData = connection.getMetaData();
-            ResultSet resultSet = null;
             for (Map.Entry<String, Set<String>> entry : tableColumnMap.entrySet()) {
                 Set<String> columns = entry.getValue();
-                resultSet = dbMetaData.getColumns(null, null, entry.getKey(), null);
+                ResultSet resultSet = dbMetaData.getColumns(null, null, entry.getKey(), null);
                 Set<String> tableColumns = getTableColumns(resultSet);
-                if (columns.size() > 0 && tableColumns.size() == 0) {
+                if (!columns.isEmpty() && tableColumns.isEmpty()) {
                     throw new SQLInjectionException();
                 }
                 for (String requestedColumn : columns) {
@@ -111,17 +114,19 @@
     private static Map<String, Set<String>> getTableColumnMap(String schema, Map<String, Set<String>> tableColumnAliasMap) {
         Map<String, Set<String>> tableColumnMap = new HashMap<>();
         schema = schema.substring(schema.indexOf("from"));
-        for (String alias : tableColumnAliasMap.keySet()) {
-            int index = schema.indexOf(" " + alias + " ");
+
+        for (Map.Entry<String, Set<String>> entry : tableColumnAliasMap.entrySet()) {
+            int index = schema.indexOf(" " + entry.getKey() + " ");
             if (index > -1) {
-                int startPos = 0;
+                int startPos;
                 startPos = schema.substring(0, index - 1).lastIndexOf(' ', index);
-                Set<String> columns = tableColumnAliasMap.get(alias);
+                Set<String> columns = entry.getValue();
                 tableColumnMap.put(schema.substring(startPos, index).trim(), columns);
             } else {
                 throw new SQLInjectionException();
             }
         }
+
         return tableColumnMap;
     }
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/organisation/holiday/domain/HolidayStatusType.java b/fineract-core/src/main/java/org/apache/fineract/organisation/holiday/domain/HolidayStatusType.java
index 85abe07..b07d299 100644
--- a/fineract-core/src/main/java/org/apache/fineract/organisation/holiday/domain/HolidayStatusType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/organisation/holiday/domain/HolidayStatusType.java
@@ -31,20 +31,21 @@
     private final Integer value;
     private final String code;
 
-    public static HolidayStatusType fromInt(final Integer type) {
-        HolidayStatusType enumeration = HolidayStatusType.INVALID;
-        switch (type) {
-            case 100:
-                enumeration = HolidayStatusType.PENDING_FOR_ACTIVATION;
-            break;
-            case 300:
-                enumeration = HolidayStatusType.ACTIVE;
-            break;
-            case 600:
-                enumeration = HolidayStatusType.DELETED;
-            break;
+    public static HolidayStatusType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return enumeration;
+
+        switch (v) {
+            case 100:
+                return PENDING_FOR_ACTIVATION;
+            case 300:
+                return ACTIVE;
+            case 600:
+                return DELETED;
+            default:
+                return INVALID;
+        }
     }
 
     HolidayStatusType(final Integer value, final String code) {
@@ -52,10 +53,6 @@
         this.code = code;
     }
 
-    public boolean hasStateOf(final HolidayStatusType state) {
-        return this.value.equals(state.getValue());
-    }
-
     public Integer getValue() {
         return this.value;
     }
diff --git a/fineract-core/src/main/java/org/apache/fineract/organisation/holiday/domain/RescheduleType.java b/fineract-core/src/main/java/org/apache/fineract/organisation/holiday/domain/RescheduleType.java
index 6a9e8e3..ea165f1 100644
--- a/fineract-core/src/main/java/org/apache/fineract/organisation/holiday/domain/RescheduleType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/organisation/holiday/domain/RescheduleType.java
@@ -31,17 +31,19 @@
         this.code = code;
     }
 
-    public static RescheduleType fromInt(int rescheduleTypeValue) {
-        RescheduleType enumerration = RescheduleType.INVALID;
-        switch (rescheduleTypeValue) {
-            case 1:
-                enumerration = RescheduleType.RESCHEDULETONEXTREPAYMENTDATE;
-            break;
-            case 2:
-                enumerration = RescheduleType.RESCHEDULETOSPECIFICDATE;
-            break;
+    public static RescheduleType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return enumerration;
+
+        switch (v) {
+            case 1:
+                return RESCHEDULETONEXTREPAYMENTDATE;
+            case 2:
+                return RESCHEDULETOSPECIFICDATE;
+            default:
+                return INVALID;
+        }
     }
 
     public boolean isRescheduleToSpecificDate() {
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/account/PortfolioAccountType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/account/PortfolioAccountType.java
index 6c2108d..e70dfab 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/account/PortfolioAccountType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/account/PortfolioAccountType.java
@@ -18,9 +18,6 @@
  */
 package org.apache.fineract.portfolio.account;
 
-import java.util.ArrayList;
-import java.util.List;
-
 public enum PortfolioAccountType {
 
     INVALID(0, "accountType.invalid"), //
@@ -43,20 +40,9 @@
         return this.code;
     }
 
-    public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final PortfolioAccountType enumType : values()) {
-            if (enumType.getValue() > 0) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
-    }
-
     public static PortfolioAccountType fromInt(final Integer type) {
 
-        PortfolioAccountType enumType = PortfolioAccountType.INVALID;
+        PortfolioAccountType enumType = INVALID;
         if (type != null) {
             switch (type) {
                 case 1:
@@ -65,16 +51,20 @@
                 case 2:
                     enumType = SAVINGS;
                 break;
+                default:
+                    enumType = INVALID;
             }
         }
         return enumType;
     }
 
+    // TODO: bad practice and unnecessary code! why not just use the enum values themselves!?!
     public boolean isSavingsAccount() {
-        return this.value.equals(2);
+        return this.equals(SAVINGS);
     }
 
+    // TODO: bad practice and unnecessary code! why not just use the enum values themselves!?!
     public boolean isLoanAccount() {
-        return this.value.equals(1);
+        return this.equals(LOAN);
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarUtils.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarUtils.java
index aa9fed2..1b4f568 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarUtils.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarUtils.java
@@ -272,12 +272,14 @@
 
             humanReadable += " on ";
             final WeekDayList weekDayList = recur.getDayList();
+            StringBuilder sb = new StringBuilder();
 
             for (@SuppressWarnings("rawtypes")
             final Iterator iterator = weekDayList.iterator(); iterator.hasNext();) {
                 final WeekDay weekDay = (WeekDay) iterator.next();
-                humanReadable += DayNameEnum.from(weekDay.getDay().name()).getCode();
+                sb.append(DayNameEnum.from(weekDay.getDay().name()).getCode());
             }
+            humanReadable += sb.toString();
 
         } else if (recur.getFrequency().equals(Recur.Frequency.MONTHLY)) {
             NumberList nthDays = recur.getSetPosList();
@@ -684,13 +686,15 @@
      * @return
      */
     public static String getSqlCalendarTypeOptionsInString(final List<Integer> calendarTypeOptions) {
-        String sqlCalendarTypeOptions = "";
-        final int size = calendarTypeOptions.size();
-        for (int i = 0; i < size - 1; i++) {
-            sqlCalendarTypeOptions += calendarTypeOptions.get(i).toString() + ",";
+        StringBuilder sb = new StringBuilder();
+
+        for (int i = 0; i < calendarTypeOptions.size() - 1; i++) {
+            sb.append(calendarTypeOptions.get(i).toString() + ",");
         }
-        sqlCalendarTypeOptions += calendarTypeOptions.get(size - 1).toString();
-        return sqlCalendarTypeOptions;
+
+        sb.append(calendarTypeOptions.get(calendarTypeOptions.size() - 1).toString());
+
+        return sb.toString();
     }
 
     public static LocalDate getRecentEligibleMeetingDate(final String recurringRule, final LocalDate seedDate,
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/DaysInMonthType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/DaysInMonthType.java
index 32d58cc..20eca6b 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/DaysInMonthType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/DaysInMonthType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.common.domain;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 /**
  *
@@ -51,15 +50,9 @@
         return this.code;
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final DaysInMonthType enumType : values()) {
-            if (enumType.getValue() > 0) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 
     public static DaysInMonthType fromInt(final Integer type) {
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/DaysInYearType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/DaysInYearType.java
index d08fff7..80a42d4 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/DaysInYearType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/DaysInYearType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.common.domain;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 /**
  *
@@ -55,15 +54,9 @@
         return this.code;
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final DaysInYearType enumType : values()) {
-            if (enumType.getValue() > 0) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 
     public static DaysInYearType fromInt(final Integer type) {
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/PeriodFrequencyType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/PeriodFrequencyType.java
index 4a44786..f2e8561 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/PeriodFrequencyType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/common/domain/PeriodFrequencyType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.common.domain;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 public enum PeriodFrequencyType {
 
@@ -46,62 +45,59 @@
         return this.code;
     }
 
-    public static PeriodFrequencyType fromInt(final Integer frequency) {
-        PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.INVALID;
-        if (frequency != null) {
-            switch (frequency) {
-                case 0:
-                    repaymentFrequencyType = PeriodFrequencyType.DAYS;
-                break;
-                case 1:
-                    repaymentFrequencyType = PeriodFrequencyType.WEEKS;
-                break;
-                case 2:
-                    repaymentFrequencyType = PeriodFrequencyType.MONTHS;
-                break;
-                case 3:
-                    repaymentFrequencyType = PeriodFrequencyType.YEARS;
-                break;
-                case 4:
-                    repaymentFrequencyType = PeriodFrequencyType.WHOLE_TERM;
-                break;
-            }
+    public static PeriodFrequencyType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return repaymentFrequencyType;
+
+        switch (v) {
+            case 0:
+                return DAYS;
+            case 1:
+                return WEEKS;
+            case 2:
+                return MONTHS;
+            case 3:
+                return YEARS;
+            case 4:
+                return WHOLE_TERM;
+            default:
+                return INVALID;
+        }
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isMonthly() {
-        return this.value.equals(PeriodFrequencyType.MONTHS.getValue());
+        return this.equals(MONTHS);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isYearly() {
-        return this.value.equals(PeriodFrequencyType.YEARS.getValue());
+        return this.equals(YEARS);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isWeekly() {
-        return this.value.equals(PeriodFrequencyType.WEEKS.getValue());
+        return this.equals(WEEKS);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isDaily() {
-        return this.value.equals(PeriodFrequencyType.DAYS.getValue());
+        return this.equals(DAYS);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isWholeTerm() {
-        return this.value.equals(PeriodFrequencyType.WHOLE_TERM.getValue());
+        return this.equals(WHOLE_TERM);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isInvalid() {
-        return this.value.equals(PeriodFrequencyType.INVALID.getValue());
+        return this.equals(INVALID);
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final PeriodFrequencyType enumType : values()) {
-            if (!enumType.isInvalid()) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnClosureType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnClosureType.java
index aded4a0..9513838 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnClosureType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnClosureType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.savings;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 /**
  * An enumeration of different options available on account closure {@link FixedDepositAccount} &amp;
@@ -49,63 +48,57 @@
         return this.code;
     }
 
-    public static DepositAccountOnClosureType fromInt(final Integer closureTypeValue) {
-
-        if (closureTypeValue == null) {
-            return DepositAccountOnClosureType.INVALID;
+    public static DepositAccountOnClosureType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
 
-        DepositAccountOnClosureType accountOnClosureType = DepositAccountOnClosureType.INVALID;
-        switch (closureTypeValue) {
+        switch (v) {
             case 100:
-                accountOnClosureType = DepositAccountOnClosureType.WITHDRAW_DEPOSIT;
-            break;
+                return WITHDRAW_DEPOSIT;
             case 200:
-                accountOnClosureType = DepositAccountOnClosureType.TRANSFER_TO_SAVINGS;
-            break;
+                return TRANSFER_TO_SAVINGS;
             case 300:
-                accountOnClosureType = DepositAccountOnClosureType.REINVEST_PRINCIPAL_AND_INTEREST;
-            break;
+                return REINVEST_PRINCIPAL_AND_INTEREST;
             case 400:
-                accountOnClosureType = DepositAccountOnClosureType.REINVEST_PRINCIPAL_ONLY;
-            break;
+                return REINVEST_PRINCIPAL_ONLY;
+            default:
+                return INVALID;
         }
-        return accountOnClosureType;
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isWithdarwDeposit() {
-        return this.value.equals(DepositAccountOnClosureType.WITHDRAW_DEPOSIT.getValue());
+        return this.equals(WITHDRAW_DEPOSIT);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isTransferToSavings() {
-        return this.value.equals(DepositAccountOnClosureType.TRANSFER_TO_SAVINGS.getValue());
+        return this.equals(TRANSFER_TO_SAVINGS);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isReinvest() {
-        return this.value.equals(DepositAccountOnClosureType.REINVEST_PRINCIPAL_AND_INTEREST.getValue())
-                || this.value.equals(DepositAccountOnClosureType.REINVEST_PRINCIPAL_ONLY.getValue());
+        return this.equals(REINVEST_PRINCIPAL_AND_INTEREST) || this.equals(REINVEST_PRINCIPAL_ONLY);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isReinvestPrincipal() {
-        return this.value.equals(DepositAccountOnClosureType.REINVEST_PRINCIPAL_ONLY.getValue());
+        return this.equals(REINVEST_PRINCIPAL_ONLY);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isReinvestPrincipalAndInterest() {
-        return this.value.equals(DepositAccountOnClosureType.REINVEST_PRINCIPAL_AND_INTEREST.getValue());
+        return this.equals(REINVEST_PRINCIPAL_AND_INTEREST);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isInvalid() {
-        return this.value.equals(DepositAccountOnClosureType.INVALID.getValue());
+        return this.equals(INVALID);
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final DepositAccountOnClosureType enumType : values()) {
-            if (!enumType.isInvalid()) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnHoldTransactionType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnHoldTransactionType.java
index 816d22d..ee29375 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnHoldTransactionType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountOnHoldTransactionType.java
@@ -43,31 +43,28 @@
         return this.code;
     }
 
-    public static DepositAccountOnHoldTransactionType fromInt(final Integer transactionType) {
-
-        if (transactionType == null) {
-            return DepositAccountOnHoldTransactionType.INVALID;
+    public static DepositAccountOnHoldTransactionType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
 
-        DepositAccountOnHoldTransactionType savingsAccountTransactionType = DepositAccountOnHoldTransactionType.INVALID;
-        switch (transactionType) {
+        switch (v) {
             case 1:
-                savingsAccountTransactionType = DepositAccountOnHoldTransactionType.HOLD;
-            break;
+                return HOLD;
             case 2:
-                savingsAccountTransactionType = DepositAccountOnHoldTransactionType.RELEASE;
-            break;
-
+                return RELEASE;
+            default:
+                return INVALID;
         }
-        return savingsAccountTransactionType;
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isHold() {
-        return this.value.equals(DepositAccountOnHoldTransactionType.HOLD.getValue());
+        return this.equals(HOLD);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isRelease() {
-        return this.value.equals(DepositAccountOnHoldTransactionType.RELEASE.getValue());
+        return this.equals(RELEASE);
     }
-
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountType.java
index f9b3178..ca60bb5 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/DepositAccountType.java
@@ -48,44 +48,48 @@
         return this.code;
     }
 
-    public static DepositAccountType fromInt(final Integer transactionType) {
-
-        if (transactionType == null) {
-            return DepositAccountType.INVALID;
+    public static DepositAccountType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
 
-        DepositAccountType depositAccountType = DepositAccountType.INVALID;
-        switch (transactionType) {
+        switch (v) {
             case 100:
-                depositAccountType = DepositAccountType.SAVINGS_DEPOSIT;
-            break;
+                return SAVINGS_DEPOSIT;
             case 200:
-                depositAccountType = DepositAccountType.FIXED_DEPOSIT;
-            break;
+                return FIXED_DEPOSIT;
             case 300:
-                depositAccountType = DepositAccountType.RECURRING_DEPOSIT;
-            break;
+                return RECURRING_DEPOSIT;
             case 400:
-                depositAccountType = DepositAccountType.CURRENT_DEPOSIT;
-            break;
+                return CURRENT_DEPOSIT;
+            default:
+                return INVALID;
         }
-        return depositAccountType;
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isSavingsDeposit() {
-        return this.value.equals(DepositAccountType.SAVINGS_DEPOSIT.getValue());
+        return this.equals(SAVINGS_DEPOSIT);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isFixedDeposit() {
-        return this.value.equals(DepositAccountType.FIXED_DEPOSIT.getValue());
+        return this.equals(FIXED_DEPOSIT);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isRecurringDeposit() {
-        return this.value.equals(DepositAccountType.RECURRING_DEPOSIT.getValue());
+        return this.equals(RECURRING_DEPOSIT);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isCurrentDeposit() {
-        return this.value.equals(DepositAccountType.CURRENT_DEPOSIT.getValue());
+        return this.equals(CURRENT_DEPOSIT);
+    }
+
+    // TODO: why not just use the enum values... just more boilerplate code here!!
+    public boolean isInvalid() {
+        return this.equals(INVALID);
     }
 
     @Override
@@ -94,28 +98,15 @@
     }
 
     public String resourceName() {
-
-        String resourceName;
-
         switch (this) {
             case FIXED_DEPOSIT:
-                resourceName = DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME;
-            break;
+                return DepositsApiConstants.FIXED_DEPOSIT_ACCOUNT_RESOURCE_NAME;
             case RECURRING_DEPOSIT:
-                resourceName = DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME;
-            break;
+                return DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME;
             case SAVINGS_DEPOSIT:
-                resourceName = DepositsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
-            break;
+                return DepositsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
             default:
-                resourceName = "INVALID";
-            break;
+                return "INVALID";
         }
-
-        return resourceName;
-    }
-
-    public boolean isInvalid() {
-        return this.value.equals(DepositAccountType.INVALID.value);
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/PreClosurePenalInterestOnType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/PreClosurePenalInterestOnType.java
index 8bd52c8..f66656e 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/PreClosurePenalInterestOnType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/PreClosurePenalInterestOnType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.savings;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 /**
  * An enumeration of supported calendar periods used in savings.
@@ -45,41 +44,38 @@
         return this.code;
     }
 
-    public static PreClosurePenalInterestOnType fromInt(final Integer type) {
-        PreClosurePenalInterestOnType penalInterestType = PreClosurePenalInterestOnType.INVALID;
-        if (type != null) {
-            switch (type) {
-                case 1:
-                    penalInterestType = PreClosurePenalInterestOnType.WHOLE_TERM;
-                break;
-                case 2:
-                    penalInterestType = PreClosurePenalInterestOnType.TILL_PREMATURE_WITHDRAWAL;
-                break;
-            }
+    public static PreClosurePenalInterestOnType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return penalInterestType;
+
+        switch (v) {
+            case 1:
+                return WHOLE_TERM;
+            case 2:
+                return TILL_PREMATURE_WITHDRAWAL;
+            default:
+                return INVALID;
+        }
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final PreClosurePenalInterestOnType enumType : values()) {
-            if (enumType.getValue() > 0) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isInvalid() {
-        return this.value.equals(PreClosurePenalInterestOnType.INVALID.value);
+        return this.equals(INVALID);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isWholeTerm() {
-        return this.value.equals(PreClosurePenalInterestOnType.WHOLE_TERM.getValue());
+        return this.equals(WHOLE_TERM);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isTillPrematureWithdrawal() {
-        return this.value.equals(PreClosurePenalInterestOnType.TILL_PREMATURE_WITHDRAWAL.getValue());
+        return this.equals(TILL_PREMATURE_WITHDRAWAL);
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/RecurringDepositType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/RecurringDepositType.java
index 1462121..2994b07 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/RecurringDepositType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/RecurringDepositType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.savings;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 /**
  * An enumeration of supported calendar periods used in savings.
@@ -45,32 +44,27 @@
         return this.code;
     }
 
-    public static RecurringDepositType fromInt(final Integer type) {
-        RecurringDepositType rdType = RecurringDepositType.INVALID;
-        if (type != null) {
-            switch (type) {
-                case 1:
-                    rdType = RecurringDepositType.VOLUNTARY;
-                break;
-                case 2:
-                    rdType = RecurringDepositType.MANDATORY;
-                break;
-            }
+    public static RecurringDepositType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return rdType;
+
+        switch (v) {
+            case 1:
+                return VOLUNTARY;
+            case 2:
+                return MANDATORY;
+            default:
+                return INVALID;
+        }
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final RecurringDepositType enumType : values()) {
-            if (enumType.getValue() > 0) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isInvalid() {
         return this.value.equals(RecurringDepositType.INVALID.value);
     }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsAccountTransactionType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsAccountTransactionType.java
index 48f5e00..639806c 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsAccountTransactionType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsAccountTransactionType.java
@@ -51,9 +51,7 @@
     AMOUNT_HOLD(20, "savingsAccountTransactionType.onHold", TransactionEntryType.DEBIT), //
     AMOUNT_RELEASE(21, "savingsAccountTransactionType.release", TransactionEntryType.CREDIT); //
 
-    public static final SavingsAccountTransactionType[] VALUES = values();
-
-    private static final Map<Integer, SavingsAccountTransactionType> BY_ID = Arrays.stream(VALUES)
+    private static final Map<Integer, SavingsAccountTransactionType> BY_ID = Arrays.stream(values())
             .collect(Collectors.toMap(SavingsAccountTransactionType::getValue, v -> v));
 
     private final int value;
@@ -195,6 +193,6 @@
 
     @NotNull
     public static List<SavingsAccountTransactionType> getFiltered(Predicate<SavingsAccountTransactionType> filter) {
-        return Arrays.stream(VALUES).filter(filter).toList();
+        return Arrays.stream(values()).filter(filter).toList();
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsCompoundingInterestPeriodType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsCompoundingInterestPeriodType.java
index ba4b612..3a326cd 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsCompoundingInterestPeriodType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsCompoundingInterestPeriodType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.savings;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 /**
  * <p>
@@ -28,18 +27,15 @@
  */
 public enum SavingsCompoundingInterestPeriodType {
 
-    INVALID(0, "savingsCompoundingInterestPeriodType.invalid"), //
-    DAILY(1, "savingsCompoundingInterestPeriodType.daily"), //
-    // WEEKLY(2, "savingsCompoundingInterestPeriodType.weekly"), //
-    // BIWEEKLY(3, "savingsCompoundingInterestPeriodType.biweekly"), //
+    INVALID(0, "savingsCompoundingInterestPeriodType.invalid"), DAILY(1, "savingsCompoundingInterestPeriodType.daily"),
+    // WEEKLY(2, "savingsCompoundingInterestPeriodType.weekly"),
+    // BIWEEKLY(3, "savingsCompoundingInterestPeriodType.biweekly"),
     MONTHLY(4, "savingsCompoundingInterestPeriodType.monthly"),
 
-    QUATERLY(5, "savingsCompoundingInterestPeriodType.quarterly"), //
-    BI_ANNUAL(6, "savingsCompoundingInterestPeriodType.biannual"), //
-    ANNUAL(7, "savingsCompoundingInterestPeriodType.annual"); //
+    QUATERLY(5, "savingsCompoundingInterestPeriodType.quarterly"), BI_ANNUAL(6, "savingsCompoundingInterestPeriodType.biannual"), ANNUAL(7,
+            "savingsCompoundingInterestPeriodType.annual");
 
-    // NO_COMPOUNDING_SIMPLE_INTEREST(8,
-    // "savingsCompoundingInterestPeriodType.nocompounding");
+    // NO_COMPOUNDING_SIMPLE_INTEREST(8, "savingsCompoundingInterestPeriodType.nocompounding");
 
     private final Integer value;
     private final String code;
@@ -57,50 +53,35 @@
         return this.code;
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final SavingsCompoundingInterestPeriodType enumType : values()) {
-            if (enumType.getValue() > 0) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 
-    public static SavingsCompoundingInterestPeriodType fromInt(final Integer type) {
-        SavingsCompoundingInterestPeriodType repaymentFrequencyType = SavingsCompoundingInterestPeriodType.INVALID;
-        if (type != null) {
-            switch (type) {
-                case 1:
-                    repaymentFrequencyType = SavingsCompoundingInterestPeriodType.DAILY;
-                break;
-                case 2:
-                // repaymentFrequencyType =
-                // SavingsCompoundingInterestPeriodType.WEEKLY;
-                break;
-                case 3:
-                // repaymentFrequencyType =
-                // SavingsCompoundingInterestPeriodType.BIWEEKLY;
-                break;
-                case 4:
-                    repaymentFrequencyType = SavingsCompoundingInterestPeriodType.MONTHLY;
-                break;
-                case 5:
-                    repaymentFrequencyType = SavingsCompoundingInterestPeriodType.QUATERLY;
-                break;
-                case 6:
-                    repaymentFrequencyType = SavingsCompoundingInterestPeriodType.BI_ANNUAL;
-                break;
-                case 7:
-                    repaymentFrequencyType = SavingsCompoundingInterestPeriodType.ANNUAL;
-                break;
-                case 8:
-                // repaymentFrequencyType =
-                // SavingsCompoundingInterestPeriodType.NO_COMPOUNDING_SIMPLE_INTEREST;
-                break;
-            }
+    public static SavingsCompoundingInterestPeriodType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return repaymentFrequencyType;
+
+        switch (v) {
+            case 1:
+                return DAILY;
+            // case 2:
+            // return WEEKLY;
+            // case 3:
+            // return BIWEEKLY;
+            case 4:
+                return MONTHLY;
+            case 5:
+                return QUATERLY;
+            case 6:
+                return BI_ANNUAL;
+            case 7:
+                return ANNUAL;
+            // case 8:
+            // return NO_COMPOUNDING_SIMPLE_INTEREST;
+            default:
+                return INVALID;
+        }
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsInterestCalculationDaysInYearType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsInterestCalculationDaysInYearType.java
index 616f017..e495b7f 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsInterestCalculationDaysInYearType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsInterestCalculationDaysInYearType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.savings;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 /**
  *
@@ -51,29 +50,23 @@
         return this.code;
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final SavingsInterestCalculationDaysInYearType enumType : values()) {
-            if (enumType.getValue() > 0) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 
-    public static SavingsInterestCalculationDaysInYearType fromInt(final Integer type) {
-        SavingsInterestCalculationDaysInYearType repaymentFrequencyType = SavingsInterestCalculationDaysInYearType.INVALID;
-        if (type != null) {
-            switch (type) {
-                case 360:
-                    repaymentFrequencyType = SavingsInterestCalculationDaysInYearType.DAYS_360;
-                break;
-                case 365:
-                    repaymentFrequencyType = SavingsInterestCalculationDaysInYearType.DAYS_365;
-                break;
-            }
+    public static SavingsInterestCalculationDaysInYearType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return repaymentFrequencyType;
+
+        switch (v) {
+            case 360:
+                return DAYS_360;
+            case 365:
+                return DAYS_365;
+            default:
+                return INVALID;
+        }
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsInterestCalculationType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsInterestCalculationType.java
index 72701c7..c3f63dd 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsInterestCalculationType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsInterestCalculationType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.savings;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 /**
  *
@@ -64,29 +63,23 @@
         return this.code;
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final SavingsInterestCalculationType enumType : values()) {
-            if (enumType.getValue() > 0) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 
-    public static SavingsInterestCalculationType fromInt(final Integer type) {
-        SavingsInterestCalculationType repaymentFrequencyType = SavingsInterestCalculationType.INVALID;
-        if (type != null) {
-            switch (type) {
-                case 1:
-                    repaymentFrequencyType = SavingsInterestCalculationType.DAILY_BALANCE;
-                break;
-                case 2:
-                    repaymentFrequencyType = SavingsInterestCalculationType.AVERAGE_DAILY_BALANCE;
-                break;
-            }
+    public static SavingsInterestCalculationType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return repaymentFrequencyType;
+
+        switch (v) {
+            case 1:
+                return DAILY_BALANCE;
+            case 2:
+                return AVERAGE_DAILY_BALANCE;
+            default:
+                return INVALID;
+        }
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsPeriodFrequencyType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsPeriodFrequencyType.java
index 0fb4ccb..cfebadc 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsPeriodFrequencyType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsPeriodFrequencyType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.savings;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 /**
  * An enumeration of supported calendar periods used in savings.
@@ -48,39 +47,32 @@
         return this.code;
     }
 
-    public static SavingsPeriodFrequencyType fromInt(final Integer type) {
-        SavingsPeriodFrequencyType repaymentFrequencyType = SavingsPeriodFrequencyType.INVALID;
-        if (type != null) {
-            switch (type) {
-                case 0:
-                    repaymentFrequencyType = SavingsPeriodFrequencyType.DAYS;
-                break;
-                case 1:
-                    repaymentFrequencyType = SavingsPeriodFrequencyType.WEEKS;
-                break;
-                case 2:
-                    repaymentFrequencyType = SavingsPeriodFrequencyType.MONTHS;
-                break;
-                case 3:
-                    repaymentFrequencyType = SavingsPeriodFrequencyType.YEARS;
-                break;
-            }
+    public static SavingsPeriodFrequencyType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return repaymentFrequencyType;
+
+        switch (v) {
+            case 0:
+                return DAYS;
+            case 1:
+                return WEEKS;
+            case 2:
+                return MONTHS;
+            case 3:
+                return YEARS;
+            default:
+                return INVALID;
+        }
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isInvalid() {
-        return this.value.equals(SavingsPeriodFrequencyType.INVALID.value);
+        return this.equals(INVALID);
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final SavingsPeriodFrequencyType enumType : values()) {
-            if (!enumType.isInvalid()) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsPostingInterestPeriodType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsPostingInterestPeriodType.java
index aefdb5f..4da0987 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsPostingInterestPeriodType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsPostingInterestPeriodType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.savings;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 /**
  * The interest posting period is the span of time at the end of which savings earned but not yet credited/posted in a
@@ -49,38 +48,29 @@
         return this.code;
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final SavingsPostingInterestPeriodType enumType : values()) {
-            if (enumType.getValue() > 0) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 
-    public static SavingsPostingInterestPeriodType fromInt(final Integer type) {
-        SavingsPostingInterestPeriodType repaymentFrequencyType = SavingsPostingInterestPeriodType.INVALID;
-        if (type != null) {
-            switch (type) {
-                case 1:
-                    repaymentFrequencyType = SavingsPostingInterestPeriodType.DAILY;
-                break;
-                case 4:
-                    repaymentFrequencyType = SavingsPostingInterestPeriodType.MONTHLY;
-                break;
-                case 5:
-                    repaymentFrequencyType = SavingsPostingInterestPeriodType.QUATERLY;
-                break;
-                case 6:
-                    repaymentFrequencyType = SavingsPostingInterestPeriodType.BIANNUAL;
-                break;
-                case 7:
-                    repaymentFrequencyType = SavingsPostingInterestPeriodType.ANNUAL;
-                break;
-            }
+    public static SavingsPostingInterestPeriodType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return repaymentFrequencyType;
+
+        switch (v) {
+            case 1:
+                return DAILY;
+            case 4:
+                return MONTHLY;
+            case 5:
+                return QUATERLY;
+            case 6:
+                return BIANNUAL;
+            case 7:
+                return ANNUAL;
+            default:
+                return INVALID;
+        }
     }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsWithdrawalFeesType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsWithdrawalFeesType.java
index e8b1f80..7aaaed0 100644
--- a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsWithdrawalFeesType.java
+++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/SavingsWithdrawalFeesType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.savings;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 public enum SavingsWithdrawalFeesType {
 
@@ -43,28 +42,23 @@
         return this.code;
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final SavingsWithdrawalFeesType enumType : values()) {
-            if (enumType.getValue() > 0) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 
-    public static SavingsWithdrawalFeesType fromInt(final Integer type) {
-
-        SavingsWithdrawalFeesType withdrawalFeeType = SavingsWithdrawalFeesType.INVALID;
-        switch (type) {
-            case 1:
-                withdrawalFeeType = FLAT;
-            break;
-            case 2:
-                withdrawalFeeType = PERCENT_OF_AMOUNT;
-            break;
+    public static SavingsWithdrawalFeesType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return withdrawalFeeType;
+
+        switch (v) {
+            case 1:
+                return FLAT;
+            case 2:
+                return PERCENT_OF_AMOUNT;
+            default:
+                return INVALID;
+        }
     }
 }
diff --git a/fineract-doc/.asciidoctorconfig b/fineract-doc/.asciidoctorconfig
index b8b6216..c6fcc35 100644
--- a/fineract-doc/.asciidoctorconfig
+++ b/fineract-doc/.asciidoctorconfig
@@ -1,5 +1,5 @@
-:years: 2015-2022
-:revnumber: 1.8.0
+:years: 2015-2024
+:revnumber: 1.9.0-xxxx
 :draft: true
 :rootdir: {asciidoctorconfigdir}/..
 :generated: {asciidoctorconfigdir}/build/generated/asciidoc
diff --git a/fineract-doc/build.gradle b/fineract-doc/build.gradle
index d9464d2..7f1c6bb 100644
--- a/fineract-doc/build.gradle
+++ b/fineract-doc/build.gradle
@@ -30,7 +30,7 @@
         generated: "${buildDir}/generated/asciidoc",
         imagesdir: "${projectDir}/src/docs/en/images",
         diagramsdir: "${projectDir}/src/docs/en/diagrams",
-        years: '2015-2022',
+        years: '2015-2024',
         revnumber: "${project.version}".toString(),
         rootdir: "${rootDir}".toString(),
         baseurl: 'fineract.apache.org',
diff --git a/fineract-doc/src/docs/en/config.adoc b/fineract-doc/src/docs/en/config.adoc
index dd47f4e..fe60469 100644
--- a/fineract-doc/src/docs/en/config.adoc
+++ b/fineract-doc/src/docs/en/config.adoc
@@ -14,7 +14,7 @@
 :source-highlighter: coderay
 :experimental:
 :source-language: java
-:years: 2015-2022
+:years: 2015-2024
 :lang: en
 :encoding: utf-8
 :linkattrs:
diff --git a/fineract-investor/dependencies.gradle b/fineract-investor/dependencies.gradle
index 44a84d1..943673f 100644
--- a/fineract-investor/dependencies.gradle
+++ b/fineract-investor/dependencies.gradle
@@ -52,7 +52,7 @@
             'org.springdoc:springdoc-openapi-starter-webmvc-ui',
             'org.mapstruct:mapstruct',
 
-            'io.github.resilience4j:resilience4j-spring-boot2',
+            'io.github.resilience4j:resilience4j-spring-boot3',
             )
     compileOnly 'org.projectlombok:lombok'
     annotationProcessor 'org.projectlombok:lombok'
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerJournalEntryServiceImpl.java b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerJournalEntryServiceImpl.java
index dcd41fc..186bb64 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerJournalEntryServiceImpl.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerJournalEntryServiceImpl.java
@@ -22,7 +22,6 @@
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
-import org.apache.fineract.infrastructure.event.business.BusinessEventListener;
 import org.apache.fineract.infrastructure.event.business.domain.journalentry.LoanJournalEntryCreatedBusinessEvent;
 import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
 import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
@@ -46,26 +45,17 @@
 
     @PostConstruct
     public void addListeners() {
-        businessEventNotifierService.addPostBusinessEventListener(LoanJournalEntryCreatedBusinessEvent.class,
-                new HandleLoanJournalEntryCreatedBusinessEvent());
-    }
-
-    private final class HandleLoanJournalEntryCreatedBusinessEvent implements BusinessEventListener<LoanJournalEntryCreatedBusinessEvent> {
-
-        @Override
-        public void onBusinessEvent(LoanJournalEntryCreatedBusinessEvent event) {
+        businessEventNotifierService.addPostBusinessEventListener(LoanJournalEntryCreatedBusinessEvent.class, event -> {
             JournalEntry journalEntry = event.get();
-            createMapping(journalEntry);
-        }
 
-        private void createMapping(JournalEntry journalEntry) {
             Long loanId = loanTransactionRepository.findLoanIdById(journalEntry.getLoanTransactionId()).orElseThrow();
+
             externalAssetOwnerTransferLoanMappingRepository.findByLoanId(loanId).ifPresent(transferLoanMapping -> {
                 ExternalAssetOwnerJournalEntryMapping mapping = new ExternalAssetOwnerJournalEntryMapping();
                 mapping.setJournalEntry(journalEntry);
                 mapping.setOwner(transferLoanMapping.getOwnerTransfer().getOwner());
                 externalAssetOwnerJournalEntryMappingRepository.saveAndFlush(mapping);
             });
-        }
+        });
     }
 }
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerLoanStatusChangePlatformServiceImpl.java b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerLoanStatusChangePlatformServiceImpl.java
index e1855f0..efe3d72 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerLoanStatusChangePlatformServiceImpl.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerLoanStatusChangePlatformServiceImpl.java
@@ -21,7 +21,6 @@
 import jakarta.annotation.PostConstruct;
 import lombok.RequiredArgsConstructor;
 import org.apache.fineract.infrastructure.configuration.service.ConfigurationReadPlatformService;
-import org.apache.fineract.infrastructure.event.business.BusinessEventListener;
 import org.apache.fineract.infrastructure.event.business.domain.loan.LoanStatusChangedBusinessEvent;
 import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
@@ -39,19 +38,12 @@
 
     @PostConstruct
     public void addListeners() {
-        businessEventNotifierService.addPostBusinessEventListener(LoanStatusChangedBusinessEvent.class,
-                new ExternalAssetOwnerLoanStatusChangedListener());
-    }
-
-    private final class ExternalAssetOwnerLoanStatusChangedListener implements BusinessEventListener<LoanStatusChangedBusinessEvent> {
-
-        @Override
-        public void onBusinessEvent(LoanStatusChangedBusinessEvent event) {
+        businessEventNotifierService.addPostBusinessEventListener(LoanStatusChangedBusinessEvent.class, event -> {
             final Loan loan = event.get();
             if (configurationReadPlatformService.retrieveGlobalConfiguration(ASSET_EXTERNALIZATION_OF_NON_ACTIVE_LOANS).isEnabled()
                     && (loan.isClosed() || loan.getStatus().isOverpaid())) {
                 loanAccountOwnerTransferService.handleLoanClosedOrOverpaid(loan);
             }
-        }
+        });
     }
 }
diff --git a/fineract-loan/dependencies.gradle b/fineract-loan/dependencies.gradle
index c6f4d7c..bd2a158 100644
--- a/fineract-loan/dependencies.gradle
+++ b/fineract-loan/dependencies.gradle
@@ -47,7 +47,7 @@
             'org.springdoc:springdoc-openapi-starter-webmvc-ui',
             'org.mapstruct:mapstruct',
 
-            'io.github.resilience4j:resilience4j-spring-boot2',
+            'io.github.resilience4j:resilience4j-spring-boot3',
             'org.apache.httpcomponents:httpcore',
             )
     compileOnly 'org.projectlombok:lombok'
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/collateral/api/CollateralApiConstants.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/collateral/api/CollateralApiConstants.java
index 597791b..cc0d8b3 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/collateral/api/CollateralApiConstants.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/collateral/api/CollateralApiConstants.java
@@ -18,8 +18,9 @@
  */
 package org.apache.fineract.portfolio.collateral.api;
 
-import java.util.HashSet;
+import java.util.Arrays;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 public final class CollateralApiConstants {
 
@@ -43,16 +44,8 @@
             this.value = value;
         }
 
-        private static final Set<String> values = new HashSet<>();
-
-        static {
-            for (final CollateralJSONinputParams type : CollateralJSONinputParams.values()) {
-                values.add(type.value);
-            }
-        }
-
         public static Set<String> getAllValues() {
-            return values;
+            return Arrays.stream(values()).map(CollateralJSONinputParams::getValue).collect(Collectors.toSet());
         }
 
         @Override
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/command/LoanChargeCommand.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/command/LoanChargeCommand.java
index 4b906bd..a135c5a 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/command/LoanChargeCommand.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/command/LoanChargeCommand.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.portfolio.loanaccount.command;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
@@ -49,6 +50,7 @@
     }
 
     @Override
+    @SuppressFBWarnings(value = "EQ_COMPARETO_USE_OBJECT_EQUALS", justification = "TODO: fix this! See: https://stackoverflow.com/questions/2609037/findbugs-how-to-solve-eq-compareto-use-object-equals")
     public int compareTo(final LoanChargeCommand o) {
         int comparison = this.chargeId.compareTo(o.chargeId);
         if (comparison == 0) {
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java
index 52ca276..c258ef1 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java
@@ -26,6 +26,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
@@ -688,7 +689,7 @@
                 if (loanTransaction.isChargePayment()) {
                     for (final LoanChargePaidBy chargePaidBy : chargesPaidBies) {
                         LoanCharge loanCharge = chargePaidBy.getLoanCharge();
-                        if (loanCharge.getId().equals(unpaidCharge.getId())) {
+                        if (loanCharge != null && Objects.equals(loanCharge.getId(), unpaidCharge.getId())) {
                             chargePaidBy.setAmount(amountPaidTowardsCharge.getAmount());
                         }
                     }
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/ChargeOrTransaction.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/ChargeOrTransaction.java
index 5c5a4a0..4e69c90 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/ChargeOrTransaction.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/ChargeOrTransaction.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.time.LocalDate;
 import java.time.OffsetDateTime;
 import java.util.Optional;
@@ -81,6 +82,7 @@
     }
 
     @Override
+    @SuppressFBWarnings(value = "EQ_COMPARETO_USE_OBJECT_EQUALS", justification = "TODO: fix this! See: https://stackoverflow.com/questions/2609037/findbugs-how-to-solve-eq-compareto-use-object-equals")
     public int compareTo(@NotNull ChargeOrTransaction o) {
         int datePortion = this.getEffectiveDate().compareTo(o.getEffectiveDate());
         if (datePortion == 0) {
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/HeavensFamilyLoanRepaymentScheduleTransactionProcessor.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/HeavensFamilyLoanRepaymentScheduleTransactionProcessor.java
index 984609e..f9d065a 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/HeavensFamilyLoanRepaymentScheduleTransactionProcessor.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/HeavensFamilyLoanRepaymentScheduleTransactionProcessor.java
@@ -221,7 +221,6 @@
             List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
 
         final LocalDate transactionDate = loanTransaction.getTransactionDate();
-        final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
         Money transactionAmountRemaining = transactionAmountUnprocessed;
         Money principalPortion = Money.zero(transactionAmountRemaining.getCurrency());
         Money interestPortion = Money.zero(transactionAmountRemaining.getCurrency());
diff --git a/fineract-provider/build.gradle b/fineract-provider/build.gradle
index c767aa1..18926a9 100644
--- a/fineract-provider/build.gradle
+++ b/fineract-provider/build.gradle
@@ -336,6 +336,12 @@
     tags = 'not @ignore'
     main = 'io.cucumber.core.cli.Main'
     shorten = 'argfile'
+    plugin = [
+        'pretty',
+        'html:build/reports/cucumber/report.html',
+        'json:build/reports/cucumber/report.json',
+        'junit:build/reports/cucumber/report.xml'
+    ]
 }
 
 tasks.jibDockerBuild.dependsOn(bootJar)
diff --git a/fineract-provider/dependencies.gradle b/fineract-provider/dependencies.gradle
index 60a5e7c..75ba8b9 100644
--- a/fineract-provider/dependencies.gradle
+++ b/fineract-provider/dependencies.gradle
@@ -18,6 +18,12 @@
  */
 
 dependencies {
+    modules {
+        module("io.swagger.core.v3:swagger-annotations") {
+            replacedBy("io.swagger.core.v3:swagger-annotations-jakarta")
+        }
+    }
+
     implementation(project(path: ':fineract-core'))
     implementation(project(path: ':fineract-investor'))
     implementation(project(path: ':fineract-loan'))
@@ -96,14 +102,14 @@
             'org.springdoc:springdoc-openapi-starter-webmvc-ui',
             'org.mapstruct:mapstruct',
 
-            'io.github.resilience4j:resilience4j-spring-boot2',
+            'io.github.resilience4j:resilience4j-spring-boot3',
             )
 
-    implementation ('software.amazon.msk:aws-msk-iam-auth:2.0.0') {
+    implementation ('software.amazon.msk:aws-msk-iam-auth:2.0.2') {
         exclude group: 'commons-logging'
     }
 
-    implementation 'io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.11'
+    implementation 'io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.19'
 
     implementation ('org.apache.commons:commons-email') {
         exclude group: 'com.sun.mail', module: 'javax.mail'
@@ -122,7 +128,7 @@
     implementation ('jakarta.xml.bind:jakarta.xml.bind-api') {
         exclude group: 'jakarta.activation'
     }
-    implementation ('org.apache.activemq:activemq-client') {
+    implementation ('org.apache.activemq:activemq-client-jakarta') {
         exclude group: 'org.apache.geronimo.specs'
         exclude group: 'javax.annotation', module: 'javax.annotation-api'
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/api/JournalEntriesApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/api/JournalEntriesApiResource.java
index c107c8a..48b655a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/api/JournalEntriesApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/api/JournalEntriesApiResource.java
@@ -83,7 +83,7 @@
             "entityType", "entityId", "createdByUserId", "createdDate", "submittedOnDate", "createdByUserName", "comments", "reversed",
             "referenceNumber", "currency", "transactionDetails"));
 
-    private final String resourceNameForPermission = "JOURNALENTRY";
+    private static final String RESOURCE_NAME_FOR_PERMISSION = "JOURNALENTRY";
 
     private final PlatformSecurityContext context;
     private final JournalEntryReadPlatformService journalEntryReadPlatformService;
@@ -125,7 +125,7 @@
             @QueryParam("runningBalance") @Parameter(description = "runningBalance") final boolean runningBalance,
             @QueryParam("transactionDetails") @Parameter(description = "transactionDetails") final boolean transactionDetails) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
 
         final DateFormat dateFormat = StringUtils.isBlank(rawDateFormat) ? null : new DateFormat(rawDateFormat);
 
@@ -174,7 +174,7 @@
             @QueryParam("runningBalance") @Parameter(description = "runningBalance") final boolean runningBalance,
             @QueryParam("transactionDetails") @Parameter(description = "transactionDetails") final boolean transactionDetails) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
         JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(transactionDetails,
                 runningBalance);
         final JournalEntryData glJournalEntryData = this.journalEntryReadPlatformService.retrieveGLJournalEntryById(journalEntryId,
@@ -260,7 +260,7 @@
     public String retrieveOpeningBalance(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId,
             @QueryParam("currencyCode") final String currencyCode) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
         final OfficeOpeningBalancesData officeOpeningBalancesData = this.journalEntryReadPlatformService
                 .retrieveOfficeOpeningBalances(officeId, currencyCode);
         final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
index 1272055..49aaf44 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
@@ -724,10 +724,6 @@
                 populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
                         AccrualAccountsForLoan.GOODWILL_CREDIT.getValue(), accountMapForCredit, accountMapForDebit);
 
-            } else if (loanTransactionDTO.getTransactionType().isRepayment()) {
-                populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
-                        AccrualAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
-
             } else {
                 populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
                         AccrualAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java
index 6786c8a..88f5f39 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java
@@ -701,10 +701,6 @@
             } else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
                 populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
                         CashAccountsForLoan.GOODWILL_CREDIT.getValue(), accountMapForCredit, accountMapForDebit);
-            } else if (loanTransactionDTO.getTransactionType().isRepayment()) {
-                populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
-                        CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
-
             } else {
                 populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
                         CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java
index bfc1929..fa1d727 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryWritePlatformServiceJpaRepositoryImpl.java
@@ -27,7 +27,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.Set;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -401,50 +400,46 @@
             }
         }
 
-        Set<OfficeCurrencyKey> officeSet = officeMap.keySet();
         Map<GLAccount, BigDecimal> liabilityMap = new HashMap<>();
         Map<GLAccount, BigDecimal> expenseMap = new HashMap<>();
 
-        for (OfficeCurrencyKey key : officeSet) {
+        for (Map.Entry<OfficeCurrencyKey, List<LoanProductProvisioningEntry>> entry : officeMap.entrySet()) {
             liabilityMap.clear();
             expenseMap.clear();
-            List<LoanProductProvisioningEntry> entries = officeMap.get(key);
-            for (LoanProductProvisioningEntry entry : entries) {
-                if (liabilityMap.containsKey(entry.getLiabilityAccount())) {
-                    BigDecimal amount = liabilityMap.get(entry.getLiabilityAccount());
-                    amount = amount.add(entry.getReservedAmount());
-                    liabilityMap.put(entry.getLiabilityAccount(), amount);
+            for (LoanProductProvisioningEntry lppEntry : entry.getValue()) {
+                if (liabilityMap.containsKey(lppEntry.getLiabilityAccount())) {
+                    BigDecimal amount = liabilityMap.get(lppEntry.getLiabilityAccount());
+                    amount = amount.add(lppEntry.getReservedAmount());
+                    liabilityMap.put(lppEntry.getLiabilityAccount(), amount);
                 } else {
-                    BigDecimal amount = BigDecimal.ZERO.add(entry.getReservedAmount());
-                    liabilityMap.put(entry.getLiabilityAccount(), amount);
+                    BigDecimal amount = BigDecimal.ZERO.add(lppEntry.getReservedAmount());
+                    liabilityMap.put(lppEntry.getLiabilityAccount(), amount);
                 }
 
-                if (expenseMap.containsKey(entry.getExpenseAccount())) {
-                    BigDecimal amount = expenseMap.get(entry.getExpenseAccount());
-                    amount = amount.add(entry.getReservedAmount());
-                    expenseMap.put(entry.getExpenseAccount(), amount);
+                if (expenseMap.containsKey(lppEntry.getExpenseAccount())) {
+                    BigDecimal amount = expenseMap.get(lppEntry.getExpenseAccount());
+                    amount = amount.add(lppEntry.getReservedAmount());
+                    expenseMap.put(lppEntry.getExpenseAccount(), amount);
                 } else {
-                    BigDecimal amount = BigDecimal.ZERO.add(entry.getReservedAmount());
-                    expenseMap.put(entry.getExpenseAccount(), amount);
+                    BigDecimal amount = BigDecimal.ZERO.add(lppEntry.getReservedAmount());
+                    expenseMap.put(lppEntry.getExpenseAccount(), amount);
                 }
             }
-            createJournalEntry(provisioningEntry.getCreatedDate(), provisioningEntry.getId(), key.office, key.currency, liabilityMap,
-                    expenseMap);
+            createJournalEntry(provisioningEntry.getCreatedDate(), provisioningEntry.getId(), entry.getKey().office,
+                    entry.getKey().currency, liabilityMap, expenseMap);
         }
         return "P" + provisioningEntry.getId();
     }
 
     private void createJournalEntry(LocalDate transactionDate, Long entryId, Office office, String currencyCode,
             Map<GLAccount, BigDecimal> liabilityMap, Map<GLAccount, BigDecimal> expenseMap) {
-        Set<GLAccount> liabilityAccounts = liabilityMap.keySet();
-        for (GLAccount account : liabilityAccounts) {
-            this.helper.createProvisioningCreditJournalEntry(transactionDate, entryId, office, currencyCode, account,
-                    liabilityMap.get(account));
+        for (Map.Entry<GLAccount, BigDecimal> entry : liabilityMap.entrySet()) {
+            this.helper.createProvisioningCreditJournalEntry(transactionDate, entryId, office, currencyCode, entry.getKey(),
+                    entry.getValue());
         }
-        Set<GLAccount> expenseAccounts = expenseMap.keySet();
-        for (GLAccount account : expenseAccounts) {
-            this.helper.createProvisioningDebitJournalEntry(transactionDate, entryId, office, currencyCode, account,
-                    expenseMap.get(account));
+        for (Map.Entry<GLAccount, BigDecimal> entry : expenseMap.entrySet()) {
+            this.helper.createProvisioningDebitJournalEntry(transactionDate, entryId, office, currencyCode, entry.getKey(),
+                    entry.getValue());
         }
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/api/AccountingRuleApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/api/AccountingRuleApiResource.java
index 114db83..40e155e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/api/AccountingRuleApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/api/AccountingRuleApiResource.java
@@ -86,7 +86,7 @@
                     "allowedCreditTagOptions", "allowedDebitTagOptions", "debitTags", "creditTags", "creditAccounts", "debitAccounts",
                     "allowMultipleCreditEntries", "allowMultipleDebitEntries", "tag"));
 
-    private final String resourceNameForPermission = "ACCOUNTINGRULE";
+    private static final String RESOURCE_NAME_FOR_PERMISSION = "ACCOUNTINGRULE";
 
     private final AccountingRuleReadPlatformService accountingRuleReadPlatformService;
     private final GLAccountReadPlatformService accountReadPlatformService;
@@ -107,7 +107,7 @@
             @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.GetAccountRulesTemplateResponse.class))) })
     public String retrieveTemplate(@Context final UriInfo uriInfo) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
 
         AccountingRuleData accountingRuleData = null;
         accountingRuleData = handleTemplate(accountingRuleData);
@@ -126,7 +126,7 @@
     public String retrieveAllAccountingRules(@Context final UriInfo uriInfo) {
 
         final AppUser currentUser = this.context.authenticatedUser();
-        currentUser.validateHasReadPermission(this.resourceNameForPermission);
+        currentUser.validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
 
         final String hierarchy = currentUser.getOffice().getHierarchy();
         final String hierarchySearchString = hierarchy + "%";
@@ -159,7 +159,7 @@
             @PathParam("accountingRuleId") @Parameter(description = "accountingRuleId") final Long accountingRuleId,
             @Context final UriInfo uriInfo) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
         final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
 
         AccountingRuleData accountingRuleData = this.accountingRuleReadPlatformService.retrieveAccountingRuleById(accountingRuleId);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetDatatableEntryByQueryCommandStrategy.java b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetDatatableEntryByQueryCommandStrategy.java
index 75e7180..4bb42c1 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetDatatableEntryByQueryCommandStrategy.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/GetDatatableEntryByQueryCommandStrategy.java
@@ -23,6 +23,7 @@
 import jakarta.ws.rs.core.UriInfo;
 import java.util.Map;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.batch.command.CommandStrategy;
 import org.apache.fineract.batch.command.CommandStrategyUtils;
@@ -39,6 +40,7 @@
  * raised by {@link DatatablesApiResource} and map those errors to appropriate status codes in BatchResponse.
  */
 @Component
+@Slf4j
 @RequiredArgsConstructor
 public class GetDatatableEntryByQueryCommandStrategy implements CommandStrategy {
 
@@ -81,6 +83,7 @@
                     case "columnFilter" -> columnFilter = entry.getValue();
                     case "valueFilter" -> valueFilter = entry.getValue();
                     case "resultColumns" -> resultColumns = entry.getValue();
+                    default -> log.warn("Query parameter could not be mapped: {}", entry.getKey());
                 }
             }
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/listener/AbstractLoanItemListener.java b/fineract-provider/src/main/java/org/apache/fineract/cob/listener/AbstractLoanItemListener.java
index d021791..df2bc95 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/cob/listener/AbstractLoanItemListener.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/cob/listener/AbstractLoanItemListener.java
@@ -68,9 +68,12 @@
 
     @OnReadError
     public void onReadError(Exception e) {
-        LoanReadException ee = (LoanReadException) e;
-        log.warn("Error was triggered during reading of Loan (id={}) due to: {}", ee.getId(), ThrowableSerialization.serialize(e));
-        updateAccountLockWithError(List.of(ee.getId()), "Loan (id: %d) reading is failed", e);
+        if (e instanceof LoanReadException ee) {
+            log.warn("Error was triggered during reading of Loan (id={}) due to: {}", ee.getId(), ThrowableSerialization.serialize(e));
+            updateAccountLockWithError(List.of(ee.getId()), "Loan (id: %d) reading is failed", e);
+        } else {
+            log.error("Could not handle read error", e);
+        }
     }
 
     @OnProcessError
diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/service/LoanCOBCatchUpServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/cob/service/LoanCOBCatchUpServiceImpl.java
index 07a427f..8643df3 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/cob/service/LoanCOBCatchUpServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/cob/service/LoanCOBCatchUpServiceImpl.java
@@ -18,7 +18,6 @@
  */
 package org.apache.fineract.cob.service;
 
-import com.google.gson.Gson;
 import java.time.LocalDate;
 import java.util.List;
 import lombok.RequiredArgsConstructor;
@@ -30,11 +29,8 @@
 import org.apache.fineract.cob.loan.RetrieveLoanIdService;
 import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
 import org.apache.fineract.infrastructure.core.domain.FineractContext;
-import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
-import org.apache.fineract.infrastructure.jobs.domain.CustomJobParameterRepository;
 import org.apache.fineract.infrastructure.jobs.domain.JobExecutionRepository;
-import org.springframework.batch.core.explore.JobExplorer;
 import org.springframework.context.annotation.Conditional;
 import org.springframework.stereotype.Service;
 
@@ -45,12 +41,8 @@
 
     private final AsyncLoanCOBExecutorService asyncLoanCOBExecutorService;
     private final JobExecutionRepository jobExecutionRepository;
-    private final JobExplorer jobExplorer;
     private final RetrieveLoanIdService retrieveLoanIdService;
-
     private final LoanAccountLockService accountLockService;
-    private final CustomJobParameterRepository customJobParameterRepository;
-    protected Gson gson = GoogleGsonSerializerHelper.createSimpleGson();
 
     @Override
     public void unlockHardLockedLoans() {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/api/AuditsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/commands/api/AuditsApiResource.java
index 744b100..4348650 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/commands/api/AuditsApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/commands/api/AuditsApiResource.java
@@ -105,7 +105,7 @@
             @QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy,
             @QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.RESOURCE_NAME_FOR_PERMISSIONS);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
         final PaginationParameters parameters = PaginationParameters.instance(paged, offset, limit, orderBy, sortOrder);
         final SQLBuilder extraCriteria = getExtraCriteria(actionName, entityName, resourceId, makerId, makerDateTimeFrom, makerDateTimeTo,
                 checkerId, checkerDateTimeFrom, checkerDateTimeTo, processingResult, officeId, groupId, clientId, loanId, savingsAccountId);
@@ -135,7 +135,7 @@
     public String retrieveAuditEntry(@PathParam("auditId") @Parameter(description = "auditId") final Long auditId,
             @Context final UriInfo uriInfo) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.RESOURCE_NAME_FOR_PERMISSIONS);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
 
         final AuditData auditEntry = this.auditReadPlatformService.retrieveAuditEntry(auditId);
 
@@ -153,7 +153,7 @@
             @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = MakercheckersApiResourceSwagger.GetMakerCheckersSearchTemplateResponse.class))) })
     public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) {
 
-        this.context.authenticatedUser().validateHasReadPermission(this.RESOURCE_NAME_FOR_PERMISSIONS);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
 
         final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/ImportHandlerUtils.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/ImportHandlerUtils.java
index 07c720d..9adaee5 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/ImportHandlerUtils.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/importhandler/ImportHandlerUtils.java
@@ -21,6 +21,8 @@
 import com.google.common.base.Splitter;
 import java.time.LocalDate;
 import java.util.List;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
@@ -40,6 +42,7 @@
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.util.CellReference;
 
+@Slf4j
 public final class ImportHandlerUtils {
 
     private ImportHandlerUtils() {
@@ -73,20 +76,20 @@
         FormulaEvaluator eval = row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
         if (c.getCellType() == CellType.FORMULA) {
             if (eval != null) {
-                CellValue val = null;
+                CellValue value;
                 try {
-                    val = eval.evaluate(c);
-                } catch (NullPointerException npe) {
-                    return null;
+                    value = eval.evaluate(c);
+                    return ((Double) value.getNumberValue()).longValue();
+                } catch (Exception e) {
+                    log.error("Cell evaluation error: ", e);
                 }
-                return ((Double) val.getNumberValue()).longValue();
             }
+            return null;
         } else if (c.getCellType() == CellType.NUMERIC) {
             return ((Double) c.getNumericCellValue()).longValue();
         } else {
             return Long.parseLong(row.getCell(colIndex).getStringCellValue());
         }
-        return null;
     }
 
     public static String readAsString(int colIndex, Row row) {
@@ -98,26 +101,20 @@
         FormulaEvaluator eval = row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
         if (c.getCellType() == CellType.FORMULA) {
             if (eval != null) {
-                CellValue val = null;
+                CellValue value;
                 try {
-                    val = eval.evaluate(c);
-                } catch (NullPointerException npe) {
-                    return null;
-                }
+                    value = eval.evaluate(c);
 
-                String res = trimEmptyDecimalPortion(val.getStringValue());
-                if (res != null) {
-                    if (!res.equals("")) {
+                    String res = trimEmptyDecimalPortion(value.getStringValue());
+
+                    if (!StringUtils.isNotEmpty(res)) {
                         return res.trim();
-                    } else {
-                        return null;
                     }
-                } else {
-                    return null;
+                } catch (Exception e) {
+                    log.error("Cell evaluation error: ", e);
                 }
-            } else {
-                return null;
             }
+            return null;
         } else if (c.getCellType() == CellType.STRING) {
             String res = trimEmptyDecimalPortion(c.getStringCellValue().trim());
             return res.trim();
@@ -156,13 +153,13 @@
         FormulaEvaluator eval = row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
         if (c.getCellType() == CellType.FORMULA) {
             if (eval != null) {
-                CellValue val = null;
+                CellValue value;
                 try {
-                    val = eval.evaluate(c);
-                } catch (NullPointerException npe) {
-                    return false;
+                    value = eval.evaluate(c);
+                    return value.getBooleanValue();
+                } catch (Exception e) {
+                    log.error("Cell evaluation error: ", e);
                 }
-                return val.getBooleanValue();
             }
             return false;
         } else if (c.getCellType() == CellType.BOOLEAN) {
@@ -185,13 +182,13 @@
         FormulaEvaluator eval = row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
         if (c.getCellType() == CellType.FORMULA) {
             if (eval != null) {
-                CellValue val = null;
+                CellValue value;
                 try {
-                    val = eval.evaluate(c);
-                } catch (NullPointerException npe) {
-                    return null;
+                    value = eval.evaluate(c);
+                    return ((Double) value.getNumberValue()).intValue();
+                } catch (Exception e) {
+                    log.error("Cell evaluation error: ", e);
                 }
-                return ((Double) val.getNumberValue()).intValue();
             }
             return null;
         } else if (c.getCellType() == CellType.NUMERIC) {
@@ -209,16 +206,15 @@
         FormulaEvaluator eval = row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
         if (c.getCellType() == CellType.FORMULA) {
             if (eval != null) {
-                CellValue val = null;
+                CellValue value;
                 try {
-                    val = eval.evaluate(c);
-                } catch (NullPointerException npe) {
-                    return 0.0;
+                    value = eval.evaluate(c);
+                    return value.getNumberValue();
+                } catch (Exception e) {
+                    log.error("Cell evaluation error: ", e);
                 }
-                return val.getNumberValue();
-            } else {
-                return 0.0;
             }
+            return 0.0;
         } else if (c.getCellType() == CellType.NUMERIC) {
             return row.getCell(colIndex).getNumericCellValue();
         } else {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/CenterSheetPopulator.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/CenterSheetPopulator.java
index d406407..d3dad4e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/CenterSheetPopulator.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/CenterSheetPopulator.java
@@ -58,7 +58,7 @@
     }
 
     private void centerNameToCenterIdMap() {
-        centerNameToCenterId = new HashMap<String, Long>();
+        centerNameToCenterId = new HashMap<>();
         for (CenterData centerData : allCenters) {
             centerNameToCenterId.put(centerData.getName(), centerData.getId());
         }
@@ -68,12 +68,12 @@
         int rowIndex = 1;
         int officeIndex = 0;
         int startIndex = 1;
-        officeNameToBeginEndIndexesOfCenters = new HashMap<Integer, Integer[]>();
+        officeNameToBeginEndIndexesOfCenters = new HashMap<>();
         Row row = centerSheet.createRow(rowIndex);
         for (OfficeData office : offices) {
             startIndex = rowIndex + 1;
             writeString(OFFICE_NAME_COL, row, office.getName());
-            ArrayList<String> centersList = new ArrayList<String>();
+            ArrayList<String> centersList;
 
             if (officeToCenters.containsKey(office.getName().trim().replaceAll("[ )(]", "_"))) {
                 centersList = officeToCenters.get(office.getName().trim().replaceAll("[ )(]", "_"));
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/SavingsAccountSheetPopulator.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/SavingsAccountSheetPopulator.java
index 133fd50..f33bdc3 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/SavingsAccountSheetPopulator.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/SavingsAccountSheetPopulator.java
@@ -19,9 +19,7 @@
 package org.apache.fineract.infrastructure.bulkimport.populator;
 
 import java.util.List;
-import java.util.Map;
 import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
-import org.apache.fineract.portfolio.client.data.ClientData;
 import org.apache.fineract.portfolio.savings.data.SavingsAccountData;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
@@ -30,8 +28,6 @@
 public class SavingsAccountSheetPopulator extends AbstractWorkbookPopulator {
 
     private List<SavingsAccountData> savingsAccountDataList;
-    private Map<ClientData, List<SavingsAccountData>> clientToSavingsMap;
-
     private static final int SAVINGS_ACCOUNT_ID_COL = 0;
     private static final int SAVING_ACCOUNT_NO = 1;
     private static final int CURRENCY_COL = 2;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/comparator/LoanComparatorByStatusActive.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/comparator/LoanComparatorByStatusActive.java
index 5bfc772..4a29c91 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/comparator/LoanComparatorByStatusActive.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/populator/comparator/LoanComparatorByStatusActive.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.infrastructure.bulkimport.populator.comparator;
 
+import java.io.Serializable;
 import java.util.Comparator;
 import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
 
@@ -25,7 +26,7 @@
  * Sorting the loan values based on loan status giving priority to active loans
  */
 
-public class LoanComparatorByStatusActive implements Comparator<LoanAccountData> {
+public class LoanComparatorByStatusActive implements Comparator<LoanAccountData>, Serializable {
 
     @Override
     public int compare(LoanAccountData o1, LoanAccountData o2) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/constants/CampaignType.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/constants/CampaignType.java
index 13e765c..fffe54a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/constants/CampaignType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/constants/CampaignType.java
@@ -41,19 +41,20 @@
     }
 
     public static CampaignType fromInt(final Integer typeValue) {
-        CampaignType type = null;
+        if (typeValue == null) {
+            return INVALID;
+        }
+
         switch (typeValue) {
             case 0:
-                type = INVALID;
-            break;
+                return INVALID;
             case 1:
-                type = SMS;
-            break;
+                return SMS;
             case 2:
-                type = NOTIFICATION;
-            break;
+                return NOTIFICATION;
+            default:
+                return INVALID;
         }
-        return type;
     }
 
     public static EnumOptionData campaignType(final Integer campaignTypeId) {
@@ -61,28 +62,22 @@
     }
 
     public static EnumOptionData campaignType(final CampaignType campaignType) {
-        EnumOptionData optionData = new EnumOptionData(CampaignType.INVALID.getValue().longValue(), CampaignType.INVALID.getCode(),
-                "Invalid");
+        EnumOptionData optionData = new EnumOptionData(INVALID.getValue().longValue(), INVALID.getCode(), "Invalid");
         switch (campaignType) {
             case INVALID:
-                optionData = new EnumOptionData(CampaignType.INVALID.getValue().longValue(), CampaignType.INVALID.getCode(), "Invalid");
+                optionData = new EnumOptionData(INVALID.getValue().longValue(), INVALID.getCode(), "Invalid");
             break;
             case SMS:
-                optionData = new EnumOptionData(CampaignType.SMS.getValue().longValue(), CampaignType.SMS.getCode(), "SMS");
+                optionData = new EnumOptionData(SMS.getValue().longValue(), SMS.getCode(), "SMS");
             break;
             case NOTIFICATION:
-                optionData = new EnumOptionData(CampaignType.NOTIFICATION.getValue().longValue(), CampaignType.NOTIFICATION.getCode(),
-                        "NOTIFICATION");
+                optionData = new EnumOptionData(NOTIFICATION.getValue().longValue(), NOTIFICATION.getCode(), "NOTIFICATION");
             break;
         }
         return optionData;
     }
 
     public boolean isSms() {
-        return this.value.equals(CampaignType.SMS.getValue());
-    }
-
-    public boolean isNotificaion() {
-        return this.value.equals(CampaignType.NOTIFICATION.getValue());
+        return this.equals(SMS);
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignReadPlatformServiceImpl.java
index 0ef6b2b..ce0aee7 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignReadPlatformServiceImpl.java
@@ -30,7 +30,6 @@
 import org.apache.fineract.infrastructure.campaigns.email.data.EmailBusinessRulesData;
 import org.apache.fineract.infrastructure.campaigns.email.data.EmailCampaignData;
 import org.apache.fineract.infrastructure.campaigns.email.data.EmailCampaignTimeLine;
-import org.apache.fineract.infrastructure.campaigns.email.data.ScheduledEmailEnumerations;
 import org.apache.fineract.infrastructure.campaigns.email.domain.EmailCampaignStatus;
 import org.apache.fineract.infrastructure.campaigns.email.domain.EmailCampaignStatusEnumerations;
 import org.apache.fineract.infrastructure.campaigns.email.domain.EmailCampaignType;
@@ -116,24 +115,7 @@
             final String emailMessage = rs.getString("emailMessage");
             final String emailAttachmentFileFormatString = rs.getString("emailAttachmentFileFormat");
             final String stretchyReportParamMap = rs.getString("stretchyReportParamMap");
-            EnumOptionData emailAttachmentFileFormat = null;
-            if (emailAttachmentFileFormatString != null) {
-                emailAttachmentFileFormat = ScheduledEmailEnumerations.emailAttachementFileFormat(emailAttachmentFileFormatString);
-            }
             final Long reportId = JdbcSupport.getLong(rs, "stretchyReportId");
-            final String reportName = rs.getString("reportName");
-            final String reportType = rs.getString("reportType");
-            final String reportSubType = rs.getString("reportSubType");
-            final String reportCategory = rs.getString("reportCategory");
-            final String reportSql = rs.getString("reportSql");
-            final String reportDescription = rs.getString("reportDescription");
-            final boolean coreReport = rs.getBoolean("coreReport");
-            final boolean useReport = rs.getBoolean("useReport");
-
-            /*
-             * final ReportData stretchyReport = new ReportData(reportId, reportName, reportType, reportSubType,
-             * reportCategory, reportDescription, reportSql, coreReport, useReport, null);
-             */
 
             final Integer statusId = JdbcSupport.getInteger(rs, "statusEnum");
             final EnumOptionData status = EmailCampaignStatusEnumerations.status(statusId);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignWritePlatformCommandHandlerImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignWritePlatformCommandHandlerImpl.java
index 3b206bc..ba3e487 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignWritePlatformCommandHandlerImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignWritePlatformCommandHandlerImpl.java
@@ -350,11 +350,11 @@
             throws IOException {
         final String reportType = "report";
 
-        List<HashMap<String, Object>> resultList = new ArrayList<HashMap<String, Object>>();
+        List<HashMap<String, Object>> resultList;
         final GenericResultsetData results = this.readReportingService.retrieveGenericResultSetForSmsEmailCampaign(reportName, reportType,
                 queryParams);
         final String response = this.genericDataService.generateJsonFromGenericResultsetData(results);
-        resultList = new ObjectMapper().readValue(response, new TypeReference<List<HashMap<String, Object>>>() {});
+        resultList = new ObjectMapper().readValue(response, new TypeReference<>() {});
         // loop changes array date to string date
         for (Iterator<HashMap<String, Object>> it = resultList.iterator(); it.hasNext();) {
             HashMap<String, Object> entry = it.next();
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailConfigurationWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailConfigurationWritePlatformServiceImpl.java
index 21f7a6c..9409e99 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailConfigurationWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailConfigurationWritePlatformServiceImpl.java
@@ -30,7 +30,6 @@
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
-import org.apache.fineract.useradministration.domain.AppUser;
 import org.springframework.stereotype.Service;
 
 @Service
@@ -43,8 +42,9 @@
 
     @Override
     public CommandProcessingResult update(final JsonCommand command) {
-
-        final AppUser currentUser = this.context.authenticatedUser();
+        // TODO: leaving function call for backward compatibility... but security configuration should be done somewhere
+        // else
+        this.context.authenticatedUser();
 
         this.emailConfigurationValidator.validateUpdateConfiguration(command.json());
         final String smtpUsername = command.stringValueOfParameterNamed("SMTP_USERNAME");
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/jobs/executeemail/ExecuteEmailTasklet.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/jobs/executeemail/ExecuteEmailTasklet.java
index 069afb9..9016879 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/jobs/executeemail/ExecuteEmailTasklet.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/jobs/executeemail/ExecuteEmailTasklet.java
@@ -193,6 +193,8 @@
                 case "environementUrl":
                     actualParams.put(entry.getKey(), entry.getKey());
                 break;
+                default:
+                    log.warn("Query parameter could not be mapped: {}", entry.getKey());
             }
         }
         return actualParams;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignStatus.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignStatus.java
index 399e90a..5f02b2a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignStatus.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignStatus.java
@@ -34,20 +34,16 @@
     }
 
     public static SmsCampaignStatus fromInt(final Integer statusValue) {
-
-        SmsCampaignStatus enumeration = SmsCampaignStatus.INVALID;
         switch (statusValue) {
             case 100:
-                enumeration = SmsCampaignStatus.PENDING;
-            break;
+                return PENDING;
             case 300:
-                enumeration = SmsCampaignStatus.ACTIVE;
-            break;
+                return ACTIVE;
             case 600:
-                enumeration = SmsCampaignStatus.CLOSED;
-            break;
+                return CLOSED;
+            default:
+                return INVALID;
         }
-        return enumeration;
     }
 
     public Integer getValue() {
@@ -58,15 +54,18 @@
         return code;
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isActive() {
-        return this.value.equals(SmsCampaignStatus.ACTIVE.getValue());
+        return this.equals(ACTIVE);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isPending() {
-        return this.value.equals(SmsCampaignStatus.PENDING.getValue());
+        return this.equals(PENDING);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isClosed() {
-        return this.value.equals(SmsCampaignStatus.CLOSED.getValue());
+        return this.equals(CLOSED);
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignTriggerType.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignTriggerType.java
index 83349e9..7f4cdef 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignTriggerType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/constants/SmsCampaignTriggerType.java
@@ -41,20 +41,21 @@
         return code;
     }
 
-    public static SmsCampaignTriggerType fromInt(final Integer typeValue) {
-        SmsCampaignTriggerType type = null;
-        switch (typeValue) {
-            case 1:
-                type = DIRECT;
-            break;
-            case 2:
-                type = SCHEDULE;
-            break;
-            case 3:
-                type = TRIGGERED;
-            break;
+    public static SmsCampaignTriggerType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return type;
+
+        switch (v) {
+            case 1:
+                return DIRECT;
+            case 2:
+                return SCHEDULE;
+            case 3:
+                return TRIGGERED;
+            default:
+                return INVALID;
+        }
     }
 
     public static EnumOptionData triggerType(final Integer triggerTypeId) {
@@ -62,38 +63,32 @@
     }
 
     public static EnumOptionData triggerType(final SmsCampaignTriggerType triggerType) {
-        EnumOptionData optionData = new EnumOptionData(SmsCampaignTriggerType.INVALID.getValue().longValue(),
-                SmsCampaignTriggerType.INVALID.getCode(), "Invalid");
         switch (triggerType) {
             case INVALID:
-                optionData = new EnumOptionData(SmsCampaignTriggerType.INVALID.getValue().longValue(),
-                        SmsCampaignTriggerType.INVALID.getCode(), "Invalid");
-            break;
+                return new EnumOptionData(INVALID.getValue().longValue(), INVALID.getCode(), "Invalid");
             case DIRECT:
-                optionData = new EnumOptionData(SmsCampaignTriggerType.DIRECT.getValue().longValue(),
-                        SmsCampaignTriggerType.DIRECT.getCode(), "Direct");
-            break;
+                return new EnumOptionData(DIRECT.getValue().longValue(), DIRECT.getCode(), "Direct");
             case SCHEDULE:
-                optionData = new EnumOptionData(SmsCampaignTriggerType.SCHEDULE.getValue().longValue(),
-                        SmsCampaignTriggerType.SCHEDULE.getCode(), "Schedule");
-            break;
+                return new EnumOptionData(SCHEDULE.getValue().longValue(), SCHEDULE.getCode(), "Schedule");
             case TRIGGERED:
-                optionData = new EnumOptionData(SmsCampaignTriggerType.TRIGGERED.getValue().longValue(),
-                        SmsCampaignTriggerType.TRIGGERED.getCode(), "Triggered");
-            break;
+                return new EnumOptionData(TRIGGERED.getValue().longValue(), TRIGGERED.getCode(), "Triggered");
+            default:
+                return new EnumOptionData(INVALID.getValue().longValue(), INVALID.getCode(), "Invalid");
         }
-        return optionData;
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isDirect() {
-        return this.value.equals(SmsCampaignTriggerType.DIRECT.getValue());
+        return this.equals(DIRECT);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isSchedule() {
-        return this.value.equals(SmsCampaignTriggerType.SCHEDULE.getValue());
+        return this.equals(SCHEDULE);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isTriggered() {
-        return this.value.equals(SmsCampaignTriggerType.TRIGGERED.getValue());
+        return this.equals(TRIGGERED);
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java
index 62debdf..2cdf3d2 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDomainServiceImpl.java
@@ -183,18 +183,18 @@
 
                             });
 
-                    if (groupClients.size() > 0) {
+                    if (!groupClients.isEmpty()) {
                         for (Client client : groupClients) {
                             HashMap<String, Object> smsParams = processRepaymentDataForSms(loanTransaction, client);
-                            for (String key : campaignParams.keySet()) {
-                                String value = campaignParams.get(key);
+                            for (Map.Entry<String, String> entry : campaignParams.entrySet()) {
+                                String value = entry.getValue();
                                 String spvalue = null;
-                                boolean spkeycheck = smsParams.containsKey(key);
+                                boolean spkeycheck = smsParams.containsKey(entry.getKey());
                                 if (spkeycheck) {
-                                    spvalue = smsParams.get(key).toString();
+                                    spvalue = smsParams.get(entry.getKey()).toString();
                                 }
                                 if (spkeycheck && !(value.equals("-1") || spvalue.equals(value))) {
-                                    if (key.equals("officeId")) {
+                                    if (entry.getKey().equals("officeId")) {
                                         Long officeId = Long.valueOf(value);
                                         Office campaignOffice = this.officeRepository.findById(Long.valueOf(value))
                                                 .orElseThrow(() -> new OfficeNotFoundException(officeId));
@@ -244,15 +244,15 @@
 
                             });
                     HashMap<String, Object> smsParams = processSavingsTransactionDataForSms(savingsTransaction, client);
-                    for (String key : campaignParams.keySet()) {
-                        String value = campaignParams.get(key);
+                    for (Map.Entry<String, String> entry : campaignParams.entrySet()) {
+                        String value = entry.getValue();
                         String spvalue = null;
-                        boolean spkeycheck = smsParams.containsKey(key);
+                        boolean spkeycheck = smsParams.containsKey(entry.getKey());
                         if (spkeycheck) {
-                            spvalue = smsParams.get(key).toString();
+                            spvalue = smsParams.get(entry.getKey()).toString();
                         }
                         if (spkeycheck && !(value.equals("-1") || spvalue.equals(value))) {
-                            if (key.equals("officeId")) {
+                            if (entry.getKey().equals("officeId")) {
                                 Long officeId = Long.valueOf(value);
                                 Office campaignOffice = this.officeRepository.findById(officeId)
                                         .orElseThrow(() -> new OfficeNotFoundException(officeId));
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformServiceImpl.java
index 61e5df6..c333a42 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignDropdownReadPlatformServiceImpl.java
@@ -19,7 +19,6 @@
 package org.apache.fineract.infrastructure.campaigns.sms.service;
 
 import java.net.URI;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
@@ -72,7 +71,7 @@
 
     @Override
     public Collection<SmsProviderData> retrieveSmsProviders() {
-        Collection<SmsProviderData> smsProviderOptions = new ArrayList<>();
+        Collection<SmsProviderData> smsProviderOptions;
         Map<String, Object> hostConfig = this.smsConfigUtils.getMessageGateWayRequestURI("smsbridges", null);
         URI uri = (URI) hostConfig.get("uri");
         HttpEntity<?> entity = (HttpEntity<?>) hostConfig.get("entity");
@@ -80,8 +79,7 @@
         ResponseEntity<Collection<SmsProviderData>> responseOne = null;
 
         try {
-            responseOne = restTemplate.exchange(uri, HttpMethod.GET, entity,
-                    new ParameterizedTypeReference<Collection<SmsProviderData>>() {});
+            responseOne = restTemplate.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference<>() {});
         } catch (ResourceAccessException ex) {
             LOG.debug("Mobile service provider {} not available", uri, ex);
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/OkHttp3Config.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/OkHttp3Config.java
new file mode 100644
index 0000000..eb5d81c
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/OkHttp3Config.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.core.config;
+
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.OkHttpClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Slf4j
+@RequiredArgsConstructor
+@Configuration
+public class OkHttp3Config {
+
+    private final FineractProperties fineractProperties;
+
+    @Bean
+    public OkHttpClient okHttpClient() throws Exception {
+        var okBuilder = new OkHttpClient.Builder();
+
+        if (Boolean.TRUE.equals(fineractProperties.getInsecureHttpClient())) {
+            final X509TrustManager insecureX509TrustManager = new X509TrustManager() {
+
+                @Override
+                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}// NOSONAR
+
+                @Override
+                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}// NOSONAR
+
+                @Override
+                public X509Certificate[] getAcceptedIssuers() {
+                    return new X509Certificate[] {};
+                }
+            };
+
+            SSLContext insecureSSLContext = SSLContext.getInstance("TLS");
+            insecureSSLContext.init(null, new TrustManager[] { insecureX509TrustManager }, new SecureRandom());
+
+            okBuilder.sslSocketFactory(insecureSSLContext.getSocketFactory(), insecureX509TrustManager);
+            HostnameVerifier insecureHostnameVerifier = (hostname, session) -> true;// NOSONAR
+            okBuilder.hostnameVerifier(insecureHostnameVerifier);
+        }
+
+        return okBuilder.build();
+    }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/cache/CacheConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/cache/CacheConfig.java
index e4202ae..216328b 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/cache/CacheConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/cache/CacheConfig.java
@@ -61,25 +61,53 @@
                 CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, ResourcePoolsBuilder.heap(10000))
                         .withExpiry(ExpiryPolicyBuilder.noExpiration()).build());
 
-        cacheManager.createCache("users", defaultTemplate);
-        cacheManager.createCache("usersByUsername", defaultTemplate);
-        cacheManager.createCache("tenantsById", defaultTemplate);
-        cacheManager.createCache("offices", defaultTemplate);
-        cacheManager.createCache("officesForDropdown", defaultTemplate);
-        cacheManager.createCache("officesById", defaultTemplate);
-        cacheManager.createCache("charges", defaultTemplate);
-        cacheManager.createCache("funds", defaultTemplate);
-        cacheManager.createCache("code_values", defaultTemplate);
-        cacheManager.createCache("codes", defaultTemplate);
-        cacheManager.createCache("hooks", defaultTemplate);
-        cacheManager.createCache("tfConfig", defaultTemplate);
-        cacheManager.createCache(CONFIG_BY_NAME_CACHE_NAME, defaultTemplate);
+        if (cacheManager.getCache("users") == null) {
+            cacheManager.createCache("users", defaultTemplate);
+        }
+        if (cacheManager.getCache("usersByUsername") == null) {
+            cacheManager.createCache("usersByUsername", defaultTemplate);
+        }
+        if (cacheManager.getCache("tenantsById") == null) {
+            cacheManager.createCache("tenantsById", defaultTemplate);
+        }
+        if (cacheManager.getCache("offices") == null) {
+            cacheManager.createCache("offices", defaultTemplate);
+        }
+        if (cacheManager.getCache("officesForDropdown") == null) {
+            cacheManager.createCache("officesForDropdown", defaultTemplate);
+        }
+        if (cacheManager.getCache("officesById") == null) {
+            cacheManager.createCache("officesById", defaultTemplate);
+        }
+        if (cacheManager.getCache("charges") == null) {
+            cacheManager.createCache("charges", defaultTemplate);
+        }
+        if (cacheManager.getCache("funds") == null) {
+            cacheManager.createCache("funds", defaultTemplate);
+        }
+        if (cacheManager.getCache("code_values") == null) {
+            cacheManager.createCache("code_values", defaultTemplate);
+        }
+        if (cacheManager.getCache("codes") == null) {
+            cacheManager.createCache("codes", defaultTemplate);
+        }
+        if (cacheManager.getCache("hooks") == null) {
+            cacheManager.createCache("hooks", defaultTemplate);
+        }
+        if (cacheManager.getCache("tfConfig") == null) {
+            cacheManager.createCache("tfConfig", defaultTemplate);
+        }
+        if (cacheManager.getCache(CONFIG_BY_NAME_CACHE_NAME) == null) {
+            cacheManager.createCache(CONFIG_BY_NAME_CACHE_NAME, defaultTemplate);
+        }
 
         javax.cache.configuration.Configuration<Object, Object> accessTokenTemplate = Eh107Configuration.fromEhcacheCacheConfiguration(
                 CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, ResourcePoolsBuilder.heap(10000))
                         .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofHours(2))).build());
 
-        cacheManager.createCache("userTFAccessToken", accessTokenTemplate);
+        if (cacheManager.getCache("userTFAccessToken") == null) {
+            cacheManager.createCache("userTFAccessToken", accessTokenTemplate);
+        }
 
         return cacheManager;
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantPasswordEncryptionTask.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantPasswordEncryptionTask.java
index e8d693f..63822ce 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantPasswordEncryptionTask.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantPasswordEncryptionTask.java
@@ -21,6 +21,8 @@
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.sql.ResultSet;
 import java.sql.Statement;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import liquibase.change.custom.CustomTaskChange;
 import liquibase.database.Database;
 import liquibase.database.jvm.JdbcConnection;
@@ -42,6 +44,9 @@
 
     private static DatabasePasswordEncryptor databasePasswordEncryptor;
 
+    // NOTE: workaround for double execution bug; see: https://github.com/liquibase/liquibase/issues/3945
+    private Map<String, Boolean> done = new ConcurrentHashMap<>();
+
     @Override
     public void execute(Database database) throws CustomChangeException {
         JdbcConnection dbConn = (JdbcConnection) database.getConnection(); // autocommit is false
@@ -50,16 +55,18 @@
             try (ResultSet rs = selectStatement.executeQuery("SELECT id, schema_password FROM tenant_server_connections")) {
                 while (rs.next()) {
                     String id = rs.getString("id");
-                    String schemaPassword = rs.getString("schema_password");
-                    String encryptedPassword = TenantPasswordEncryptionTask.databasePasswordEncryptor.encrypt(schemaPassword);
+                    if (!Boolean.TRUE.equals(done.get(id))) {
+                        String schemaPassword = rs.getString("schema_password");
+                        String encryptedPassword = TenantPasswordEncryptionTask.databasePasswordEncryptor.encrypt(schemaPassword);
 
-                    String updateSql = String.format(
-                            "update tenant_server_connections set schema_password = '%s', master_password_hash = '%s' where id = %s",
-                            encryptedPassword, TenantPasswordEncryptionTask.databasePasswordEncryptor.getMasterPasswordHash(), id);
-                    updateStatement.execute(updateSql);
+                        String updateSql = String.format(
+                                "update tenant_server_connections set schema_password = '%s', master_password_hash = '%s' where id = %s",
+                                encryptedPassword, TenantPasswordEncryptionTask.databasePasswordEncryptor.getMasterPasswordHash(), id);
+                        updateStatement.execute(updateSql);
+                        done.put(id, true);
+                    }
                 }
             }
-
         } catch (Exception e) {
             throw new CustomChangeException(e);
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantReadOnlyPasswordEncryptionTask.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantReadOnlyPasswordEncryptionTask.java
index e019ae1..a3537ae 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantReadOnlyPasswordEncryptionTask.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/TenantReadOnlyPasswordEncryptionTask.java
@@ -21,6 +21,8 @@
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.sql.ResultSet;
 import java.sql.Statement;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import liquibase.change.custom.CustomTaskChange;
 import liquibase.database.Database;
 import liquibase.database.jvm.JdbcConnection;
@@ -42,6 +44,9 @@
 
     private static DatabasePasswordEncryptor databasePasswordEncryptor;
 
+    // NOTE: workaround for double execution bug; see: https://github.com/liquibase/liquibase/issues/3945
+    private Map<String, Boolean> done = new ConcurrentHashMap<>();
+
     @Override
     public void execute(Database database) throws CustomChangeException {
         JdbcConnection dbConn = (JdbcConnection) database.getConnection(); // autocommit is false
@@ -51,17 +56,20 @@
                     "SELECT id, readonly_schema_password FROM tenant_server_connections WHERE readonly_schema_password IS NOT NULL")) {
                 while (rs.next()) {
                     String id = rs.getString("id");
-                    String readOnlySchemaPassword = rs.getString("readonly_schema_password");
-                    String encryptedPassword = TenantReadOnlyPasswordEncryptionTask.databasePasswordEncryptor
-                            .encrypt(readOnlySchemaPassword);
+                    if (!Boolean.TRUE.equals(done.get(id))) {
+                        String readOnlySchemaPassword = rs.getString("readonly_schema_password");
+                        String encryptedPassword = TenantReadOnlyPasswordEncryptionTask.databasePasswordEncryptor
+                                .encrypt(readOnlySchemaPassword);
 
-                    String updateSql = String.format(
-                            "update tenant_server_connections set readonly_schema_password = '%s', master_password_hash = '%s' where id = %s",
-                            encryptedPassword, TenantReadOnlyPasswordEncryptionTask.databasePasswordEncryptor.getMasterPasswordHash(), id);
-                    updateStatement.execute(updateSql);
+                        String updateSql = String.format(
+                                "update tenant_server_connections set readonly_schema_password = '%s', master_password_hash = '%s' where id = %s",
+                                encryptedPassword, TenantReadOnlyPasswordEncryptionTask.databasePasswordEncryptor.getMasterPasswordHash(),
+                                id);
+                        updateStatement.execute(updateSql);
+                        done.put(id, true);
+                    }
                 }
             }
-
         } catch (Exception e) {
             throw new CustomChangeException(e);
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
index 888a8d0..8316d71 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
@@ -39,6 +39,8 @@
 import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.function.Supplier;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import okhttp3.HttpUrl;
 import okhttp3.MediaType;
 import okhttp3.MultipartBody;
@@ -65,18 +67,14 @@
 import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-@Component
+@Slf4j
+@RequiredArgsConstructor
 @Service
 public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
 
-    private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
     public static final String UPLOAD_CREDIT_REPORT = "UploadCreditReport";
     public static final String RESPONSE_MESSAGE = "ResponseMessage";
     public static final String IS_NOT_AVAILABLE_SUFFIX = ".is.not.available";
@@ -85,29 +83,8 @@
     private final TokenRepositoryWrapper tokenRepositoryWrapper;
     private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
     private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
-
     private final OkHttpClient client;
 
-    @Autowired
-    public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
-            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepositoryWrapper,
-            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
-            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
-        this(new OkHttpClient(), context, fromApiJsonHelper, tokenRepositoryWrapper, configDataRepository, fromApiJsonDeserializer);
-    }
-
-    public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final OkHttpClient okHttpClient,
-            final PlatformSecurityContext context, final FromJsonHelper fromApiJsonHelper,
-            final TokenRepositoryWrapper tokenRepositoryWrapper, final CreditBureauConfigurationRepositoryWrapper configDataRepository,
-            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
-        this.client = okHttpClient;
-        this.context = context;
-        this.tokenRepositoryWrapper = tokenRepositoryWrapper;
-        this.configDataRepository = configDataRepository;
-        this.fromApiJsonHelper = fromApiJsonHelper;
-        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
-    }
-
     @Transactional
     @Override
     public String okHttpConnectionMethod(String userName, String password, String subscriptionKey, String subscriptionId, String url,
@@ -151,7 +128,7 @@
             responseMessage = response.body().string();
         } catch (IOException e) {
 
-            LOG.error("error occured in HTTP request-response method.", e);
+            log.error("error occured in HTTP request-response method.", e);
         }
 
         if (responseCode != HttpURLConnection.HTTP_OK) {
@@ -494,7 +471,7 @@
                         "creditBureau.Configuration." + configurationParameterName + IS_NOT_AVAILABLE_SUFFIX);
 
             }
-        } catch (NullPointerException ex) {
+        } catch (Exception ex) {
             baseDataValidator.reset().failWithCode("creditBureau.configuration.is.not.available");
             throw new PlatformApiDataValidationException("creditBureau.Configuration.is.not.available" + ex,
                     "creditBureau.Configuration.is.not.available", dataValidationErrors);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadReportingServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadReportingServiceImpl.java
index d116e1a..b845b22 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadReportingServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadReportingServiceImpl.java
@@ -37,7 +37,6 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.csv.CSVFormat;
@@ -133,11 +132,8 @@
 
         String sql = getSql(name, type);
 
-        final Set<String> keys = queryParams.keySet();
-        for (final String key : keys) {
-            final String pValue = queryParams.get(key);
-            // LOG.info("({} : {})", key, pValue);
-            sql = this.genericDataService.replace(sql, key, pValue);
+        for (Map.Entry<String, String> entry : queryParams.entrySet()) {
+            sql = this.genericDataService.replace(sql, entry.getKey(), entry.getValue());
         }
 
         final AppUser currentUser = this.context.authenticatedUser();
@@ -238,14 +234,9 @@
                 row = element.getRow();
                 rSize = row.size();
                 for (int j = 0; j < rSize; j++) {
-                    currColType = columnHeaders.get(j).getColumnType();
                     currVal = (String) row.get(j);
                     if (currVal != null) {
-                        if (currColType.isNumericType()) {
-                            table.addCell(currVal.toString());
-                        } else {
-                            table.addCell(currVal.toString());
-                        }
+                        table.addCell(currVal);
                     }
                 }
             }
@@ -453,11 +444,8 @@
     private String sqlToRunForSmsEmailCampaign(final String name, final String type, final Map<String, String> queryParams) {
         String sql = getSql(name, type);
 
-        final Set<String> keys = queryParams.keySet();
-        for (String key : keys) {
-            final String pValue = queryParams.get(key);
-            key = "${" + key + "}";
-            sql = this.genericDataService.replace(sql, key, pValue);
+        for (Map.Entry<String, String> entry : queryParams.entrySet()) {
+            sql = this.genericDataService.replace(sql, "${" + entry.getKey() + "}", entry.getValue());
         }
 
         sql = this.genericDataService.wrapSQL(sql);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
index 022ad5e..b8d587e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
@@ -371,7 +371,7 @@
 
     private void registerDataTable(final String entityName, final String dataTableName, final String entitySubType, final Integer category,
             final String permissionsSql) {
-        EntityTables entityTable = resolveEntity(entityName);
+        resolveEntity(entityName);
         validateDatatableName(dataTableName);
         validateDataTableExists(dataTableName);
 
@@ -1294,16 +1294,16 @@
                 List.of(entityTable.getForeignKeyColumnNameOnDatatable(), CREATEDAT_FIELD_NAME, UPDATEDAT_FIELD_NAME));
         LocalDateTime auditDateTime = DateUtils.getAuditLocalDateTime();
         ArrayList<Object> params = new ArrayList<>(List.of(appTableId, auditDateTime, auditDateTime));
-        for (String key : dataParams.keySet()) {
-            if (isTechnicalParam(key)) {
+        for (Map.Entry<String, String> entry : dataParams.entrySet()) {
+            if (isTechnicalParam(entry.getKey())) {
                 continue;
             }
-            ResultsetColumnHeaderData columnHeader = SearchUtil.validateToJdbcColumn(key, headersByName, false);
+            ResultsetColumnHeaderData columnHeader = SearchUtil.validateToJdbcColumn(entry.getKey(), headersByName, false);
             if (!isUserInsertable(entityTable, columnHeader)) {
                 continue;
             }
             insertColumns.add(columnHeader.getColumnName());
-            params.add(SearchUtil.parseJdbcColumnValue(columnHeader, dataParams.get(key), dateFormat, dateTimeFormat, locale, false,
+            params.add(SearchUtil.parseJdbcColumnValue(columnHeader, entry.getValue(), dateFormat, dateTimeFormat, locale, false,
                     sqlGenerator));
         }
         if (addScore) {
@@ -1403,17 +1403,17 @@
         ArrayList<String> updateColumns = new ArrayList<>(List.of(UPDATEDAT_FIELD_NAME));
         ArrayList<Object> params = new ArrayList<>(List.of(DateUtils.getAuditLocalDateTime()));
         final HashMap<String, Object> changes = new HashMap<>();
-        for (String key : dataParams.keySet()) {
-            if (isTechnicalParam(key)) {
+        for (Map.Entry<String, String> entry : dataParams.entrySet()) {
+            if (isTechnicalParam(entry.getKey())) {
                 continue;
             }
-            ResultsetColumnHeaderData columnHeader = SearchUtil.validateToJdbcColumn(key, headersByName, false);
+            ResultsetColumnHeaderData columnHeader = SearchUtil.validateToJdbcColumn(entry.getKey(), headersByName, false);
             if (!isUserUpdatable(entityTable, columnHeader)) {
                 continue;
             }
             String columnName = columnHeader.getColumnName();
             Object existingValue = valuesByHeader.get(columnHeader);
-            Object columnValue = SearchUtil.parseColumnValue(columnHeader, dataParams.get(key), dateFormat, dateTimeFormat, locale, false,
+            Object columnValue = SearchUtil.parseColumnValue(columnHeader, entry.getValue(), dateFormat, dateTimeFormat, locale, false,
                     sqlGenerator);
             if ((columnHeader.getColumnType().isDecimalType() && MathUtil.isEqualTo((BigDecimal) existingValue, (BigDecimal) columnValue))
                     || (existingValue == null ? columnValue == null : existingValue.equals(columnValue))) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformServiceJpaRepositoryImpl.java
index 21035ca..09f75bc 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformServiceJpaRepositoryImpl.java
@@ -134,15 +134,13 @@
     private CommandProcessingResult updateImage(final Object owner, final String imageLocation, final StorageType storageType) {
         Image image = null;
         Long clientId = null;
-        if (owner instanceof Client) {
-            Client client = (Client) owner;
+        if (owner instanceof Client client) {
             image = client.getImage();
             clientId = client.getId();
             image = createImage(image, imageLocation, storageType);
             client.setImage(image);
             this.clientRepositoryWrapper.save(client);
-        } else if (owner instanceof Staff) {
-            Staff staff = (Staff) owner;
+        } else if (owner instanceof Staff staff) {
             image = staff.getImage();
             clientId = staff.getId();
             image = createImage(image, imageLocation, storageType);
@@ -150,7 +148,9 @@
             this.staffRepositoryWrapper.save(staff);
         }
 
-        this.imageRepository.save(image);
+        if (image != null) {
+            this.imageRepository.save(image);
+        }
         return CommandProcessingResult.resourceResult(clientId);
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/producer/kafka/KafkaExternalEventProducer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/producer/kafka/KafkaExternalEventProducer.java
index 9cf815e..952a7b5 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/producer/kafka/KafkaExternalEventProducer.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/producer/kafka/KafkaExternalEventProducer.java
@@ -58,10 +58,9 @@
         List<CompletableFuture<SendResult<Long, byte[]>>> sendResults = new ArrayList<>();
         measure(() -> {
             Set<Long> keys = partitions.keySet();
-            for (Long key : keys) {
-                List<byte[]> messages = partitions.get(key);
-                for (byte[] message : messages) {
-                    sendResults.add(externalEventsKafkaTemplate.send(topicName, key, message));
+            for (Map.Entry<Long, List<byte[]>> entry : partitions.entrySet()) {
+                for (byte[] message : entry.getValue()) {
+                    sendResults.add(externalEventsKafkaTemplate.send(topicName, entry.getKey(), message));
                 }
             }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java
index 33a5603..6278eba 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java
@@ -47,7 +47,6 @@
 @RequiredArgsConstructor
 public class SchedulerJobListener implements JobListener {
 
-    private final String name = SchedulerServiceConstants.DEFAULT_LISTENER_NAME;
     private final SchedularWritePlatformService schedularService;
     private final AppUserRepositoryWrapper userRepository;
     private final BusinessDateReadPlatformService businessDateReadPlatformService;
@@ -55,7 +54,7 @@
 
     @Override
     public String getName() {
-        return this.name;
+        return SchedulerServiceConstants.DEFAULT_LISTENER_NAME;
     }
 
     @Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/report/service/ReportingProcessService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/report/service/ReportingProcessService.java
index 1061815..3140632 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/report/service/ReportingProcessService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/report/service/ReportingProcessService.java
@@ -23,7 +23,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import org.apache.fineract.infrastructure.dataqueries.data.ReportExportType;
 import org.apache.fineract.infrastructure.security.utils.SQLInjectionValidator;
 
@@ -35,11 +34,10 @@
 
     default Map<String, String> getReportParams(final MultivaluedMap<String, String> queryParams) {
         final Map<String, String> reportParams = new HashMap<>();
-        final Set<String> keys = queryParams.keySet();
-        for (final String k : keys) {
-            if (k.startsWith("R_")) {
-                String pKey = "${" + k.substring(2) + "}";
-                String pValue = queryParams.get(k).get(0);
+        for (Map.Entry<String, List<String>> entry : queryParams.entrySet()) {
+            if (entry.getKey().startsWith("R_")) {
+                String pKey = "${" + entry.getKey().substring(2) + "}";
+                String pValue = entry.getValue().get(0);
                 SQLInjectionValidator.validateSQLInput(pValue);
                 reportParams.put(pKey, pValue);
             }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/api/SmsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/api/SmsApiResource.java
index 841a509..e0242f2 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/api/SmsApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/api/SmsApiResource.java
@@ -59,7 +59,7 @@
 @RequiredArgsConstructor
 public class SmsApiResource {
 
-    private final String resourceNameForPermissions = "SMS";
+    private static final String RESOURCE_NAME_FOR_PERMISSIONS = "SMS";
 
     private final PlatformSecurityContext context;
     private final SmsReadPlatformService readPlatformService;
@@ -69,7 +69,7 @@
 
     @GET
     public String retrieveAll(@Context final UriInfo uriInfo) {
-        context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
+        context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
         final Collection<SmsData> smsMessages = readPlatformService.retrieveAll();
         final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
         return toApiJsonSerializer.serialize(settings, smsMessages);
@@ -98,7 +98,7 @@
             @QueryParam("dateFormat") final String rawDateFormat, @QueryParam("offset") final Integer offset,
             @QueryParam("limit") final Integer limit, @QueryParam("orderBy") final String orderBy,
             @QueryParam("sortOrder") final String sortOrder) {
-        context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
+        context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
         final SearchParameters searchParameters = SearchParameters.forSMSCampaign(offset, limit, orderBy, sortOrder);
 
         final DateFormat dateFormat = StringUtils.isBlank(rawDateFormat) ? null : new DateFormat(rawDateFormat);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/api/SurveyApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/api/SurveyApiResourceSwagger.java
index 8f26777..4cd6ba6 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/api/SurveyApiResourceSwagger.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/api/SurveyApiResourceSwagger.java
@@ -86,7 +86,7 @@
         @Schema(example = "201")
         public Long ppi_fryingpans_cd_q10_fryingpans;
         @Schema(example = "2014-12-02 20:30:00")
-        public ZonedDateTime Date;
+        public ZonedDateTime date;
         @Schema(example = "Y-m-d H:i:s")
         public ZonedDateTime dateFormat;
         @Schema(example = "en_GB")
diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/api/TellerApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/api/TellerApiResource.java
index b881254..bd42683 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/api/TellerApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/api/TellerApiResource.java
@@ -308,8 +308,10 @@
             @QueryParam("limit") @Parameter(description = "limit") final Integer limit,
             @QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy,
             @QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder) {
-        final TellerData teller = this.readPlatformService.findTeller(tellerId);
-        final CashierData cashier = this.readPlatformService.findCashier(cashierId);
+        // TODO: can we remove these 2 calls? we don't use the results, but left it here in case something is done in
+        // the functions
+        this.readPlatformService.findTeller(tellerId);
+        this.readPlatformService.findCashier(cashierId);
 
         final LocalDate fromDate = null;
         final LocalDate toDate = null;
@@ -334,8 +336,10 @@
             @QueryParam("limit") @Parameter(description = "limit") final Integer limit,
             @QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy,
             @QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder) {
-        final TellerData teller = this.readPlatformService.findTeller(tellerId);
-        final CashierData cashier = this.readPlatformService.findCashier(cashierId);
+        // TODO: can we remove these 2 calls? we don't use the results, but left it here in case something is done in
+        // the functions
+        this.readPlatformService.findTeller(tellerId);
+        this.readPlatformService.findCashier(cashierId);
 
         final LocalDate fromDate = null;
         final LocalDate toDate = null;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java
index 3f64940..b00b5c9 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java
@@ -355,8 +355,8 @@
 
             this.fromApiJsonDeserializer.validateForCashTxnForCashier(command.json());
 
+            // TODO: can we please remove this whole block?!? this is 20 lines of dead code!!!
             final String entityType = command.stringValueOfParameterNamed("entityType");
-            final Long entityId = command.longValueOfParameterNamed("entityId");
             if (entityType != null) {
                 if (entityType.equals("loan account")) {
                     // TODO : Check if loan account exists
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/service/AddressReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/service/AddressReadPlatformServiceImpl.java
index ebe5660..5e0a60f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/service/AddressReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/service/AddressReadPlatformServiceImpl.java
@@ -65,8 +65,6 @@
 
             final long addressId = rs.getLong("id");
 
-            final long clientId = rs.getLong("client_id");
-
             final String street = rs.getString("street");
 
             final String address_line_1 = rs.getString("address_line_1");
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/common/domain/ConditionType.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/common/domain/ConditionType.java
index ea46442..dbe9c31 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/common/domain/ConditionType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/common/domain/ConditionType.java
@@ -18,33 +18,37 @@
  */
 package org.apache.fineract.portfolio.common.domain;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.Arrays;
 
 public enum ConditionType {
 
     INVALID(0, "ConditionType.invalid"), //
     LESSTHAN(1, "ConditionType.lessthan"), //
     EQUAL(2, "ConditionType.equal"), //
+    // TODO: fix typo "GREATERTHAN"
     GRETERTHAN(3, "ConditionType.greterthan"), //
     NOT_EQUAL(4, "ConditionType.notequal");//
 
     private final Integer value;
     private final String code;
 
-    private static final Map<Integer, ConditionType> intToEnumMap = new HashMap<>();
-
-    static {
-        for (final ConditionType type : ConditionType.values()) {
-            intToEnumMap.put(type.value, type);
+    public static ConditionType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-    }
 
-    public static ConditionType fromInt(final Integer ruleTypeValue) {
-        final ConditionType type = intToEnumMap.get(ruleTypeValue);
-        return type;
+        switch (v) {
+            case 1:
+                return LESSTHAN;
+            case 2:
+                return EQUAL;
+            case 3:
+                return GRETERTHAN;
+            case 4:
+                return NOT_EQUAL;
+            default:
+                return INVALID;
+        }
     }
 
     ConditionType(final Integer value, final String code) {
@@ -65,34 +69,13 @@
         return this.code;
     }
 
-    public boolean isConditionTypeEqual() {
-        return ConditionType.EQUAL.getValue().equals(this.value);
-    }
-
-    public boolean isConditionTypeGreterThan() {
-        return ConditionType.GRETERTHAN.getValue().equals(this.value);
-    }
-
-    public boolean isConditionTypeNotEqual() {
-        return ConditionType.NOT_EQUAL.getValue().equals(this.value);
-    }
-
-    public boolean isConditionTypeLessThan() {
-        return ConditionType.LESSTHAN.getValue().equals(this.value);
-    }
-
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isInvalid() {
         return ConditionType.INVALID.getValue().equals(this.value);
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final ConditionType enumType : values()) {
-            if (!enumType.isInvalid()) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveAttributeName.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveAttributeName.java
index b5993c3..ff8208b 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveAttributeName.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveAttributeName.java
@@ -18,10 +18,7 @@
  */
 package org.apache.fineract.portfolio.interestratechart.incentive;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.Arrays;
 
 public enum InterestIncentiveAttributeName {
 
@@ -34,19 +31,21 @@
     private final Integer value;
     private final String code;
 
-    private static final Map<Integer, InterestIncentiveAttributeName> intToEnumMap = new HashMap<>();
-
-    static {
-        for (final InterestIncentiveAttributeName type : InterestIncentiveAttributeName.values()) {
-            intToEnumMap.put(type.value, type);
+    public static InterestIncentiveAttributeName fromInt(final Integer value) {
+        switch (value) {
+            case 2:
+                return GENDER;
+            case 3:
+                return AGE;
+            case 4:
+                return CLIENT_TYPE;
+            case 5:
+                return CLIENT_CLASSIFICATION;
+            default:
+                return INVALID;
         }
     }
 
-    public static InterestIncentiveAttributeName fromInt(final Integer ruleTypeValue) {
-        final InterestIncentiveAttributeName type = intToEnumMap.get(ruleTypeValue);
-        return type;
-    }
-
     InterestIncentiveAttributeName(final Integer value, final String code) {
         this.value = value;
         this.code = code;
@@ -65,49 +64,45 @@
         return this.code;
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isGender() {
-        return InterestIncentiveAttributeName.GENDER.getValue().equals(this.value);
+        return GENDER.equals(this);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isAge() {
-        return InterestIncentiveAttributeName.AGE.getValue().equals(this.value);
+        return AGE.equals(this);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isClientType() {
-        return InterestIncentiveAttributeName.CLIENT_TYPE.getValue().equals(this.value);
+        return CLIENT_TYPE.equals(this);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isClientClassification() {
-        return InterestIncentiveAttributeName.CLIENT_CLASSIFICATION.getValue().equals(this.value);
+        return CLIENT_CLASSIFICATION.equals(this);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isInvalid() {
-        return InterestIncentiveAttributeName.INVALID.getValue().equals(this.value);
+        return INVALID.equals(this);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public static boolean isCodeValueAttribute(InterestIncentiveAttributeName attributeName) {
-        boolean isCodeValue = false;
         switch (attributeName) {
             case GENDER:
             case CLIENT_TYPE:
             case CLIENT_CLASSIFICATION:
-                isCodeValue = true;
-            break;
+                return true;
             default:
-            break;
+                return false;
         }
-        return isCodeValue;
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final InterestIncentiveAttributeName enumType : values()) {
-            if (!enumType.isInvalid()) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
-
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveEntityType.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveEntityType.java
index b500863..8f00b48 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveEntityType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveEntityType.java
@@ -18,10 +18,7 @@
  */
 package org.apache.fineract.portfolio.interestratechart.incentive;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.Arrays;
 
 public enum InterestIncentiveEntityType {
 
@@ -32,17 +29,19 @@
     private final Integer value;
     private final String code;
 
-    private static final Map<Integer, InterestIncentiveEntityType> intToEnumMap = new HashMap<>();
-
-    static {
-        for (final InterestIncentiveEntityType type : InterestIncentiveEntityType.values()) {
-            intToEnumMap.put(type.value, type);
+    public static InterestIncentiveEntityType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-    }
 
-    public static InterestIncentiveEntityType fromInt(final Integer ruleTypeValue) {
-        final InterestIncentiveEntityType type = intToEnumMap.get(ruleTypeValue);
-        return type;
+        switch (v) {
+            case 2:
+                return CUSTOMER;
+            case 3:
+                return ACCOUNT;
+            default:
+                return INVALID;
+        }
     }
 
     InterestIncentiveEntityType(final Integer value, final String code) {
@@ -64,21 +63,15 @@
     }
 
     public boolean isCustomer() {
-        return InterestIncentiveEntityType.CUSTOMER.getValue().equals(this.value);
+        return CUSTOMER.equals(this);
     }
 
     public boolean isInvalid() {
-        return InterestIncentiveEntityType.INVALID.getValue().equals(this.value);
+        return INVALID.equals(this);
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final InterestIncentiveEntityType enumType : values()) {
-            if (!enumType.isInvalid()) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveType.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveType.java
index f14014d..cc55c4e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/incentive/InterestIncentiveType.java
@@ -18,10 +18,7 @@
  */
 package org.apache.fineract.portfolio.interestratechart.incentive;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.Arrays;
 
 public enum InterestIncentiveType {
 
@@ -32,17 +29,19 @@
     private final Integer value;
     private final String code;
 
-    private static final Map<Integer, InterestIncentiveType> intToEnumMap = new HashMap<>();
-
-    static {
-        for (final InterestIncentiveType type : InterestIncentiveType.values()) {
-            intToEnumMap.put(type.value, type);
+    public static InterestIncentiveType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-    }
 
-    public static InterestIncentiveType fromInt(final Integer ruleTypeValue) {
-        final InterestIncentiveType type = intToEnumMap.get(ruleTypeValue);
-        return type;
+        switch (v) {
+            case 2:
+                return FIXED;
+            case 3:
+                return INCENTIVE;
+            default:
+                return INVALID;
+        }
     }
 
     InterestIncentiveType(final Integer value, final String code) {
@@ -63,27 +62,23 @@
         return this.code;
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isIncentive() {
-        return InterestIncentiveType.INCENTIVE.getValue().equals(this.value);
+        return INCENTIVE.equals(this);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isFixed() {
-        return InterestIncentiveType.FIXED.getValue().equals(this.value);
+        return FIXED.equals(this);
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isInvalid() {
-        return InterestIncentiveType.INVALID.getValue().equals(this.value);
+        return INVALID.equals(this);
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final InterestIncentiveType enumType : values()) {
-            if (!enumType.isInvalid()) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
-
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java
index 1e84c80..c9eb31f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResource.java
@@ -84,7 +84,7 @@
     private final Set<String> responseDataParameters = new HashSet<>(Arrays.asList("id", "type", "date", "currency", "amount", "externalId",
             LoanApiConstants.REVERSAL_EXTERNAL_ID_PARAMNAME, LoanApiConstants.REVERSED_ON_DATE_PARAMNAME));
 
-    private final String resourceNameForPermissions = "LOAN";
+    private static final String RESOURCE_NAME_FOR_PERMISSIONS = "LOAN";
 
     private final PlatformSecurityContext context;
     private final LoanReadPlatformService loanReadPlatformService;
@@ -414,7 +414,7 @@
 
     private String retrieveTransaction(final Long loanId, final String loanExternalIdStr, final Long transactionId,
             final String transactionExternalIdStr, final UriInfo uriInfo) {
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
 
         ExternalId loanExternalId = ExternalIdFactory.produce(loanExternalIdStr);
         ExternalId transactionExternalId = ExternalIdFactory.produce(transactionExternalIdStr);
@@ -488,7 +488,7 @@
 
     private String retrieveTransactionTemplate(Long loanId, String loanExternalIdStr, String commandParam, UriInfo uriInfo,
             DateFormat dateFormat, DateParam transactionDateParam, String locale) {
-        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+        this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
 
         ExternalId loanExternalId = ExternalIdFactory.produce(loanExternalIdStr);
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/applychargetooverdueloaninstallment/ApplyChargeToOverdueLoanInstallmentTasklet.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/applychargetooverdueloaninstallment/ApplyChargeToOverdueLoanInstallmentTasklet.java
index bce7e33..bd09da8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/applychargetooverdueloaninstallment/ApplyChargeToOverdueLoanInstallmentTasklet.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/applychargetooverdueloaninstallment/ApplyChargeToOverdueLoanInstallmentTasklet.java
@@ -66,23 +66,23 @@
             }
 
             List<Throwable> exceptions = new ArrayList<>();
-            for (final Long loanId : overdueScheduleData.keySet()) {
+            for (Map.Entry<Long, Collection<OverdueLoanScheduleData>> entry : overdueScheduleData.entrySet()) {
                 try {
-                    loanChargeWritePlatformService.applyOverdueChargesForLoan(loanId, overdueScheduleData.get(loanId));
+                    loanChargeWritePlatformService.applyOverdueChargesForLoan(entry.getKey(), entry.getValue());
 
                 } catch (final PlatformApiDataValidationException e) {
                     final List<ApiParameterError> errors = e.getErrors();
                     for (final ApiParameterError error : errors) {
-                        log.error("Apply Charges due for overdue loans failed for account {} with message: {}", loanId,
+                        log.error("Apply Charges due for overdue loans failed for account {} with message: {}", entry.getKey(),
                                 error.getDeveloperMessage(), e);
                     }
                     exceptions.add(e);
                 } catch (final AbstractPlatformDomainRuleException e) {
-                    log.error("Apply Charges due for overdue loans failed for account {} with message: {}", loanId,
+                    log.error("Apply Charges due for overdue loans failed for account {} with message: {}", entry.getKey(),
                             e.getDefaultUserMessage(), e);
                     exceptions.add(e);
                 } catch (Exception e) {
-                    log.error("Apply Charges due for overdue loans failed for account {}", loanId, e);
+                    log.error("Apply Charges due for overdue loans failed for account {}", entry.getKey(), e);
                     exceptions.add(e);
                 }
             }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/generateloanlossprovisioning/GenerateLoanlossProvisioningConfig.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/generateloanlossprovisioning/GenerateLoanlossProvisioningConfig.java
index 4fcf6f9..564549f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/generateloanlossprovisioning/GenerateLoanlossProvisioningConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/generateloanlossprovisioning/GenerateLoanlossProvisioningConfig.java
@@ -39,7 +39,6 @@
     private JobRepository jobRepository;
     @Autowired
     private PlatformTransactionManager transactionManager;
-    private StepBuilder steps;
     @Autowired
     private ProvisioningCriteriaReadPlatformService provisioningCriteriaReadPlatformService;
     @Autowired
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/setloandelinquencytags/SetLoanDelinquencyTagsTasklet.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/setloandelinquencytags/SetLoanDelinquencyTagsTasklet.java
index 292be13..d1cd7ab 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/setloandelinquencytags/SetLoanDelinquencyTagsTasklet.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/setloandelinquencytags/SetLoanDelinquencyTagsTasklet.java
@@ -75,7 +75,7 @@
             loanScheduleDelinquencyData = this.loanRepaymentScheduleInstallmentRepository
                     .fetchLoanScheduleDataByDueDateAndObligationsMet(LoanStatus.ACTIVE.getValue(), businessDate, false, processedLoans);
         }
-        processedLoans = applyDelinquencyTagToLoans(loanScheduleDelinquencyData);
+        applyDelinquencyTagToLoans(loanScheduleDelinquencyData);
 
         return RepeatStatus.FINISHED;
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
index 0ec8d3e..3676496 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
@@ -771,10 +771,9 @@
                 graceApplicable = installment.getDueDate();
             }
         }
-        Collection<LocalDate> keySet = adjustDueDateVariations.keySet();
-        dueDates.addAll(keySet);
-        for (final LocalDate date : keySet) {
-            LocalDate removeDate = adjustDueDateVariations.get(date);
+        dueDates.addAll(adjustDueDateVariations.keySet());
+        for (Map.Entry<LocalDate, LocalDate> entry : adjustDueDateVariations.entrySet()) {
+            LocalDate removeDate = entry.getValue();
             if (removeDate != null) {
                 dueDates.remove(removeDate);
             }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
index f15cb39..15f359f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
@@ -1453,8 +1453,6 @@
     @Override
     public CommandProcessingResult undoApplicationApproval(final Long loanId, final JsonCommand command) {
 
-        AppUser currentUser = getAppUserIfPresent();
-
         this.fromApiJsonDeserializer.validateForUndo(command.json());
 
         final Loan loan = retrieveLoanBy(loanId);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java
index 52a76ac..795bbec 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java
@@ -125,14 +125,16 @@
 
     @Override
     public void updateLoanArrearsAgeingDetails(final Loan loan) {
-        int count = this.jdbcTemplate.queryForObject("select count(mla.loan_id) from m_loan_arrears_aging mla where mla.loan_id =?",
-                Integer.class, loan.getId());
-        String updateStatement = constructUpdateStatement(loan, count == 0);
-        if (updateStatement == null) {
-            String deletestatement = "DELETE FROM m_loan_arrears_aging WHERE  loan_id=?";
-            this.jdbcTemplate.update(deletestatement, loan.getId()); // NOSONAR
-        } else {
-            this.jdbcTemplate.update(updateStatement);
+        if (loan != null) {
+            int count = this.jdbcTemplate.queryForObject("select count(mla.loan_id) from m_loan_arrears_aging mla where mla.loan_id =?",
+                    Integer.class, loan.getId());
+            String updateStatement = constructUpdateStatement(loan, count == 0);
+            if (updateStatement == null) {
+                String deletestatement = "DELETE FROM m_loan_arrears_aging WHERE  loan_id=?";
+                this.jdbcTemplate.update(deletestatement, loan.getId()); // NOSONAR
+            } else {
+                this.jdbcTemplate.update(updateStatement);
+            }
         }
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/attendance/AttendanceType.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/attendance/AttendanceType.java
index fae5105..f9f1cae 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/attendance/AttendanceType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/attendance/AttendanceType.java
@@ -48,31 +48,24 @@
         return this.code;
     }
 
-    public static AttendanceType fromInt(final Integer attendanceTypeId) {
-
-        if (attendanceTypeId == null) {
-            return AttendanceType.INVALID;
+    public static AttendanceType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
 
-        AttendanceType attendanceType = AttendanceType.INVALID;
-        switch (attendanceTypeId) {
+        switch (v) {
             case 1:
-                attendanceType = AttendanceType.PRESENT;
-            break;
+                return PRESENT;
             case 2:
-                attendanceType = AttendanceType.ABSENT;
-            break;
+                return ABSENT;
             case 3:
-                attendanceType = AttendanceType.APPROVED;
-            break;
+                return APPROVED;
             case 4:
-                attendanceType = AttendanceType.LEAVE;
-            break;
+                return LEAVE;
             case 5:
-                attendanceType = AttendanceType.LATE;
-            break;
+                return LATE;
+            default:
+                return INVALID;
         }
-        return attendanceType;
     }
-
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/rate/service/RateAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/rate/service/RateAssembler.java
index e769238..9150a9d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/rate/service/RateAssembler.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/rate/service/RateAssembler.java
@@ -23,7 +23,6 @@
 import com.google.gson.JsonObject;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
 import lombok.RequiredArgsConstructor;
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
 import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
@@ -42,7 +41,6 @@
 
         if (element.isJsonObject()) {
             final JsonObject topLevelJsonElement = element.getAsJsonObject();
-            final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
 
             if (topLevelJsonElement.has(LoanProductConstants.RATES_PARAM_NAME)
                     && topLevelJsonElement.get(LoanProductConstants.RATES_PARAM_NAME).isJsonArray()) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/ApplyAnnualFeeSavingsAccountCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/ApplyAnnualFeeSavingsAccountCommandHandler.java
index acd81ac..a73e445 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/ApplyAnnualFeeSavingsAccountCommandHandler.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/ApplyAnnualFeeSavingsAccountCommandHandler.java
@@ -18,7 +18,6 @@
  */
 package org.apache.fineract.portfolio.savings.handler;
 
-import java.time.LocalDate;
 import org.apache.fineract.commands.annotation.CommandType;
 import org.apache.fineract.commands.handler.NewCommandSourceHandler;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
@@ -43,9 +42,9 @@
     @Transactional
     @Override
     public CommandProcessingResult processCommand(final JsonCommand command) {
-
-        @SuppressWarnings("unused")
-        final LocalDate annualFeeTransactionDate = command.localDateValueOfParameterNamed("annualFeeTransactionDate");
+        // TODO: why do we keep this class when we literally do nothing here?!?
+        // final LocalDate annualFeeTransactionDate =
+        // command.localDateValueOfParameterNamed("annualFeeTransactionDate");
 
         // return
         // this.writePlatformService.applyAnnualFee(command.getSavingsId(),
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
index d98e18b..3506183 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
@@ -264,15 +264,8 @@
     @Transactional
     @Override
     public CommandProcessingResult gsimDeposit(final Long gsimId, final JsonCommand command) {
-        Long parentSavingId = gsimId;
-        // GroupSavingsIndividualMonitoringparentSavings=gsimRepository.findById(parentSavingId).get();
-        List<SavingsAccount> childSavings = this.savingAccountRepositoryWrapper.findByGsimId(gsimId);
-
         JsonArray savingsArray = command.arrayOfParameterNamed("savingsArray");
 
-        JsonArray childAccounts = command.arrayOfParameterNamed("childAccounts");
-        int count = 0;
-
         CommandProcessingResult result = null;
         for (JsonElement element : savingsArray) {
             result = deposit(element.getAsJsonObject().get("childAccountId").getAsLong(),
@@ -1457,13 +1450,6 @@
         existingReversedTransactionIds.addAll(account.findCurrentReversedTransactionIdsWithPivotDateConfig());
     }
 
-    @SuppressWarnings("unused")
-    private void updateSavingsTransactionsDetails(SavingsAccountData account, Set<Long> existingTransactionIds,
-            Set<Long> existingReversedTransactionIds) {
-        existingTransactionIds.addAll(account.findCurrentTransactionIdsWithPivotDateConfig());
-        existingReversedTransactionIds.addAll(account.findCurrentReversedTransactionIdsWithPivotDateConfig());
-    }
-
     private void postJournalEntries(final SavingsAccount savingsAccount, final Set<Long> existingTransactionIds,
             final Set<Long> existingReversedTransactionIds, final boolean backdatedTxnsAllowedTill) {
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
index 3a24de7..295d3f5 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
@@ -83,8 +83,8 @@
                 } catch (DataAccessException exception) {
                     log.error("Batch update failed due to DataAccessException", exception);
                     errors.add(exception);
-                } catch (NullPointerException exception) {
-                    log.error("Batch update failed due to NullPointerException", exception);
+                } catch (Exception exception) {
+                    log.error("Batch update failed", exception);
                     errors.add(exception);
                 }
             }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/SharePeriodFrequencyType.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/SharePeriodFrequencyType.java
index 2506ee6..ed237dc 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/SharePeriodFrequencyType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/SharePeriodFrequencyType.java
@@ -18,8 +18,7 @@
  */
 package org.apache.fineract.portfolio.shareproducts;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
 
 /**
  * An enumeration of supported calendar periods used in savings.
@@ -48,39 +47,32 @@
         return this.code;
     }
 
-    public static SharePeriodFrequencyType fromInt(final Integer type) {
-        SharePeriodFrequencyType repaymentFrequencyType = SharePeriodFrequencyType.INVALID;
-        if (type != null) {
-            switch (type) {
-                case 0:
-                    repaymentFrequencyType = SharePeriodFrequencyType.DAYS;
-                break;
-                case 1:
-                    repaymentFrequencyType = SharePeriodFrequencyType.WEEKS;
-                break;
-                case 2:
-                    repaymentFrequencyType = SharePeriodFrequencyType.MONTHS;
-                break;
-                case 3:
-                    repaymentFrequencyType = SharePeriodFrequencyType.YEARS;
-                break;
-            }
+    public static SharePeriodFrequencyType fromInt(final Integer v) {
+        if (v == null) {
+            return INVALID;
         }
-        return repaymentFrequencyType;
+
+        switch (v) {
+            case 0:
+                return DAYS;
+            case 1:
+                return WEEKS;
+            case 2:
+                return MONTHS;
+            case 3:
+                return YEARS;
+            default:
+                return INVALID;
+        }
     }
 
+    // TODO: why not just use the enum values... just more boilerplate code here!!
     public boolean isInvalid() {
-        return this.value.equals(SharePeriodFrequencyType.INVALID.value);
+        return this.equals(INVALID);
     }
 
+    // TODO: do we really need this?!?
     public static Object[] integerValues() {
-        final List<Integer> values = new ArrayList<>();
-        for (final SharePeriodFrequencyType enumType : values()) {
-            if (!enumType.isInvalid()) {
-                values.add(enumType.getValue());
-            }
-        }
-
-        return values.toArray();
+        return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/template/service/JpaTemplateDomainService.java b/fineract-provider/src/main/java/org/apache/fineract/template/service/JpaTemplateDomainService.java
index 9fe12fe..8fc798d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/template/service/JpaTemplateDomainService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/template/service/JpaTemplateDomainService.java
@@ -81,7 +81,7 @@
         template.setText(command.stringValueOfParameterNamed(PROPERTY_TEXT));
         template.setEntity(TemplateEntity.values()[command.integerValueSansLocaleOfParameterNamed(PROPERTY_ENTITY)]);
         final int templateTypeId = command.integerValueSansLocaleOfParameterNamed(PROPERTY_TYPE);
-        TemplateType type = null;
+        TemplateType type;
         switch (templateTypeId) {
             case 0:
                 type = TemplateType.DOCUMENT;
@@ -89,6 +89,8 @@
             case 2:
                 type = TemplateType.SMS;
             break;
+            default:
+                type = null;
         }
         template.setType(type);
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PermissionWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PermissionWritePlatformServiceJpaRepositoryImpl.java
index 193ea27..c351fb9 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PermissionWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PermissionWritePlatformServiceJpaRepositoryImpl.java
@@ -55,19 +55,19 @@
         final Map<String, Boolean> commandPermissions = permissionsCommand.getPermissions();
         final Map<String, Object> changes = new HashMap<>();
         final Map<String, Boolean> changedPermissions = new HashMap<>();
-        for (final String permissionCode : commandPermissions.keySet()) {
+        for (Map.Entry<String, Boolean> entry : commandPermissions.entrySet()) {
 
-            final Permission permission = findPermissionInCollectionByCode(allPermissions, permissionCode);
+            final Permission permission = findPermissionInCollectionByCode(allPermissions, entry.getKey());
 
             if (permission.getCode().endsWith("_CHECKER") || permission.getCode().startsWith("READ_")
                     || permission.getGrouping().equalsIgnoreCase("special")) {
-                throw new PermissionNotFoundException(permissionCode);
+                throw new PermissionNotFoundException(entry.getKey());
             }
 
-            final boolean isSelected = commandPermissions.get(permissionCode).booleanValue();
+            final boolean isSelected = entry.getValue();
             final boolean changed = permission.enableMakerChecker(isSelected);
             if (changed) {
-                changedPermissions.put(permissionCode, isSelected);
+                changedPermissions.put(entry.getKey(), isSelected);
                 this.permissionRepository.saveAndFlush(permission);
             }
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java
index c06ac88..8c80ec7 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java
@@ -148,13 +148,13 @@
         final Map<String, Boolean> commandPermissions = permissionsCommand.getPermissions();
         final Map<String, Object> changes = new HashMap<>();
         final Map<String, Boolean> changedPermissions = new HashMap<>();
-        for (final String permissionCode : commandPermissions.keySet()) {
-            final boolean isSelected = commandPermissions.get(permissionCode).booleanValue();
+        for (Map.Entry<String, Boolean> entry : commandPermissions.entrySet()) {
+            final boolean isSelected = entry.getValue();
 
-            final Permission permission = findPermissionByCode(allPermissions, permissionCode);
+            final Permission permission = findPermissionByCode(allPermissions, entry.getKey());
             final boolean changed = role.updatePermission(permission, isSelected);
             if (changed) {
-                changedPermissions.put(permissionCode, isSelected);
+                changedPermissions.put(entry.getKey(), isSelected);
             }
         }
 
diff --git a/fineract-provider/src/main/resources/application.properties b/fineract-provider/src/main/resources/application.properties
index fbbe866..81833a3 100644
--- a/fineract-provider/src/main/resources/application.properties
+++ b/fineract-provider/src/main/resources/application.properties
@@ -171,6 +171,8 @@
 
 fineract.module.investor.enabled=${FINERACT_MODULE_INVESTOR_ENABLED:true}
 
+fineract.insecure-http-client=${FINERACT_INSECURE_HTTP_CLIENT:true}
+
 # Logging pattern for the console
 logging.pattern.console=${CONSOLE_LOG_PATTERN:%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%replace([%X{correlationId}]){'\\[\\]', ''}) %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}}
 logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]
diff --git a/fineract-provider/src/main/resources/banner.txt b/fineract-provider/src/main/resources/banner.txt
index 6103c57..31df8c9 100644
--- a/fineract-provider/src/main/resources/banner.txt
+++ b/fineract-provider/src/main/resources/banner.txt
@@ -6,7 +6,7 @@
 /_/   \_\ .__/ \__,_|\___|_| |_|\___| |_|   |_|_| |_|\___|_|  \__,_|\___|\__|
         |_|
 
-${AnsiStyle.FAINT}${AnsiColor.WHITE}(c) 2015-2022 ${application.title} (https://fineract.apache.org)${AnsiColor.BLACK}
+${AnsiStyle.FAINT}${AnsiColor.WHITE}(c) 2015-2024 ${application.title} (https://fineract.apache.org)${AnsiColor.BLACK}
 
 ${AnsiStyle.FAINT}${AnsiColor.WHITE}Powered by Spring Boot ${spring-boot.version}${AnsiColor.BLACK}
 
diff --git a/fineract-provider/src/test/java/org/apache/fineract/TestConfiguration.java b/fineract-provider/src/test/java/org/apache/fineract/TestConfiguration.java
index 8eb9a36..9c8d14e 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/TestConfiguration.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/TestConfiguration.java
@@ -25,6 +25,7 @@
 import java.util.List;
 import javax.sql.DataSource;
 import liquibase.change.custom.CustomTaskChange;
+import okhttp3.OkHttpClient;
 import org.apache.fineract.infrastructure.core.config.FineractProperties;
 import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
 import org.apache.fineract.infrastructure.core.service.database.DatabaseIndependentQueryService;
@@ -188,4 +189,10 @@
     public JobOperator jobOperator() {
         return mock(JobOperator.class, RETURNS_MOCKS);
     }
+
+    @Primary
+    @Bean
+    public OkHttpClient okHttpClient() {
+        return mock(OkHttpClient.class, RETURNS_MOCKS);
+    }
 }
diff --git a/fineract-provider/src/test/java/org/apache/fineract/cob/COBBusinessStepServiceStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/cob/COBBusinessStepServiceStepDefinitions.java
index c020be0..7b3ca48 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/cob/COBBusinessStepServiceStepDefinitions.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/cob/COBBusinessStepServiceStepDefinitions.java
@@ -26,10 +26,9 @@
 import static org.mockito.Mockito.verify;
 
 import com.google.common.base.Splitter;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.cucumber.java8.En;
-import java.math.BigDecimal;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Set;
 import java.util.TreeMap;
@@ -44,12 +43,12 @@
 import org.apache.fineract.infrastructure.core.domain.ActionContext;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
 import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
-import org.apache.fineract.mix.data.MixTaxonomyData;
 import org.mockito.Mockito;
 import org.springframework.beans.factory.BeanCreationException;
 import org.springframework.beans.factory.ListableBeanFactory;
 import org.springframework.context.ApplicationContext;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class COBBusinessStepServiceStepDefinitions implements En {
 
     private ApplicationContext applicationContext = mock(ApplicationContext.class);
@@ -68,10 +67,6 @@
     private AbstractAuditableCustom outputItem = mock(AbstractAuditableCustom.class);
 
     private AbstractAuditableCustom resultItem;
-
-    private HashMap<MixTaxonomyData, BigDecimal> data = new HashMap<>();
-
-    private String result;
     private Class clazz;
     private String jobName;
     private BatchBusinessStep batchBusinessStep = mock(BatchBusinessStep.class);
diff --git a/fineract-provider/src/test/java/org/apache/fineract/cob/common/InitialisationTaskletStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/cob/common/InitialisationTaskletStepDefinitions.java
index 80f831f..17df55f 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/cob/common/InitialisationTaskletStepDefinitions.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/cob/common/InitialisationTaskletStepDefinitions.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.mock;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.cucumber.java8.En;
 import java.time.LocalDate;
 import java.time.ZoneId;
@@ -41,6 +42,7 @@
 import org.springframework.batch.repeat.RepeatStatus;
 import org.springframework.security.core.context.SecurityContextHolder;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class InitialisationTaskletStepDefinitions implements En {
 
     private static final LocalDate TODAY = LocalDate.now(ZoneId.systemDefault());
diff --git a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/ApplyLoanLockTaskletStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/ApplyLoanLockTaskletStepDefinitions.java
index ead0129..7f4393e 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/ApplyLoanLockTaskletStepDefinitions.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/ApplyLoanLockTaskletStepDefinitions.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.cucumber.java8.En;
 import java.time.LocalDate;
 import java.time.ZoneId;
@@ -50,6 +51,7 @@
 import org.springframework.transaction.PlatformTransactionManager;
 import org.springframework.transaction.support.TransactionTemplate;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class ApplyLoanLockTaskletStepDefinitions implements En {
 
     ArgumentCaptor<List> valueCaptor = ArgumentCaptor.forClass(List.class);
diff --git a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemProcessorStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemProcessorStepDefinitions.java
index 15d0f31..a5b1998 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemProcessorStepDefinitions.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemProcessorStepDefinitions.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.mock;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.cucumber.java8.En;
 import java.time.LocalDate;
 import java.time.ZoneId;
@@ -36,6 +37,7 @@
 import org.springframework.batch.core.StepExecution;
 import org.springframework.batch.item.ExecutionContext;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class LoanItemProcessorStepDefinitions implements En {
 
     private COBBusinessStepService cobBusinessStepService = mock(COBBusinessStepService.class);
diff --git a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemReaderStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemReaderStepDefinitions.java
index 562d4b9..26d2be8 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemReaderStepDefinitions.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/cob/loan/LoanItemReaderStepDefinitions.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.mock;
 
 import com.google.common.base.Splitter;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.cucumber.java8.En;
 import java.time.LocalDate;
 import java.time.ZoneId;
@@ -47,6 +48,7 @@
 import org.springframework.batch.core.StepExecution;
 import org.springframework.batch.item.ExecutionContext;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class LoanItemReaderStepDefinitions implements En {
 
     private LoanRepository loanRepository = mock(LoanRepository.class);
diff --git a/fineract-provider/src/test/java/org/apache/fineract/cob/service/COBBulkEventConfigurationTest.java b/fineract-provider/src/test/java/org/apache/fineract/cob/service/COBBulkEventConfigurationTest.java
index 31c7cb9..055009b 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/cob/service/COBBulkEventConfigurationTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/cob/service/COBBulkEventConfigurationTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.time.LocalDate;
 import java.time.ZoneId;
 import java.util.HashMap;
@@ -54,6 +55,7 @@
 import org.springframework.context.ApplicationContext;
 
 @ExtendWith(MockitoExtension.class)
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class COBBulkEventConfigurationTest {
 
     @Mock
diff --git a/fineract-provider/src/test/java/org/apache/fineract/cob/service/InlineLoanCOBExecutorServiceImplTest.java b/fineract-provider/src/test/java/org/apache/fineract/cob/service/InlineLoanCOBExecutorServiceImplTest.java
index 3324bb8..af2cec6 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/cob/service/InlineLoanCOBExecutorServiceImplTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/cob/service/InlineLoanCOBExecutorServiceImplTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.time.LocalDate;
@@ -52,6 +53,7 @@
 
 @ExtendWith(MockitoExtension.class)
 @MockitoSettings(strictness = Strictness.LENIENT)
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 class InlineLoanCOBExecutorServiceImplTest {
 
     @InjectMocks
diff --git a/fineract-provider/src/test/java/org/apache/fineract/commands/provider/CommandHandlerExceptionStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/commands/provider/CommandHandlerExceptionStepDefinitions.java
index c5d84d1..1740044 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/commands/provider/CommandHandlerExceptionStepDefinitions.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/commands/provider/CommandHandlerExceptionStepDefinitions.java
@@ -20,10 +20,12 @@
 
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.cucumber.java8.En;
 import org.apache.fineract.commands.exception.UnsupportedCommandException;
 import org.springframework.beans.factory.annotation.Autowired;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class CommandHandlerExceptionStepDefinitions implements En {
 
     @Autowired
diff --git a/fineract-provider/src/test/java/org/apache/fineract/commands/service/CommandSourceServiceTest.java b/fineract-provider/src/test/java/org/apache/fineract/commands/service/CommandSourceServiceTest.java
index 6cf486b..04c30e4 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/commands/service/CommandSourceServiceTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/commands/service/CommandSourceServiceTest.java
@@ -21,6 +21,7 @@
 import static org.apache.fineract.commands.domain.CommandProcessingResultType.UNDER_PROCESSING;
 import static org.mockito.ArgumentMatchers.any;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.time.ZoneId;
 import java.util.Optional;
 import org.apache.fineract.batch.exception.ErrorInfo;
@@ -44,6 +45,7 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class CommandSourceServiceTest {
 
     @Mock
diff --git a/fineract-provider/src/test/java/org/apache/fineract/commands/service/SynchronousCommandProcessingServiceTest.java b/fineract-provider/src/test/java/org/apache/fineract/commands/service/SynchronousCommandProcessingServiceTest.java
index 1c9e024..9fdcf69 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/commands/service/SynchronousCommandProcessingServiceTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/commands/service/SynchronousCommandProcessingServiceTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import jakarta.servlet.http.HttpServletRequest;
 import java.util.Map;
 import org.apache.fineract.commands.domain.CommandProcessingResultType;
@@ -48,6 +49,7 @@
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class SynchronousCommandProcessingServiceTest {
 
     @Mock
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformServiceTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformServiceTest.java
index a73f7d6..9fdcb12 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformServiceTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/businessdate/service/BusinessDateWritePlatformServiceTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.time.LocalDate;
 import java.time.ZoneId;
 import java.util.Optional;
@@ -55,6 +56,7 @@
 
 @ExtendWith(MockitoExtension.class)
 @MockitoSettings(strictness = Strictness.LENIENT)
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class BusinessDateWritePlatformServiceTest {
 
     @InjectMocks
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/LiquibaseStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/LiquibaseStepDefinitions.java
index 0e72639..bec504a 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/LiquibaseStepDefinitions.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/LiquibaseStepDefinitions.java
@@ -105,7 +105,7 @@
         });
 
         Then("The database migration did not do anything", () -> {
-            verify(databaseStateVerifier).isLiquibaseDisabled();
+            assertThat(verify(databaseStateVerifier).isLiquibaseDisabled()).isFalse();
             verifyNoMoreInteractions(databaseStateVerifier);
             verifyNoInteractions(tenantDetailsService, tenantStoreDataSource, liquibaseFactory, tenantDataSourceFactory);
         });
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/MultiExceptionStepDefinitions.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/MultiExceptionStepDefinitions.java
index 86539a4..b4fce11 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/MultiExceptionStepDefinitions.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/core/MultiExceptionStepDefinitions.java
@@ -20,18 +20,18 @@
 
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.cucumber.java8.En;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.infrastructure.core.exception.MultiException;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class MultiExceptionStepDefinitions implements En {
 
     private List<Throwable> exceptions = new ArrayList<>();
 
-    private MultiException multiException;
-
     public MultiExceptionStepDefinitions() {
         Given("/^A multi exception with exceptions (.*) and (.*)$/", (String exception1, String exception2) -> {
             if (!StringUtils.isBlank(exception1)) {
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest.java
index 47fb2e8..26e545a 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest.java
@@ -32,8 +32,10 @@
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.gson.JsonParser;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.time.ZoneId;
@@ -71,14 +73,12 @@
 import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest {
 
     @Spy
     private FromJsonHelper fromJsonHelper = new FromJsonHelper();
 
-    @Spy
-    private CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer = new CreditBureauTokenCommandFromApiJsonDeserializer(
-            fromJsonHelper);
     @Mock
     private OkHttpClient okHttpClient;
 
@@ -86,10 +86,13 @@
     private CreditBureauConfigurationRepositoryWrapper configurationRepositoryWrapper;
 
     @Mock
+    private TokenRepositoryWrapper tokenRepositoryWrapper;
+
+    @Mock
     private PlatformSecurityContext platformSecurityContext;
 
     @Mock
-    private TokenRepositoryWrapper tokenRepositoryWrapper;
+    private CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
 
     private final ObjectMapper mapper = new ObjectMapper();
 
@@ -261,7 +264,7 @@
         String jsonResponse = createResponseObjectArrayData(() -> "UPLOADED", data -> data);
 
         Path temp = Files.createTempFile("upload_test" + System.currentTimeMillis(), ".data");
-        Files.writeString(temp, "test");
+        Files.writeString(temp, "test", StandardCharsets.UTF_8);
 
         mockOkHttpCall(request -> {
             assertEquals(request.header("Authorization"), "Bearer AccessToken");
@@ -474,7 +477,7 @@
         String jsonResponse = createResponseObjectArrayData(() -> "ADD_CREDIT_RESPONSE", data -> data);
 
         Path temp = Files.createTempFile("add_credit_report" + System.currentTimeMillis(), ".data");
-        Files.writeString(temp, "test");
+        Files.writeString(temp, "test", StandardCharsets.UTF_8);
 
         mockOkHttpCall(request -> {
             if (request.url().host().equals("addcredit.report.url")) {
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImplTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImplTest.java
index f38920c..b8bd947 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImplTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImplTest.java
@@ -29,6 +29,7 @@
 import static org.mockito.Mockito.when;
 
 import com.google.gson.JsonObject;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.List;
 import java.util.stream.Stream;
 import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
@@ -49,6 +50,7 @@
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.support.rowset.SqlRowSet;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class ReadWriteNonCoreDataServiceImplTest {
 
     @Mock
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/producer/kafka/KafkaExternalEventProducerTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/producer/kafka/KafkaExternalEventProducerTest.java
index 21ab34d..a76ba42 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/producer/kafka/KafkaExternalEventProducerTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/producer/kafka/KafkaExternalEventProducerTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.Mockito.times;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.nio.charset.Charset;
 import java.util.List;
 import java.util.Map;
@@ -36,6 +37,7 @@
 import org.springframework.kafka.support.SendResult;
 
 @ExtendWith(MockitoExtension.class)
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 class KafkaExternalEventProducerTest {
 
     public static final String TOPIC_NAME = "unit-test";
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/CustomExternalEventConfigurationRepositoryImplTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/CustomExternalEventConfigurationRepositoryImplTest.java
index 1793ac9..ed708f1 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/CustomExternalEventConfigurationRepositoryImplTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/CustomExternalEventConfigurationRepositoryImplTest.java
@@ -23,6 +23,7 @@
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.Mockito.when;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import jakarta.persistence.EntityManager;
 import org.apache.fineract.infrastructure.event.external.exception.ExternalEventConfigurationNotFoundException;
 import org.apache.fineract.infrastructure.event.external.repository.CustomExternalEventConfigurationRepositoryImpl;
@@ -35,6 +36,7 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 
 @ExtendWith(MockitoExtension.class)
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class CustomExternalEventConfigurationRepositoryImplTest {
 
     @Mock
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanRepaymentBusinessEventSerializerTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanRepaymentBusinessEventSerializerTest.java
index 6519ea6..be92158 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanRepaymentBusinessEventSerializerTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanRepaymentBusinessEventSerializerTest.java
@@ -53,7 +53,6 @@
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanSummary;
 import org.apache.fineract.portfolio.loanaccount.service.LoanCalculateRepaymentPastDueService;
-import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -153,7 +152,6 @@
         LocalDate loanInstallmentRepaymentDueDate = DateUtils.getBusinessLocalDate().plusDays(1);
 
         Loan loanForProcessing = Mockito.mock(Loan.class);
-        LoanProduct loanProduct = Mockito.mock(LoanProduct.class);
         LoanSummary loanSummary = Mockito.mock(LoanSummary.class);
         MonetaryCurrency loanCurrency = Mockito.mock(MonetaryCurrency.class);
 
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java
index f99f300..f1597f2 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java
@@ -53,7 +53,6 @@
 import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
-import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
 import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequestRepository;
 import org.apache.fineract.useradministration.domain.AppUser;
 import org.apache.http.HttpStatus;
@@ -254,7 +253,6 @@
         given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
         given(fineractProperties.getQuery()).willReturn(fineractQueryProperties);
         given(fineractQueryProperties.getInClauseParameterSizeLimit()).willReturn(65000);
-        LoanRescheduleRequest rescheduleRequest = mock(LoanRescheduleRequest.class);
         given(loanRescheduleRequestRepository.getLoanIdByRescheduleRequestId(resourceId)).willReturn(Optional.of(2L));
         given(context.authenticatedUser()).willReturn(appUser);
 
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionValidatorTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionValidatorTest.java
index a76e2ee..cda6583 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionValidatorTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionValidatorTest.java
@@ -18,10 +18,12 @@
  */
 package org.apache.fineract.infrastructure.security.utils;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.Arrays;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class SQLInjectionValidatorTest {
 
     private static final String[] DDL_COMMANDS = { "create", "drop", "alter", "truncate", "comment", "sleep" };
diff --git a/fineract-provider/src/test/java/org/apache/fineract/investor/event/EnricherTest.java b/fineract-provider/src/test/java/org/apache/fineract/investor/event/EnricherTest.java
index 64a4956..8e11b5e 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/investor/event/EnricherTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/investor/event/EnricherTest.java
@@ -53,16 +53,16 @@
 @ExtendWith(MockitoExtension.class)
 public class EnricherTest {
 
-    private final LocalDate actualDate = LocalDate.now(ZoneId.systemDefault());
+    private static final LocalDate ACTUAL_DATE = LocalDate.now(ZoneId.systemDefault());
 
-    private final String purchasePriceRatio = "100.123";
-    private final String settlementDate = DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.now(ZoneId.systemDefault()));
+    private static final String PURCHASE_PRICE_RATIO = "100.123";
+    private static final String SETTLEMENT_DATE = DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.now(ZoneId.systemDefault()));
 
     @BeforeEach
     public void setUp() {
         ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
         ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
-        ThreadLocalContextUtil.setBusinessDates(new HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, actualDate)));
+        ThreadLocalContextUtil.setBusinessDates(new HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, ACTUAL_DATE)));
 
     }
 
@@ -73,8 +73,8 @@
         doAnswer(a -> {
             LoanAccountDataV1 data = a.getArgument(0, LoanAccountDataV1.class);
             data.setExternalOwnerId("1");
-            data.setSettlementDate(settlementDate);
-            data.setPurchasePriceRatio(purchasePriceRatio);
+            data.setSettlementDate(SETTLEMENT_DATE);
+            data.setPurchasePriceRatio(PURCHASE_PRICE_RATIO);
             return null;
         }).when(loanAccountDataV1Enricher).enrich(any(LoanAccountDataV1.class));
 
@@ -86,8 +86,8 @@
         verify(loanAccountDataV1Enricher, times(1)).enrich(any(LoanAccountDataV1.class));
 
         assertEquals("1", original.getExternalOwnerId());
-        assertEquals(settlementDate, original.getSettlementDate());
-        assertEquals(purchasePriceRatio, original.getPurchasePriceRatio());
+        assertEquals(SETTLEMENT_DATE, original.getSettlementDate());
+        assertEquals(PURCHASE_PRICE_RATIO, original.getPurchasePriceRatio());
     }
 
     @Test
@@ -143,8 +143,8 @@
         doAnswer(a -> {
             LoanAccountDataV1 data = a.getArgument(0, LoanAccountDataV1.class);
             data.setExternalOwnerId("1");
-            data.setSettlementDate(settlementDate);
-            data.setPurchasePriceRatio(purchasePriceRatio);
+            data.setSettlementDate(SETTLEMENT_DATE);
+            data.setPurchasePriceRatio(PURCHASE_PRICE_RATIO);
             return null;
         }).when(loanAccountDataV1Enricher).enrich(any(LoanAccountDataV1.class));
 
@@ -174,8 +174,8 @@
         verify(loanTransactionDataV1Enricher, times(1)).isDataTypeSupported(any());
 
         assertEquals("1", data.getExternalOwnerId());
-        assertEquals(settlementDate, data.getSettlementDate());
-        assertEquals(purchasePriceRatio, data.getPurchasePriceRatio());
+        assertEquals(SETTLEMENT_DATE, data.getSettlementDate());
+        assertEquals(PURCHASE_PRICE_RATIO, data.getPurchasePriceRatio());
 
     }
 
diff --git a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/ReplayedTransactionBusinessEventServiceIntegrationTest.java b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/ReplayedTransactionBusinessEventServiceIntegrationTest.java
index 824f22c..9517041 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/ReplayedTransactionBusinessEventServiceIntegrationTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/ReplayedTransactionBusinessEventServiceIntegrationTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.verify;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.Optional;
 import org.apache.fineract.infrastructure.event.business.domain.loan.LoanAdjustTransactionBusinessEvent;
 import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
@@ -37,6 +38,7 @@
 import org.mockito.junit.jupiter.MockitoExtension;
 
 @ExtendWith(MockitoExtension.class)
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 class ReplayedTransactionBusinessEventServiceIntegrationTest {
 
     @Mock
diff --git a/fineract-war/setenv.sh b/fineract-war/setenv.sh
index 5d69b5a..2d48674 100644
--- a/fineract-war/setenv.sh
+++ b/fineract-war/setenv.sh
@@ -53,3 +53,4 @@
 export FINERACT_DEFAULT_TENANTDB_IDENTIFIER="default"
 export FINERACT_DEFAULT_TENANTDB_NAME="fineract_default"
 export FINERACT_DEFAULT_TENANTDB_DESCRIPTION="Default Demo Tenant"
+export FINERACT_INSECURE_HTTP_CLIENT="true"
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 249e583..7f93135 100644
--- a/gradle/wrapper/gradle-wrapper.jar
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index e411586..eed8d3c 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,7 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+networkTimeout=100000
+validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index a69d9cb..1aa94a4 100755
--- a/gradlew
+++ b/gradlew
@@ -55,7 +55,7 @@
 #       Darwin, MinGW, and NonStop.
 #
 #   (3) This script is generated from the Groovy template
-#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
 #       within the Gradle project.
 #
 #       You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +80,11 @@
     esac
 done
 
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
-
-APP_NAME="Gradle"
+# This is normally unused
+# shellcheck disable=SC2034
 APP_BASE_NAME=${0##*/}
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 MAX_FD=maximum
@@ -133,22 +131,29 @@
     fi
 else
     JAVACMD=java
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+    if ! command -v java >/dev/null 2>&1
+    then
+        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 
 Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
+    fi
 fi
 
 # Increase the maximum file descriptors if we can.
 if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
     case $MAX_FD in #(
       max*)
+        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
         MAX_FD=$( ulimit -H -n ) ||
             warn "Could not query maximum file descriptor limit"
     esac
     case $MAX_FD in  #(
       '' | soft) :;; #(
       *)
+        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
         ulimit -n "$MAX_FD" ||
             warn "Could not set maximum file descriptor limit to $MAX_FD"
     esac
@@ -193,11 +198,15 @@
     done
 fi
 
-# Collect all arguments for the java command;
-#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
-#     shell script including quotes and variable substitutions, so put them in
-#     double quotes to make sure that they get re-expanded; and
-#   * put everything else in single quotes, so that it's not re-expanded.
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
 
 set -- \
         "-Dorg.gradle.appname=$APP_BASE_NAME" \
diff --git a/gradlew.bat b/gradlew.bat
index 53a6b23..6689b85 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -26,6 +26,7 @@
 

 set DIRNAME=%~dp0

 if "%DIRNAME%"=="" set DIRNAME=.

+@rem This is normally unused

 set APP_BASE_NAME=%~n0

 set APP_HOME=%DIRNAME%

 

diff --git a/integration-tests/dependencies.gradle b/integration-tests/dependencies.gradle
index 206bd6a..460d5c3 100644
--- a/integration-tests/dependencies.gradle
+++ b/integration-tests/dependencies.gradle
@@ -20,7 +20,7 @@
     // testCompile dependencies are ONLY used in src/test, not src/main.
     // Do NOT repeat dependencies which are ALREADY in implementation or runtimeOnly!
     //
-    tomcat 'org.apache.tomcat:tomcat:10.1.16@zip'
+    tomcat 'org.apache.tomcat:tomcat:10.1.17@zip'
     testImplementation( files("$rootDir/fineract-provider/build/classes/java/main/"),
             project(path: ':fineract-core', configuration: 'runtimeElements'),
             project(path: ':fineract-investor', configuration: 'runtimeElements'),
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
index b0287e9..3618bd1 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
@@ -28,6 +28,7 @@
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.restassured.builder.RequestSpecBuilder;
 import io.restassured.builder.ResponseSpecBuilder;
 import io.restassured.http.ContentType;
@@ -127,6 +128,7 @@
  */
 @SuppressWarnings({ "rawtypes", "unchecked" })
 @ExtendWith(LoanTestLifecycleExtension.class)
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class ClientLoanIntegrationTest {
 
     static {
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/StaffTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/StaffTest.java
index eb83bd5..cbbb19d 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/StaffTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/StaffTest.java
@@ -19,6 +19,7 @@
 package org.apache.fineract.integrationtests;
 
 import com.google.gson.Gson;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.restassured.builder.RequestSpecBuilder;
 import io.restassured.builder.ResponseSpecBuilder;
 import io.restassured.http.ContentType;
@@ -35,6 +36,7 @@
 import org.junit.jupiter.api.Test;
 
 @Deprecated // TODO move this into new org.apache.fineract.integrationtests.client.StaffTest
+@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
 public class StaffTest {
 
     private RequestSpecification requestSpec;
diff --git a/kubernetes/fineractmysql-deployment.yml b/kubernetes/fineractmysql-deployment.yml
index f4c6709..582e3d2 100644
--- a/kubernetes/fineractmysql-deployment.yml
+++ b/kubernetes/fineractmysql-deployment.yml
@@ -86,7 +86,7 @@
         tier: fineractmysql
     spec:
       containers:
-        - image: mariadb:10.9
+        - image: mariadb:11.2
           name: mysql
           resources:
             requests:
diff --git a/oauth2-tests/dependencies.gradle b/oauth2-tests/dependencies.gradle
index d05ea66..d1041fe 100644
--- a/oauth2-tests/dependencies.gradle
+++ b/oauth2-tests/dependencies.gradle
@@ -20,7 +20,7 @@
     // testCompile dependencies are ONLY used in src/test, not src/main.
     // Do NOT repeat dependencies which are ALREADY in implementation or runtimeOnly!
     //
-    tomcat 'org.apache.tomcat:tomcat:10.1.16@zip'
+    tomcat 'org.apache.tomcat:tomcat:10.1.17@zip'
     testImplementation( files("$rootDir/fineract-provider/build/classes/java/main/"),
             project(path: ':fineract-provider', configuration: 'runtimeElements'),
             'org.junit.jupiter:junit-jupiter-api',
diff --git a/oauth2-tests/src/test/java/org/apache/fineract/oauth2tests/OAuth2AuthenticationTest.java b/oauth2-tests/src/test/java/org/apache/fineract/oauth2tests/OAuth2AuthenticationTest.java
index 52132dc..391ba7e 100644
--- a/oauth2-tests/src/test/java/org/apache/fineract/oauth2tests/OAuth2AuthenticationTest.java
+++ b/oauth2-tests/src/test/java/org/apache/fineract/oauth2tests/OAuth2AuthenticationTest.java
@@ -39,7 +39,6 @@
 public class OAuth2AuthenticationTest {
 
     private ResponseSpecification responseSpec;
-    private ResponseSpecification responseSpec403;
     private ResponseSpecification responseSpec401;
     private RequestSpecification requestSpec;
     private RequestSpecification requestFormSpec;
@@ -61,7 +60,6 @@
         this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
         this.requestFormSpec = new RequestSpecBuilder().setContentType(ContentType.URLENC).build();
         this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
-        this.responseSpec403 = new ResponseSpecBuilder().expectStatusCode(403).build();
         this.responseSpec401 = new ResponseSpecBuilder().expectStatusCode(401).build();
     }
 
diff --git a/settings.gradle b/settings.gradle
index 871f543..c33ea27 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -18,8 +18,8 @@
  */
 
 plugins {
-    id 'com.gradle.enterprise' version '3.15.1'
-    id 'com.gradle.common-custom-user-data-gradle-plugin' version '1.12'
+    id 'com.gradle.enterprise' version '3.16.1'
+    id 'com.gradle.common-custom-user-data-gradle-plugin' version '1.12.1'
 }
 
 def isCI = System.getenv('JENKINS_URL') != null
diff --git a/twofactor-tests/dependencies.gradle b/twofactor-tests/dependencies.gradle
index 9e0a6e1..40c7f68 100644
--- a/twofactor-tests/dependencies.gradle
+++ b/twofactor-tests/dependencies.gradle
@@ -20,7 +20,7 @@
     // testCompile dependencies are ONLY used in src/test, not src/main.
     // Do NOT repeat dependencies which are ALREADY in implementation or runtimeOnly!
     //
-    tomcat 'org.apache.tomcat:tomcat:10.1.16@zip'
+    tomcat 'org.apache.tomcat:tomcat:10.1.17@zip'
     testImplementation( files("$rootDir/fineract-provider/build/classes/java/main/"),
             project(path: ':fineract-provider', configuration: 'runtimeElements'),
             'org.junit.jupiter:junit-jupiter-api',