@Override
  public List<AclReaders> getAclsReaders(List<Long> aclIds) {
    if (enabled) {
      // We don't want the caches to lie and we may not be part of the cluster
      aclDAO.setCheckAclConsistency();

      /*
       * This is an N+1 query that should, in theory, make use of cached ACL readers data.
       */

      Map<Long, String> aclChangeSetTenant = new HashMap<Long, String>(aclIds.size());

      List<AclReaders> aclsReaders = new ArrayList<AclReaders>(aclIds.size() * 10);
      for (Long aclId : aclIds) {
        AclReaders readers = new AclReaders();
        readers.setAclId(aclId);
        Set<String> readersSet = permissionService.getReaders(aclId);
        readers.setReaders(readersSet);
        Set<String> deniedSet = permissionService.getReadersDenied(aclId);
        readers.setDenied(deniedSet);

        Long aclChangeSetId =
            aclDAO.getAccessControlList(aclId).getProperties().getAclChangeSetId();
        readers.setAclChangeSetId(aclChangeSetId);

        if (AuthenticationUtil.isMtEnabled()) {
          // MT - for now, derive the tenant for acl (via acl change set)
          String tenantDomain = aclChangeSetTenant.get(aclChangeSetId);
          if (tenantDomain == null) {
            tenantDomain = getTenant(aclId, aclChangeSetId);
            if (tenantDomain == null) {
              // skip this acl !
              continue;
            }
            aclChangeSetTenant.put(aclChangeSetId, tenantDomain);
          }
          readers.setTenantDomain(tenantDomain);
        }

        aclsReaders.add(readers);
      }

      return aclsReaders;
    } else {
      return Collections.<AclReaders>emptyList();
    }
  }