             new target_class(options)
 
     # returns a collection for the given association.
-    collectionFor: (name) ->
+    collectionFor: (name, model, options = {}) ->
+        options = _.extend({}, this.getOptions(name, model), options)
         @collections[name] ||= (
-            klass = @getClassFor(name)
-            klass = klass.Collection if true == klass::isModel
-            new klass
+            Klass = @getClassFor(name)
+            if true == Klass::isModel
+                new Lanes.Models.AssociationCollection(options.models || [],
+                    _.extend({}, options, model: Klass)
+                )
+            else
+                new Klass(options.models || [], options)
         )
-
-    # set from collection
-    getModelFromCollection: (model, name, collection) ->
-        throw("#{name} isn't an association") unless _.has(@definitions, name)
-        if not model[name].isNew()
-            return model[name]
-        else
-            id = model[@pk(name)]
-            model = collection.get(id)
-            collection.fetchId(id) if id and not model
-            model
 
     # will be called in the scope of the parent model
     createCollection: (association, name, definition, fk, pk, target_class) ->
         target_class ||= association.getClassFor(name)
-        options = association.getOptions(name, definition, this)
+        options = association.getOptions(name, this)
         options.filter ||= {}
         options.filter[fk] = this.get(pk)
 

            new target_class(options.models || [], options)
        else
            options.model = target_class
            new Lanes.Models.AssociationCollection(options. models || [], options)
    # returns the definition for the derived property
    derivedDefinition: (name, definition) ->
        defaultCreator = if definition.model then this.createModel else this.createCollection

            -> definition.default.apply(this, args) || defaultCreator.apply(this, args)
        else
            defaultCreator
        { fn: _.partial(createFn, args...) }


    # Sets the assocations for "model"
    set: (model, data, options) ->
        this._set(model, data, options, 'set')
        for name, value of data
            if @definitions[name] && Lanes.u.isModel(value) && !value.isNew()
                model[@pk(name)] = if value then value.getId() else null

    setFromServer: (model, data, options) ->
        this._set(model, data, options, 'setFromServer')

    _set: (model, data, options, fn_name) ->
        for name, value of data
            continue unless @definitions[name]
            association = model[name]
            attributes = if _.isFunction(value.serialize) then value.serialize() else value
            association[fn_name]( attributes )
            if Lanes.u.isModel(association)
                model.set(this.pk(name), association.id) unless association.isNew()
                model.trigger("change:#{name}", value) unless options?.silent
                association.isDirty = if value.isDirty? then value.isDirty else true
                unless _.isObject(value)
                    association.clear()
                    continue

    pk: (name) ->
        def = @definitions[name]
        return null unless name and def
        _.result(def, 'pk', ( if def.model then "#{name}_id" else "id" ) )

    fk: (name) ->
        def = @definitions[name]
        return null unless name and def
        _.result(def,'fk', ( if def.model then "id" else "#{name}_id" ) )

    # returns the data from all assocations for saving
    dataForSave: (model, options) ->
