diff --git a/src/Data/Torrent.hs b/src/Data/Torrent.hs
--- a/src/Data/Torrent.hs
+++ b/src/Data/Torrent.hs
@@ -1,8 +1,10 @@
+{-# OPTIONS -fglasgow-exts #-}
 module Data.Torrent
     ( Torrent(..)
     , TorrentInfo(..)
     , TorrentFile(..)
     , readTorrent      -- :: ByteString -> Either String Torrent
+    , serializeTorrent
     , torrentSize      -- :: Torrent -> Int
     ) where
 
@@ -10,42 +12,53 @@
 
 import Data.BEncode
 import Data.BEncode.Parser
-import System.FilePath
 import Data.Torrent.SHA1
+import Data.Maybe
+import Data.Binary
+import Data.Generics
 
 import qualified Data.ByteString.Char8 as BS
 import Data.ByteString (ByteString)
 
+import qualified Data.Map as Map
+
 data Torrent
     = Torrent
-    { tAnnounce     :: String
-    , tAnnounceList :: [String]
-    , tComment      :: String
-    , tCreatedBy    :: Maybe String
+    { tAnnounce     :: ByteString
+    , tAnnounceList :: [ByteString]
+    , tComment      :: ByteString
+    , tCreatedBy    :: Maybe ByteString
     , tInfo         :: TorrentInfo
     , tInfoHash     :: ByteString
-    } deriving Show
+    } deriving (Show, Read, Typeable, Data)
 
 data TorrentInfo
     = SingleFile
     { tLength      :: Int
-    , tName        :: String
+    , tName        :: ByteString
     , tPieceLength :: Int
     , tPieces      :: ByteString }
     | MultiFile
     { tFiles       :: [TorrentFile]
-    , tName        :: String
+    , tName        :: ByteString
     , tPieceLength :: Int
     , tPieces      :: ByteString
-    } deriving Show
+    } deriving (Show, Read, Typeable, Data)
 
 data TorrentFile
     = TorrentFile
     { fileLength :: Int
-    , filePath   :: FilePath
-    } deriving Show
+    , filePath   :: [ByteString]
+    } deriving (Show, Read, Typeable, Data)
 
+instance Binary Torrent where
+    put = put . serializeTorrent
+    get = do e <- get
+             case readTorrent e of
+               Left err -> fail $ "Failed to parse torrent: " ++ err
+               Right t  -> return t
 
+
 torrentSize :: Torrent -> Int
 torrentSize torrent
     = case tInfo torrent of
@@ -68,24 +81,39 @@
 
 parseTorrent :: BParser Torrent
 parseTorrent =
-    do announce <- bstring $ dict "announce"
-       creator  <- optional $ bstring $ dict "created by"
+    do announce <- bbytestring $ dict "announce"
+       creator  <- optional $ bbytestring $ dict "created by"
        info     <- dict "info"
        setInput info
-       name     <- bstring $ dict "name"
+       name     <- bbytestring $ dict "name"
        pLen     <- bint $ dict "piece length"
-       pieces   <- bfaststring $ dict "pieces"
+       pieces   <- bbytestring $ dict "pieces"
        torrentInfo      <- parseTorrentInfo name pLen pieces
        let infoHash = sha1 (BS.pack $ bShow info "")
-       return $ Torrent announce [] "" creator torrentInfo infoHash
+       return $ Torrent announce [] BS.empty creator torrentInfo infoHash
 
-parseTorrentInfo :: String -> Int -> ByteString -> BParser TorrentInfo
+parseTorrentInfo :: ByteString -> Int -> ByteString -> BParser TorrentInfo
 parseTorrentInfo name pLen pieces
     = do len <- bint $ dict "length"
          return $ SingleFile len name pLen pieces
       <|>
       do files <- list "files" $ do len <- bint $ dict "length"
-                                    filePaths <- list "path" $ bstring token
-                                    return $ TorrentFile len (foldr1 (</>) filePaths)
+                                    filePaths <- list "path" $ bbytestring token
+                                    return $ TorrentFile len filePaths
          return $ MultiFile files name pLen pieces
 
+serializeTorrent :: Torrent -> BEncode
+serializeTorrent torrent
+    = BDict $ Map.fromList [("announce",BString $ tAnnounce torrent)
+                           ,("comment", BString $ tComment torrent)
+                           ,("info",info)
+                           ]
+      where info = BDict $ Map.fromList $ [("name", BString $ tName (tInfo torrent))
+                                          ,("pieces", BString $ tPieces (tInfo torrent))
+                                          ,("piece length", BInt $ tPieceLength (tInfo torrent))
+                                          ] ++ case tInfo torrent of
+                                                SingleFile len _ _ _ -> [("length", BInt len)]
+                                                MultiFile files _ _ _ -> [("files", BList $ flip map files $ \file ->
+                                                                               BDict $ Map.fromList [("length", BInt (fileLength file))
+                                                                                                    ,("path", BList (map BString $ filePath file))]
+                                                                          )]
diff --git a/torrent.cabal b/torrent.cabal
--- a/torrent.cabal
+++ b/torrent.cabal
@@ -1,11 +1,11 @@
 Name: torrent
-Version: 2007.6.29
+Version: 2007.10.27
 Maintainer: Lemmih (lemmih@gmail.com)
 Author: Lemmih (lemmih@gmail.com)
 Copyright: 2005-2007, Lemmih
 License-File: LICENSE
 License: BSD3
-Build-Depends: base, bencode, filepath, network
+Build-Depends: base, binary, bencode >=0.2, filepath, network
 Category: Network
 Synopsis: BitTorrent file parser.
 Tested-with: GHC ==6.6
