 
     :escape-slash boolean
 
-       If true (default) the slash / is escaped as \\/"
+       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]
+  (let [{:keys [escape-unicode escape-slash key-fn value-fn]
          :or {escape-unicode true
-              escape-slash true}} options]
+              escape-slash true
+              key-fn default-write-key-fn
+              value-fn default-value-fn}} options]
     (binding [*escape-unicode* escape-unicode
-              *escape-slash* escape-slash]
-      (-write-json x (PrintWriter. writer)))))
+              *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

(extend java.lang.Object       JSONWriter {:-write-json write-generic})

(defn write-json
  "Write JSON-formatted output to a java.io.Writer.
   Options are key-value pairs, valid options are:

    :escape-unicode boolean


        name (transformed by key-fn) and the value. The return value
        of value-fn will replace the value in the output. If value-fn
        returns itself, the property will be omitted from the output.
        The default value-fn returns the value unchanged."
  [reader & options]
  (let [{:keys [eof-error? eof-value bigdec key-fn value-fn]
         :or {bigdec false
              eof-error? true
              key-fn identity
              value-fn default-value-fn}} options]
    (binding [*bigdec* bigdec
              *key-fn* key-fn
              *value-fn* value-fn]
      (-parse reader eof-error? eof-value))))

(defn parse-string
  "Reads one JSON value from input String. Options are the same as for
