   weakReference: (obj) ->
     unless obj.hasOwnProperty @id
       id = @counter++
-
-      @weakmap[id] =
-        callbacks: {}
-
       Object.defineProperty obj, @id, value: id
 
-    @weakmap[obj[@id]]
+    @weakmap[obj[@id]] or= callbacks: {}
+
+  cleanupWeakReference: (ref, id) ->
+    unless Object.keys(ref.callbacks).length
+      unless Object.keys(ref.pointers).length
+        delete @weakmap[id]
 
   stubFunction: (obj, fn) ->
     original = obj[fn]

    @observeMutations obj[keypath], obj[@id], keypath

  unobserve: (obj, keypath, callback) ->
    callbacks = @weakmap[obj[@id]].callbacks[keypath]

    idx = callbacks.indexOf(callback);
    if idx >= 0
      callbacks.splice idx, 1
    @unobserveMutations obj[keypath], obj[@id], keypath

  get: (obj, keypath) ->
    obj[keypath]

        get: -> value
        set: (newValue) =>
          if newValue isnt value
            @unobserveMutations value, obj[@id], keypath
            value = newValue
            callback() for callback in callbacks[keypath].slice() when callback in callbacks[keypath]
            @observeMutations newValue, obj[@id], keypath
