diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,19 @@
+0.5.2 (2020-03-19)
+------------------
+
+ - Improved Monad failure messages from sendCommmand (thanks Scott
+   Fleischman)
+ - Fixed IMAP append (thanks Keijo Kapp)
+ - Added support for GHC 8.8.1 (thanks Oleg Grenrus)
+ - Added support for network-3 (thanks Oleg Grenrus)
+ - Increased upper bound on mime-mail to include 0.5 (thanks Marek
+   Suchánek)
+ - Improved failure message for AUTH failures (thanks Tom McLaughlin)
+ - Avoided unsafe use of unsafe bytestring length functions in
+   getResponse (thanks Javran Cheng)
+ - Added support for UNSEEN in STATUS commands (thanks Dominik Xaver
+   Hörl)
+
 0.5.1 (2016-05-05)
 ------------------
 
diff --git a/HaskellNet.cabal b/HaskellNet.cabal
--- a/HaskellNet.cabal
+++ b/HaskellNet.cabal
@@ -4,7 +4,7 @@
                 SMTP, and IMAP protocols.  NOTE: this package will be
                 split into smaller, protocol-specific packages in the
                 future.
-Version:        0.5.1
+Version:        0.5.2
 Copyright:      (c) 2006 Jun Mukai
 Author:         Jun Mukai
 Maintainer:     Jonathan Daugherty <cygnus@foobox.com>,
@@ -13,8 +13,20 @@
 License-file:   LICENSE
 Category:       Network
 Homepage:       https://github.com/jtdaugherty/HaskellNet
-Cabal-version:  >=1.6
+Cabal-version:  >=1.8
 Build-type:     Simple
+Tested-with:
+  GHC ==7.0.4
+   || ==7.2.2
+   || ==7.4.2
+   || ==7.6.3
+   || ==7.8.4
+   || ==7.10.3
+   || ==8.0.2
+   || ==8.2.2
+   || ==8.4.4
+   || ==8.6.5
+   || ==8.8.1
 
 Extra-Source-Files:
   CHANGELOG
@@ -25,6 +37,11 @@
   type:     git
   location: git://github.com/jtdaugherty/HaskellNet.git
 
+Flag network-bsd
+ description: Use network-bsd
+ manual:      False
+ default:     True
+
 Library
   Hs-Source-Dirs: src
   GHC-Options: -Wall -fno-warn-unused-do-bind
@@ -43,18 +60,28 @@
     Network.HaskellNet.Debug
 
   Other-modules:
+    Network.Compat
     Text.Packrat.Pos
     Text.Packrat.Parse
 
   Build-Depends:
-    base >= 4 && < 5,
-    network,
+    base >= 4.3 && < 4.14,
+    network >= 2.6.3.1 && < 3.2,
     mtl,
-    bytestring,
+    bytestring >=0.10.2,
     pretty,
     array,
-    cryptohash,
+    cryptohash >=0.6,
     base64-string,
     old-time,
-    mime-mail >= 0.4.7 && < 0.5,
+    mime-mail >= 0.4.7 && < 0.6,
     text
+
+  if !impl(ghc >= 8.0)
+    Build-depends: fail >= 4.9.0.0 && <4.10
+
+  if flag(network-bsd)
+    Build-Depends: network-bsd >=2.7 && <2.9,
+                   network >=2.7
+  else
+    Build-Depends: network <2.7
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,6 +3,8 @@
 
 [![Build Status](https://travis-ci.org/lemol/HaskellNet.svg)](https://travis-ci.org/lemol/HaskellNet)
 
+**NOTE: I am seeking a maintainer for this package. If you are interested, let me know!**
+
 This package provides client support for the E-mail protocols POP3,
 SMTP, and IMAP.
 
diff --git a/src/Network/Compat.hs b/src/Network/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/Compat.hs
@@ -0,0 +1,53 @@
+module Network.Compat where
+
+import Network.Socket
+import Network.BSD (getProtocolNumber)
+import System.IO (Handle, IOMode (..))
+
+import qualified Control.Exception as Exception
+
+connectTo :: String             -- Hostname
+          -> PortNumber         -- Port Identifier
+          -> IO Handle          -- Connected Socket
+connectTo host port = do
+    proto <- getProtocolNumber "tcp"
+    let hints = defaultHints { addrFlags = [AI_ADDRCONFIG]
+                             , addrProtocol = proto
+                             , addrSocketType = Stream }
+    addrs <- getAddrInfo (Just hints) (Just host) (Just serv)
+    firstSuccessful "connectTo" $ map tryToConnect addrs
+  where
+  serv = show port
+
+  tryToConnect addr =
+    Exception.bracketOnError
+        (socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr))
+        close  -- only done if there's an error
+        (\sock -> do
+          connect sock (addrAddress addr)
+          socketToHandle sock ReadWriteMode
+        )
+
+-- Returns the first action from a list which does not throw an exception.
+-- If all the actions throw exceptions (and the list of actions is not empty),
+-- the last exception is thrown.
+-- The operations are run outside of the catchIO cleanup handler because
+-- catchIO masks asynchronous exceptions in the cleanup handler.
+-- In the case of complete failure, the last exception is actually thrown.
+firstSuccessful :: String -> [IO a] -> IO a
+firstSuccessful caller = go Nothing
+  where
+  -- Attempt the next operation, remember exception on failure
+  go _ (p:ps) =
+    do r <- tryIO p
+       case r of
+         Right x -> return x
+         Left  e -> go (Just e) ps
+
+  -- All operations failed, throw error if one exists
+  go Nothing  [] = ioError $ userError $ caller ++ ": firstSuccessful: empty list"
+  go (Just e) [] = Exception.throwIO e
+
+-- Version of try implemented in terms of the locally defined catchIO
+tryIO :: IO a -> IO (Either Exception.IOException a)
+tryIO m = Exception.catch (fmap Right m) (return . Left)
diff --git a/src/Network/HaskellNet/IMAP.hs b/src/Network/HaskellNet/IMAP.hs
--- a/src/Network/HaskellNet/IMAP.hs
+++ b/src/Network/HaskellNet/IMAP.hs
@@ -23,7 +23,8 @@
     )
 where
 
