code: function(key, options){
      options || (options = {});
      var parts  = $.splitPath(key),
          result = this,
          i, l=parts.length;
  
      if(_.isUndefined(key) || _.isNull(key)){ return void 0; }
      if(key === '' || parts.length === 0){ return result; }
  
      for (i = 0; i < l; i++) {
        if(result && result.isComputedProperty && options.raw) return result;
        if(result && result.isComputedProperty) result = result.value();
        if(_.isUndefined(result) || _.isNull(result)) return result;
        if(parts[i] === '@parent') result = result.__parent__;
        else if(result.isCollection) result = result.models[parts[i]];
        else if(result.isModel) result = result.attributes[parts[i]];
        else if(result && result.hasOwnProperty(parts[i])) result = result[parts[i]];
      }
  
      if(result && result.isComputedProperty && !options.raw) result = result.value();
      return result;
    }
docs: **Model.Get** is overridden to provide support for getting from a deep data tree. `key` may now be any valid json-like identifier. Ex: `obj.coll[3].value`. It needs to traverse `Models`, `Collections` and `Computed Properties` to find the correct value. - If key is undefined, return `undefined`. - If key is empty string, return `this`.  For each part: - If a `Computed Property` and `options.raw` is true, return it. - If a `Computed Property` traverse to its value. - If not set, return its falsy value. - If a `Model` or `Collection`, traverse to it.