 
   (equals
     [this that]
-    (cond
-      (identical? this that) true
-      (instance? Block that)
-        (and (= id   (:id   that))
-             (= size (:size that)))
-      :else false))
+    (boolean
+      (or (identical? this that)
+          (when (identical? (class this) (class that))
+            (let [that ^Block that]
+              (and (= id     (.id     that))
+                   (= size   (.size   that))
+                   (= _attrs (._attrs that))))))))
 
   (hashCode
     [this]
-    (hash [Block id size]))
-
-
-  clojure.lang.IHashEq
-
-  (hasheq
-    [this]
-    (.hashCode this))
+    (hash [(class this) id size _attrs]))
 
 
   java.lang.Comparable

  "Creates a block from a reader function. Each time the function is called, it
  should return a new `InputStream` to read the block contents. The block is
  given the id and size directly, without being checked."
  ^Block
  [id size reader]
  (Block. id size nil reader nil nil))


            result))))

  (equiv
    [this that]
    (.equals this that))

  (containsKey
    [this k]