-import Network
+import Network.Socket (PortNumber)
+import Network.Compat
 import Network.HaskellNet.BSStream
 import Network.HaskellNet.IMAP.Connection
 import Network.HaskellNet.IMAP.Types
@@ -33,7 +34,7 @@
 import Data.ByteString (ByteString)
 import qualified Data.ByteString.Char8 as BS
 
-import Control.Applicative ((<$>))
+import Control.Applicative ((<$>), (<*>))
 import Control.Monad
 
 import System.Time
@@ -116,7 +117,7 @@
 
 connectIMAPPort :: String -> PortNumber -> IO IMAPConnection
 connectIMAPPort hostname port =
-    handleToStream <$> connectTo hostname (PortNumber port)
+    handleToStream <$> connectTo hostname port
     >>= connectStream
 
 connectIMAP :: String -> IO IMAPConnection
@@ -165,7 +166,8 @@
           getLs =
               do l <- strip <$> bsGetLine s
                  case () of
-                   _ | isLiteral l ->  do l' <- getLiteral l (getLitLen l)
+                   _ | BS.null l -> return [l]
+                     | isLiteral l ->  do l' <- getLiteral l (getLitLen l)
                                           ls <- getLs
                                           return (l' : ls)
                      | isTagged l -> (l:) <$> getLs
@@ -313,17 +315,18 @@
     in sendCommand conn cmd pStatus
 
 append :: IMAPConnection -> MailboxName -> ByteString -> IO ()
-append conn mbox mailData = appendFull conn mbox mailData [] Nothing
+append conn mbox mailData = appendFull conn mbox mailData Nothing Nothing
 
 appendFull :: IMAPConnection -> MailboxName -> ByteString
-           -> [Flag] -> Maybe CalendarTime -> IO ()
+           -> Maybe [Flag] -> Maybe CalendarTime -> IO ()
 appendFull conn mbox mailData flags' time =
     do (buf, num) <- sendCommand' conn
-                (unwords ["APPEND", mbox
-                         , fstr, tstr,  "{" ++ show len ++ "}"])
-       unless (BS.null buf || (BS.head buf /= '+')) $
+                (concat ["APPEND ", mbox
+                        , fstr, tstr, " {" ++ show len ++ "}"])
+       when (BS.null buf || (BS.head buf /= '+')) $
               fail "illegal server response"
        mapM_ (bsPutCrLf $ stream conn) mailLines
+       bsPutCrLf (stream conn) BS.empty
        buf2 <- getResponse $ stream conn
        let (resp, mboxUp, ()) = eval pNone (show6 num) buf2
        case resp of
@@ -333,8 +336,8 @@
          PREAUTH _ msg -> fail ("PREAUTH: "++msg)
     where mailLines = BS.lines mailData
           len       = sum $ map ((2+) . BS.length) mailLines
-          tstr      = maybe "" show time
-          fstr      = unwords $ map show flags'
+          tstr      = maybe "" ((" "++) . show) time
+          fstr      = maybe "" ((" ("++) . (++")") . unwords . map show) flags'
 
 check :: IMAPConnection -> IO ()
 check conn = sendCommand conn "CHECK" pNone
diff --git a/src/Network/HaskellNet/IMAP/Parsers.hs b/src/Network/HaskellNet/IMAP/Parsers.hs
--- a/src/Network/HaskellNet/IMAP/Parsers.hs
+++ b/src/Network/HaskellNet/IMAP/Parsers.hs
@@ -268,6 +268,7 @@
                                 , string "RECENT"      >>= return . read
                                 , string "UIDNEXT"     >>= return . read
                                 , string "UIDVALIDITY" >>= return . read
+                                , string "UNSEEN"      >>= return . read
                                 ]
                  space
                  num <- many1 digit >>= return . read
