/**
     * Save the given fragment in the cache. (Also registers as a DataListener on the appropriate
     * rollup instance list, so it can invalidate this cache entry if the instance list changes.)
     */
    public String put(String rollupID, String fragment) {
      if (!contents.containsKey(rollupID))
        data.addDataListener(rollupInstanceList(rollupID), this, false);

      contents.put(rollupID, fragment);
      return fragment;
    }
  protected void writeContents() throws IOException {
    DataRepository data = getDataRepository();
    if (data == null) return;
    init(data);

    // get the [Use_Rollup] data element for the current
    // project. If it is null, return immediately.
    String prefix = getPrefix();
    if (prefix == null) return;
    String useRollupName = DataRepository.createDataName(prefix, "Use_Rollup");
    ListData rollupIDs = getList(data, useRollupName);
    if (rollupIDs == null) return;

    String tableStart = TABLE_START, tableEnd = "", tableRow;
    for (int i = 0; i < rollupIDs.size(); i++) {
      tableRow = getFragment(data, rollupIDs.get(i).toString());
      if (tableRow != null && tableRow.length() > 0) {
        out.print(tableStart);
        out.print(tableRow);
        tableStart = "";
        tableEnd = TABLE_END;
      }
    }
    out.print(tableEnd);
  }
 private String getWorkflowParent(String path) {
   String result = null;
   while (path != null) {
     if (getValue(path, "Workflow_Source_ID") != null) result = path;
     path = DataRepository.chopPath(path);
   }
   return result;
 }
 private SimpleData getValue(String path, String name) {
   String dataName = DataRepository.createDataName(path, name);
   return context.getData().getSimpleValue(dataName);
 }
 private ListData getList(DataRepository data, String dataName) {
   SimpleData d = data.getSimpleValue(dataName);
   if (d instanceof ListData) return (ListData) d;
   else if (d instanceof StringData) return ((StringData) d).asList();
   else return null;
 }