public String getAttributeName(Long id) {

    if (resolvedAttributeIds.contains(id)) return "";

    Attribute a = attributeDAO.findByID(id);
    resolvedAttributeIds.add(id);
    if (a == null) return "";

    return a.getName();
  }
  public String undo(ValueEvent ve) {
    List<ValueEvent> newer = eventDAO.getNewerEvents(ve);
    Collections.sort(newer);

    if (stillExists(newer)) {
      Value v = valueDAO.findByID(new Value.ValueId(ve.getAttributeId(), ve.getTrialdataId()));

      if (ve instanceof ValueCreateEvent) {
        log.debug("Removing Value #0/#1", v.getId().getAttributeId(), v.getId().getTrialDataId());
        valueDAO.remove(v);
      } else {
        log.debug(
            "reversing value of #0/#1 to #2",
            v.getId().getAttributeId(),
            v.getId().getTrialDataId(),
            ve.getOldValue());
        v.setValueObject(ve.getOldValue());
      }
    } else {

      if (!(ve instanceof ValueCreateEvent)) {
        log.debug(
            "restoring value #0/#1 with value #2",
            ve.getAttributeId(),
            ve.getTrialdataId(),
            ve.getOldValue());
        Attribute a = attributeDAO.findByID(ve.getAttributeId());
        if (a == null)
          throw new IllegalArgumentException(
              "Could not restore value, attribute has been removed!");

        Value v = valueFactory.getValueObject(a.getFormElement().getDataType());
        v.setAttribute(a);
        TrialData td = new TrialData();
        td.setId(ve.getTrialdataId());
        v.setTrialData(td);
        v.setValueObject(ve.getOldValue());

        valueDAO.persist(v);
      }
    }

    // remove all newer Events
    for (ValueEvent ve1 : newer) {
      eventDAO.remove(ve1);
    }

    // reset datamodel
    changes = null;

    return null;
  }