/**
  * GetDataAvailability processing is series mapping is supported.
  *
  * @param request GetDataAvailability request
  * @param session Hibernate session
  * @return List of valid data availability information
  * @throws OwsExceptionReport If an error occurs
  */
 private List<?> querySeriesDataAvailabilities(GetDataAvailabilityRequest request, Session session)
     throws OwsExceptionReport {
   List<DataAvailability> dataAvailabilityValues = Lists.newLinkedList();
   Map<String, ReferenceType> procedures = new HashMap<String, ReferenceType>();
   Map<String, ReferenceType> observableProperties = new HashMap<String, ReferenceType>();
   Map<String, ReferenceType> featuresOfInterest = new HashMap<String, ReferenceType>();
   AbstractSeriesObservationDAO seriesObservationDAO = getSeriesObservationDAO();
   SeriesMinMaxTransformer seriesMinMaxTransformer = new SeriesMinMaxTransformer();
   boolean supportsNamedQuery =
       HibernateHelper.isNamedQuerySupported(SQL_QUERY_GET_DATA_AVAILABILITY_FOR_SERIES, session);
   for (final Series series :
       DaoFactory.getInstance()
           .getSeriesDAO()
           .getSeries(
               request.getProcedures(),
               request.getObservedProperties(),
               request.getFeaturesOfInterest(),
               session)) {
     TimePeriod timePeriod = null;
     if (!request.isSetOfferings()) {
       // get time information from series object
       if (series.isSetFirstLastTime()) {
         timePeriod = new TimePeriod(series.getFirstTimeStamp(), series.getLastTimeStamp());
       }
       // get time information from a named query
       else if (timePeriod == null && supportsNamedQuery) {
         timePeriod =
             getTimePeriodFromNamedQuery(series.getSeriesId(), seriesMinMaxTransformer, session);
       }
     }
     // get time information from SeriesGetDataAvailability mapping if
     // supported
     if (timePeriod == null) {
       SeriesObservationTimeDAO seriesObservationTimeDAO =
           (SeriesObservationTimeDAO) DaoFactory.getInstance().getObservationTimeDAO();
       timePeriod =
           getTimePeriodFromSeriesGetDataAvailability(
               seriesObservationTimeDAO, series, request, seriesMinMaxTransformer, session);
     }
     // create DataAvailabilities
     if (timePeriod != null && !timePeriod.isEmpty()) {
       DataAvailability dataAvailability =
           new DataAvailability(
               getProcedureReference(series, procedures),
               getObservedPropertyReference(series, observableProperties),
               getFeatureOfInterestReference(series, featuresOfInterest, session),
               timePeriod);
       if (isShowCount(request)) {
         dataAvailability.setCount(getCountFor(series, request, session));
       }
       if (isIncludeResultTime(request)) {
         dataAvailability.setResultTimes(
             getResultTimesFromSeriesObservation(seriesObservationDAO, series, request, session));
       }
       dataAvailabilityValues.add(dataAvailability);
     }
   }
   return dataAvailabilityValues;
 }
 /**
  * Get count of available observation for this time series
  *
  * @param series Time series
  * @param request GetDataAvailability request
  * @param session Hibernate session
  * @return Count of available observations
  */
 private Long getCountFor(Series series, GetDataAvailabilityRequest request, Session session) {
   Criteria criteria =
       session
           .createCriteria(SeriesObservationInfo.class)
           .add(Restrictions.eq(AbstractObservation.DELETED, false));
   criteria.add(Restrictions.eq(SeriesObservationInfo.SERIES, series));
   if (request.isSetOfferings()) {
     criteria
         .createCriteria(SeriesObservationTime.OFFERINGS)
         .add(Restrictions.in(Offering.IDENTIFIER, request.getOfferings()));
   }
   criteria.setProjection(Projections.rowCount());
   return (Long) criteria.uniqueResult();
 }