@Override
 public synchronized YieldCurveDefinitionDocument update(YieldCurveDefinitionDocument document) {
   ArgumentChecker.notNull(document, "document");
   ArgumentChecker.notNull(document.getYieldCurveDefinition(), "document.yieldCurveDefinition");
   final Currency currency = document.getYieldCurveDefinition().getCurrency();
   final String name = document.getYieldCurveDefinition().getName();
   final UniqueId uid = UniqueId.of(getUniqueIdScheme(), name + "_" + currency.getCode());
   if (!uid.equals(document.getUniqueId())) {
     throw new IllegalArgumentException("Invalid unique identifier");
   }
   final Pair<Currency, String> key = Pair.of(currency, name);
   final TreeMap<Instant, YieldCurveDefinition> value = _definitions.get(key);
   if (value == null) {
     throw new DataNotFoundException("UID '" + uid + "' not found");
   }
   if (_sourceVersionCorrection.getVersionAsOf() != null) {
     // Don't need to keep the old values before the one needed by "versionAsOfInstant"
     final Instant oldestNeeded = value.floorKey(_sourceVersionCorrection.getVersionAsOf());
     value.headMap(oldestNeeded).clear();
   } else {
     // Don't need any old values
     value.clear();
   }
   Instant now = Instant.now();
   value.put(now, document.getYieldCurveDefinition());
   document.setUniqueId(uid);
   changeManager().entityChanged(ChangeType.CHANGED, uid.getObjectId(), null, null, now);
   return document;
 }
 // -------------------------------------------------------------------------
 @Override
 public synchronized YieldCurveDefinitionDocument add(YieldCurveDefinitionDocument document) {
   ArgumentChecker.notNull(document, "document");
   ArgumentChecker.notNull(document.getYieldCurveDefinition(), "document.yieldCurveDefinition");
   final Currency currency = document.getYieldCurveDefinition().getCurrency();
   final String name = document.getYieldCurveDefinition().getName();
   final Pair<Currency, String> key = Pair.of(currency, name);
   if (_definitions.containsKey(key)) {
     throw new IllegalArgumentException("Duplicate definition");
   }
   final TreeMap<Instant, YieldCurveDefinition> value =
       new TreeMap<Instant, YieldCurveDefinition>();
   Instant now = Instant.now();
   value.put(now, document.getYieldCurveDefinition());
   _definitions.put(key, value);
   final UniqueId uid = UniqueId.of(getUniqueIdScheme(), name + "_" + currency.getCode());
   document.setUniqueId(uid);
   changeManager()
       .entityChanged(
           ChangeType.ADDED,
           document.getObjectId(),
           document.getVersionFromInstant(),
           document.getVersionToInstant(),
           now);
   return document;
 }
 @Override
 public synchronized YieldCurveDefinitionDocument addOrUpdate(
     YieldCurveDefinitionDocument document) {
   ArgumentChecker.notNull(document, "document");
   ArgumentChecker.notNull(document.getYieldCurveDefinition(), "document.yieldCurveDefinition");
   final Currency currency = document.getYieldCurveDefinition().getCurrency();
   final String name = document.getYieldCurveDefinition().getName();
   final Pair<Currency, String> key = Pair.of(currency, name);
   TreeMap<Instant, YieldCurveDefinition> value = _definitions.get(key);
   final UniqueId uid = UniqueId.of(getUniqueIdScheme(), name + "_" + currency.getCode());
   Instant now = Instant.now();
   if (value != null) {
     if (_sourceVersionCorrection.getVersionAsOf() != null) {
       // Don't need to keep the old values before the one needed by "versionAsOfInstant"
       final Instant oldestNeeded = value.floorKey(_sourceVersionCorrection.getVersionAsOf());
       if (oldestNeeded != null) {
         value.headMap(oldestNeeded).clear();
       }
     } else {
       // Don't need any old values
       value.clear();
     }
     value.put(now, document.getYieldCurveDefinition());
     changeManager().entityChanged(ChangeType.CHANGED, uid.getObjectId(), null, null, now);
   } else {
     value = new TreeMap<Instant, YieldCurveDefinition>();
     value.put(now, document.getYieldCurveDefinition());
     _definitions.put(key, value);
     changeManager()
         .entityChanged(
             ChangeType.ADDED,
             uid.getObjectId(),
             document.getVersionFromInstant(),
             document.getVersionToInstant(),
             now);
   }
   document.setUniqueId(uid);
   return document;
 }
  @Override
  public List<UniqueId> replaceAllVersions(
      ObjectIdentifiable objectIdentifiable,
      List<YieldCurveDefinitionDocument> replacementDocuments) {
    ArgumentChecker.notNull(replacementDocuments, "replacementDocuments");
    ArgumentChecker.notNull(objectIdentifiable, "objectIdentifiable");

    final Instant now = Instant.now();

    for (YieldCurveDefinitionDocument replacementDocument : replacementDocuments) {
      ArgumentChecker.notNull(replacementDocument, "document");
      ArgumentChecker.notNull(
          replacementDocument.getYieldCurveDefinition(), "document.yieldCurveDefinition");
      final Currency currency = replacementDocument.getYieldCurveDefinition().getCurrency();
      final String name = replacementDocument.getYieldCurveDefinition().getName();
      final UniqueId id = UniqueId.of(getUniqueIdScheme(), name + "_" + currency.getCode());
      ArgumentChecker.isTrue(id.equals(objectIdentifiable), "Invalid object identifier");
    }

    YieldCurveDefinitionDocument storedDocument = get(objectIdentifiable, null);
    if (storedDocument == null) {
      throw new DataNotFoundException("Document not found: " + objectIdentifiable);
    }
    final Currency currency = storedDocument.getYieldCurveDefinition().getCurrency();
    final String name = storedDocument.getYieldCurveDefinition().getName();
    Pair<Currency, String> key = Pair.of(currency, name);

    final TreeMap<Instant, YieldCurveDefinition> value = _definitions.get(key);
    if (value == null) {
      throw new DataNotFoundException("OID '" + objectIdentifiable + "' not found");
    }
    value.clear();

    List<YieldCurveDefinitionDocument> orderedReplacementDocuments =
        MasterUtils.adjustVersionInstants(now, null, null, replacementDocuments);

    final Instant lowestVersionFrom = orderedReplacementDocuments.get(0).getVersionFromInstant();

    ArgumentChecker.notNull(
        lowestVersionFrom, "You must define version from of the first document");

    for (YieldCurveDefinitionDocument replacementDocument : orderedReplacementDocuments) {
      value.put(
          replacementDocument.getVersionFromInstant(),
          replacementDocument.getYieldCurveDefinition());
      changeManager()
          .entityChanged(ChangeType.CHANGED, replacementDocument.getObjectId(), null, null, now);
    }
    return MasterUtils.mapToUniqueIDs(orderedReplacementDocuments);
  }
  @Override
  public List<UniqueId> replaceVersions(
      ObjectIdentifiable objectIdentifiable,
      List<YieldCurveDefinitionDocument> replacementDocuments) {
    ArgumentChecker.notNull(replacementDocuments, "replacementDocuments");
    ArgumentChecker.notNull(objectIdentifiable, "objectIdentifiable");

    final Instant now = Instant.now();

    for (YieldCurveDefinitionDocument replacementDocument : replacementDocuments) {
      ArgumentChecker.notNull(replacementDocument, "document");
      ArgumentChecker.notNull(
          replacementDocument.getYieldCurveDefinition(), "document.yieldCurveDefinition");
      final Currency currency = replacementDocument.getYieldCurveDefinition().getCurrency();
      final String name = replacementDocument.getYieldCurveDefinition().getName();
      final UniqueId id = UniqueId.of(getUniqueIdScheme(), name + "_" + currency.getCode());
      ArgumentChecker.isTrue(id.equals(objectIdentifiable), "Invalid object identifier");
    }

    YieldCurveDefinitionDocument storedDocument = get(objectIdentifiable, null);
    if (storedDocument == null) {
      throw new DataNotFoundException("Document not found: " + objectIdentifiable);
    }
    final Currency currency = storedDocument.getYieldCurveDefinition().getCurrency();
    final String name = storedDocument.getYieldCurveDefinition().getName();
    Pair<Currency, String> key = Pair.of(currency, name);

    final TreeMap<Instant, YieldCurveDefinition> value = _definitions.get(key);
    if (value == null) {
      throw new DataNotFoundException("OID '" + objectIdentifiable + "' not found");
    }
    if (_sourceVersionCorrection.getVersionAsOf() != null) {
      // Don't need to keep the old values before the one needed by "versionAsOfInstant"
      final Instant oldestNeeded = value.floorKey(_sourceVersionCorrection.getVersionAsOf());
      value.headMap(oldestNeeded).clear();
    } else {
      // Don't need any old values
      value.clear();
    }

    Instant lowestCurrentVersionFrom = value.firstKey();

    List<YieldCurveDefinitionDocument> orderedReplacementDocuments =
        MasterUtils.adjustVersionInstants(
            now, lowestCurrentVersionFrom, null, replacementDocuments);

    final Instant lowestVersionFrom = orderedReplacementDocuments.get(0).getVersionFromInstant();
    final Instant highestVersionTo =
        orderedReplacementDocuments
            .get(orderedReplacementDocuments.size() - 1)
            .getVersionToInstant();

    if (orderedReplacementDocuments.size() > 0) {
      value.subMap(lowestVersionFrom, true, highestVersionTo, false).clear();
    }

    for (YieldCurveDefinitionDocument replacementDocument : orderedReplacementDocuments) {
      value.put(
          replacementDocument.getVersionFromInstant(),
          replacementDocument.getYieldCurveDefinition());
      changeManager()
          .entityChanged(ChangeType.CHANGED, replacementDocument.getObjectId(), null, null, now);
    }
    return MasterUtils.mapToUniqueIDs(orderedReplacementDocuments);
  }