class SecurityService {

    public Boolean hasUserPermissionToObject(final User user, final PermissionName permissionName, final SecurableModel securableModel) {
        if (user == null) {
            throw new IllegalArgumentException("User can not be null.");
        }
        if (permissionName == null) {
            throw new IllegalArgumentException("Permission Name can not be null.");
        }
        if (securableModel == null) {
            throw new IllegalArgumentException("SecurableModel can not be null.");
        }

        if (hasUserPermissionToClass(user, permissionName, securableModel.getClass().getCanonicalName())) {
            return true;
        }

        final List<Long> userRoleIds = new ArrayList<>();
        for (Role role : user.getRoles()) {
            userRoleIds.add(role.getId());
        }
        final List<AclEntry> rolesAclEntries = aclEntryService.findAll(permissionName, AclSidType.ROLE, userRoleIds, AclClassName.getByName(securableModel.getClass().getCanonicalName()), securableModel.getId());

        if (rolesAclEntries.size() > 0) {
            if (log.isDebugEnabled()) {
                log.debug("User " + user.getUsername() + " has permission " + permissionName + " to object " + securableModel.getClass().getCanonicalName() + "[id=" + securableModel.getId() + "] based on the ACL security settings.");
            }
            return true;
        }

        if (securableModel.getCreatedBy() != null && securableModel.getCreatedBy().getId().equals(user.getId())) {
            List<AclEntry> ownerAclEntries = aclEntryService.findAll(permissionName, AclSidType.OWNER, 0L, AclClassName.getByName(securableModel.getClass().getCanonicalName()), securableModel.getId());
            if (ownerAclEntries.size() > 0) {
                if (log.isDebugEnabled()) {
                    log.debug("User " + user.getUsername() + " has permission " + permissionName + " to object " + securableModel.getClass().getCanonicalName() + "[id=" + securableModel.getId() + "] based on that he is the owner.");
                }
                return true;
            }
        }

        if (log.isDebugEnabled()) {
            log.debug("User " + user.getUsername() + " has not permission " + permissionName + " to object " + securableModel.getClass().getCanonicalName() + "[id=" + securableModel.getId() + "].");
        }
        return false;
    }

    @Autowired public  SecurityService(UserService userService,
                           AclEntryService aclEntryService);

}