public function checkPermission($user, $ability, $arguments)
	{
		if ($user->role === 'admin') {
			return true;
		}

		// У пользователя роль, которой нет в списке
		$roles = $this->getRoles();
		if (!isset($roles[$user->role])) {
			return null;
		}

		// Ищем разрешение для данной роли среди наследников текущего разрешения
		$role = $roles[$user->role];
		$permissions = $this->getPermissions();
		$current = $ability;
		// Если для разрешения указана замена - элемент 'equal', то проверяется замена
		// (только при наличии оригинального разрешения в роли).
		// Callback оригинального не вызывается.
		if (in_array($current, $role) and isset($permissions[$current]['equal'])) {
			$current = $permissions[$current]['equal'];
		}

		$i = 0;
		$suitable = false;
		while (true) {
			if ($i++ > 100) {
				throw new \Exception("Seems like permission '{$ability}' is in infinite loop");
			}

			if (in_array($current, $role)) {
				$suitable = $suitable || $this->testUsingUserMethod($user, $ability, $current, $arguments);
			}
			if (isset($permissions[$current]['next']) and !$suitable) {
				$current = $permissions[$current]['next'];
			} else {
				return $suitable ? true : null;
			}
		}
		return null;
	}