private function filesWithFullPaths($dir, $include_hidden = true, $recursive = false)
    {
        $dir = $this->withSlash($dir);

        $result = [];

        if ($dirstream = opendir($dir)) {
            while (false !== ($filename = readdir($dirstream))) {
                $path = $dir . $filename;

                if ($filename != '.' && $filename != '..') {
                    if (is_dir($path)) {
                        if ($recursive) {
                            $files_from_subdir = $this->filesWithFullPaths($path, $recursive);

                            if (is_array($files_from_subdir)) {
                                $result = array_merge($result, $files_from_subdir);
                            }
                        }
                    } else {
                        if (is_file($path) || (is_link($path) && is_file(readlink($path)))) {
                            if (mb_substr($filename, 0, 1) == '.' && !$include_hidden) {
                                continue;
                            }

                            $result[] = $path;
                        }
                    }
                }
            }
        }

        closedir($dirstream);

        return $result;
    }