class SecurityCatalogService {

    public boolean checkUserPermissions(String objectNamespace, Long objectId, Long userId, EnumSet<Permission> required) {
        User user = getUser(userId);
        if (user == null) {
            return false;
        }
        EnumSet<Permission> remaining = EnumSet.copyOf(required);
        // try direct user acl entry first
        List<QueryParam> qps = QueryParam.params(
                AclEntry.OBJECT_NAMESPACE, objectNamespace,
                AclEntry.OBJECT_ID, String.valueOf(objectId),
                AclEntry.SID_TYPE, USER.toString(),
                AclEntry.SID_ID, String.valueOf(userId));
        Collection<AclEntry> acls = listAcls(qps);
        if (acls.size() > 1) {
            throw new IllegalStateException("More than one ACL entry for " + qps);
        } else if (acls.size() == 1) {
            AclEntry aclEntry = acls.iterator().next();
            remaining.removeAll(aclEntry.getPermissions());
        }
        // try role based permissions next
        if (!remaining.isEmpty() && user.getRoles() != null) {
            qps = QueryParam.params(
                    AclEntry.OBJECT_NAMESPACE, objectNamespace,
                    AclEntry.OBJECT_ID, String.valueOf(objectId),
                    AclEntry.SID_TYPE, AclEntry.SidType.ROLE.toString());
            acls = listAcls(qps);
            Set<Role> userRoles = getAllUserRoles(user);
            Iterator<AclEntry> it = acls.iterator();
            while (!remaining.isEmpty() && it.hasNext()) {
                AclEntry roleEntry = it.next();
                if (userRoles.contains(getRole(roleEntry.getSidId()))) {
                    remaining.removeAll(roleEntry.getPermissions());
                }
            }
        }
        return remaining.isEmpty();
    }

    public  SecurityCatalogService(StorageManager storageManager);

}