 	lhs-indeces (first old-indeces)
 	lhses (lhses-get lhs-indeces i fk)
 	rhs-indeces (rest new-indeces)
-	joins (mapcat (fn [lhs] (derive-joins lhs rhs-indeces lhs-fk-keys join-fn)) lhses)
+	joins (mapcat (fn [lhs] (derive-joins rhs-indeces lhs-fk-keys lhs join-fn)) lhses)
 	]
     [new-indeces (fn [_] (on-upserts joined-model joins))]
     ))

(defn- lhs-upserts [old-indeces i ks vs join-fn])
(defn- lhs-deletes [old-indeces i ks vs join-fn])

(defn- lhs-view [indeces i keys join-fn joined-model]
  (reify
   View
   ;; singleton changes
   (on-upsert [_ upsertion] ((swap*! indeces lhs-upsert keys upsertion join-fn joined-model) []) nil) ;TODO - pass in views to notifier
   (on-delete [_ deletion]  (swap! indeces lhs-delete keys deletion join-fn) nil)
   ;; batch changes
   (on-upserts [_ upsertions] (swap! indeces lhs-upserts keys upsertions join-fn) nil)
   (on-deletes [_ deletions]  (swap! indeces lhs-deletes keys deletions join-fn) nil)))

;; TODO: return a pair - first is notification fn, second is new-indeces - use swap*! to apply


  "return seq of lhses indexed by i/fk"
  ((nth lhs-indeces (dec i)) fk))	;TODO - don't like dec here

(defn- lhs-assoc [old-indeces lhs-fk-keys lhs]
  "associate a new lhs with existing index"
  (let [new-lhs-index (mapv
		       (fn [lhs-index lhs-fk-key] (group lhs-index (lhs-fk-key lhs) lhs))
		       (first old-indeces)
		       lhs-fk-keys)
	new-indeces (assoc old-indeces 0 new-lhs-index)]
    new-indeces))

;;--------------------------------------------------------------------------------
;; this layer encapsulates access to rhs indeces

(defn- rhses-get [rhs-indeces lhs-fk-keys lhs]
  "return a lazy seq of seqs of rhses indexed by their respective fks"
  (map (fn [rhs-index lhs-fk-key] (rhs-index (lhs-fk-key lhs))) rhs-indeces lhs-fk-keys))

(defn- rhs-assoc [old-indeces i fk rhs]
  "associate a new rhs with existing index"
