@Override
 public synchronized YieldCurveDefinitionDocument get(
     ObjectIdentifiable objectIdable, VersionCorrection versionCorrection) {
   ArgumentChecker.notNull(objectIdable, "objectIdable");
   ObjectId objectId = objectIdable.getObjectId();
   if (!getUniqueIdScheme().equals(objectId.getScheme())) {
     throw new DataNotFoundException(
         "Scheme '" + objectId.getScheme() + "' not valid for '" + getUniqueIdScheme() + "'");
   }
   final int i = objectId.getValue().indexOf('_');
   if (i <= 0) {
     throw new DataNotFoundException(
         "Identifier '" + objectId.getValue() + "' not valid for '" + getUniqueIdScheme() + "'");
   }
   final String name = objectId.getValue().substring(0, i);
   final String iso = objectId.getValue().substring(i + 1);
   final Currency currency;
   try {
     currency = Currency.of(iso);
   } catch (IllegalArgumentException e) {
     throw new DataNotFoundException(
         "Identifier '" + objectId.getValue() + "' not valid for '" + getUniqueIdScheme() + "'",
         e);
   }
   final TreeMap<Instant, YieldCurveDefinition> definitions =
       _definitions.get(Pair.of(currency, name));
   if (definitions == null) {
     throw new DataNotFoundException("Curve definition not found");
   }
   final YieldCurveDefinition definition = definitions.lastEntry().getValue();
   if (definition == null) {
     throw new DataNotFoundException("Curve definition not found");
   }
   return new YieldCurveDefinitionDocument(objectId.atLatestVersion(), definition);
 }
  /**
   * Updates an existing time-series in the master. If the time series provided has overlaps with
   * the existing time series, the old versions of intersecting points will be corrected to the new
   * ones. After that, points later than the existing latest point of the time series will be
   * appended.
   *
   * @param description a description of the time-series for display purposes, not null
   * @param dataSource the data source, not null
   * @param dataProvider the data provider, not null
   * @param dataField the data field, not null
   * @param observationTime the descriptive observation time key, e.g. LONDON_CLOSE, not null
   * @param oId the unique identifier of the time-series to be updated, not null
   * @param timeSeries the time-series, not null
   * @return the unique identifier of the time-series
   */
  public UniqueId writeTimeSeries(
      String description,
      String dataSource,
      String dataProvider,
      String dataField,
      String observationTime,
      ObjectId oId,
      LocalDateDoubleTimeSeries timeSeries) {

    UniqueId uId = oId.atLatestVersion();

    ManageableHistoricalTimeSeries existingManageableTs = _htsMaster.getTimeSeries(uId);
    LocalDateDoubleTimeSeries existingTs = existingManageableTs.getTimeSeries();

    if (existingTs.isEmpty()) {
      uId = _htsMaster.updateTimeSeriesDataPoints(oId, timeSeries);
      s_logger.debug(
          "Updating time series " + oId + "[" + dataField + "] with all as currently emtpy)");
    } else {
      // There is a non-empty matching time-series already in the master so update it to reflect the
      // new time-series
      // 1: 'correct' any differences in the subseries already present
      LocalDateDoubleTimeSeries tsIntersection =
          timeSeries.subSeries(
              existingTs.getEarliestTime(), true, existingTs.getLatestTime(), true);
      if (!tsIntersection.equals(existingTs)) {
        s_logger.debug(
            "Correcting time series "
                + oId
                + "["
                + dataField
                + "] from "
                + existingTs.getEarliestTime()
                + " to "
                + existingTs.getLatestTime());
        uId = _htsMaster.correctTimeSeriesDataPoints(oId, tsIntersection);
      }
      // 2: 'update' the time-series to add any new, later points
      if (existingTs.getLatestTime().isBefore(timeSeries.getLatestTime())) {
        LocalDateDoubleTimeSeries newSeries =
            timeSeries.subSeries(
                existingTs.getLatestTime(), false, timeSeries.getLatestTime(), true);
        if (newSeries.size() > 0) {
          s_logger.debug(
              "Updating time series "
                  + oId
                  + "["
                  + dataField
                  + "] from "
                  + newSeries.getEarliestTime()
                  + " to "
                  + newSeries.getLatestTime());
          uId = _htsMaster.updateTimeSeriesDataPoints(oId, newSeries);
        }
      }
    }
    return uId;
  }