docs: function wrapMethod(name, method, constructor, isStatic) {
          if (method[$wrapped]) {
              method = method[$wrapped];
          }
  
          var parentClass = constructor.$parent,
              parentSource = parentClass && (isStatic ? parentClass : parentClass.prototype),
              parentMeta = parentClass && parentClass[$class][isStatic ? 'staticMethods' : 'methods'][name],
              parentLocked = parentClass && parentClass[$class].locked && !parentClass[$class].forceUnlocked,
              parentMethod,
              wrapper;
  
          if (parentMeta) {
              if (!isStatic && parentMeta.isPrivate && name === 'initialize') {
                  parentMethod = callingPrivateConstructor;
                  parentSource = null;
              } else {
                  parentMethod = parentMeta.implementation;
              }
          } else {
              parentMethod = defaultSuper;
          }
  
          wrapper = function () {
              var that = this == null || this === glob ? {} : this,
                  _super = that.$super,
                  _self = that.$self,
                  prevCaller,
                  ret,
                  parent;
  
              // Use the real source of the method if available, fallbacking to the
              // cached one because private/protected are not on the parent prototype
              // See: https://github.com/IndigoUnited/dejavu/issues/49
              parent = parentLocked || !parentSource ? parentMethod : parentSource[name];
  
              prevCaller = caller;
              caller = {
                  method: method,
                  constructor: constructor,
                  constructorId: constructor[$class].id
              };
              that.$super = parent;
              that.$self = constructor;
  
              try {
                  ret = method.apply(this, arguments);
              } finally {
                  that.$super = _super;
                  that.$self = _self;
                  caller = prevCaller;
              }
  
              return ret;
          };
  
          obfuscateProperty(wrapper, $wrapped, method);
  
          if (method[$name]) {
              obfuscateProperty(wrapper, $name, method[$name]);
          }
  
          return wrapper;
      }