 (defn associative-static-spec
   [data dict types]
   (reify
-    ISpecSize
+    clojure.lang.Counted
+    (count [_]
+      (count types))
+
+    IStaticSize
     (size [_]
-      (reduce #(+ %1 (types/size %2)) 0 types))
-    (size [_ data]
       (reduce #(+ %1 (types/size %2)) 0 types))
 
     IReadableSpec
-    (read [_ buff]
-      (reduce (fn [acc [name t]]
-                (assoc acc name (types/read t buff)))
-              {}
-              data))
+    (read [_ buff offset]
+      (loop [index offset result {} pairs data]
+        (if-let [[fieldname type] (first pairs)]
+          (let [[readeddata readedbytes] (types/read type buff index)]
+            (recur (+ index readedbytes)
+                   (assoc result fieldname readeddata)
+                   (rest pairs)))
+          [(- index offset) result])))
 
     IWritableSpec
-    (write [_ buff data']
-      (reduce (fn [buff [fieldname type]]
-                (let [value (get data' fieldname nil)]
-                  (types/write type buff value)
-                  buff))
-              buff data))
+    (write [_ buff offset data']
+      (let [written (reduce (fn [index [fieldname type]]
+                              (let [value (get data' fieldname nil)
+                                    written (types/write type buff index value)]
+                                (+ index written)))
+                            offset data)]
+        (- written offset)))))
 
-    IAssocReadableSpec
-    (read-field [_ buff field]
-      (let [ftype (get dict field)
-            startpos (reduce (fn [acc [key val]]
-                               (if (= key field)
-                                 (reduced acc)
-                                 (+ acc (types/size val))))
-                             0 data)]
-        ;; Set the buffer position
-        (buffer/seek buff startpos)
-        (types/read ftype buff)))))
+    ;; IAssocReadableSpec
+    ;; (read-field [_ buff field]
+    ;;   (let [ftype (get dict field)
+    ;;         startpos (reduce (fn [acc [key val]]
+    ;;                            (if (= key field)
+    ;;                              (reduced acc)
+    ;;                              (+ acc (types/size val))))
+    ;;                          0 data)]
+    ;;     ;; Set the buffer position
+    ;;     (buffer/seek buff startpos)
+    ;;     (types/read ftype buff)))))
 
 (defn associative-dynamic-spec
   [])

(defn associative-spec
  [params]
  {:pre [(even? (count params))]}
  (let [data (partition 2 params)
        dict (into {} data)
        types (map second data)]
    (if (every? #(satisfies? types/IStaticType %) types)

;; (defprotocol ISpec
;;   (type [_] "Get the type of spec."))

(defprotocol IReadableSpec
  (read [_ buff start] "Read all data from buffer."))

(defprotocol IWritableSpec
  (write [_ buff start data] "Read all data from buffer."))

;; (defprotocol IAssocReadableSpec
;;   (read-field [_ buff field] "Read one concrete field from buffer."))

;; (defprotocol IAssocWritableSpec
;;   (write-field [_ buff field data] "Read one concrete field from buffer."))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Types implementation
