docs: function ComponentWidget(ViewConstructor, model, template, options, key) {
    this.ViewConstructor = ViewConstructor;
    this.model = model;
    this.model.isComponentModel = true;
    this.template = template;
    this._isInitializedCallbacks = [];
    this.isInitialized = false;
    this.key = key || _.uniqueId('w_component');
    this.model.session = (this.model.session || []).concat(['content', 'yield']);
    if (typeof TUNGSTENJS_DEBUG_MODE !== 'undefined') {
      this.model._private = {
        content: true, yield: true
      };
    }
  
    // Start with generic model functions
    var methodsToExpose = modelFunctionsToMap;
    // Add any methods declared by the model
    if (model.exposedFunctions && _.isArray(model.exposedFunctions)) {
      methodsToExpose = methodsToExpose.concat(model.exposedFunctions);
    }
    // Add any methods declared by the component
    if (options && options.exposedFunctions && _.isArray(options.exposedFunctions)) {
      methodsToExpose = methodsToExpose.concat(options.exposedFunctions);
    }
    // dedupe
    methodsToExpose = _.uniq(methodsToExpose);
  
    var i, fn;
    for (i = 0; i < methodsToExpose.length; i++) {
      fn = methodsToExpose[i];
      if (typeof model[fn] === 'function') {
        if (typeof this[fn] === 'undefined') {
          this[fn] = _.bind(model[fn], model);
        } else {
          errors.cannotOverwriteComponentMethod(fn);
        }
      }
    }
  
    if (options && options.exposedEvents === true || model.exposedEvents === true) {
      this.exposedEvents = true;
    } else {
      this.exposedEvents = [];
      if (options && options.exposedEvents && _.isArray(options.exposedEvents)) {
        this.exposedEvents = this.exposedEvents.concat(options.exposedEvents);
      }
      if (model.exposedEvents && _.isArray(model.exposedEvents)) {
        this.exposedEvents = this.exposedEvents.concat(model.exposedEvents);
      }
      this.exposedEvents = _.uniq(this.exposedEvents);
    }
  
    // Other model functions should be present, but noops
    for (i = 0; i < modelFunctionsToDummy.length; i++) {
      fn = modelFunctionsToDummy[i];
      this[fn] = getDummyFunction(fn);
    }
    // Setting some values for Collection use
    this.idAttribute = 'key';
    this.attributes = model.attributes;
    this.cid = model.cid;
  
    if (options && options.collection) {
      // If passed a collection during construction, save a reference
      this.collection = options.collection;
    }
  
    // Ensure that destroying the model destroys the component
    if (typeof this.model.destroy === 'function') {
      var self = this;
      var _destroy = _.bind(this.model.destroy, this.model);
      this.model.destroy = function(opts) {
        if (self.collection) {
          self.collection.remove(self);
        } else if (self.parent) {
          self.parent.unset(self.parentProp);
        }
        _destroy(opts);
      };
    }
  }