docs: function createMethodsManager() {
      var methods = {};
  
      return {
          addMethod: addMethod,
          setTarget: setTarget
      };
  
      /*
       * Adds a method that will be available to extend the object.
       *
       * @param {string} name The method name
       * @param {function} [method] The handler for the specified method name.
       * @return {function} The handler for the specified method name.
       */
      function addMethod(name, method) {
          if (method !== undefined) {
              methods[name] = method;
          }
          return methods[name];
      }
  
      /*
       * Sets the target object to extend.
       *
       * @param {object} target The target object.
       */
      function setTarget(target) {
          var targetMethods = {};
          for (var name in methods) {
              targetMethods[name] = wrapMethod(target, methods[name]);
          }
          return targetMethods;
      }
  
      /*
       * Wraps the method so that it is executed with the appropriate
       * arguments.
       *
       * @param {object} target The target object.
       * @param {function} method The method to wrap.
       */
      function wrapMethod(target, method) {
          return function() {
  
              // Put arguments into a real array.
              var methodArgs = [];
              for (var i = 0; i < arguments.length; i++) {
                  methodArgs.push(arguments[i]);
              }
  
              var params = method(target, parseMethodArgs, methodArgs);
  
              modifyTarget(target,
                  params.source,
                  params.sourceKeys,
                  params.filters,
                  params.overrideKeys);
              return this;
          };
      }
  }