diff --git a/Network/IRC/Base.hs b/Network/IRC/Base.hs
--- a/Network/IRC/Base.hs
+++ b/Network/IRC/Base.hs
@@ -22,15 +22,19 @@
   ) where
 
 import Data.Maybe
+import Data.Char
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as B8
 
 -- ---------------------------------------------------------
 -- Data Types
 
-type Parameter  = String
-type ServerName = String
-type UserName   = String
-type RealName   = String
-type Command    = String
+type Parameter  = ByteString
+type ServerName = ByteString
+type UserName   = ByteString
+type RealName   = ByteString
+type Command    = ByteString
 
 
 -- | IRC messages are parsed as:
@@ -47,7 +51,7 @@
   = -- | Server Prefix
     Server ServerName
   | -- | Nickname Prefix
-    NickName String (Maybe UserName) (Maybe ServerName)
+    NickName ByteString (Maybe UserName) (Maybe ServerName)
     deriving (Show,Read,Eq)
 
 
@@ -56,27 +60,32 @@
 
 
 -- | Encode a message to its string representation
-encode :: Message -> String
-encode m = showMessage m
+encode :: Message -> ByteString
+encode = showMessage
 
 -- | This is the deprecated version of encode
-render :: Message -> String
+render :: Message -> ByteString
 render  = encode
 
-showMessage :: Message -> String
-showMessage (Message p c ps) = showMaybe p ++ c ++ showParameters ps
-  where showMaybe = maybe "" ((++ " ") . (':':) . showPrefix)
+showMessage :: Message -> ByteString
+showMessage (Message p c ps) = showMaybe p `BS.append` c `BS.append` showParameters ps
+  where showMaybe Nothing = BS.empty
+        showMaybe (Just prefix) = BS.concat [ B8.pack ":"
+                                            , showPrefix prefix
+                                            , B8.pack " " ]
 
-showPrefix :: Prefix -> String
+bsConsAscii :: Char -> ByteString -> ByteString
+bsConsAscii c = BS.cons (fromIntegral . ord $ c)
+
+showPrefix :: Prefix -> ByteString
 showPrefix (Server s)       = s
-showPrefix (NickName n u h) = n ++ showMaybe '!' u ++ showMaybe '@' h
-  where showMaybe c e = maybe "" (c:) e
+showPrefix (NickName n u h) = BS.concat [n, showMaybe '!' u, showMaybe '@' h]
+  where showMaybe c e = maybe BS.empty (bsConsAscii c) e
 
-showParameters :: [Parameter] -> String
-showParameters []     = []
-showParameters params = " " ++ (unwords $ showp params)
-  where showp [p] | ' ' `elem` p || null p || head p == ':' = [':' : p]
-                  | otherwise = [p]
+showParameters :: [Parameter] -> ByteString
+showParameters []     = BS.empty
+showParameters params = BS.intercalate (B8.pack " ") (BS.empty : showp params)
+  where showp [p]    = [bsConsAscii ':' p]
         showp (p:ps) = p : showp ps
         showp []     = []
 
@@ -86,13 +95,13 @@
 -- | Translate a reply into its text description.
 --   If no text is available, the argument is returned.
 translateReply :: Command -- ^ Reply
-               -> String  -- ^ Text translation
+               -> ByteString  -- ^ Text translation
 translateReply r = fromMaybe r $ lookup r replyTable
 
 
 -- One big lookup table of codes and errors
-replyTable :: [(String,String)]
-replyTable  =
+replyTable :: [(ByteString, ByteString)]
+replyTable  = map mkPair
   [ ("401","ERR_NOSUCHNICK")
   , ("402","ERR_NOSUCHSERVER")
   , ("403","ERR_NOSUCHCHANNEL")
@@ -212,3 +221,5 @@
   , ("258","RPL_ADMINLOC2")
   , ("259","RPL_ADMINEMAIL")
   ]
