class DBAlertManager extends DBManager<Alert> implements AlertManager {

    public final int countUnresolvedDevices(final DeviceGroup deviceGroup) {

        if (deviceGroup == null) {
            String msg = "invalid argument - null value for device group";
            LOGGER.error(msg);
            throw new IllegalArgumentException(msg);
        }

        Transaction tx = null;
        Session session = getFactory().getCurrentSession();
        try {
            LOGGER.debug("querying alerts table for unresolved devices");
            tx = session.beginTransaction();

            // first use a subquery to list the devices in the given group
            DetachedCriteria deviceQuery = DetachedCriteria.forClass(Device.class);
            deviceQuery.createAlias("deviceGroup", "g");
            deviceQuery.add(Restrictions.eq("g.name", deviceGroup.getName()));
            deviceQuery.setProjection(Property.forName("name"));

            // now query within that group for unique device names among unresolved alerts
            Criteria criteria = session.createCriteria(Alert.class);
            criteria.add(Restrictions.isNull("archivedTime"));
            criteria.add(Subqueries.propertyIn("deviceName", deviceQuery));
            criteria.setProjection(Projections.countDistinct("deviceName"));
            Long result = (Long) criteria.uniqueResult();
            tx.commit();
            if (result == null) {
                throw new AlertManagerException("failed to query unresolved alert count");
            } else {
                return result.intValue();
            }

        } catch (HibernateException e) {
            final String msg = "unable to query alerts table";
            LOGGER.error(msg, e);
            if (tx != null) {
                LOGGER.debug("rolling back transaction");
                tx.rollback();
            }
            throw e;
        }
    }

    public  DBAlertManager(final SessionFactory factory);

}