public function exec()
    {
        $this->setup();

        // get the annotation metadata for this resource
        $resourceMetadata = $this->app->getResourceMetadata($this);

        $methodPriorities = $this->calculateMethodPriorities($resourceMetadata);

        $methodName = null;
        $bestMatch = -2;
        foreach ($methodPriorities as $name => $priority) {
            if ($priority['value'] > $bestMatch) {
                $bestMatch = $priority['value'];
                $methodName = $name;
            }
        }

        if (!$methodName) {
            throw new Exception('No method matches request method');

        } elseif (isset($methodPriorities[$methodName]['response'])) {
            $response = Response::create($methodPriorities[$methodName]['response']);

        } elseif (isset($methodPriorities[$methodName]['exception'])) {
            throw $methodPriorities[$methodName]['exception'];

        } else {
            foreach (array('*', $methodName) as $mn) {
                if (isset($this->before[$mn])) {
                    foreach ($this->before[$mn] as $action) {
                        call_user_func($action, $this->request, $mn);
                    }
                }
            }
            $response = Response::create(call_user_func_array(array($this, $methodName), $this->params));
            foreach (array('*', $methodName) as $mn) {
                if (isset($this->after[$mn])) {
                    foreach ($this->after[$mn] as $action) {
                        call_user_func($action, $response, $mn);
                    }
                }
            }
        }

        return $response;
    }