@Override
 public AbstractProcess getDataSourceDescriptionAtTime(double time) {
   Iterator<AbstractProcess> it =
       descriptionTimeIndex.iterator(KEY_SML_START_ALL_TIME, new Key(time), Index.DESCENT_ORDER);
   if (it.hasNext()) return it.next();
   return null;
 }
 @Override
 public AbstractProcess getLatestDataSourceDescription() {
   Iterator<AbstractProcess> it =
       descriptionTimeIndex.iterator(
           KEY_SML_START_ALL_TIME, KEY_SML_END_ALL_TIME, Index.DESCENT_ORDER);
   if (it.hasNext()) return it.next();
   return null;
 }
 @Override
 public void removeDataSourceDescription(double time) {
   Iterator<AbstractProcess> it =
       descriptionTimeIndex.iterator(KEY_SML_START_ALL_TIME, new Key(time), Index.DESCENT_ORDER);
   if (it.hasNext()) {
     AbstractProcess sml = it.next();
     it.remove();
     getStorage().deallocate(sml);
   }
 }
  @Override
  public void removeDataSourceDescriptionHistory(double startTime, double endTime) {
    Storage db = getStorage();

    Iterator<AbstractProcess> it =
        descriptionTimeIndex.iterator(new Key(startTime), new Key(endTime), Index.ASCENT_ORDER);
    while (it.hasNext()) {
      AbstractProcess sml = it.next();

      // get end of validity of process description
      double endValidity = Double.NaN;
      AbstractTimeGeometricPrimitive validTime = sml.getValidTimeList().get(0);
      if (validTime instanceof TimePeriod)
        endValidity = ((TimePeriod) validTime).getEndPosition().getDecimalValue();

      // check that end of validity is also within time range
      // if end of validity is now, endValidity will be NaN
      // if this is the last description returned, don't remove it if end of validity is now
      if (endValidity <= endTime || (Double.isNaN(endValidity) && it.hasNext())) {
        it.remove();
        db.deallocate(sml);
      }
    }
  }