   "Parse a single item of JSON data from a java.io.Reader. Options are
   key-value pairs, valid options are:
 
+     :eof-error? boolean
+
+        If true (default) will throw exception if the stream is empty.
+
+     :eof-value Object
+
+        Object to return if the stream is empty and eof-error? is
+        false. Default is nil.
+
      :bigdec boolean
 
         If true use BigDecimal for decimal numbers instead of Double.
         Default is false.
 
-     :eof-error? boolean
-
-        If true (default) will throw exception if the stream is empty.
-
-     :eof-value Object
-
-        Object to return if the stream is empty and eof-error? is
-        false. Default is nil.
-
      :key-fn function
 
         Single-argument function called on JSON property names; return
         value will replace the property names in the output. Default
-        is clojure.core/keyword.
+        is clojure.core/identity, use clojure.core/keyword to get
+        keyword properties.
 
      :value-fn function
 

    (.append sb \")
    (.print out (str sb))))

(defn- as-str
  [x]
  (if (instance? clojure.lang.Named x)
    (name x)
    (str x)))

(defn- write-object [m ^PrintWriter out] 
  (.print out \{)
  (loop [x m]
    (when (seq m)
      (let [[k v] (first x)]
        (when (nil? k)
          (throw (Exception. "JSON object keys cannot be nil/null")))
	(write-string (as-str k) out)
        (.print out \:)
        (-write-json v out))
      (let [nxt (next x)]
        (when (seq nxt)
          (.print out \,)


    :escape-slash boolean

       If true (default) the slash / is escaped as \\/

    :key-fn function

        Single-argument function called on map keys; return value will
        replace the property names in the output. Must return a
        string. Default calls clojure.core/name on symbols and
        keywords and clojure.core/str on everything else.

    :value-fn function

        Function to transform values before writing. For each
        key-value pair in the input, called with two arguments: the
        key (BEFORE transformation by key-fn) and the value. The
        return value of value-fn will replace the value in the output.
        If the return value is a number, boolean, string, or nil it
        will be included literally in the output. If the return value
        is a non-map collection, it will be processed recursively. If
        the return value is a map, it will be processed recursively,
        calling value-fn again on its key-value pairs. If value-fn
        returns itself, the key-value pair will be omitted from the
        output."
  [x ^Writer writer & options]
  (let [{:keys [escape-unicode escape-slash key-fn value-fn]
         :or {escape-unicode true
              escape-slash true
              key-fn default-write-key-fn
              value-fn default-value-fn}} options]
    (binding [*escape-unicode* escape-unicode
              *escape-slash* escape-slash
              *key-fn* key-fn
              *value-fn* value-fn]
      (let [out-value (value-fn x)]
        (when-not (= *value-fn* out-value)
          (-write-json out-value (PrintWriter. writer)))))))

(defn json-str
  "Converts x to a JSON-formatted string. Options are the same as
