diff --git a/Codec/MIME/String/Flatten.hs b/Codec/MIME/String/Flatten.hs
--- a/Codec/MIME/String/Flatten.hs
+++ b/Codec/MIME/String/Flatten.hs
@@ -1,10 +1,13 @@
 
-module Codec.MIME.String.Flatten (flatten, flattenXXX) where
+module Codec.MIME.String.Flatten
+    (flatten, flattenXXX, Attachments, Attachment)
+    where
 
 import qualified Codec.Binary.Base64.String as Base64 (encode)
 import Codec.MIME.String.Date
 import Codec.MIME.String.EncodedWord
 import qualified Codec.MIME.String.QuotedPrintable as QP (encode)
+import Codec.MIME.String.Headers
 import Codec.MIME.String.Internal.Utils
 import Codec.MIME.String.Parse
 import Codec.MIME.String.Types
@@ -18,10 +21,12 @@
 import System.Time (getClockTime, toCalendarTime, formatCalendarTime)
 -}
 
+type Attachments = [Attachment]
+type Attachment = (String, FilePath, Maybe ContentType)
+
 -- XXX This has the API of the old function. Should go at some point.
 -- Flatten {meta info, message body and list of attachments} to a raw message
-flattenXXX :: String -> String -> String -> FullDate
-        -> String -> [(String, FilePath)]
+flattenXXX :: String -> String -> String -> FullDate -> String -> Attachments
         -> IO String
 flattenXXX from_name from_email subject date body attachments
  = let -- XXX This (\n) could be prettier - check llengths of bits
@@ -34,7 +39,7 @@
    in flatten headers body attachments
 
 -- XXX This should take a headers structure
-flatten :: Headers -> String -> [(String, FilePath)] -> IO String
+flatten :: Headers -> String -> Attachments -> IO String
 flatten headers body attachments
  = do -- XXX Could add one of one isn't already found? msgid <- mk_msgid
       let -- XXX This (\n) could be prettier - check llengths of bits
@@ -49,20 +54,27 @@
               "Content-Disposition: inline"]
           -- This is overly paranoid
           safe_char c = isAsciiAlphaNum c || (c `elem` " .-_")
-          mime_attachment (a, fn)
-              = part_start
-                -- XXX Can we give a better MIME type than this?
-             ++ "Content-type: application/octet-stream\n"
-             ++ "Content-transfer-encoding: base64\n"
-             ++ "Content-Disposition: attachment; filename=\""
-                    ++ (case reverse $ filter safe_char
-                                     $ takeWhile ('/' /=)
-                                     $ reverse fn of
-                            [] -> "unknown"
-                            fn' -> fn')
-                    ++ "\"\n"
-             ++ "\n"
-             ++ Base64.encode a
+          mime_attachment (a, fn, mct)
+              = let -- XXX showParam and ct should do some sanity checking
+                    -- of the values they are passed
+                    showParam (Parameter k v) = "; " ++ k ++ "=\"" ++ v ++ "\""
+                    ct = case mct of
+                         Just (ContentType x y ps) ->
+                             "Content-type: " ++ x ++ "/" ++ y
+                          ++ concatMap showParam ps ++ "\n"
+                         Nothing -> "Content-type: application/octet-stream\n"
+                in part_start
+                ++ ct
+                ++ "Content-transfer-encoding: base64\n"
+                ++ "Content-Disposition: attachment; filename=\""
+                       ++ (case reverse $ filter safe_char
+                                        $ takeWhile ('/' /=)
+                                        $ reverse fn of
+                               [] -> "unknown"
+                               fn' -> fn')
+                       ++ "\"\n"
+                ++ "\n"
+                ++ Base64.encode a
           msg = if single_part
                 then common_headers
                   ++ text_content_headers
diff --git a/mime-string.cabal b/mime-string.cabal
--- a/mime-string.cabal
+++ b/mime-string.cabal
@@ -1,5 +1,5 @@
 Name:               mime-string
-Version:            0.2
+Version:            0.3
 License:            OtherLicense
 License-File:       COPYING
 Copyright:          Ian Lynagh, 2005, 2007
