                 (if (or (= (count update) 1) (not (filter update)))
                   (do
                     (set! avl-set (disj avl-set k))
-                    (-proj-remove-elem target cur-idx))
+                    (target-remove target cur-idx))
                   (do
                     (set! avl-set (conj avl-set k))
                     (let [new-idx (.rankOf this k)]
                       (when-not (identical? cur-idx new-idx)
-                        (-proj-move-elem target cur-idx new-idx)))))
+                        (target-move target cur-idx new-idx)))))
                 (when (filter update)
                   (set! avl-set (conj avl-set k))
-                  (-proj-insert-elem target (rx* (fn [] (proj-fn (cursor cur k)))) (.rankOf this k))))))))
-
-       IReactiveProjection
-       (-project-elements [this proj-target enqueue]
+                  (target-insert target (rx* (fn [] (target-fn (cursor cur k)))) (.rankOf this k))))))))
+
+       IProjection
+       (-project [this proj-target enqueue]
          (set! target proj-target)
          (set! enqueue-fn enqueue)
-         (let [{:keys [filter sort-by offset limit placeholder-idx placeholder]} opts]
+         (let [{:keys [filter sort-by offset limit]} opts]
            (when filter (bind-attr* filter #(.updateFilter this %) enqueue))
            (bind-attr* sort-by #(.updateSortBy this %) enqueue)
            (when offset (bind-attr* offset #(.updateOffset this %) enqueue))

  (-parent-cursor [this]
    (when tkey
      parent))
  (-cursor-keyset [this] (coll-keyset state))

  IChangeNotifications
  (-add-change-watch [this key f]

                           (fn [k r updates] (.onUpdates this updates)))
         (.project this)))

     (deftype SeqProjectionSource [elements target enqueue]
       Object
       (refresh [this]
         (dotimes [i (count elements)]
           (target-insert target (nth elements i) nil)))

       IProjectionSource
       (-source-pull [this idx]
         (when (< idx (count elements))
           (aget elements idx)))) 

     (defn seq-projection [elements]
       (reify IProjection
         (-project [this target enqueue]
           (let [source (SeqProjectionSource. elements target enqueue)]
             (target-init target source)
             (enqueue (fn [] (.refresh source)))))))

     (defprotocol IAsVirtualElement
       (-as-velem [this as-velem-fn]))

     (deftype VirtualElementWrapper [])

     (defn- wrap [wrap-fn elem] (wrap-fn elem))

     (defn- unwrap [elem] elem)

     (deftype MapProjection [wrap-fn target ^:mutable source]
       IProjectionSource
       (-source-pull [this idx]
         (wrap wrap-fn (source-pull source idx)))
       
       IProjectionTarget
       (-target-init [this src]
         (set! source src))
       (-target-insert [this elem before-idx]
         (target-insert target (wrap wrap-fn elem) before-idx))
       (-target-peek [this i]
         (unwrap (target-peek target i)))
       (-target-take [this i]
         (unwrap (target-peek target i)))
       (-target-count [this]
         (target-count target))
       (-target-move [this elem-idx before-idx]
         (target-move target elem-idx before-idx))
       (-target-remove [this elem-idx]
         (target-remove target elem-idx))
       (-target-clear [this]
         (target-clear target)))

     (defn pwrap [proj wrap-fn]
       (reify IProjection
         (-project [this target enqueue-fn]
           (let [pproj (MapProjection. wrap-fn target nil)]
             (target-init target pproj)
             (project proj pproj enqueue-fn)))))

     (deftype OffsetProjection [offset source target]
       Object
       (translate [i]
         (let [j (- i offset)]
           (when (>= j 0)
             j)))
       IProjectionTarget
       (-target-insert [this elem before-idx]
         (if (> before-idx offset)
           (target-insert target elem (- before-idx offset))))
       (-target-peek [this i]
         (when-let [j (translate i)]
           (target-peek target j)))
       (-target-take [this i]
         (when-let [j (translate i)]
           (target-take target j)))
       (-target-count [this]
         (target-count target))
       (-target-move [this elem-idx before-idx])
       (-target-remove [this elem-idx])
       (-target-clear [this]))

     (defn poffset [proj offset]
       (reify IProjection
         (-project [this target enqueue-fn]
           (let [pproj (OffsetProjection. offset target nil)]
             (target-init target pproj)
             (project proj pproj enqueue-fn)))))

     (deftype LimitProjection [offset source target]
       Object
       (translate [i]
         (let [j (- i offset)]
           (when (>= j 0)
             j)))
       IProjectionTarget
       (-target-insert [this elem before-idx]
         (if (> before-idx offset)
           (target-insert target elem (- before-idx offset))))
       (-target-peek [this i]
         (when-let [j (translate i)]
           (target-peek target j)))
       (-target-take [this i]
         (when-let [j (translate i)]
           (target-take target j)))
       (-target-count [this]
         (target-count target))
       (-target-move [this elem-idx before-idx])
       (-target-remove [this elem-idx])
       (-target-clear [this]))

     (defn plimit [proj limit]
       (reify IProjection
         (-project [this target enqueue-fn]
           (project proj (LimitProjection. limit proj target) enqueue-fn))))

     (defn- cmap2* [f keyset-cursor
                    {:keys [filter sort offset limit placeholder-idx placeholder] :as opts}]
       (cond-> keyset-cursor
         filter (cursor-filter filter)
         true (cursor-sort sort)
         offset (poffset offset)
         limit (plimit limit)
         true (pwrap f)))

     (defn cmap*
       [f keyset-cursor opts]
       (KeysetCursorProjection. keyset-cursor f opts nil nil nil identity 0 nil nil nil nil))
