public static function findClassesPsr4($namespace, $recursively = false, $withoutAutoload = false) {
        $classNames = [];
        if(is_array($namespace)) {
            foreach ($namespace as $ns) {
                $classNames = ArrayHelper::merge($classNames, static::findClassesPsr4($ns, $recursively, $withoutAutoload));
            }
            return $classNames;
        }
        $namespace = trim($namespace, static::CS);
        list($nsPrefix, $namespacePaths) = static::getNamespacePaths($namespace);
        if (empty($namespacePaths)) {
            return [];
        }
        $files = [];
        $regEx = '/\.php$/';
        for ($i = 0; $i < count($namespacePaths); $i++) {
            $dir = $namespacePaths[$i];
            $dirIt = new \RecursiveDirectoryIterator($dir);
            $files = [];
            if($recursively) {
                foreach(new \RecursiveIteratorIterator($dirIt) as $file)
                {
                    $fileStr = (string)$file;
                    if (!preg_match($regEx, $fileStr)) {
                        continue;
                    }
                    $fileStr = substr($fileStr, strlen($dir) + 1, -4);
                    $files[] = $fileStr;
                }
            } else {
                $_files = glob($dir . static::DS . '*.php');
                for ($j = 0; $j < count($_files); $j++) {
                    $fileStr = $_files[$j];
                    $fileStr = substr($fileStr, strlen($dir) + 1, -4);
                    $files[] = $fileStr;
                }
            }
        }

        for ($i = 0; $i < count($files); $i++) {
            $fileStr = $files[$i];
            $className = $namespace . static::CS . str_replace(static::DS, static::CS, $fileStr);
            if ($withoutAutoload || class_exists($className, true)) {
                $classNames[] = $className;
            }
        }
        return $classNames;
    }