public function matches(Request $request, Application $app) {
        if (!$this->matchesMethods($request)) {
            return null;
        }

        if ($this->getMatchFullPath()) {
            $path = $request->getFullPath();
        } else {
            $path = $request->getPath();
        }

        // If this route is off of a root then check that first.
        if ($root = $this->pattern()) {
            if (stripos($path, $root) === 0) {
                // Strip the root off the path that we are examining.
                $path = substr($path, strlen($root));
            } else {
                return null;
            }
        }

        $pathParts = explode('/', trim($path, '/'));

        $controller = array_shift($pathParts);
        if (!$controller) {
            return null;
        }

        // Check to see if a class exists with the desired controller name.
        // If a controller is found then it is responsible for the route, regardless of any other parameters.
        $basename = sprintf($this->controllerPattern, ucfirst($controller));
        if (class_exists('\Garden\Addons', false)) {
            list($classname) = Addons::classMap($basename);

            // TODO: Optimize this second check.
            if (!$classname && class_exists($basename)) {
                $classname = $basename;
            }
        } elseif (class_exists($basename)) {
            $classname = $basename;
        } else {
            $classname = '';
        }

        if (!$classname) {
            return null;
        }

        $result = array(
            'controller' => $classname,
            'method' => $request->getMethod(),
            'path' => $path,
            'pathArgs' => $pathParts,
            'query' => $request->getQuery()
        );
        return $result;
    }