protected function checkAccessPolicy($access_policy_name, Reference $ref)
	{
		// Allow by default
		if (empty($access_policy_name)) {
			return true;
		}

		if (!isset($this->access_policies[$access_policy_name])) {
			throw new \InvalidArgumentException('Unknown policy: '.$access_policy_name);
		}
		$access_policy = $this->access_policies[$access_policy_name];

		//debug_dump($access_policy, 'POLICY: '.$access_policy_name.' @ '.get_class($this));

		if ($this->auth->isAllMighty()) {
			return true;
		}

		switch ($access_policy['type']) {

			// anyone: Completely open for anyone
			case 'anyone':
				return true;

			// nobody: Nobody is allowed, except all mighty users.
			case 'nobody':
				return false;

			// anonymous: Only anonymous users allowed (not logged in)
			case 'anonymous':
				$user_id = $this->auth->getUserId();
				return $user_id === null;

			// user: All logged-in users allowed
			case 'user':
				$user_id = $this->auth->getUserId();
				return $user_id !== null;

			// owner: Owner must match current user
			case 'owner':
				if ($ref->isNullRef()) {
					// Everyone owns nothing :)
					return true;
				}
				$properties = $ref->properties;
				$user_id = $this->auth->getUserId();
				$owner_property = $access_policy['owner_property'];
				if (isset($access_policy['session_state'])) {
					$session_machine = $this->auth->getSessionMachine();
					if (!$session_machine || $session_machine->state != $access_policy['session_state']) {
						return false;
					}
				}
				return $user_id !== null ? $user_id == $properties[$owner_property] : $properties[$owner_property] === null;

			// role: Current user must have specified role ($ref is ignored)
			case 'role':
				return $this->auth->hasUserRoles($access_policy['required_role']);

			// These are done by SQL select.
			case 'condition':
				if ($ref->isNullRef()) {
					// Nonexistent entity has nulls everywhere
					// FIXME: Are we sure?
					return false;
				}
				$properties = $ref->properties;
				return !empty($properties['_access_policy_'.$access_policy_name]);

			// These are done by SQL select.
			case 'user_relation':
				if ($ref->isNullRef()) {
					// No relation to nonexistent entity.
					return false;
				}
				$properties = $ref->properties;
				return !empty($properties['_access_policy_'.$access_policy_name]);

			// unknown policies are considered unsafe
			default:
				return false;
		}

		// This should not happen.
		throw new \RuntimeException('Policy '.$policy.' did not decide.');
	}