   and v is the new value and returns a new nested structure. The associative structure
   can have transients in it, but if any levels do not exist, non-transient hash-maps will
   be created."
-  [m [k & ks :as keys] v]
+  [m [k & ks] v]
   (let [assoc (if (instance? clojure.lang.ITransientCollection m) assoc! assoc)]
     (if ks
       (assoc m k (assoc-in! (get m k) ks v))

  (last (first (filter (comp pred first) (zip keys vals)))))

(defn filter-keys-by-val
  "Returns a keys of map for which (pred value) returns true."
  [pred map]
  (if map
    (for [[key val] map :when (pred val)] key)))

(defn remove-keys-by-val

(defn include?
  "Check if val exists in coll."
  [val coll]
  (some #{val} coll))

(defn extract
  "Extracts the first item that matches pred from coll, returning a vector of that item
   followed by coll with the items removed."
  [pred coll]
  (let [[head [item & tail]] (split-with (complement pred) coll)]
    [item (concat head tail)]))

(defn separate
  "Split coll into two sequences, one that matches pred and one that doesn't. Unlike, the
  version in clojure.contrib.seq-utils, this is not lazy, but pred is only called once per item."
  [pred coll]
  (reduce (fn [[yes no] item]
            (if (pred item)
              [(conj yes item) no]
              [yes (conj no item)]))
          [[] []]
          coll))

(defmacro if-ns [ns-reference then-form & [else-form]]
  "Try to load a namespace reference. If successful, evaluate then-form otherwise evaluate else-form."
  `(try (ns ~(ns-name *ns*) ~ns-reference)
        (eval '~then-form)
        (catch Exception e#
          (when-not (instance? java.io.FileNotFoundException e#)
            (println "Error loading" '~ns-reference (.getMessage e#)))
          (eval '~else-form))))

