async expandFromRoles () {
    if (this.#allRoles !== undefined) { return; }
    const allRoles = new Set();

    // The roles we need to process to see if any subroles
    const rolesQ = [...this.roles ?? []];

    if (this.expression && this.expression.trim().length > 0) {
      this.#allExpression = '(' + this.expression.trim() + ')';
    }

    this.#allTimeLimit = this.timeLimit;

    while (rolesQ.length) {
      const r = rolesQ.pop();

      // Deal with system roles first, they are easy
      if (systemRolesMapping[r]) {
        allRoles.add(r);
        systemRolesMapping[r].forEach(allRoles.add, allRoles);
        continue;
      }

      // Already processed
      if (allRoles.has(r)) { continue; }

      // See if role actually exists
      const role = await User.getUserCache(r);
      if (!role || !role.enabled) { continue; }
      allRoles.add(r);

      if (role.expression && role.expression.trim().length > 0) {
        if (!this.#allExpression) {
          this.#allExpression = '(' + role.expression.trim() + ')';
        } else {
          this.#allExpression += ' && (' + role.expression.trim() + ')';
        }
      }

      if (role.timeLimit !== undefined) {
        if (this.#allTimeLimit === undefined) {
          this.#allTimeLimit = role.timeLimit;
        } else {
          this.#allTimeLimit = Math.min(this.timeLimit, role.timeLimit);
        }
      }

      // schedule any sub roles
      if (!role.roles) { continue; }
      role.roles.forEach(r2 => {
        if (allRoles.has(r2)) { return; } // Already processed
        rolesQ.push(r2);
      });
    }

    this.#allRoles = allRoles;
  }
Create the combined variables from ourselves and enabled roles we use.