   (when-let [node-attached (get-state-attr state "node/on-attached")]
     (node-attached node)))
 
+(defn- on-moving [state node cb]
+  (if-let [node-moving (get-state-attr state "node/on-moving")]
+    (node-moving node cb)
+    (cb)))
+
+(defn- on-moved [state node]
+  (when-let [node-moved (get-state-attr state "node/on-moved")]
+    (node-moved node)))
+
+(defn- insert-node* [parent new-elem insert-fn]
+  (let [state (register-element-with-parent parent new-elem)]
+    (insert-fn)
+    (on-attached state new-elem)))
+
+(defn- move-node* [node move-fn]
+  (on-moving (get-element-state node) node move-fn))
+
+(defn- do-replace-node [parent new-elem cur-dom-node]
+  (insert-node* parent new-elem 
+                  (fn [] (.replaceChild parent new-elem cur-dom-node))))
+
 (defn- replace-node-completely [parent new-elem-spec cur-dom-node top-level]
   (let [new-elem
         (if top-level

        (replace-node-completely
          parent new-elem-spec cur-dom-node top-level)))))

(defn- append-or-insert-child [parent vdom before]
  (if (satisfies? IDeref vdom)
    (bind-child parent vdom before nil)
    (let [new-elem (build vdom)]
      (let [state (register-element-with-parent parent new-elem)]
        (if before
          (.insertBefore parent new-elem before)
          (.appendChild parent new-elem))
        (on-attached state new-elem))
      new-elem)))

;; Reactive Element Handling


;; Building Elements

(defn insert-before! [parent child before]
  (append-or-insert-child parent child before))

(defn append-child! [parent child]
