diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,22 +1,86 @@
-language: haskell
+# This file has been generated -- see https://github.com/hvr/multi-ghc-travis
+language: c
+sudo: false
+
+cache:
+  directories:
+    - $HOME/.cabsnap
+    - $HOME/.cabal/packages
+
+before_cache:
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
+
+matrix:
+  include:
+    - env: CABALVER=1.16 GHCVER=7.4.2
+      compiler: ": #GHC 7.4.2"
+      addons: {apt: {packages: [cabal-install-1.16,ghc-7.4.2], sources: [hvr-ghc]}}
+    - env: CABALVER=1.16 GHCVER=7.6.3
+      compiler: ": #GHC 7.6.3"
+      addons: {apt: {packages: [cabal-install-1.16,ghc-7.6.3], sources: [hvr-ghc]}}
+    - env: CABALVER=1.18 GHCVER=7.8.4
+      compiler: ": #GHC 7.8.4"
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.4], sources: [hvr-ghc]}}
+    - env: CABALVER=1.22 GHCVER=7.10.2
+      compiler: ": #GHC 7.10.2"
+      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2], sources: [hvr-ghc]}}
+
 before_install:
-  # Uncomment whenever hackage is down.
-  # - mkdir -p ~/.cabal && cp travis/config ~/.cabal/config && cabal update
-  # - cabal update
-  - travis/cabal-apt-install $mode
+ - unset CC
+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
 
 install:
-  - export PATH=~/.cabal/bin:$PATH
-  - cabal configure -flib-Werror $mode
-  - cabal install packdeps packunused
-  - cabal build --ghc-option=-ddump-minimal-imports
+ - cabal --version
+ - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
+ - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
+   then
+     zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
+          $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
+   fi
+ - travis_retry cabal update -v
+ - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
+ - cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v > installplan.txt
+ - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt
 
+# check whether current requested install-plan matches cached package-db snapshot
+ - if diff -u installplan.txt $HOME/.cabsnap/installplan.txt;
+   then
+     echo "cabal build-cache HIT";
+     rm -rfv .ghc;
+     cp -a $HOME/.cabsnap/ghc $HOME/.ghc;
+     cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;
+   else
+     echo "cabal build-cache MISS";
+     rm -rf $HOME/.cabsnap;
+     mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;
+     cabal install --only-dependencies --enable-tests --enable-benchmarks;
+   fi
+ 
+# snapshot package-db on cache miss
+ - if [ ! -d $HOME/.cabsnap ];
+   then
+      echo "snapshotting package-db to build-cache";
+      mkdir $HOME/.cabsnap;
+      cp -a $HOME/.ghc $HOME/.cabsnap/ghc;
+      cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;
+   fi
+
+# Here starts the actual work to be performed for the package under test;
+# any command which exits with a non-zero exit code causes the build to fail.
 script:
-  - $script
-  - packdeps bytes.cabal
-  - packunused --ignore-package=transformers-compat
-  - hlint src --cpp-define HLINT
+ - if [ -f configure.ac ]; then autoreconf -i; fi
+ - cabal configure --enable-tests --enable-benchmarks -v2  # -v2 provides useful information for debugging
+ - cabal build   # this builds all libraries and executables (including tests/benchmarks)
+ - cabal test
+ - cabal sdist   # tests that a source-distribution can be generated
 
+# Check that the resulting source distribution can be built & installed.
+# If there are no other `.tar.gz` files in `dist`, this can be even simpler:
+# `cabal install --force-reinstalls dist/*-*.tar.gz`
+ - SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&
+   (cd dist && cabal install --force-reinstalls "$SRC_TGZ")
+
 notifications:
   irc:
     channels:
@@ -25,5 +89,4 @@
     template:
       - "\x0313bytes\x03/\x0306%{branch}\x03 \x0314%{commit}\x03 %{build_url} %{message}"
 
