@Override
  public void storeDataSourceDescription(AbstractProcess process) {
    if (process.getNumValidTimes() > 0) {
      // we add the description in index for each validity period/instant
      for (AbstractTimeGeometricPrimitive validTime : process.getValidTimeList()) {
        double time = Double.NaN;

        if (validTime instanceof TimeInstant)
          time = ((TimeInstant) validTime).getTimePosition().getDecimalValue();
        else if (validTime instanceof TimePeriod)
          time = ((TimePeriod) validTime).getBeginPosition().getDecimalValue();

        if (!Double.isNaN(time)) {
          AbstractProcess oldProcess = descriptionTimeIndex.set(new Key(time), process);
          if (oldProcess != null) getStorage().deallocate(oldProcess);
        }
      }
    } else {
      // if no validity period is specified, we just add with current time
      double time = System.currentTimeMillis() / 1000.;
      descriptionTimeIndex.put(new Key(time), process);
    }
  }
  @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);
      }
    }
  }