+  where
+  mkPair (a,b) = (B8.pack a, B8.pack b)
diff --git a/Network/IRC/Commands.hs b/Network/IRC/Commands.hs
--- a/Network/IRC/Commands.hs
+++ b/Network/IRC/Commands.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE OverloadedStrings #-}
+
 module Network.IRC.Commands (
     -- * Types
     Channel
@@ -10,15 +12,20 @@
   , part
   , quit
   , privmsg
+  , kick
+  , pong
   ) where
 
+import Data.ByteString
+
 import Network.IRC.Base
 
-type Channel    = String
-type Password   = String
+type Channel    = ByteString
+type Password   = ByteString
+type Reason     = ByteString
 
-mkMessage           :: String -> [Parameter] -> Message
-mkMessage cmd params = Message Nothing cmd params
+mkMessage :: Command -> [Parameter] -> Message
+mkMessage = Message Nothing
 
 
 
@@ -32,12 +39,19 @@
 joinChan  :: Channel -> Message
 joinChan c = mkMessage "JOIN" [c]
 
+kick :: Channel -> UserName -> Maybe Reason -> Message
+kick c u (Just r) = mkMessage "KICK" [c,u,r]
+kick c u Nothing  = mkMessage "KICK" [c,u]
+
 part  :: Channel -> Message
 part c = mkMessage "PART" [c]
 
-quit :: Maybe String -> Message
+quit :: Maybe Reason -> Message
 quit (Just m) = mkMessage "QUIT" [m]
 quit Nothing  = mkMessage "QUIT" []
 
-privmsg    :: String -> String -> Message
+privmsg    :: Channel -> ByteString -> Message
 privmsg c m = mkMessage "PRIVMSG" [c,m]
+
+pong  :: ServerName -> Message
+pong s = mkMessage "PONG" [s]
diff --git a/Network/IRC/Parser.hs b/Network/IRC/Parser.hs
--- a/Network/IRC/Parser.hs
+++ b/Network/IRC/Parser.hs
@@ -4,18 +4,14 @@
     decode -- :: String -> Maybe Message
 
     -- * Parsec Combinators for Parsing IRC messages
-  , prefix         -- :: CharParser st Prefix
-  , serverPrefix   -- :: CharParser st Prefix
-  , nicknamePrefix -- :: CharParser st Prefix
-  , command        -- :: CharParser st Command
-  , parameter      -- :: CharParser st Parameter
-  , message        -- :: CharParser st Message
-  , crlf           -- :: CharParser st ()
-  , spaces         -- :: CharParser st ()
-
-    -- * Other Parser Combinators
-  , tokenize  -- :: CharParser st a -> CharParser st a
-  , takeUntil -- :: String -> CharParser st String
+  , prefix         -- :: Parser Prefix
+  , serverPrefix   -- :: Parser Prefix
+  , nicknamePrefix -- :: Parser Prefix
+  , command        -- :: Parser Command
+  , parameter      -- :: Parser Parameter
+  , message        -- :: Parser Message
+  , crlf           -- :: Parser ()
+  , spaces         -- :: Parser ()
 
     -- * Deprecated Functions
   , parseMessage
@@ -23,73 +19,134 @@
 
 import Network.IRC.Base
 
-import Control.Monad
-import Data.Maybe
-import Text.ParserCombinators.Parsec hiding (spaces)
+import Data.Char
+import Data.Word
+import Data.ByteString hiding (elem, map, empty)
 
+import Control.Monad (void)
+import Control.Applicative
+import Data.Attoparsec.ByteString
+
+-- | Casts a character (assumed to be ASCII) to its corresponding byte.
+asciiToWord8 :: Char -> Word8
+asciiToWord8 = fromIntegral . ord
+
+wSpace :: Word8
+wSpace = asciiToWord8 ' '
+
+wTab :: Word8
+wTab = asciiToWord8 '\t'
+
+wBell :: Word8
+wBell = asciiToWord8 '\b'
+
+wDot :: Word8
+wDot = asciiToWord8 '.'
+
+wExcl :: Word8
+wExcl = asciiToWord8 '!'
+
+wAt :: Word8
+wAt = asciiToWord8 '@'
+
+wCR :: Word8
+wCR = asciiToWord8 '\r'
+
+wLF :: Word8
+wLF = asciiToWord8 '\n'
+
+wColon :: Word8
+wColon = asciiToWord8 ':'
+
 -- | Parse a String into a Message.
