public static function getFile($tree, $request)
    {
        $request = explode('/', $request);
        foreach ($request as $node) {
            // If the element we're in currently is not a
            // directory, we failed to find the requested file
            if (!$tree instanceof Directory) {
                return false;
            }

            // Some relative paths may start with ./
            if ($node == '.') {
                continue;
            }

            if ($node == '..') {
                $tree = $tree->getParent();
                continue;
            }

            $node = urldecode($node);

            // if the node exists in the current request tree,
            // change the $tree variable to reference the new
            // node and proceed to the next url part
            if (isset($tree->getEntries()[$node])) {
                $tree = $tree->getEntries()[$node];
                continue;
            }

            // if the node doesn't exist, we can try
            // two variants of the requested file:
            // with and w/o the .html extension
            foreach (static::getFilenames($tree->getConfig(), $node) as $filename) {
                if (isset($tree->getEntries()[$filename])) {
                    $tree = $tree->getEntries()[$filename];
                    continue 2;
                }
            }

            // At this stage, we're in a directory, but no
            // sub-item matches, so the current node must
            // be an index page or we failed
            if ($node !== 'index' && $node !== 'index.html') {
                return false;
            }

            return $tree->getIndexPage();
        }

        // If the entry we found is not a directory, we're done
        if (!$tree instanceof Directory) {
            return $tree;
        }

        if ($index = $tree->getIndexPage()) {
            return $index;
        }

        return false;
    }