public function resolve($uri, $version, $resource, array $paramDefs, array $paramValues)
    {
        foreach ($paramValues as $param => $value) {
            if (!array_key_exists($param, $paramDefs)) {
                throw new \InvalidArgumentException("Unknown uri parameter \"$param\" provided");
            }
        }

        foreach ($paramDefs as $key => $def) {
            if (!isset($paramValues[$key])) {
                if (isset($def['default'])) {
                    $paramValues[$key] = is_callable($def['default'])
                        ? $def['default']($paramValues)
                        : $def['default'];
                } elseif (empty($def['required'])) {
                    continue;
                } else {
                    $this->throwRequired($paramDefs, $paramValues);
                }
            }

            $this->checkType($def['valid'], $key, $paramValues[$key]);

            if (isset($def['fn'])) {
                $def['fn']($paramValues[$key], $paramValues);
            }
        }

        return (
            "$uri/".
            "$version/".
            $this->fillPathParams($resource, $paramValues).
            $this->buildQueryParameters($paramValues)
        );
    }