-decode :: String        -- ^ Message string
+decode :: ByteString    -- ^ Message string
        -> Maybe Message -- ^ Parsed message
-decode = (either (const Nothing) Just) . (parse message "")
+decode str = case parseOnly message str of
+  Left _ -> Nothing
+  Right r -> Just r
 
 -- | The deprecated version of decode
-parseMessage :: String -> Maybe Message
+parseMessage :: ByteString -> Maybe Message
 parseMessage  = decode
 
--- | Take all tokens until one character from a given string is found
-takeUntil :: String -> CharParser st String
-takeUntil s = anyChar `manyTill` (lookAhead (oneOf s))
-
 -- | Convert a parser that consumes all space after it
-tokenize  :: CharParser st a -> CharParser st a
-tokenize p = p >>= \x -> spaces >> return x
+tokenize  :: Parser a -> Parser a
+tokenize p = p <* spaces
 
--- | Consume only spaces tabs or the bell character
-spaces :: CharParser st ()
-spaces  = skipMany1 (oneOf " \t\b")
+-- | Consume only spaces, tabs, or the bell character
+spaces :: Parser ()
+spaces  = skip (\w -> w == wSpace ||
+                      w == wTab ||
+                      w == wBell)
 
 -- | Parse a Prefix
-prefix :: CharParser st Prefix
-prefix  = char ':' >> (try nicknamePrefix <|> serverPrefix)
+prefix :: Parser Prefix
+prefix  = word8 wColon *> (try nicknamePrefix <|> serverPrefix)
+          <?> "prefix"
 
 -- | Parse a Server prefix
-serverPrefix :: CharParser st Prefix
-serverPrefix  = takeUntil " " >>= return . Server
+serverPrefix :: Parser Prefix
+serverPrefix  = Server <$> takeTill (== wSpace)
+                <?> "serverPrefix"
 
+-- | optionMaybe p tries to apply parser p. If p fails without consuming input,
+-- | it return Nothing, otherwise it returns Just the value returned by p.
+optionMaybe :: Parser a -> Parser (Maybe a)
+optionMaybe p = option Nothing (Just <$> p)
+
 -- | Parse a NickName prefix
-nicknamePrefix :: CharParser st Prefix
+nicknamePrefix :: Parser Prefix
 nicknamePrefix  = do
-  n <- takeUntil " .!@\r\n"
-  p <- option False (char '.' >> return True)
-  when p (fail "")
-  u <- optionMaybe $ char '!' >> takeUntil " @\r\n"
-  s <- optionMaybe $ char '@' >> takeUntil " \r\n"
-  return $ NickName n u s
+  n <- takeTill (inClass " .!@\r\n")
+  p <- peekWord8
+  case p of
+    Just c | c == wDot -> empty
+    _                  -> NickName n <$>
+                                optionMaybe (word8 wExcl *> takeTill (\w -> w == wSpace ||
+                                                                            w == wAt ||
+                                                                            w == wCR ||
+                                                                            w == wLF))
+                            <*> optionMaybe (word8 wAt *> takeTill (\w -> w == wSpace ||
+                                                                          w == wCR ||
+                                                                          w == wLF))
+  <?> "nicknamePrefix"
 
+isWordAsciiUpper :: Word8 -> Bool
+isWordAsciiUpper w = asciiToWord8 'A' <= w && w <= asciiToWord8 'Z'
+
+digit :: Parser Word8
+digit = satisfy (\w -> asciiToWord8 '0' <= w && w <= asciiToWord8 '9')
+
 -- | Parse a command.  Either a string of capital letters, or 3 digits.
