diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d56b4bc1d9bb08f650c32d05a24f4408a3caefd8..13fe2e05641daccb4e81674411f6e8b1513d6c05 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -73,15 +73,21 @@ jobs:
         uses: "shivammathur/setup-php@v2"
         with:
           php-version: "${{ matrix.php-version }}"
-          coverage: "pcov"
+          coverage: "xdebug"
 
       - name: "Install dependencies with Composer"
         run: "./tools/composer update --no-ansi --no-interaction --no-progress"
 
       - name: "Run tests with PHPUnit"
-        run: "vendor/bin/phpunit --coverage-clover=coverage.xml"
+        run: "vendor/bin/phpunit --log-junit junit.xml --coverage-clover=coverage.xml"
 
-      - name: "Send code coverage report to Codecov.io"
-        env:
-          CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"
-        run: "bash <(curl -s https://codecov.io/bash) || true"
+      - name: Upload test results to Codecov.io
+        if: ${{ !cancelled() }}
+        uses: codecov/test-results-action@v1
+        with:
+          token: ${{ secrets.CODECOV_TOKEN }}
+
+      - name: Upload code coverage data to Codecov.io
+        uses: codecov/codecov-action@v4
+        with:
+          token: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.phive/phars.xml b/.phive/phars.xml
index 4817da71b394359dd9a4e623de1ab849dab53d4c..0ff594ab4db6bcc5dd79e31792b46a70d962823f 100644
--- a/.phive/phars.xml
+++ b/.phive/phars.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <phive xmlns="https://phar.io/phive">
-  <phar name="php-cs-fixer" version="^3.59" installed="3.59.3" location="./tools/php-cs-fixer" copy="true"/>
-  <phar name="composer" version="^2.7" installed="2.7.7" location="./tools/composer" copy="true"/>
-  <phar name="phpstan" version="^1.11" installed="1.11.5" location="./tools/phpstan" copy="true"/>
+  <phar name="php-cs-fixer" version="^3.59" installed="3.63.1" location="./tools/php-cs-fixer" copy="true"/>
+  <phar name="composer" version="^2.7" installed="2.7.8" location="./tools/composer" copy="true"/>
+  <phar name="phpstan" version="^1.11" installed="1.11.11" location="./tools/phpstan" copy="true"/>
 </phive>
diff --git a/ChangeLog.md b/ChangeLog.md
index 970f762489ce21a793cc43d106a58cda79c077b4..bc3d8707044bb93098ad4b384da44aa62f32be32 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -2,6 +2,12 @@
 
 All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
 
