 
 (defn- rhs-upsert [[lhs-indeces old-rhs-indeces old-joins] i rhs-pk-key rhs-fk-key lhs-fk-keys rhs join-fn join-pk joined-model]
   (let [fk (rhs-fk-key rhs)
-	new-rhs-indeces (rhs-assoc-2 old-rhs-indeces i rhs-pk-key fk rhs)
+	new-rhs-indeces (rhs-assoc old-rhs-indeces i rhs-pk-key fk rhs)
 	lhses (lhses-get lhs-indeces i fk)
 	joins (mapcat (fn [lhs] (derive-joins new-rhs-indeces lhs-fk-keys lhs join-fn)) lhses)
 	new-joins (reduce (fn [old-joins join] (assoc old-joins (join-pk join) join)) old-joins joins)

  (let [fk (rhs-fk-key rhs)
	lhses (lhses-get lhs-indeces i fk)
	old-joins2 (mapcat (fn [lhs] (derive-joins old-rhs-indeces lhs-fk-keys lhs join-fn)) lhses)
	new-rhs-indeces (rhs-dissoc-2 old-rhs-indeces i rhs-pk-key fk rhs)
	new-joins2 (mapcat (fn [lhs] (derive-joins new-rhs-indeces lhs-fk-keys lhs join-fn)) lhses)
	joins (remove (fn [i] (contains? (apply hash-set new-joins2) i)) old-joins2)
	new-joins (reduce (fn [old-joins join] (dissoc old-joins (join-pk join))) old-joins joins)

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

(defn- rhs-assoc [rhs-indeces i rhs-pk-key fk rhs]
  "associate a new rhs with existing index"
  (assoc-in rhs-indeces [i fk (rhs-pk-key rhs)] rhs))

(defn- rhs-dissoc [rhs-indeces i rhs-pk-key fk rhs]
  "dissociate an rhs from existing index"
  (let [rhs-pk (rhs-pk-key rhs)]
    (assoc-in rhs-indeces [i fk] (dissoc ((rhs-indeces i) fk) rhs-pk))))

(deftest test-rhs-access
  (let [before [{}]
	after  [{String {3 "xxx"}}]]
    (is (= after (rhs-assoc before 0 count String "xxx")))
    (is (= '(("xxx")) (rhses-get after [first] [String])))
    (is (= [{String {}}] (rhs-dissoc after 0 count String "xxx")))))

;;--------------------------------------------------------------------------------
;; this layer encapsulates access to both lhs and rhs at the same time...
