public function scan() : ModularCollection
    {
        if ($this->hasScanned) {
            return $this;
        }

        /**
         * @var SplFileInfo $path
         */
        foreach (new RecursiveDirectoryIterator($this->getModularDirectory()) as $path) {
            $baseName = $path->getBaseName();
            // skip dotted
            if ($baseName == '.' || $baseName == '..') {
                continue;
            }

            $directory = $this->getModularDirectory() . DIRECTORY_SEPARATOR . $baseName;
            // don't allow symlink to be execute & skip if contains file
            if ($path->isLink() || ! $path->isDir()) {
                $this->unwantedPath[$baseName] = $path->getType();
                continue;
            }

            $file = $directory . DIRECTORY_SEPARATOR . $baseName .'.php';
            if (! file_exists($file)) {
                $this->invalidModular[$baseName] = new ModularNotFoundException(
                    $file,
                    sprintf(
                        '%1$s file for %2$s has not found',
                        $this->modularParser->getName(),
                        $baseName
                    )
                );

                continue;
            }

            try {
                $modular = $this
                    ->modularParser
                    ->create($file)
                    ->process();
                if (! $modular->isValid()) {
                    throw new InvalidModularException(
                        sprintf(
                            '%1$s Is not valid.',
                            $this->modularParser->getName()
                        )
                    );
                }

                $this->validModular[$this->sanitizeModularName($baseName)] = [
                    static::CLASS_NAME_KEY => $modular->getClassName(),
                    static::FILE_PATH_KEY => $modular->getFile(),
                ];
            } catch (\Exception $e) {
                $this->invalidModular[$this->sanitizeModularName($baseName)] = $e;
            }
        }

        return $this;
    }