     {:consumed-capacity-units (.getConsumedCapacityUnits result)
      :items (some->> (.getItems result)
                      (into [])
-                     (utils/fmap #(utils/fmap get-value (into {} %))))})
+                     (utils/fmap #(utils/fmap db-val->clj-val (into {} %))))})
   KeysAndAttributes
   (as-map [result]
     (merge

  [{:keys [hash-key range-key]}]
  (let [key (Key.)]
    (when hash-key
      (.setHashKeyElement key (to-attr-value hash-key)))
    (when range-key
      (.setRangeKeyElement key (to-attr-value range-key)))
    key))

(defn get-item


;;;; Coercions

(defn- str->num [^String s] (if (.contains s ".") (Double. s) (Long. s)))
(defn- bb->ba   [^ByteBuffer bb] (.array bb))

(defn- db-val->clj-val
  "Returns the Clojure value of given AttributeValue object."
  [^AttributeValue x]
  (or (.getS x)
      (some->> (.getN  x) str->num)
      (some->> (.getB  x) bb->ba)
      (some->> (.getSS x) (into #{}))
      (some->> (.getNS x) (map str->num) (into #{}))
      (some->> (.getBS x) (map bb->ba)   (into #{}))))

(defn- set-of [pred s] (and (set? s) (every? pred s)))
(def ^:private ^:const ba-class (Class/forName "[B"))
(defn- ba? [x] (instance? ba-class x))
(defn- ba-buffer [^bytes ba] (ByteBuffer/wrap ba))
(defn- simple-num? [x] (or (instance? Long    x)
                           (instance? Double  x)
                           (instance? Integer x)
                           (instance? Float   x)))

(defn- clj-val->db-val
  "Returns an AttributeValue object for given Clojure value."
  ;; TODO Nippy support (will require special marker bin-wrapping)
  ;; TODO More efficient set-type dispatch
  [x]
  (cond
   (string? x)        (doto (AttributeValue.) (.setS x))
   (simple-num? x)    (doto (AttributeValue.) (.setN (str x)))
   (ba?     x)        (doto (AttributeValue.) (.setB (ba-buffer x)))
   (set-of string? x) (doto (AttributeValue.) (.setSS x))
   (set-of number? x) (doto (AttributeValue.) (.setNS (map str x)))