-env:
-  - mode="--enable-tests" script="cabal test --show-details=always"
+# EOF
diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,9 @@
+0.15.1
+------
+* Drop `Trustworthy` claim in `Data.Bytes.Put` as we now can sometimes infer `Safe`.
+* Bump `cereal` bound for 0.5.0.0
+* Add instance `Serial Natural`
+
 0.15.0.1
 --------
 * Updated github URLs in the .cabal file.
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -1,7 +1,7 @@
 bytes
 =====
 
-[![Build Status](https://secure.travis-ci.org/ekmett/bytes.png)](http://travis-ci.org/ekmett/bytes)
+[![Hackage](https://img.shields.io/hackage/v/bytes.svg)](https://hackage.haskell.org/package/bytes) [![Build Status](https://secure.travis-ci.org/ekmett/bytes.png?branch=master)](http://travis-ci.org/ekmett/bytes)
 
 This package provides a simple compatibility shim that lets you work with both `binary` and `cereal` with one chunk of serialization code.
 
diff --git a/bytes.cabal b/bytes.cabal
--- a/bytes.cabal
+++ b/bytes.cabal
@@ -1,6 +1,6 @@
 name:          bytes
 category:      Data, Serialization
-version:       0.15.0.1
+version:       0.15.1
 license:       BSD3
 cabal-version: >= 1.8
 license-file:  LICENSE
@@ -11,7 +11,7 @@
 bug-reports:   https://github.com/ekmett/bytes/issues
 copyright:     Copyright (C) 2013-2015 Edward A. Kmett
 build-type:    Custom
-tested-with:   GHC == 7.4.1, GHC == 7.6.1
+tested-with:   GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.2
 synopsis:      Sharing code for serialization between binary and cereal
 description:   Sharing code for serialization between binary and cereal
 
@@ -39,16 +39,19 @@
 
 library
   build-depends:
-    base                      >= 4.3      && < 5,
+    base                      >= 4.5      && < 5,
     binary                    >= 0.5.1    && < 0.8,
     bytestring                >= 0.9      && < 0.11,
-    cereal                    >= 0.3.5    && < 0.5,
+    cereal                    >= 0.3.5    && < 0.6,
     containers                >= 0.3      && < 1,
+    hashable                  >= 1.0.1.1  && < 1.4,
     mtl                       >= 2.0      && < 2.3,
     text                      >= 0.2      && < 1.3,
     time                      >= 1.2      && < 1.6,
     transformers              >= 0.2      && < 0.5,
     transformers-compat       >= 0.3      && < 1,
+    unordered-containers      >= 0.2      && < 0.3,
+    scientific                >= 0.0      && < 1,
     void                      >= 0.6      && < 1
 
   if impl(ghc >= 7.4 && < 7.6)
diff --git a/src/Data/Bytes/Put.hs b/src/Data/Bytes/Put.hs
--- a/src/Data/Bytes/Put.hs
+++ b/src/Data/Bytes/Put.hs
@@ -5,7 +5,6 @@
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE Trustworthy #-}
 --------------------------------------------------------------------
 -- |
 -- Copyright :  (c) Edward Kmett 2013-2015
diff --git a/src/Data/Bytes/Serial.hs b/src/Data/Bytes/Serial.hs
--- a/src/Data/Bytes/Serial.hs
+++ b/src/Data/Bytes/Serial.hs
@@ -61,18 +61,19 @@
 import Data.Int
 import Data.Bits
 import Data.Monoid as Monoid
-#if MIN_VERSION_base(4, 6, 0)
-import Data.Ord (Down(..))
-#endif
 import Data.Functor.Identity as Functor
 import Data.Functor.Constant as Functor
 import Data.Functor.Product  as Functor
 import Data.Functor.Reverse  as Functor
+import Data.Hashable (Hashable)
+import qualified Data.HashMap.Lazy as HMap
+import qualified Data.HashSet      as HSet
 import Data.Time
 import Data.Time.Clock.TAI
 import qualified Data.IntMap as IMap
 import qualified Data.IntSet as ISet
 import qualified Data.Map as Map
+import qualified Data.Scientific as Sci
 import qualified Data.Sequence as Seq
 import qualified Data.Set as Set
 import Data.Text as SText
@@ -87,9 +88,14 @@
 import Foreign.ForeignPtr
 import Foreign.Ptr
 import Foreign.Storable
+import GHC.Exts (Down(..))
 import GHC.Generics
 import System.IO.Unsafe
 
+#if MIN_VERSION_base(4,8,0)
+import Numeric.Natural
+#endif
+
 foreign import ccall floatToWord32 :: Float -> Word32
 foreign import ccall word32ToFloat :: Word32 -> Float
 foreign import ccall doubleToWord64 :: Double -> Word64
@@ -324,6 +330,10 @@
   serialize = putWord8 . fromIntegral
   deserialize = liftM fromIntegral getWord8
 
+instance Serial Sci.Scientific where
+  serialize s = serialize (Sci.coefficient s, Sci.base10Exponent s)
+  deserialize = uncurry Sci.scientific <$> deserialize
+
 instance Serial Void where
   serialize = absurd
   deserialize = fail "I looked into the void."
@@ -348,6 +358,14 @@
   serialize = serializeWith serialize
   deserialize = deserializeWith deserialize
 
+instance (Serial k, Serial v, Hashable k, Eq k) => Serial (HMap.HashMap k v) where
+  serialize = serializeWith serialize
+  deserialize = deserializeWith deserialize
+
+instance (Serial v, Hashable v, Eq v) => Serial (HSet.HashSet v) where
+  serialize = serialize . HSet.toList
+  deserialize = HSet.fromList `liftM` deserialize
+
 putVarInt :: (MonadPut m, Integral a, Bits a) => a -> m ()
 putVarInt n
   | n < 0x80 = putWord8 $ fromIntegral n
@@ -391,7 +409,16 @@
   serialize = serialize . VarInt
   deserialize = unVarInt `liftM` deserialize
 
+#if MIN_VERSION_base(4,8,0)
 -- |
+-- >>> runGetL deserialize (runPutL (serialize (10^10::Natural))) :: Natural
+-- 10000000000
+instance Serial Natural where
+  serialize = serialize . VarInt . toInteger
+  deserialize = fromInteger . unVarInt <$> deserialize
+#endif
+
+-- |
 -- >>> (runGetL deserialize $ runPutL $ serialize (1.82::Fixed E2))::Fixed E2
 -- 1.82
 instance HasResolution a => Serial (Fixed a) where
@@ -480,11 +507,9 @@
   serialize = serialize . (fromIntegral::Int -> Int8) . fromEnum
   deserialize = (toEnum . (fromIntegral::Int8 -> Int)) `liftM` deserialize
 
-#if MIN_VERSION_base(4, 6, 0)
 instance Serial a => Serial (Down a) where
     serialize (Down a) = serialize a
     deserialize = Down `liftM` deserialize
-#endif
 
 instance Serial Version where
     serialize (Version vb ts) = serialize (fmap VarInt vb, ts)
@@ -698,6 +723,12 @@
   serializeWith pv = serializeWith (serializeWith2 serialize pv)
                    . Map.toAscList
   deserializeWith gv = Map.fromList
+               `liftM` deserializeWith (deserializeWith2 deserialize gv)
+
+instance (Hashable k, Eq k, Serial k) => Serial1 (HMap.HashMap k) where
+  serializeWith pv = serializeWith (serializeWith2 serialize pv)
+                   . HMap.toList
+  deserializeWith gv = HMap.fromList
                `liftM` deserializeWith (deserializeWith2 deserialize gv)
 
 serialize1 :: (MonadPut m, Serial1 f, Serial a) => f a -> m ()
