+ @SuppressWarnings({ "synthetic-access", "unchecked" })
+ protected <T> Value<T> value(String name, Class<T> clazz) {
+ if (!attributes.containsKey(name)) {
+ attributes.put(name, new Value<T>());
+ }
+ return (Value<T>) attributes.get(name);
+ }
+
+ protected static class Value<T> {
+
+ private T original;
+
+ private T current;
+
+ public T get() {
+ return current;
+ }
+
+ public Value<T> set(T value) {
+ current = value;
+ return this;
+ }
+
+ public boolean dirty() {
+ return (original != null) ? !original.equals(current) : current != null;
+ }
+
+ public Value<T> commit() {
+ original = current;
+ return this;
+ }
+
+ }
+