      :post-path post-path
      :post-params group-post-params
      :preprocess (partial mact/fetch-and-pre-assoc :server-groups :set)
-     :pre-node-action groups-pre-node-action})
+     :pre-node-action (partial pre-node-action :server-groups :set :channelGroup)})
    
    (make-api
     {:rest-path (constantly "/channels")

     :post-path post-path
     :post-params codelib-post-params
     :preprocess (partial mact/fetch-and-pre-assoc :server-codelibs :list)
     :pre-node-action codelibs-pre-node-action})

   (make-api
    {:rest-path (constantly "/codeTemplates")
     :local-path (local-path "CodeTemplates")

   ["updatedCodeTemplates" "<list/>"]
   ["removedCodeTemplateIds" "<set/>"]))

;FIXME: The logic is fine but the function could stand to have some
;attention to make it a little less ugly both here and in the apis
;that use it below.
(defn pre-node-action
  "Returns an updated app-conf with the current api element node added
  to the relevant api list/set in app conf. If node matching by id is
  found - it is removed before the new element is appended. set-key is
  the key used to find the root loc in app-conf and root-tag is the
  key for the root tag. node tag is the wrapper tag keyword."
  [set-key root-tag node-tag
   {:keys [el-loc] :as app-conf
    {:keys [find-id]} :api}]
  (let [set (set-key app-conf)
        found-id-loc (zx/xml1-> set
                                root-tag
                                node-tag
                                :id
                                (zx/text= (find-id el-loc)))

        set (if found-id-loc
              (zip/remove (zip/up found-id-loc))
              set)

        set (zip/append-child set (zip/node el-loc))]
    (assoc app-conf set-key set)))

(defn safe-name?
  "Takes and returns an unmodified string that should represent a
