public static void BeginEdit(this IEditableObject self) { // store current state to temporary storage var state = self.GetPublicState(); object temp; if (state.TryGetValue(SystemFields.Shapshot, out temp)) { return; // idempotent } var deepClone = self is IComposite; var clone = self.Clone(deepClone); self.SetPropertyInternal(SystemFields.Shapshot, clone); self.SetPropertyInternal(SystemFields.IsChanged, false); }