docs: function wrapFunctions(name, obj, protoLevel, hooks, state, rules){
    if (!(obj && (util.isObject(obj) || util.isFunction(obj)))){
      return;
    }
  
    if (obj.__concurix_blacklisted || (obj.constructor && obj.constructor.__concurix_blacklisted)) {
      return;
    }
  
    if (obj.__concurix_wrapped_obj__ || !Object.isExtensible(obj)){
      return;
    }
  
    tagObject(obj, '__concurix_wrapped_obj__');
  
  
    protoLevel = protoLevel ? protoLevel : 0;
    util.iterateOwnProperties(obj, function(key){
      var desc = Object.getOwnPropertyDescriptor(obj, key);
  
      // We got a property that wasn't a property.
      if (desc == null) {
        return;
      }
  
      // ignore properties that cannot be set
      if (!desc.configurable || !desc.writable || desc.set){
        return;
      }
  
      // ignore blacklisted properties
      if (desc.value && desc.value.__concurix_blacklisted) {
        return;
      }
  
      // if we are supposed to skip a function, blacklist it so we don't wrap it.
      if( !rules.wrapKey(key) ){
        blacklist(obj[key]);
        return;
      }
  
      if ( util.isFunction(desc.value) && !wrap.isWrapper(obj[key]) && rules.wrapKey(key) ) {
        //console.log('wrapping ', key, ' for ', name, state.modInfo.top);
        obj[key] = wrap(obj[key])
                    .before(hooks.beforeHook)
                    .after(hooks.afterHook)
                    .module(name)
                    .state(state)
                    .nameIfNeeded(key)
                    .getProxy();
      } else if (util.isObject(desc.value) && !wrap.isWrapper(obj[key]) && rules.wrapKey(key)) {
        // to save cycles do not go up through the prototype chain for object-type properties
        wrapFunctions(name, desc.value, 0, hooks, state, rules);
      }
    });
    // protoLevel is how deep you want to traverse the prototype chain.
    // protoLevel = -1 - this will go all the way up excluding Object.prototype
    if (protoLevel != 0){
      protoLevel--;
      var proto = Object.getPrototypeOf(obj);
      wrapFunctions(name, proto, protoLevel, hooks, state, rules);
    }
  }