docs: function Model(defaults){
  
      // Make sure "new" is always used,
      // so we can use "instanceof" to check if something is a Model.
      if (!(this instanceof Model)) {
        return new Model(defaults);
      }
  
      // `model` is the public API object returned from invoking `new Model()`.
      var model = this,
  
          // The internal stored values for tracked properties. { property -> value }
          values = {},
  
          // The callback functions for each tracked property. { property -> [callback] }
          listeners = {},
  
          // The set of tracked properties. { property -> true }
          trackedProperties = {};
  
      // The functional reactive "when" operator.
      //
      //  * `properties` An array of property names (can also be a single property string).
      //  * `callback` A callback function that is called:
      //    * with property values as arguments, ordered corresponding to the properties array,
      //    * only if all specified properties have values,
      //    * once for initialization,
      //    * whenever one or more specified properties change,
      //    * on the next tick of the JavaScript event loop after properties change,
      //    * only once as a result of one or more synchronous changes to dependency properties.
      function when(properties, callback, thisArg){
        
        // Make sure the default `this` becomes 
        // the object you called `.on` on.
        thisArg = thisArg || this;
  
        // Handle either an array or a single string.
        properties = (properties instanceof Array) ? properties : [properties];
  
        // This function will trigger the callback to be invoked.
        var listener = debounce(function (){
          var args = properties.map(function(property){
            return values[property];
          });
          if(allAreDefined(args)){
            callback.apply(thisArg, args);
          }
        });
  
        // Trigger the callback once for initialization.
        listener();
        
        // Trigger the callback whenever specified properties change.
        properties.forEach(function(property){
          on(property, listener);
        });
  
        // Return this function so it can be removed later with `model.cancel(listener)`.
        return listener;
      }
  
      // Adds a change listener for a given property with Backbone-like behavior.
      // Similar to http://backbonejs.org/#Events-on
      function on(property, callback, thisArg){
        thisArg = thisArg || this;
        getListeners(property).push(callback);
        track(property, thisArg);
      }
      
      // Gets or creates the array of listener functions for a given property.
      function getListeners(property){
        return listeners[property] || (listeners[property] = []);
      }
  
      // Tracks a property if it is not already tracked.
      function track(property, thisArg){
        if(!(property in trackedProperties)){
          trackedProperties[property] = true;
          values[property] = model[property];
          Object.defineProperty(model, property, {
            get: function () { return values[property]; },
            set: function(newValue) {
              var oldValue = values[property];
              values[property] = newValue;
              getListeners(property).forEach(function(callback){
                callback.call(thisArg, newValue, oldValue);
              });
            }
          });
        }
      }
  
      // Cancels a listener returned by a call to `model.when(...)`.
      function cancel(listener){
        for(var property in listeners){
          off(property, listener);
        }
      }
  
      // Removes a change listener added using `on`.
      function off(property, callback){
        listeners[property] = listeners[property].filter(function (listener) {
          return listener !== callback;
        });
      }
  
      // Sets all of the given values on the model.
      // `newValues` is an object { property -> value }.
      function set(newValues){
        for(var property in newValues){
          model[property] = newValues[property];
        }
      }
  
      // Transfer defaults passed into the constructor to the model.
      set(defaults);
  
      // Public API.
      model.when = when;
      model.cancel = cancel;
      model.on = on;
      model.off = off;
      model.set = set;
    }