     return unless @_runHook 'beforeUpdate', item
 
     # Computes its value.
-    @_computeValue rule, item
+    do ->
+      # Item is not passed directly to function to avoid direct
+      # modification.
+      #
+      # This is not a true security but better than nothing.
+      proxy = Object.create item
+
+      updateValue = (parent, prop, def) ->
+        if not $_.isObject def
+          parent[prop] = def
+        else if $_.isFunction def
+          parent[prop] = def.call proxy
+        else if $_.isArray def
+          i = 0
+          n = def.length
+
+          current = parent[prop] ?= new Array n
+          while i < n
+            updateValue current, i, def[i]
+            ++i
+        else
+          # It's a plain object.
+          current = parent[prop] ?= {}
+          for i of def
+            updateValue current, i, def[i]
+
+      updateValue item, 'val', rule.val
 
     return unless @_runHook 'beforeSave', item
 
     # Registers the new item.
-    @_byKey[key] = item
+    @_byKey[item.key] = item
+
+    # Emits events.
+    @emit "key: #{item.key}", item
+    @emit "rule: #{rule}", item
+
+    # TODO: checks for loops.
+
+  _removeItem: (item) ->
+
+    delete @_byKey[item.key]
 
     # TODO: Cascades changes.
 
-  _removeItem: (item) ->
-
-    delete @_byKey[item.key]
-
-    # TODO: Cascades changes.
-
 #=====================================================================
 
 module.exports = $MappedCollection2

      }

      # Searches for a rule to handle it.
      rule = @_rules[@_dispatch.call item]
      @_assert(
        rule?
        "undefined rule “#{rule}”"
      )

      # Computes its key.
      key = rule.key item

      if key in @_byKey
        # Marks this item as not to be removed.

    # Extracts the rule definition.
    if $_.isFunction definition
      ctx = {
        rule: name
        key: undefined
        val: undefined
        singleton
