diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml
index e5b672b..4a4efbd 100644
--- a/.github/workflows/run-tests.yml
+++ b/.github/workflows/run-tests.yml
@@ -22,7 +22,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        php: [7.2, 7.3, 7.4, 8.0, 8.1, '8.2']
+        php: [8.1, 8.2]
 
     name: P${{ matrix.php }}
 
diff --git a/composer.json b/composer.json
index 037244d..c4d4c64 100644
--- a/composer.json
+++ b/composer.json
@@ -16,10 +16,11 @@
         }
     ],
     "require": {
-        "php": "^7.2.5|^8.0",
+        "php": "^8.0",
         "illuminate/support": "^7.0|^8.0|^9.0|^10.0|^11.0|^12.0",
         "illuminate/database": "^7.0|^8.0|^9.0|^10.0|^11.0|^12.0",
-        "illuminate/events": "^7.0|^8.0|^9.0|^10.0|^11.0|^12.0"
+        "illuminate/events": "^7.0|^8.0|^9.0|^10.0|^11.0|^12.0",
+        "laravel/serializable-closure": "^2.0"
     },
     "autoload": {
         "psr-4": {
diff --git a/phpunit.xml b/phpunit.xml
index 10f1f41..fac2e3f 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -3,6 +3,8 @@
   <testsuites>
     <testsuite name="Package Test Suite">
       <directory suffix=".php">./tests/</directory>
+      <exclude>./tests/data</exclude>
+      <exclude>./tests/models</exclude>
     </testsuite>
   </testsuites>
   <source>
diff --git a/src/NodeTrait.php b/src/NodeTrait.php
index c406ed8..9d20e6b 100644
--- a/src/NodeTrait.php
+++ b/src/NodeTrait.php
@@ -671,7 +671,7 @@ public function newEloquentBuilder($query)
      *
      * @return QueryBuilder
      */
-    public function newNestedSetQuery($table = null)
+    public function newNestedSetQuery(?string $table = null)
     {
         $builder = $this->usesSoftDelete()
             ? $this->withTrashed()
@@ -681,22 +681,19 @@ public function newNestedSetQuery($table = null)
     }
 
     /**
-     * @param string $table
-     *
      * @return QueryBuilder
      */
-    public function newScopedQuery($table = null)
+    public function newScopedQuery(?string $table = null)
     {
         return $this->applyNestedSetScope($this->newQuery(), $table);
     }
 
     /**
      * @param mixed $query
-     * @param string $table
      *
      * @return mixed
      */
-    public function applyNestedSetScope($query, $table = null)
+    public function applyNestedSetScope($query, ?string $table = null)
     {
         if ( ! $scoped = $this->getScopeAttributes()) {
             return $query;
@@ -748,10 +745,8 @@ public function newCollection(array $models = array())
      * {@inheritdoc}
      *
      * Use `children` key on `$attributes` to create child nodes.
-     *
-     * @param self $parent
      */
-    public static function create(array $attributes = [], self $parent = null)
+    public static function create(array $attributes = [], ?self $parent = null)
     {
         $children = Arr::pull($attributes, 'children');
 
@@ -1221,11 +1216,9 @@ protected function isSameScope(self $node): bool
     }
 
     /**
-     * @param array|null $except
-     *
      * @return \Illuminate\Database\Eloquent\Model
      */
-    public function replicate(array $except = null)
+    public function replicate(?array $except = null)
     {
         $defaults = [
             $this->getParentIdName(),
diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php
index 10edb27..65bf7fa 100644
--- a/src/QueryBuilder.php
+++ b/src/QueryBuilder.php
@@ -188,7 +188,7 @@ public function ancestorsAndSelf($id, array $columns = [ '*' ])
      *
      * @return $this
      */
-    public function whereNodeBetween($values, $boolean = 'and', $not = false, $query = null)
+    public function whereNodeBetween($values, $boolean = 'and', $not = false, ?Query $query = null)
     {
         ($query ?? $this->query)->whereBetween($this->model->getTable() . '.' . $this->model->getLftName(), $values, $boolean, $not);
 
@@ -861,7 +861,7 @@ public function isBroken()
      *
      * @return int The number of changed nodes
      */
-    public function fixTree($root = null)
+    public function fixTree(?Model $root = null)
     {
         $columns = [
             $this->model->getKeyName(),
@@ -899,7 +899,7 @@ public function fixSubtree($root)
      *
      * @return int
      */
-    protected function fixNodes(array &$dictionary, $parent = null)
+    protected function fixNodes(array &$dictionary, ?Model $parent = null)
     {
         $parentId = $parent ? $parent->getKey() : null;
         $cut = $parent ? $parent->getLft() + 1 : 1;
@@ -941,7 +941,7 @@ protected function fixNodes(array &$dictionary, $parent = null)
      * @internal param int $fixed
      */
     protected static function reorderNodes(
-        array &$dictionary, array &$updated, $parentId = null, $cut = 1
+        array &$dictionary, array &$updated, null|int|string $parentId = null, $cut = 1
     ) {
         if ( ! isset($dictionary[$parentId])) {
             return $cut;
@@ -973,11 +973,11 @@ protected static function reorderNodes(
      * @param array $data
      * @param bool $delete Whether to delete nodes that exists but not in the data
      *                     array
-     * @param null $root
+     * @param ?Model|NodeTrait $root
      *
      * @return int
      */
-    public function rebuildTree(array $data, $delete = false, $root = null)
+    public function rebuildTree(array $data, $delete = false, ?Model $root = null)
     {
         if ($this->model->usesSoftDelete()) {
             $this->withTrashed();
@@ -1084,7 +1084,7 @@ protected function buildRebuildDictionary(array &$dictionary,
      *
      * @return $this
      */
-    public function applyNestedSetScope($table = null)
+    public function applyNestedSetScope(?string $table = null)
     {
         return $this->model->applyNestedSetScope($this, $table);
     }
diff --git a/tests/NodeTest.php b/tests/NodeTest.php
index 3b0831a..c5ef004 100644
--- a/tests/NodeTest.php
+++ b/tests/NodeTest.php
@@ -82,7 +82,7 @@ public function assertTreeNotBroken($table = 'categories')
         $this->assertEquals(array('errors' => null), $actual, "The tree structure of $table is broken!");
     }
 
-    public function dumpTree($items = null)
+    public function dumpTree(?array $items = null)
     {
         if ( ! $items) $items = Category::withTrashed()->defaultOrder()->get();
 
@@ -997,4 +997,4 @@ public function testReplication()
 function all($items)
 {
     return is_array($items) ? $items : $items->all();
-}
\ No newline at end of file
+}