     [new-indeces (fn [_] (on-upserts joined-model joins))]
     ))
 
+;;; TODO - ugly, slow and should remove key rather than leaving a key:nil assoc...
+(defn- rhs-delete [old-indeces i rhs-pk-key rhs-fk-key lhs-fk-keys rhs join-fn joined-model]
+  (let [fk (rhs-fk-key rhs)
+	old-rhs-indeces (rest old-indeces)
+	lhs-indeces (first old-indeces)
+	lhses (lhses-get lhs-indeces (dec i) fk)
+	old-joins (mapcat (fn [lhs] (derive-joins old-rhs-indeces lhs-fk-keys lhs join-fn)) lhses)
+	new-indeces (rhs-dissoc old-indeces i rhs-pk-key fk rhs)
+	new-rhs-indeces (rest new-indeces)
+	new-joins (mapcat (fn [lhs] (derive-joins new-rhs-indeces lhs-fk-keys lhs join-fn)) lhses)
+	joins (remove (fn [i] (contains? (apply hash-set new-joins) i)) old-joins)
+	]
+    [new-indeces (fn [_] (on-deletes joined-model joins))]
+    ))
+
 ;;; TODO
-(defn- rhs-delete [old-indeces i ks v join-fn])
 (defn- rhs-upserts [old-indeces i ks vs join-fn])
 (defn- rhs-deletes [old-indeces i ks vs join-fn])
 

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

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

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

	   }
	   (data joined-model)))

    ;; join - delete lhs - a2
    (on-delete as a2)
    (is (= [[{:b {:a1 a1v1}}{:c {:a1 a1v1}}]
	    {:b {:b1 b1v1 :b2 b2}} {:c {:c1 c1v1 :c2 c2}}] (data join)))
