gt:                 DateTime end = new DateTime(maxEnd);
context: /**
   * Copyright (C) 2013
   * by 52 North Initiative for Geospatial Open Source Software GmbH
   *
   * Contact: Andreas Wytzisk
   * 52 North Initiative for Geospatial Open Source Software GmbH
   * Martin-Luther-King-Weg 24
   * 48155 Muenster, Germany
   * info@52north.org
   *
   * This program is free software; you can redistribute and/or modify it under
   * the terms of the GNU General Public License version 2 as published by the
   * Free Software Foundation.
   *
   * This program is distributed WITHOUT ANY WARRANTY; even without the implied
   * WARRANTY OF MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License along with
   * this program (see gnu-gpl v2.txt). If not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA or
   * visit the Free Software Foundation web page, http://www.fsf.org.
   */
  package org.n52.sos.ds.hibernate.dao;
  
  import java.sql.Timestamp;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Set;
  
  import org.hibernate.Criteria;
  import org.hibernate.Session;
  import org.hibernate.criterion.Projections;
  import org.hibernate.criterion.Restrictions;
  import org.joda.time.DateTime;
  import org.n52.sos.ds.hibernate.entities.BlobObservation;
  import org.n52.sos.ds.hibernate.entities.BooleanObservation;
  import org.n52.sos.ds.hibernate.entities.CategoryObservation;
  import org.n52.sos.ds.hibernate.entities.CountObservation;
  import org.n52.sos.ds.hibernate.entities.FeatureOfInterest;
  import org.n52.sos.ds.hibernate.entities.GeometryObservation;
  import org.n52.sos.ds.hibernate.entities.NumericObservation;
  import org.n52.sos.ds.hibernate.entities.Observation;
  import org.n52.sos.ds.hibernate.entities.ObservationConstellation;
  import org.n52.sos.ds.hibernate.entities.Offering;
  import org.n52.sos.ds.hibernate.entities.SweDataArrayObservation;
  import org.n52.sos.ds.hibernate.entities.TextObservation;
  import org.n52.sos.ds.hibernate.util.HibernateObservationUtilities;
  import org.n52.sos.exception.CodedException;
  import org.n52.sos.exception.ows.NoApplicableCodeException;
  import org.n52.sos.ogc.OGCConstants;
  import org.n52.sos.ogc.gml.time.Time;
  import org.n52.sos.ogc.gml.time.TimeInstant;
  import org.n52.sos.ogc.gml.time.TimePeriod;
  import org.n52.sos.ogc.om.OMConstants;
  import org.n52.sos.ogc.om.OmObservation;
  import org.n52.sos.ogc.om.SingleObservationValue;
  import org.n52.sos.ogc.om.values.BooleanValue;
  import org.n52.sos.ogc.om.values.CategoryValue;
  import org.n52.sos.ogc.om.values.CountValue;
  import org.n52.sos.ogc.om.values.GeometryValue;
  import org.n52.sos.ogc.om.values.QuantityValue;
  import org.n52.sos.ogc.om.values.SweDataArrayValue;
  import org.n52.sos.ogc.om.values.TextValue;
  import org.n52.sos.ogc.om.values.UnknownValue;
  import org.n52.sos.ogc.om.values.Value;
  import org.n52.sos.ogc.ows.OwsExceptionReport;
  import org.n52.sos.ogc.sos.Sos2Constants;
  import org.n52.sos.util.CollectionHelper;
  import org.n52.sos.util.StringHelper;
  
  /**
   * Hibernate data access class for observation
   * 
   * @author CarstenHollmann
   * @since 4.0.0
   */
  public class ObservationDAO extends TimeCreator {
  
      /**
       * Get all observation identifiers
       * 
       * @param session
       *            Hibernate session
       * @return Observation identifiers
       */
      @SuppressWarnings("unchecked")
      public List<String> getObservationIdentifiers(Session session) {
          return session.createCriteria(Observation.class).add(Restrictions.eq(Observation.DELETED, false))
                  .add(Restrictions.isNotNull(Observation.IDENTIFIER))
                  .setProjection(Projections.distinct(Projections.property(Observation.IDENTIFIER))).list();
      }
  
      /**
       * Check if there are numeric observations for the offering
       * 
       * @param offeringIdentifier
       *            Offering identifier
       * @param session
       *            Hibernate session
       * @return If there are observations or not
       */
      public boolean checkNumericObservationsFor(String offeringIdentifier, Session session) {
          return checkObservationFor(NumericObservation.class, offeringIdentifier, session);
      }
  
      /**
       * Check if there are boolean observations for the offering
       * 
       * @param offeringIdentifier
       *            Offering identifier
       * @param session
       *            Hibernate session
       * @return If there are observations or not
       */
      public boolean checkBooleanObservationsFor(String offeringIdentifier, Session session) {
          return checkObservationFor(BooleanObservation.class, offeringIdentifier, session);
      }
  
      /**
       * Check if there are count observations for the offering
       * 
       * @param offeringIdentifier
       *            Offering identifier
       * @param session
       *            Hibernate session
       * @return If there are observations or not
       */
      public boolean checkCountObservationsFor(String offeringIdentifier, Session session) {
          return checkObservationFor(CountObservation.class, offeringIdentifier, session);
      }
  
      /**
       * Check if there are category observations for the offering
       * 
       * @param offeringIdentifier
       *            Offering identifier
       * @param session
       *            Hibernate session
       * @return If there are observations or not
       */
      public boolean checkCategoryObservationsFor(String offeringIdentifier, Session session) {
          return checkObservationFor(CategoryObservation.class, offeringIdentifier, session);
      }
  
      /**
       * Check if there are text observations for the offering
       * 
       * @param offeringIdentifier
       *            Offering identifier
       * @param session
       *            Hibernate session
       * @return If there are observations or not
       */
      public boolean checkTextObservationsFor(String offeringIdentifier, Session session) {
          return checkObservationFor(TextObservation.class, offeringIdentifier, session);
      }
  
      /**
       * Check if there are blob observations for the offering
       * 
       * @param offeringIdentifier
       *            Offering identifier
       * @param session
       *            Hibernate session
       * @return If there are observations or not
       */
      public boolean checkBlobObservationsFor(String offeringIdentifier, Session session) {
          return checkObservationFor(BlobObservation.class, offeringIdentifier, session);
      }
  
      /**
       * Check if there are geometry observations for the offering
       * 
       * @param offeringIdentifier
       *            Offering identifier
       * @param session
       *            Hibernate session
       * @return If there are observations or not
       */
      public boolean checkGeometryObservationsFor(String offeringIdentifier, Session session) {
          return checkObservationFor(GeometryObservation.class, offeringIdentifier, session);
      }
      
      /**
       * Check if there are geometry observations for the offering
       * 
       * @param offeringIdentifier
       *            Offering identifier
       * @param session
       *            Hibernate session
       * @return If there are observations or not
       */
      public boolean checkSweDataArrayObservationsFor(String offeringIdentifier, Session session) {
          return checkObservationFor(SweDataArrayObservation.class, offeringIdentifier, session);
      }
  
      /**
       * Check if there are observations for the offering
       * 
       * @param clazz
       *            Observation sub class
       * @param offeringIdentifier
       *            Offering identifier
       * @param session
       *            Hibernate session
       * @return If there are observations or not
       */
      @SuppressWarnings({ "rawtypes", "unchecked" })
      private boolean checkObservationFor(Class clazz, String offeringIdentifier, Session session) {
          Criteria c = session.createCriteria(clazz).add(Restrictions.eq(Observation.DELETED, false));
          c.createCriteria(Observation.OFFERINGS).add(Restrictions.eq(Offering.IDENTIFIER, offeringIdentifier));
          c.setMaxResults(1);
          return CollectionHelper.isNotEmpty(c.list());
      }
  
      /**
       * Get min phenomenon time from observations
       * 
       * @param session
       *            Hibernate session Hibernate session
       * @return min time
       */
      public DateTime getMinPhenomenonTime(Session session) {
          Object min =
                  session.createCriteria(Observation.class)
                          .setProjection(Projections.min(Observation.PHENOMENON_TIME_START))
                          .add(Restrictions.eq(Observation.DELETED, false)).uniqueResult();
          if (min != null) {
              return new DateTime(min);
          }
          return null;
      }
  
      /**
       * Get max phenomenon time from observations
       * 
       * @param session
       *            Hibernate session Hibernate session
       * 
       * @return max time
       */
      public DateTime getMaxPhenomenonTime(Session session) {
          Object maxStart =
                  session.createCriteria(Observation.class)
                          .setProjection(Projections.max(Observation.PHENOMENON_TIME_START))
                          .add(Restrictions.eq(Observation.DELETED, false)).uniqueResult();
          Object maxEnd =
                  session.createCriteria(Observation.class)
                          .setProjection(Projections.max(Observation.PHENOMENON_TIME_END))
                          .add(Restrictions.eq(Observation.DELETED, false)).uniqueResult();
          if (maxStart == null && maxEnd == null) {
              return null;
          } else {
              DateTime start = new DateTime(maxStart);
              if (maxEnd != null) {
  