+## [5.1.0] - 2024-08-27
+
+### Added
+
+* [#83](https://github.com/sebastianbergmann/php-file-iterator/pull/83): Support for "Globstar" pattern
+
 ## [5.0.1] - 2024-07-03
 
 ### Changed
@@ -162,6 +168,7 @@ No changes
 
 * [#23](https://github.com/sebastianbergmann/php-file-iterator/pull/23): Added support for wildcards (glob) in exclude
 
+[5.1.0]: https://github.com/sebastianbergmann/php-file-iterator/compare/5.0.1...5.1.0
 [5.0.1]: https://github.com/sebastianbergmann/php-file-iterator/compare/5.0.0...5.0.1
 [5.0.0]: https://github.com/sebastianbergmann/php-file-iterator/compare/4.1...5.0.0
 [4.1.0]: https://github.com/sebastianbergmann/php-file-iterator/compare/4.0.2...4.1.0
diff --git a/README.md b/README.md
index f012ba73581ec2e52baf22d12c7f44aec1f8abf0..5bc7da65d8950af6a13be4f59bda71c95707cd5f 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Latest Stable Version](https://poser.pugx.org/phpunit/php-file-iterator/v/stable.png)](https://packagist.org/packages/phpunit/php-file-iterator)
+[![Latest Stable Version](https://poser.pugx.org/phpunit/php-file-iterator/v)](https://packagist.org/packages/phpunit/php-file-iterator)
 [![CI Status](https://github.com/sebastianbergmann/php-file-iterator/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/php-file-iterator/actions)
 [![Type Coverage](https://shepherd.dev/github/sebastianbergmann/php-file-iterator/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/php-file-iterator)
 [![codecov](https://codecov.io/gh/sebastianbergmann/php-file-iterator/branch/main/graph/badge.svg)](https://codecov.io/gh/sebastianbergmann/php-file-iterator)
diff --git a/src/Factory.php b/src/Factory.php
index a2ebce6c184f7f4c2aa9e5e3c614f95ab18f68f3..1b5012891ef99f0c2a4cc55690e91ccf10c1c4c5 100644
--- a/src/Factory.php
+++ b/src/Factory.php
@@ -13,11 +13,15 @@ use const GLOB_ONLYDIR;
 use function array_filter;
 use function array_map;
 use function array_merge;
+use function array_unique;
 use function array_values;
 use function glob;
 use function is_dir;
 use function is_string;
 use function realpath;
+use function sort;
+use function stripos;
+use function substr;
 use AppendIterator;
 use FilesystemIterator;
 use RecursiveDirectoryIterator;
@@ -92,7 +96,7 @@ final class Factory
         $_paths = [[]];
 
         foreach ($paths as $path) {
-            if ($locals = glob($path, GLOB_ONLYDIR)) {
+            if ($locals = $this->globstar($path)) {
                 $_paths[] = array_map('\realpath', $locals);
             } else {
                 // @codeCoverageIgnoreStart
@@ -103,4 +107,48 @@ final class Factory
 
         return array_values(array_filter(array_merge(...$_paths)));
     }
+
+    /**
+     * @see https://gist.github.com/funkjedi/3feee27d873ae2297b8e2370a7082aad
+     *
+     * @return list<string>
+     */
+    private function globstar(string $pattern)
+    {
+        if (stripos($pattern, '**') === false) {
+            $files = glob($pattern, GLOB_ONLYDIR);
+        } else {
+            $position    = stripos($pattern, '**');
+            $rootPattern = substr($pattern, 0, $position - 1);
+            $restPattern = substr($pattern, $position + 2);
+
+            $patterns = [$rootPattern . $restPattern];
+            $rootPattern .= '/*';
+
+            while ($dirs = glob($rootPattern, GLOB_ONLYDIR)) {
+                $rootPattern .= '/*';
+
+                foreach ($dirs as $dir) {
+                    $patterns[] = $dir . $restPattern;
+                }
+            }
+
+            $files = [];
+
+            foreach ($patterns as $pat) {
+                $files = array_merge($files, $this->globstar($pat));
+            }
+        }
+
+        if ($files !== false) {
+            $files = array_unique($files);
+            sort($files);
+
+            return $files;
+        }
+
+        // @codeCoverageIgnoreStart
+        return [];
+        // @codeCoverageIgnoreEnd
+    }
 }
diff --git a/tests/fixture/a/c/d/i/PrefixSuffix.php b/tests/fixture/a/c/d/i/PrefixSuffix.php
new file mode 100644
index 0000000000000000000000000000000000000000..e42bdc2f2ca75b1277b7872c7b16ad6ea56ffd7b
--- /dev/null
+++ b/tests/fixture/a/c/d/i/PrefixSuffix.php
@@ -0,0 +1,9 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of phpunit/php-file-iterator.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
diff --git a/tests/fixture/b/e/g/i/PrefixSuffix.php b/tests/fixture/b/e/g/i/PrefixSuffix.php
new file mode 100644
index 0000000000000000000000000000000000000000..e42bdc2f2ca75b1277b7872c7b16ad6ea56ffd7b
--- /dev/null
+++ b/tests/fixture/b/e/g/i/PrefixSuffix.php
@@ -0,0 +1,9 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of phpunit/php-file-iterator.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
diff --git a/tests/fixture/b/e/i/PrefixSuffix.php b/tests/fixture/b/e/i/PrefixSuffix.php
new file mode 100644
index 0000000000000000000000000000000000000000..e42bdc2f2ca75b1277b7872c7b16ad6ea56ffd7b
--- /dev/null
+++ b/tests/fixture/b/e/i/PrefixSuffix.php
@@ -0,0 +1,9 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of phpunit/php-file-iterator.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
diff --git a/tests/fixture/b/f/h/i/PrefixSuffix.php b/tests/fixture/b/f/h/i/PrefixSuffix.php
new file mode 100644
index 0000000000000000000000000000000000000000..e42bdc2f2ca75b1277b7872c7b16ad6ea56ffd7b
--- /dev/null
+++ b/tests/fixture/b/f/h/i/PrefixSuffix.php
@@ -0,0 +1,9 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of phpunit/php-file-iterator.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
diff --git a/tests/unit/FacadeTest.php b/tests/unit/FacadeTest.php
index 3200790702ef77a884fcde09daa994fd456b51ea..722194e731c7b95163ee5c24ae007d04a69eab02 100644
--- a/tests/unit/FacadeTest.php
+++ b/tests/unit/FacadeTest.php
@@ -41,11 +41,15 @@ final class FacadeTest extends TestCase
                     $fixtureDirectoryRealpath . '/a/c/d/Prefix.php',
                     $fixtureDirectoryRealpath . '/a/c/d/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/a/c/d/Suffix.php',
+                    $fixtureDirectoryRealpath . '/a/c/d/i/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/e/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/e/g/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/e/g/i/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/e/i/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/f/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/f/h/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/f/h/i/PrefixSuffix.php',
                 ],
                 __DIR__ . '/../fixture',
                 '',
@@ -59,6 +63,8 @@ final class FacadeTest extends TestCase
                     $fixtureDirectoryRealpath . '/b/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/e/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/e/g/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/e/g/i/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/e/i/PrefixSuffix.php',
                 ],
                 __DIR__ . '/../fixture',
                 '',
@@ -76,11 +82,15 @@ final class FacadeTest extends TestCase
                     $fixtureDirectoryRealpath . '/a/c/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/a/c/d/Prefix.php',
                     $fixtureDirectoryRealpath . '/a/c/d/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/a/c/d/i/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/e/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/e/g/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/e/g/i/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/e/i/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/f/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/f/h/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/f/h/i/PrefixSuffix.php',
                 ],
                 __DIR__ . '/../fixture',
                 '',
@@ -95,11 +105,15 @@ final class FacadeTest extends TestCase
                     $fixtureDirectoryRealpath . '/a/c/Suffix.php',
                     $fixtureDirectoryRealpath . '/a/c/d/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/a/c/d/Suffix.php',
+                    $fixtureDirectoryRealpath . '/a/c/d/i/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/e/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/e/g/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/e/g/i/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/e/i/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/f/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/b/f/h/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/f/h/i/PrefixSuffix.php',
                 ],
                 __DIR__ . '/../fixture',
                 'Suffix.php',
@@ -115,12 +129,33 @@ final class FacadeTest extends TestCase
                     $fixtureDirectoryRealpath . '/a/c/d/Prefix.php',
                     $fixtureDirectoryRealpath . '/a/c/d/PrefixSuffix.php',
                     $fixtureDirectoryRealpath . '/a/c/d/Suffix.php',
+                    $fixtureDirectoryRealpath . '/a/c/d/i/PrefixSuffix.php',
                 ],
                 __DIR__ . '/../fixture/*/c',
                 '',
                 '',
                 [],
             ],
+            'globstar, filter prefix: no, filter suffix: no, excludes: none' => [
+                [
+
+                    $fixtureDirectoryRealpath . '/a/c/d/i/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/e/g/i/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/e/i/PrefixSuffix.php',
+                    $fixtureDirectoryRealpath . '/b/f/h/i/PrefixSuffix.php',
+                ],
+                __DIR__ . '/../fixture/**/i',
+                '',
+                '',
+                [],
+            ],
+            'invalid path, filter prefix: no, filter suffix: no, excludes: none' => [
+                [],
+                __DIR__ . '/../fixture/**/this/path/does/not/exists',
+                '',
+                '',
+                [],
+            ],
         ];
     }