     (if (< 127 b) (- b 256) b)))
 
 
-(defrecord ReverseLexicoder
-  [coder]
+(extend-type ReverseLexicoder
 
   Lexicoder
 
   (lexicoder-config
-    [_]
-    [:reverse (lexicoder-config coder)])
-
-  (encode*
-    [_ value]
-    (let [encoded ^bytes (encode* coder value)
+    [this]
+    [:reverse (lexicoder-config (.coder this))])
+
+  (encode*
+    [this value]
+    (let [encoded ^bytes (encode* (.coder this) value)
           rdata (byte-array (alength encoded))]
       (dotimes [i (alength encoded)]
         (aset-byte rdata i (flip-byte (aget encoded i))))
       rdata))
 
   (decode*
-    [_ data offset len]
+    [this data offset len]
     (let [encoded (byte-array len)]
       (dotimes [i (alength encoded)]
         (aset-byte encoded i (flip-byte (aget ^bytes data (+ offset i)))))
-      (decode* coder encoded 0 len))))
-
-
-(alter-meta! #'->ReverseLexicoder assoc :private true)
-(alter-meta! #'map->ReverseLexicoder assoc :private true)
-
-
-(defn reverse-lexicoder
-  "Wraps the given lexicoder to reverse the ordering of keys encoded with it."
-  [coder]
-  (->ReverseLexicoder coder))
-
-
-(defmethod lexicoder :reverse
-  [config]
-  (when (not= 1 (count (config-params config)))
-    (throw (ex-info
-             (str "Reverse lexicoder config takes exactly one parameter: " (pr-str config))
-             {:config config})))
-  (reverse-lexicoder (lexicoder (second config))))
+      (decode* (.coder this) encoded 0 len))))

        data'))))


(alter-meta! #'->BytesLexicoder assoc :private true)
(alter-meta! #'map->BytesLexicoder assoc :private true)


(def bytes-lexicoder
  "Lexicoder for passing through raw byte arrays."
  (->BytesLexicoder))


(defmethod lexicoder :bytes
  [config]
  (when (seq (config-params config))
    (throw (ex-info
             (str "Bytes lexicoder config takes no parameters: " (pr-str config))
             {:config config})))
  bytes-lexicoder)



;; ## String Lexicoder

(def ^:private default-string-charset
  "Default character set to lexicode strings with."
  StandardCharsets/UTF_8)


(defrecord StringLexicoder
  [^Charset charset]

  Lexicoder

  (lexicoder-config
    [_]
    (if (= charset default-string-charset)
      :string
      [:string (str charset)]))

  (encode*
    [_ value]
    (when (empty? value)
      (throw (IllegalArgumentException.
               "Cannot encode empty strings")))
    (.getBytes (str value) charset))

  (decode*
    [_ data offset len]
    (when (empty? data)
      (throw (IllegalArgumentException.
               "Cannot decode empty byte arrays")))
    (String. ^bytes data (long offset) (long len) charset)))


(alter-meta! #'->StringLexicoder assoc :private true)
(alter-meta! #'map->StringLexicoder assoc :private true)


(defn string-lexicoder*

        (flip-long-sign value)))))



;; ## Double Lexicoder

(deftype DoubleLexicoder [])


(def double-lexicoder
  "Lexicoder for double-precision floating point values."
  (->DoubleLexicoder))


(ns-unmap *ns* '->DoubleLexicoder)


(defmethod lexicoder :double
  [config]
  (when (config-params config)
    (throw (ex-info
             (str "Double lexicoder config takes no parameters: " (pr-str config))
             {:config config})))
  double-lexicoder)


(extend-type DoubleLexicoder

  Lexicoder

