public function scan(array $directories) : ScannedFilesCollection
    {
        // filter out non existing dirs, because they break the symfony finder.
        $validDirectories = Psi::it($directories)
            ->filter(function ($dir) {
                return is_dir($dir);
            })
            ->toArray();

        $finder = new Finder();
        $finder->in($validDirectories)->files()->sortByName();

        /** @var string[] $filesAlreadyFound */
        $filesAlreadyFound = [];

        $files = Psi::it($finder)
            // type check
            ->filter(new IsInstanceOf(SplFileInfo::class))
            // ignore files that want to be ignored explicitly
            ->filter(function (SplFileInfo $f) {
                return strpos($f->getContents(), Scanner::PREVENT_FROM_SCAN) === false;
            })
            // ignore files we have already seen
            ->filter(function (SplFileInfo $f) use (&$filesAlreadyFound) {
                // is this a new file ?
                if (false === isset($filesAlreadyFound[$f->getRealPath()])) {
                    $filesAlreadyFound[$f->getRealPath()] = 1; // remember it

                    return true;
                }

                return false; // we have already seen it
            })
            // try to get the fqcn from the file
            ->map(function (SplFileInfo $f) {

                $realPath  = $f->getRealPath();
                $filemtime = filemtime($realPath);
                $cacheKey  = '[Aviator][Scanner]@' . $realPath;
                // We do some caching here. So we can avoid tokenizing files that where not changed.
                $cacheEntry = $this->cache->fetch($cacheKey);

                if ($cacheEntry instanceof ScannedFile && $cacheEntry->getFilemtime() >= $filemtime) {
                    return $cacheEntry;
                }

                if ($f->getExtension() === 'php' && $fqcn = Util::getFqcnFromPhpCode($f->getContents())) {
                    $result = new ScannedPhpClass($filemtime, $realPath, $fqcn);
                } else {
                    $result = new ScannedFile($filemtime, $realPath);
                }

                $this->cache->save($cacheKey, $result);

                return $result;
            })
            ->toArray();

        $this->logger->info('Scanning done. Scanned ' . count($filesAlreadyFound) . ' files');

        return new ScannedFilesCollection($files);
    }
public function scan(array $directories) : ScannedFilesCollection
    {
        // filter out non existing dirs, because they break the symfony finder.
        $validDirectories = Psi::it($directories)
            ->filter(function ($dir) {
                return is_dir($dir);
            })
            ->toArray();

        $finder = new Finder();
        $finder->in($validDirectories)->files()->sortByName();

        /** @var string[] $filesAlreadyFound */
        $filesAlreadyFound = [];

        $files = Psi::it($finder)
            // type check
            ->filter(new IsInstanceOf(SplFileInfo::class))
            // ignore files that want to be ignored explicitly
            ->filter(function (SplFileInfo $f) {
                return strpos($f->getContents(), Scanner::PREVENT_FROM_SCAN) === false;
            })
            // ignore files we have already seen
            ->filter(function (SplFileInfo $f) use (&$filesAlreadyFound) {
                // is this a new file ?
                if (false === isset($filesAlreadyFound[$f->getRealPath()])) {
                    $filesAlreadyFound[$f->getRealPath()] = 1; // remember it

                    return true;
                }

                return false; // we have already seen it
            })
            // try to get the fqcn from the file
            ->map(function (SplFileInfo $f) {

                $realPath  = $f->getRealPath();
                $filemtime = filemtime($realPath);
                $cacheKey  = '[Aviator][Scanner]@' . $realPath;
                // We do some caching here. So we can avoid tokenizing files that where not changed.
                $cacheEntry = $this->cache->fetch($cacheKey);

                if ($cacheEntry instanceof ScannedFile && $cacheEntry->getFilemtime() >= $filemtime) {
                    return $cacheEntry;
                }

                if ($f->getExtension() === 'php' && $fqcn = Util::getFqcnFromPhpCode($f->getContents())) {
                    $result = new ScannedPhpClass($filemtime, $realPath, $fqcn);
                } else {
                    $result = new ScannedFile($filemtime, $realPath);
                }

                $this->cache->save($cacheKey, $result);

                return $result;
            })
            ->toArray();

        $this->logger->info('Scanning done. Scanned ' . count($filesAlreadyFound) . ' files');

        return new ScannedFilesCollection($files);
    }
@param array $directories

@return ScannedFilesCollection