                     [(assoc ours path our-edit') (assoc theirs path their-edit')]))
                 [ours theirs]
                 shared)
-              ours'' (rebase-keys doc ours' (select-keys theirs' r))
-              theirs'' (rebase-keys doc theirs' (select-keys ours' l))]
+              ours'' (rebase-paths doc ours' (select-keys theirs' r))
+              theirs'' (rebase-paths doc theirs' (select-keys ours' l))]
           (recur (inc level) ours'' theirs''))))))

            rebased-path (when rebased-key (assoc old-path key-index rebased-key))]
        [old-path rebased-path]))))

(defn rebase-keys
  [doc old new]
  (let [mappings (mappings-for doc old new)
        rebased (set/rename-keys old mappings)]
    (dissoc rebased nil)))

(defn compose
  ([doc old new]
    (let [rebased (rebase-keys doc old new)]
      (reduce
        (fn [composed [new-path new-edit]]
          (if (contains? composed new-path)
            (assoc composed new-path (impl/compose (get-in doc new-path)
                                                   (get composed new-path)
                                                   new-edit))
            (assoc composed new-path new-edit)))
        rebased
        new)))
  ([doc old new & more]
    (reduce (partial compose doc) (compose doc old new) more)))


(def diff impl/diff)

(defn ^:private prefixes?
  [path-1 path-2]
  (and (< (count path-1) (count path-2))
       (= path-1 (subvec path-2 0 (count path-1)))))

(defn ^:private rebase-mappings
  [doc old new]
  (into {}
    (for [[new-path new-edit] new
