public static function removeExcept($path, $except, $deleteDir = true)
    {
        if (!is_array($except) || !count($except)) {
            throw new \InvalidArgumentException('list of exception is not an array or is empty');
        }

        if ($path == '' || $path == '/' || $path == DIRECTORY_SEPARATOR) {
            throw new \InvalidArgumentException('The root cannot be removed !!');
        }

        if (!file_exists($path)) {
            return true;
        }

        $allIsDeleted = true;
        $dir = new \DirectoryIterator($path);
        foreach ($dir as $dirContent) {
            // test if the basename matches one of patterns
            $exception = false;
            foreach ($except as $pattern) {
                if ($pattern[0] == '*') { // for pattern like *.foo
                    if ($dirContent->getBasename() != $dirContent->getBasename(substr($pattern, 1))) {
                        $allIsDeleted = false;
                        $exception = true;
                        break;
                    }
                } elseif ($pattern == $dirContent->getBasename()) {
                    $allIsDeleted = false;
                    $exception = true;
                    break;
                }
            }
            if ($exception) {
                continue;
            }
            // file deletion
            if ($dirContent->isFile() || $dirContent->isLink()) {
                unlink($dirContent->getPathName());
            } else {
                // recursive directory deletion
                if (!$dirContent->isDot() && $dirContent->isDir()) {
                    $removed = self::removeExcept($dirContent->getPathName(), $except, true);
                    if (!$removed) {
                        $allIsDeleted = false;
                    }
                }
            }
        }
        unset($dir);
        unset($dirContent);

        // removes the parent directory
        if ($deleteDir && $allIsDeleted) {
            rmdir($path);
        }

        return $allIsDeleted;
    }