public function rename($name = '', $append = '', $prepend = '', $overwrite = false) {
        if (is_callable($name)) {
            $name = call_user_func_array($name, array($this->name(), $this));
        } else {
            $name = $name ?: $this->name();
        }

        // Add boundaries
        $name = (string) $prepend . $name . (string) $append;

        // Remove unwanted characters
        $name = preg_replace('/[^_\-\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/imu', '-', $name);

        // Rename file
        $ext = $this->ext() ?: MimeType::getExtFromType($this->type(), true);
        $newName = $name;

        // Don't overwrite
        if (!$overwrite) {
            $no = 1;

            while (file_exists($this->dir() . $newName . '.' . $ext)) {
                $newName = $name . '-' . $no;
                $no++;
            }
        }

        $targetPath = $this->dir() . $newName . '.' . $ext;

        if (rename($this->path(), $targetPath)) {
            $this->reset($targetPath);

            return true;
        }

        return false;
    }