code: function (property, value) {
  
      var isString, hasChanged, oldValue, chain;
  
      // optimal
      if ((isString = (typeof property === "string")) && !~property.indexOf(".")) {
        hasChanged = (oldValue = this[property]) !== value;
        if (hasChanged) this[property] = value;
      } else {
  
        // avoid split if possible
        chain     = isString ? property.split(".") : property;
  
        var currentValue  = this,
        previousValue,
        currentProperty,
        newChain;
  
  
        for (var i = 0, n = chain.length - 1; i < n; i++) {
  
          currentProperty = chain[i];
          previousValue   = currentValue;
          currentValue    = currentValue[currentProperty];
  
  
          // need to take into account functions - easier not to check
          // if value exists
          if (!currentValue /* || (typeof currentValue !== "object")*/) {
            currentValue = previousValue[currentProperty] = {};
          }
  
          // is the previous value bindable? pass it on
          if (currentValue.__isBindable) {
  
            newChain = chain.slice(i + 1);
            // check if the value has changed
            hasChanged = (oldValue = currentValue.get(newChain)) !== value;
            currentValue.set(newChain, value);
            currentValue = oldValue;
            break;
          }
        }
  
  
        if (!newChain && (hasChanged = (currentValue !== value))) {
          currentProperty = chain[i];
          oldValue = currentValue[currentProperty];
          currentValue[currentProperty] = value;
        }
      }
  
      if (!hasChanged) return value;
  
      var prop = chain ? chain.join(".") : property;
  
      this.emit("change:" + prop, value, oldValue);
      this.emit("change", prop, value, oldValue);
      return value;
    }
docs: Sets a property on the bindable object's context
  @method set
  @param {String} path path to the value. Can be something like `person.city.name`.