     (.setAttributeName key-name)
     (.setAttributeType (str/upper-case (name key-type)))))
 
-(defn- attribute-definitions "Returns a new vector of AttributeDefinition objects."
+(defn- attribute-definitions "Returns a vector of AttributeDefinition objects."
   [defs] (mapv attribute-definition defs))
+
+(defn- create-projection "Returns a new Projection object."
+  [projection & [included-attrs]]
+  (let [pr (Projection.)]
+    (.setProjectionType pr (str/upper-case (name projection)))
+    (when included-attrs (.setNonKeyAttributes pr included-attrs))
+    pr))
+
+(defn- local-index "Returns a new LocalSecondaryIndex object."
+  [hash-key {:keys [name range-key projection included-attrs]
+             :or   {projection :all}}]
+  (doto (LocalSecondaryIndex.)
+    (.setIndexName  name)
+    (.setKeySchema  (key-schema hash-key range-key))
+    (.setProjection (create-projection projection included-attrs))))
+
+(defn- local-indexes "Returns a vector of LocalSecondaryIndexes objects."
+  [hash-key indexes] (mapv (partial local-index hash-key) indexes))
 
 ;;;; Coercion - values
 

    :limit - the maximum number of items to return
    :after - only return results after this key
    :consistent - return a consistent read if logical true
;;    :index - the secondary index to query ; TODO

  The items are returned as a map with the following keys:
    :items - the list of items returned


(defn- query-request
  "Create a QueryRequest object."
  [table hash-key range-clause {:keys [order limit after count consistent attrs index]}]
  (let [qr (QueryRequest.)
        hash-clause (set-hash-condition hash-key)
        [range-key operator range-value range-end] range-clause
