public static function process(Request $request)
    {
        $uri = "/" . trim($request->pathInfo(), '/');

        // Check if this is root page
        if (isset(static::$routes['root']) and $request->pathInfo() == '/') {
            return static::setRoute(static::$routes['root']);
        }

        // The fun begins
        foreach (static::$routes as $route) {
            // Replace tokens
            $route->route = str_replace(array_keys(static::$tokens), array_values(static::$tokens), $route->route);

            // Does the route match the request?
            $pattern = "#^{$route->route}" . '(?<extension>' . implode('|', static::$extensions) . ")?$#";
            if (preg_match($pattern, $uri, $params)) {
                unset($params[0]);
                $route->params = array_merge($route->params, $params);
                $route->destination = preg_replace($pattern, $route->destination, $uri);

                // Merge params with defaults
                $route->params = array_merge($route->defaults, $route->params);

                if (in_array(strtolower($request->method()), $route->method)) {
                    return static::setRoute($route);
                }
            }
        }

        // No matches, try 404 route
        if (isset(static::$routes['404'])) {
            return static::set404();
        }
        // No 404 route, Exception time! FUN :D
        else {
            throw new Exception("No routes found for '{$uri}'");
        }
    }