concept Session {} concept Event { new Ref session; } Event > EChange { int startIndex, endIndex; S text; } Event > ECaret { int pos; } static S replayEdit(EChange change, S text) { if (change == null) ret text; ret substring(text, 0, change.startIndex) + change.text + substring(text, change.endIndex); }