private ValueContainerImpl<Value> getMergedData() {
    ValueContainerImpl<Value> mergedSnapshot = myMergedSnapshot;
    if (mergedSnapshot != null) {
      return mergedSnapshot;
    }

    UpdatableValueContainer<Value> fromDisk = myInitializer.compute();

    // it makes sense to check it again before cloning and modifications application
    mergedSnapshot = myMergedSnapshot;
    if (mergedSnapshot != null) {
      return mergedSnapshot;
    }

    ValueContainerImpl<Value> newMerged = fromDisk instanceof ValueContainerImpl
                                          ? ((ValueContainerImpl<Value>)fromDisk).clone()
                                          : ((ChangeTrackingValueContainer<Value>)fromDisk).getMergedData().clone();

    FileId2ValueMapping<Value> fileId2ValueMapping;
    if ((myAdded != null || myInvalidated != null) &&
        (newMerged.size() > ValueContainerImpl.NUMBER_OF_VALUES_THRESHOLD ||
         (myAdded != null && myAdded.size() > ValueContainerImpl.NUMBER_OF_VALUES_THRESHOLD))) {
      // Calculate file ids that have Value mapped to avoid O(NumberOfValuesInMerged) during removal
      fileId2ValueMapping = new FileId2ValueMapping<>(newMerged);
    }
    else {
      fileId2ValueMapping = null;
    }

    if (myInvalidated != null) {
      myInvalidated.forEach(inputId -> {
        if (fileId2ValueMapping != null) {
          fileId2ValueMapping.removeFileId(inputId);
        }
        else {
          newMerged.removeAssociatedValue(inputId);
        }
      });
    }

    if (myAdded != null) {
      myAdded.forEach((inputId, value) -> {
        // enforcing "one-value-per-file for particular key" invariant
        if (fileId2ValueMapping != null) {
          fileId2ValueMapping.removeFileId(inputId);
          fileId2ValueMapping.associateFileIdToValue(inputId, value);
        }
        else {
          newMerged.removeAssociatedValue(inputId);
          newMerged.addValue(inputId, value);
        }

        return true;
      });
    }

    setNeedsCompacting(fromDisk.needsCompacting());

    myMergedSnapshot = newMerged;
    return newMerged;
  }
private ValueContainerImpl<Value> getMergedData()