 $.extend true, window, 
   SlickBone: {}
 
+# SlickBone.Collection. A sub-class of Backbone.Collection that implements the
+# basic interface required to be used as a backing-object for SlickGrid.
 class SlickBone.Collection extends Backbone.Collection
+  # The setGrid method is the meat of SlickBone. It sets the specified SlickGrid's data source
+  # to the collection. It subscribes to several events coming from the Grid to ensure that
+  # its subsituent models stay up-to-date. It also sets a few callbacks so that the grid will
+  # be notified in case any of the models chagne. 
+  # Do NOT call this method on a grid that already has another, established data source unless
+  # you are CERTAIN you do not mind losing the other data. 
   setGrid: (@grid) ->
     @_setGridData()
     

      attrs.cid = model.cid
    attrs

class SlickBone.Model extends Backbone.Model
  constructor: ->
    @_associations = {}
    @_derivations  = []
    super
    @bind 'change', => @_deriveFields()
    

  _addAssociation: (name, model, type) ->
    @_associations[name] = { model: model, associationType: type }

  hasMany:   (name, model) -> @_addAssociation(name, model, 'hasMany')
  hasOne:    (name, model) -> @_addAssociation(name, model, 'hasOne')
    
  derivedField: (fieldName, derivationFunction) ->
    @_derivations.push
      field: fieldName
      func:  derivationFunction

  prependDerivedField: (fieldName, derivationFunction) ->
    @_derivations.unshift
      field: fieldName
      func: derivationFunction
  
  _deriveFields: ->  
    for derivation in @_derivations
      result = {}
      result[derivation.field] = derivation.func(@)
      @set(result, silent: true)

  toJSON: ->
    result = super
    for attribute, value of result when _.include(_.keys(@_associations), attribute)
      result[attribute] = value.toJSON?()
    result

  set: (attrs, options) ->
    for attribute, value of attrs
      if _.include(_.keys(@_associations), attribute)
        associationDef = @_associations[attribute]
        attrs[attribute] = switch associationDef.associationType
          when 'hasOne' then (new associationDef.model(value))
          when 'hasMany' then (new associationDef.model).reset(value)
    super


      @grid.render()
      
    @bind 'reset', (model) => @_setGridData()
  
  # replace the grid's data with us.
  _setGridData: ->
    @grid.setData @
    @grid.invalidate()
  
  # Return the JSON associated with a particular index in the collection.
  getItem: (index) -> 
    model = @at(index)
    if model?
