public function scandir(string $dir, array $options = [])
    {
        $options = array_replace(
            [
                'sort'          => SCANDIR_SORT_NONE,
                'context'       => null,
                'recursive'     => false,
                'skipDots'      => true,
                'skipSymlinks'  => false
            ],
            $options
        );

        if (!$options['skipSymlinks'] && is_link($dir)) {
            $dir = @readlink($dir);
        }

        $args = [
            $dir,
            $options['sort']
        ];

        if ($options['context']) {
            $args[] = $options['context'];
        }

        if (($tmp = @scandir(...$args)) === false) {
            throw IOException::create(
                'Couldn\'t scan directory "'.$dir.'". Last PHP Error: '.
                print_r($this->getLastPhpError(), true)
            );
        }

        if ($options['skipDots']) {
            $tmp = array_diff($tmp, array('.', '..'));
        }

        $result = [];

        foreach ($tmp as $f) {
            $f = $dir.'/'.$f;

            if ($options['skipSymlinks'] && is_link($f)) {
                continue;
            }

            $result[] = $f;

            if ($options['recursive'] && is_dir($f)) {
                $result = array_merge(
                    $result,
                    $this->scandir($f, $options)
                );
            }
        }

        $tmp = null;

        return array_unique($result);
    }