     javax.xml.bind.DatatypeConverter))
 
 
-;; ## Specs
-
-;; Lexicoders can be specified either as a simple type keyword or a vector of
-;; a type keyword and some parameters.
-(s/def ::lexicoder
-  (s/or :simple keyword?
-        :params (s/and vector? (s/cat :type keyword?
-                                      :args (s/* any?)))))
-
-
-
 ;; ## Comparators
 
 (defn- compare-bytes






;; ## Key Construction

(deftype Key

     (decode* coder byte-data offset len))))



;; ## Lexicoder Construction

;; Lexicoders can be specified either as a simple type keyword or a vector of
;; a type keyword and some parameters.
(s/def ::lexicoder
  (s/or :simple keyword?
        :params (s/and vector? (s/cat :type keyword?
                                      :args (s/* any?)))))


(defn- config-type
  "Determine the lexicoder type specified by a configuration data structure.
  The structure should be either a keyword or a vector with the first element a
  keyword providing the type value."
  [config]
  (if (keyword? config)
    config
    (if (and (vector? config) (keyword? (first config)))
      (first config)
      (throw (ex-info
               (str "Cannot determine lexicoder type from invalid config; expecting a keyword or vector with keyword, got: "
                    (pr-str config))
               {:config config})))))


(defn- config-params
  "Returns the parameters given to a lexicoder spec. For simple keyword, this
  function returns nil; for the vector form, it returns a sequence of the
  values following the lexicoder type key."
  [config]
  (when (vector? config)
    (next config)))


(defmulti lexicoder
  "Construct a lexicoder from a configuration data structure. The structure
  should be either a keyword or a vector with the first element a keyword
  providing the dispatch value."
  #'config-type)



;; ## Key Encoding Utilities

(defn- escape-bytes
  "Escape the given byte sequence, replacing any 0x00 bytes with 0x0101 and any