-command :: CharParser st Command
-command  = (many1 upper)
-        <|> do x <- digit
-               y <- digit
-               z <- digit
-               return [x,y,z]
+command :: Parser Command
+command  = takeWhile1 isWordAsciiUpper
+        <|> digitsToByteString <$>
+                   digit
+               <*> digit
+               <*> digit
+        <?> "command"
+    where digitsToByteString x y z = pack [x,y,z]
 
 -- | Parse a command parameter.
-parameter :: CharParser st Parameter
-parameter  =  (char ':' >> takeUntil "\r\n")
-          <|> (takeUntil " \r\n")
+parameter :: Parser Parameter
+parameter  =  (word8 wColon *> takeTill (\w -> w == wCR ||
+                                               w == wLF))
+          <|> takeTill (\w -> w == wSpace ||
+                              w == wCR ||
+                              w == wLF)
+          <?> "parameter"
 
 -- | Parse a cr lf
-crlf :: CharParser st ()
-crlf  =  (char '\r' >> optional (char '\n'))
-     <|> (char '\n' >> return ()           )
-
+crlf :: Parser ()
+crlf =  void (word8 wCR *> optional (word8 wLF))
+    <|> void (word8 wLF)
 
 -- | Parse a Message
-message :: CharParser st Message
-message  = do
-  p <- optionMaybe $ tokenize prefix
-  c <- command
-  ps <- many (spaces >> parameter)
-  crlf >> eof
-  return $ Message p c ps
+message :: Parser Message
+message  = Message <$>
+      optionMaybe (tokenize prefix)
+  <*> command
+  <*> many (some spaces *> parameter)
+  <*  optional crlf
+  <*  endOfInput
+  <?> "message"
diff --git a/irc.cabal b/irc.cabal
--- a/irc.cabal
+++ b/irc.cabal
@@ -1,15 +1,13 @@
 name:               irc
 synopsis:           A small library for parsing IRC messages.
 description:        A set of combinators and types for parsing IRC messages.
-version:            0.4.4.2
+version:            0.6.1.1
 category:           Data, Network
 license:            BSD3
 license-file:       LICENSE
 author:             Trevor Elliott
 maintainer:         trevor@geekgateway.com
-extra-source-files: tests/Makefile,
-                    tests/Tests.hs
-cabal-version:      >= 1.6.0
+cabal-version:      >= 1.10
 build-type:         Simple
 
 source-repository head
@@ -18,8 +16,18 @@
 
 library
   ghc-options:     -Wall
-  build-depends:   base == 4.*, parsec == 2.1.*
+  default-language: Haskell2010
+  build-depends:   base == 4.*, attoparsec, bytestring
   exposed-Modules: Network.IRC,
                    Network.IRC.Base,
                    Network.IRC.Commands,
                    Network.IRC.Parser
