function resource($name, $controllerClass, $options = [])
	{
		if (empty($options['idString'])) {
			$options['idString'] = '{id}'; // == (?P<id>.+?)";
		}		

		// by default, create routes for all known actions
		$actions = array_keys($this->resourceActions);

		if (!empty($options['only'])) {
			$actions = $options['only'];
		
		} else if (!empty($options['except'])) {
			$actions = array_diff($actions, $options['except']);

		}

		if (!is_array($actions)) {
			$actions = [$actions];
		}

		$group = new RouteGroup();

		foreach($actions as $action) {
			// make sure this action is one we know how to process
			if (empty($this->resourceActions[$action])) {
				throw new \Exception("Action [$action] is unrecognized; please use one of: ".implode(',', array_keys($this->resourceActions)));
			}
			// get the action defintion
			$def = $this->resourceActions[$action];
			// invoke Router::route 
			$route = call_user_func_array([ $this, 'route'], [
				// the method is specified by the action definition:
				$def['methods'],
				// the route is a formatted string; drop the idString into it
				$name . sprintf($def['route'], $options['idString']),
				// inside the callback, we create our controller instance and call the proper action
				function() use ($controllerClass, $action) {
					return $this->invokeControllerAction($controllerClass, $action, func_get_args());
				},
				// pass-through options as rest config options
				$options
			]);

			if (!empty($def['args'])) {
				$route->args($def['args']);
			}

			$group[] = $route;
		}

		return $group;
	}