diff --git a/nbt.cabal b/nbt.cabal
--- a/nbt.cabal
+++ b/nbt.cabal
@@ -1,5 +1,5 @@
 Name:                nbt
-Version:             0.4
+Version:             0.5
 Synopsis: A parser/serializer for Minecraft's Named Binary Tag (NBT)
   data format.
 Description: This package includes a data type for the NBT file
@@ -30,8 +30,8 @@
   hs-source-dirs:      src
   default-language:    Haskell2010
   Build-depends:       base == 4.*,
-                       bytestring == 0.9.*,
-                       cereal >= 0.3.4 && < 0.4,
+                       bytestring >= 0.9 && < 0.11,
+                       cereal >= 0.3.4 && < 0.5,
                        text,
                        array >= 0.4
   ghc-options:         -Wall
@@ -43,8 +43,8 @@
   hs-source-dirs:      test
   default-language:    Haskell2010
   Build-depends:       base == 4.*,
-                       bytestring == 0.9.*,
-                       cereal >= 0.3.4 && < 0.4,
+                       bytestring >= 0.9 && < 0.11,
+                       cereal >= 0.3.4 && < 0.5,
                        zlib == 0.5.*,
                        text,
                        HUnit == 1.2.*,
diff --git a/src/Data/NBT.hs b/src/Data/NBT.hs
--- a/src/Data/NBT.hs
+++ b/src/Data/NBT.hs
@@ -37,7 +37,8 @@
 -- | Tag types listed in order so that deriving 'Enum' will assign
 -- them the correct number for the binary type field.
 data TagType
-    = ByteType
+    = EndType
+    | ByteType
     | ShortType
     | IntType
     | LongType
@@ -51,8 +52,8 @@
     deriving (Show, Eq, Enum)
 
 instance Serialize TagType where
-    get = fmap (toEnum . pred . fromIntegral) getWord8
-    put = putWord8 . fromIntegral . succ . fromEnum
+    get = fmap (toEnum . fromIntegral) getWord8
+    put = putWord8 . fromIntegral . fromEnum
 
 -- | Primitive representation of NBT data. This type contains only the data
 -- part, since named nodes can only exist inside compound nodes.
@@ -74,6 +75,7 @@
     deriving (Show, Eq)
 
 getByType :: TagType -> Get NbtContents
+getByType EndType = fail "Can not get end-marker elements"
 getByType ByteType = ByteTag <$> get
 getByType ShortType = ShortTag <$> get
 getByType IntType = IntTag <$> get
@@ -93,8 +95,8 @@
 getByType CompoundType = CompoundTag <$> getCompoundElements
   where
     getCompoundElements = do
-        ty <- lookAhead (get :: Get Int8)
-        if ty == 0
+        ty <- lookAhead get
+        if ty == EndType
             -- if we see an end tag, drop it and end the list
             then skip 1 >> return []
             -- otherwise keep reading
diff --git a/test/RoundTrip.hs b/test/RoundTrip.hs
--- a/test/RoundTrip.hs
+++ b/test/RoundTrip.hs
@@ -9,7 +9,6 @@
 import           Data.Array.Unboxed                   (listArray)
 import qualified Data.ByteString                      as B
 import qualified Data.ByteString.Lazy                 as L
-import           Data.Int                             (Int32)
 import           Data.NBT
 import           Data.Serialize                       (decode, encode)
 import qualified Data.Text                            as T
@@ -21,7 +20,8 @@
 import           Test.QuickCheck
 
 instance Arbitrary TagType where
-    arbitrary = toEnum <$> choose (0, 10)
+    arbitrary = toEnum <$> choose (1, 11)
+    -- don't arbitrarily pick end type, it has special meaning
 
 eitherErr :: (Either String a -> a)
 eitherErr = either error id
@@ -34,34 +34,37 @@
     where
       mkArb ty =
         case ty of
-          ByteType -> ByteTag <$> arbitrary
-          ShortType -> ShortTag <$> arbitrary
-          IntType -> IntTag <$> arbitrary
-          LongType -> LongTag <$> arbitrary
-          FloatType -> FloatTag <$> arbitrary
+          EndType    -> error "can't make end-type"
+          ByteType   -> ByteTag   <$> arbitrary
+          ShortType  -> ShortTag  <$> arbitrary
+          IntType    -> IntTag    <$> arbitrary
+          LongType   -> LongTag   <$> arbitrary
+          FloatType  -> FloatTag  <$> arbitrary
           DoubleType -> DoubleTag <$> arbitrary
           ByteArrayType -> do
-            len <- fromIntegral <$> choose (0, 100 :: Int) :: Gen Int32
-            ws <- replicateM (fromIntegral len) arbitrary
-            return $ ByteArrayTag . listArray (0, len - 1) $ ws
+            len  <- choose (0, 100)
+            ws   <- replicateM len arbitrary
+            let a = listArray (0, fromIntegral len - 1) ws
+            return (ByteArrayTag a)
           StringType -> do
-            n <- choose (0, 100) :: Gen Int
-            str <- T.pack <$> replicateM (fromIntegral n) arbitrary
-            return $ StringTag str
+            len <- choose (0, 100)
+            str <- T.pack <$> replicateM len arbitrary
+            return (StringTag str)
           ListType -> do
-            subTy <- arbitrary
-            len <- fromIntegral <$> choose (0, 11 :: Int) :: Gen Int32
-            ts <- replicateM (fromIntegral len) (mkArb subTy)
-            return $ ListTag subTy . IA.listArray (0, len - 1) $ ts
+            len   <- choose (0, 10) -- list types nest, don't get too big
+            subTy <- if len == 0 then return EndType else arbitrary
+            ts    <- replicateM len (mkArb subTy)
+            let a  = IA.listArray (0, fromIntegral len - 1) ts
+            return (ListTag subTy a)
           CompoundType -> do
-            n <- choose (0, 11)
-            ts <- replicateM n arbitrary
-            return $ CompoundTag ts
+            len <- choose (0, 10) -- compound types nest, don't get too big
+            ts  <- replicateM len arbitrary
+            return (CompoundTag ts)
           IntArrayType -> do
-            len <- fromIntegral <$> choose (0, 100 :: Int) :: Gen Int32
-            IntArrayTag
-              . listArray (0, len-1)
-              <$> (vector $ fromIntegral len)
+            len  <- choose (0, 100)
+            v    <- vector len
+            let a = listArray (0, fromIntegral len - 1) v
+            return (IntArrayTag a)
 
 prop_NBTroundTrip :: NBT -> Bool
 prop_NBTroundTrip nbt = eitherErr (decode (encode nbt)) == nbt
