public SortedMap<String, Requirement> read() throws IOException {
    SortedMap<String, Requirement> map = new ChildrenFirstOrderedMap();
    File jsonFile = new File(outputDirectory, rootDirectory + ".json");
    if (!jsonFile.exists()) {
      return map;
    }

    SortedMap<String, Requirement> storedRequirementsMap;
    Type requirementsMapType = new TypeToken<SortedMap<String, Requirement>>() {}.getType();
    try (FileReader reader = new FileReader(jsonFile)) {
      storedRequirementsMap = gson.fromJson(reader, requirementsMapType);
      if (storedRequirementsMap == null) {
        storedRequirementsMap = Collections.emptySortedMap();
      }
    }
    map.putAll(storedRequirementsMap);

    // reset the parents
    for (Map.Entry<String, Requirement> entry : storedRequirementsMap.entrySet()) {
      String key = entry.getKey();
      if (key.contains(".")) {
        String parent = key.substring(0, key.lastIndexOf("."));
        Requirement child = entry.getValue();
        updateParentChildren(map, parent, child);
      }
    }
    return map;
  }
 public synchronized java.util.SortedMap<Double, PropertyChange> getHeadMap(double time) {
   if (this.changes != null) {
     // would it be better to add on a small epsilon?
     final boolean IS_INCLUSIVE = true;
     return this.changes.headMap(time, IS_INCLUSIVE);
   } else {
     return java.util.Collections.emptySortedMap();
   }
 }