+
+test-suite Main
+  type:            exitcode-stdio-1.0
+  x-uses-tf:       true
+  build-depends:   base == 4.*, HUnit >= 1.2 && < 2, QuickCheck >= 2.4, test-framework >= 0.4.1, test-framework-quickcheck2, test-framework-hunit, bytestring, irc
+  ghc-options:     -Wall
+  hs-source-dirs:  tests
+  default-language: Haskell2010
+  main-is:         Main.hs
diff --git a/tests/Main.hs b/tests/Main.hs
new file mode 100644
--- /dev/null
+++ b/tests/Main.hs
@@ -0,0 +1,179 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Main
+    (
+      main
+    ) where
+
+import Network.IRC
+
+import Data.ByteString (ByteString, append, pack)
+import Data.Word (Word8)
+import Data.Char (ord)
+
+import Control.Applicative (liftA)
+
+import Test.HUnit
+import Test.QuickCheck
+
+import Test.Framework as TF (defaultMain, testGroup, Test)
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2 (testProperty)
+
+-- ---------------------------------------------------------
+-- Helpful Wrappers
+
+-- An identifier starts with a letter, and consists of interspersed numbers
+-- and special characters
+newtype Identifier = Identifier { unIdentifier :: ByteString }
+  deriving (Read,Show,Eq)
+
+instance Arbitrary Identifier where
+  arbitrary   = do
+      l  <- letter
+      ls <- sized $ \n -> loop n
+      return $ Identifier (pack (l:ls))
+    where loop n | n <= 0    = return []
+                 | otherwise = do i  <- identifier
+                                  is <- loop (n-1)
+                                  return (i:is)
+
+-- A hostname is a string that starts and ends with an identifier, and has
+-- periods peppered in the middle.
+newtype Host = Host { unHost :: ByteString }
+
+instance Arbitrary Host where
+  arbitrary   = do
+      l  <- identifier
+      ls <- sized $ \n -> loop n
+      js <- sized $ \n -> loop n
+      e  <- identifier
+      return $ Host (pack (l:ls ++ (w8 '.':js) ++ [e]))
+    where loop n | n <= 0    = return []
+                 | otherwise = do i  <- host
+                                  is <- loop (n-1)
+                                  return (i:is)
+
+
+w8 :: Char -> Word8
+w8 = fromIntegral . ord
+
+letter :: Gen Word8
+letter  = frequency
+  [ (50, choose (w8 'a', w8 'z'))
+  , (50, choose (w8 'A', w8 'Z'))
+  ]
+
+digit :: Gen Word8
+digit  = choose (w8 '0', w8 '9')
+
+special :: Gen Word8
+special  = elements [w8 '_', w8 '-']
+
+identifier :: Gen Word8
+identifier  = frequency
+  [ (50, letter)
+  , (30, digit)
+  , (10, special)
+  ]
+
+host :: Gen Word8
+host  = frequency
+  [ (90, identifier)
+  , (20, return (w8 '.'))
+  ]
+
+-- ---------------------------------------------------------
+-- IRC Types
+
+newtype Cmd = Cmd { unCmd :: ByteString }
+  deriving (Read,Show,Eq)
+
+instance Arbitrary Cmd where
+  arbitrary   =
+      let c = (replyTable !!) <$> choose (0, length replyTable - 1)
+       in Cmd . fst <$> c
+
+instance Arbitrary Prefix where
+  arbitrary   = oneof
+      [ NickName
+            <$> fmap unIdentifier arbitrary
+            <*> fmap (liftA unIdentifier) arbitrary
+            <*> fmap (liftA unIdentifier) arbitrary
+      , Server
+            <$> fmap unHost arbitrary
+      ]
+
+instance Arbitrary Message where
+  arbitrary   =
+      let params = map unIdentifier <$> sized vector
+          cmd    = unCmd <$> arbitrary
+       in Message <$> arbitrary <*> cmd <*> params
+
+-- ---------------------------------------------------------
+-- Properties
+
+prop_encodeDecode    :: Message -> Bool
+prop_encodeDecode msg = (decode . appendCRLF . encode $ msg)
+                     == Just msg
+  where appendCRLF bs = append bs (pack [w8 '\r', w8 '\n'])
+
+properties :: TF.Test
+properties = testGroup "QuickCheck Network.IRC"
+    [ testProperty "encodeDecode" prop_encodeDecode
+    ]
+
+-- ---------------------------------------------------------
+-- Unit Tests
+
+unitTests :: TF.Test
+unitTests = testGroup "HUnit tests Network.IRC"
+    [ -- Decoding tests
+      testCase "PRIVMSG foo :bar baz"
+               (    decode "PRIVMSG foo :bar baz"
+                @=? Just (Message Nothing "PRIVMSG" ["foo", "bar baz"]))
+    , testCase ":foo.bar NOTICE baz baz :baz baz"
+               (    decode ":foo.bar NOTICE baz baz :baz baz"
+                @=? Just (Message (Just (Server "foo.bar")) "NOTICE" ["baz", "baz", "baz baz"]))
+    , testCase ":foo.bar 001 baz baz :baz baz"
+               (    decode ":foo.bar 001 baz baz :baz baz"
+                @=? Just (Message (Just (Server "foo.bar")) "001" ["baz", "baz", "baz baz"]))
+    , testCase ":foo!bar@baz PRIVMSG #foo :bar baz"
+               (    decode ":foo!bar@baz PRIVMSG #foo :bar baz"
+                @=? Just (Message (Just (NickName "foo" (Just "bar") (Just "baz"))) "PRIVMSG" ["#foo", "bar baz"]))
+    , testCase ":foo@baz PRIVMSG #foo :bar baz"
+               (    decode ":foo@baz PRIVMSG #foo :bar baz"
+                @=? Just (Message (Just (NickName "foo" Nothing (Just "baz"))) "PRIVMSG" ["#foo", "bar baz"]))
+    , testCase ":foo!bar PRIVMSG #foo :bar baz"
+               (    decode ":foo!bar PRIVMSG #foo :bar baz"
+                @=? Just (Message (Just (NickName "foo" (Just "bar") Nothing)) "PRIVMSG" ["#foo", "bar baz"]))
+    , testCase ":foo PRIVMSG #foo :bar baz"
+               (    decode ":foo PRIVMSG #foo :bar baz"
+                @=? Just (Message (Just (NickName "foo" Nothing Nothing)) "PRIVMSG" ["#foo", "bar baz"]))
+
+      -- Decoding tests
+
+      -- Initial colon encoding tests
+    , testCase "Message Nothing \"PRIVMSG\" [\"#foo\", \":bar bas\"]"
+               (    encode (Message Nothing "PRIVMSG" ["#foo", ":bar bas"])
+                @?= "PRIVMSG #foo ::bar bas")
+    , testCase "Message Nothing \"PRIVMSG\" [\"#foo\", \":bar\"]"
+               (    encode (Message Nothing "PRIVMSG" ["#foo", ":bar"])
+                @?= "PRIVMSG #foo ::bar")
+
+    -- Corrected case
+    , testCase ":talon.nl.eu.SwiftIRC.net 332 foo #bar :\n"
+               (    decode ":talon.nl.eu.SwiftIRC.net 332 foo #bar :\n"
+                @?= Just (Message (Just $ Server "talon.nl.eu.SwiftIRC.net") "332" ["foo","#bar",""]))
+    ]
+
+-- ---------------------------------------------------------
+-- Test List
+
+tests :: [TF.Test]
+tests = [ properties
+        , unitTests
+        ]
+
+main :: IO ()
+main = defaultMain tests
+
diff --git a/tests/Makefile b/tests/Makefile
deleted file mode 100644
--- a/tests/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-ODIR   = .ghc
-TARGET = Tests
-
-all : $(ODIR)
-	ghc --make -odir=$(ODIR) -hidir=$(ODIR) $(TARGET) -i../
-	./$(TARGET)
-
-$(ODIR) :
-	mkdir $(ODIR)
-
-clean :
-	$(RM) -r $(ODIR) $(TARGET)
-
-.PHONY: all clean
diff --git a/tests/Tests.hs b/tests/Tests.hs
deleted file mode 100644
--- a/tests/Tests.hs
+++ /dev/null
@@ -1,145 +0,0 @@
-module Main where
-
--- Friends
-import Network.IRC
-
--- Libraries
-import Control.Applicative
-import Control.Monad
-import System.Random
-import Test.QuickCheck
-import Test.HUnit
-
-
-instance Applicative Gen where
-  (<*>) = ap
-  pure  = return
-
--- ---------------------------------------------------------
--- Helpful Wrappers
-
--- An identifier starts with a letter, and consists of interspersed numbers
--- and special characters
-newtype Identifier = Identifier { unIdentifier :: String }
-  deriving (Read,Show,Eq)
-
-instance Arbitrary Identifier where
-  arbitrary   = do
-      l  <- letter
-      ls <- sized $ \n -> loop n
-      return $ Identifier (l:ls)
-    where loop n | n <= 0    = return []
-                 | otherwise = do i  <- identifier
-                                  is <- loop (n-1)
-                                  return (i:is)
-
--- A hostname is a string that starts and ends with an identifier, and has
--- periods peppered in the middle.
-newtype Host = Host { unHost :: String }
-
-instance Arbitrary Host where
-  arbitrary   = do
-      l  <- identifier
-      ls <- sized $ \n -> loop n
-      js <- sized $ \n -> loop n
-      e  <- identifier
-      return $ Host (l:ls ++ ('.':js) ++ [e])
-    where loop n | n <= 0    = return []
-                 | otherwise = do i  <- host
-                                  is <- loop (n-1)
-                                  return (i:is)
-
-
-letter :: Gen Char
-letter  = frequency
-  [ (50, choose ('a','z'))
-  , (50, choose ('A','Z'))
-  ]
-
-digit :: Gen Char
-digit  = choose ('0','9')
-
-special :: Gen Char
-special  = elements ['_','-']
-
-identifier :: Gen Char
-identifier  = frequency
-  [ (50, letter)
-  , (30, digit)
-  , (10, special)
-  ]
-
-host :: Gen Char
-host  = frequency
-  [ (90, identifier)
-  , (20, return '.')
-  ]
-
--- ---------------------------------------------------------
--- IRC Types
-
-newtype Cmd = Cmd { unCmd :: String }
-  deriving (Read,Show,Eq)
-
-instance Arbitrary Cmd where
-  arbitrary   =
-      let c = (replyTable !!) <$> choose (0, length replyTable - 1)
-       in Cmd . fst <$> c
-
-
-instance Arbitrary Prefix where
-  arbitrary   = oneof
-      [ do name <- unIdentifier <$> arbitrary
-           user <- (liftM unIdentifier) <$> arbitrary
-           host <- (liftM unIdentifier) <$> arbitrary
-           return $ NickName name user host
-      , do host <- unHost <$> arbitrary
-           return $ Server host
-      ]
-
-
-instance Arbitrary Message where
-  arbitrary   =
-      let params = map unIdentifier <$> sized vector
-          cmd    = unCmd <$> arbitrary
-       in Message <$> arbitrary <*> cmd <*> params
-
-
--- ---------------------------------------------------------
--- Properties
-
-prop_ircId    :: Message -> Bool
-prop_ircId msg = (decode . (++ "\r\n") . encode $ msg) == Just msg
-
-
--- ---------------------------------------------------------
--- Unit Tests
-
-tests :: Test
-tests  = TestList $ map TestCase
-  -- Initial colon encoding tests
-  [ encode (Message Nothing "PRIVMSG" ["#foo", ":bar bas"]) @?=
-    "PRIVMSG #foo ::bar bas"
-  , encode (Message Nothing "PRIVMSG" ["#foo", ":bar"]) @?=
-    "PRIVMSG #foo ::bar"
-
-  -- Corrected case
-  , decode ":talon.nl.eu.SwiftIRC.net 332 foo #bar :\n" @?=
-    Just (Message (Just $ Server "talon.nl.eu.SwiftIRC.net")
-            "332" ["foo","#bar",""])
-  ]
-
-
--- ---------------------------------------------------------
--- Test Running
-
-header :: String -> IO ()
-header s = putStrLn "" >> putStrLn s >> putStrLn (replicate 60 '*')
-
-main :: IO Counts
-main  = do
-  header "Checking irc encode/decode identity"
-  quickCheck prop_ircId
-
-  header "Checking individual test cases"
-  runTestTT tests