diff --git a/src/Network/HaskellNet/IMAP/Types.hs b/src/Network/HaskellNet/IMAP/Types.hs
--- a/src/Network/HaskellNet/IMAP/Types.hs
+++ b/src/Network/HaskellNet/IMAP/Types.hs
@@ -97,6 +97,7 @@
                    | RECENT       -- ^ the number of messages with the \Recent flag set
                    | UIDNEXT      -- ^ the next unique identifier value of the mailbox
                    | UIDVALIDITY  -- ^ the unique identifier validity value of the mailbox
+                   | UNSEEN       -- ^ the number of messages with the \Unseen flag set
                      deriving (Show, Read, Eq)
 
 
diff --git a/src/Network/HaskellNet/POP3.hs b/src/Network/HaskellNet/POP3.hs
--- a/src/Network/HaskellNet/POP3.hs
+++ b/src/Network/HaskellNet/POP3.hs
@@ -31,7 +31,8 @@
     where
 
 import Network.HaskellNet.BSStream
-import Network
+import Network.Socket
+import Network.Compat
 import qualified Network.HaskellNet.Auth as A
 
 import Data.ByteString (ByteString)
@@ -74,7 +75,7 @@
 -- number
 connectPop3Port :: String -> PortNumber -> IO POP3Connection
 connectPop3Port hostname port =
-    handleToStream <$> (connectTo hostname (PortNumber port))
+    handleToStream <$> (connectTo hostname port)
     >>= connectStream
 
 -- | connecting to the pop3 server specified by the hostname. 110 is
diff --git a/src/Network/HaskellNet/SMTP.hs b/src/Network/HaskellNet/SMTP.hs
--- a/src/Network/HaskellNet/SMTP.hs
+++ b/src/Network/HaskellNet/SMTP.hs
@@ -74,7 +74,8 @@
 import Data.ByteString (ByteString)
 import qualified Data.ByteString.Char8 as BS
 import Network.BSD (getHostName)
-import Network
+import Network.Socket
+import Network.Compat
 
 import Control.Applicative ((<$>))
 import Control.Exception
@@ -140,7 +141,7 @@
                 -> PortNumber -- ^ port number
                 -> IO SMTPConnection
 connectSMTPPort hostname port =
-    (handleToStream <$> connectTo hostname (PortNumber port))
+    (handleToStream <$> connectTo hostname port)
     >>= connectStream
 
 -- | connecting SMTP server with the specified name and port 25.
@@ -190,8 +191,8 @@
 sendCommand :: SMTPConnection -> Command -> IO (ReplyCode, ByteString)
 sendCommand (SMTPC conn _) (DATA dat) =
     do bsPutCrLf conn $ BS.pack "DATA"
-       (code, _) <- parseResponse conn
-       unless (code == 354) $ fail "this server cannot accept any data."
+       (code, msg) <- parseResponse conn
+       unless (code == 354) $ fail $ "this server cannot accept any data. code: " ++ show code ++ ", msg: " ++ BS.unpack msg
        mapM_ (sendLine . stripCR) $ BS.lines dat ++ [BS.pack "."]
        parseResponse conn
     where sendLine = bsPutCrLf conn
@@ -210,7 +211,7 @@
 sendCommand (SMTPC conn _) (AUTH at username password) =
     do bsPutCrLf conn command
        (code, msg) <- parseResponse conn
-       unless (code == 334) $ fail "authentication failed."
+       unless (code == 334) $ fail $ "authentication failed. code: " ++ show code ++ ", msg: " ++ BS.unpack msg
        bsPutCrLf conn $ BS.pack $ auth at (BS.unpack msg) username password
        parseResponse conn
     where command = BS.pack $ unwords ["AUTH", show at]
@@ -359,7 +360,7 @@
 -- haskellNet uses strict bytestrings
 -- TODO: look at making haskellnet lazy
 lazyToStrict :: B.ByteString -> S.ByteString
-lazyToStrict = S.concat . B.toChunks
+lazyToStrict = B.toStrict
 
 crlf :: BS.ByteString
 crlf = BS.pack "\r\n"
diff --git a/src/Text/Packrat/Parse.hs b/src/Text/Packrat/Parse.hs
--- a/src/Text/Packrat/Parse.hs
+++ b/src/Text/Packrat/Parse.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 -- | Packrat parsing: Simple, Powerful, Lazy, Linear time by Bryan
 -- Ford.  This module achieves monadic parsing library similar to
 -- Parsec.
@@ -14,6 +15,8 @@
 import           Control.Applicative (Applicative(..))
 import qualified Control.Applicative as A
 
+import qualified Control.Monad.Fail as Fail
+
 -- Data types
 
 data Message = Expected String
@@ -62,6 +65,12 @@
               second err1 (NoParse err) =
                   NoParse (joinErrors err1 err)
     return = pure
+
+#if !(MIN_VERSION_base(4,13,0))
+    fail = Fail.fail
+#endif
+
+instance Derivs d => Fail.MonadFail (Parser d) where
     fail msg = Parser (\dvs -> NoParse (msgError (dvPos dvs) msg))
 
 instance Derivs d => A.Alternative (Parser d) where
