private function purgeRecurse($dir)
    {
        $base = $dir . '/';
        $time = time();
        if (substr($dir, 0, strlen($this->dir)) !== $this->dir) {
            // uh oh, we somehow tried to escape from the cache directory
            assert(0);
            return;
        }
        foreach (scandir($dir) as $f) {
            $fn = $base . $f;

            if ($f[0] === '.') {
                continue;
            }

            if (is_dir($fn)) {
                $this->purgeRecurse($fn);
            } else {
                $update = filemtime($fn);
                if ($time - $update > $this->timeout) {
                    unlink($fn);
                }
            }
        }
    }