     instrument: (opts)->
       __logger = @
       ->
+        id = __logger.getUniqueId()
         arr = Array.prototype.slice.call(arguments)
         arr.unshift(@)
-        arr.unshift "#{opts.name} call: "
+        arr.unshift "#{opts.name} call (id #{id}): "
         __logger.add('instrumented', arr)
         retval = opts.fn.apply(@, arguments)
-        __logger.add('instrumented', ["#{opts.name} return: ", retval])
+        __logger.add('instrumented', ["#{opts.name} return (id #{id}): ", retval])
         retval
+
+    logMethodCall: (name, object, method, args)->
+      id = @getUniqueId()
+      @info("method call (id #{id}): ", name, object, method, args)
+      ret = object[method].apply(object, args)
+      @info("method call return (id #{id}): ", name, object, method, args, ret)
+      ret
 
   class_mixer Logger
 

      @log_entry_types = ['error','warn','info','debug', 'log', 'instrumented']

      @log_entry_display_types = @typesForLevel(opts.log_level || 'production')

      @console_log = opts.console_log
      @stringify_objects = opts.stringify_objects
      @entries = []

    add: (type, args = []) ->
      entry = LogEntry.build(type, args)
      @entries.push entry
      entry_index = @entries.length - 1

      if @log_entry_display_types.indexOf(type) != -1
        @console_log.apply(null, entry.display(@stringify_objects, entry_index))

    typesForLevel: (level)->
      switch level
