diff --git a/Data/Text/ICU.hs b/Data/Text/ICU.hs
--- a/Data/Text/ICU.hs
+++ b/Data/Text/ICU.hs
@@ -108,7 +108,7 @@
 -- a fixed address.
 --
 -- To accommodate this need, these bindings use the functions from
--- 'Data.Text.Foreign' to copy data between the Haskell heap and the
+-- "Data.Text.Foreign" to copy data between the Haskell heap and the
 -- system heap.  The copied strings are still managed automatically,
 -- but the need to duplicate data does add some performance and memory
 -- overhead.
diff --git a/Data/Text/ICU/Break.hsc b/Data/Text/ICU/Break.hsc
--- a/Data/Text/ICU/Break.hsc
+++ b/Data/Text/ICU/Break.hsc
@@ -49,6 +49,7 @@
 
 #include <unicode/ubrk.h>
 
+import Control.DeepSeq (NFData(..))
 import Control.Monad (forM)
 import Data.IORef (newIORef, writeIORef)
 import Data.Int (Int32)
@@ -79,6 +80,9 @@
           | Hard
             deriving (Eq, Show, Enum)
 
+instance NFData Line where
+    rnf !_ = ()
+
 -- | Word break status.
 data Word = Uncategorized       -- ^ A \"word\" that does not fit into another
                                 -- category.  Includes spaces and most
@@ -90,6 +94,9 @@
           | Kana                -- ^ A word containing kana characters.
           | Ideograph           -- ^ A word containing ideographic characters.
             deriving (Eq, Show, Enum)
+
+instance NFData Word where
+    rnf !_ = ()
 
 -- | Break a string on character boundaries.
 --
diff --git a/Data/Text/ICU/Break/Pure.hs b/Data/Text/ICU/Break/Pure.hs
--- a/Data/Text/ICU/Break/Pure.hs
+++ b/Data/Text/ICU/Break/Pure.hs
@@ -38,6 +38,7 @@
     , breaksRight
     ) where
 
+import Control.DeepSeq (NFData(..))
 import Data.Text (Text, empty)
 import Data.Text.Foreign (dropWord16, takeWord16)
 import Data.Text.ICU.Break (Line, Word)
@@ -98,6 +99,9 @@
     , brkStatus :: !a
     -- ^ Status of the current break (only meaningful if 'Line' or 'Word').
     } deriving (Eq, Show)
+
+instance (NFData a) => NFData (Break a) where
+    rnf Break{..} = rnf brkStatus
 
 -- | Return a list of all breaks in a string, from left to right.
 breaks :: Breaker a -> Text -> [Break a]
diff --git a/Data/Text/ICU/Char.hsc b/Data/Text/ICU/Char.hsc
--- a/Data/Text/ICU/Char.hsc
+++ b/Data/Text/ICU/Char.hsc
@@ -85,6 +85,7 @@
 
 #include <unicode/uchar.h>
 
+import Control.DeepSeq (NFData(..))
 import Data.Char (chr, ord)
 import Data.Int (Int32)
 import Data.Text.ICU.Error (u_INVALID_CHAR_FOUND)
@@ -131,6 +132,9 @@
   | BoundaryNeutral
   deriving (Eq, Enum, Show, Typeable)
 
+instance NFData Direction where
+    rnf !_ = ()
+
 -- | Descriptions of Unicode blocks.
 data BlockCode =
     NoBlock
@@ -305,8 +309,60 @@
   | Lydian
   | MahjongTiles
   | DominoTiles
-  deriving (Eq, Enum, Show, Typeable)
+  | Samaritan
+  | UnifiedCanadianAboriginalSyllabicsExtended
+  | TaiTham
+  | VedicExtensions
+  | Lisu
+  | Bamum
+  | CommonIndicNumberForms
+  | DevanagariExtended
+  | HangulJamoExtendedA
+  | Javanese
+  | MyanmarExtendedA
+  | TaiViet
+  | MeeteiMayek
+  | HangulJamoExtendedB
+  | ImperialAramaic
+  | OldSouthArabian
+  | Avestan
+  | InscriptionalParthian
+  | InscriptionalPahlavi
+  | OldTurkic
+  | RumiNumeralSymbols
+  | Kaithi
+  | EgyptianHieroglyphs
+  | EnclosedAlphanumericSupplement
+  | EnclosedIdeographicSupplement
+  | CJKUnifiedIdeographsExtensionC
+  | Mandaic
+  | Batak
+  | EthiopicExtendedA
+  | Brahmi
+  | BamumSupplement
+  | KanaSupplement
+  | PlayingCards
+  | MiscellaneousSymbolsAndPictographs
+  | Emoticons
+  | TransportAndMapSymbols
+  | AlchemicalSymbols
+  | CJKUnifiedIdeographsExtensionD
+  | ArabicExtendedA
+  | ArabicMathematicalAlphabeticSymbols
+  | Chakma
+  | MeeteiMayekExtensions
+  | MeroiticCursive
+  | MeroiticHieroglyphs
+  | Miao
+  | Sharada
+  | SoraSompeng
+  | SundaneseSupplement
+  | Takri
+  deriving (Eq, Enum, Bounded, Show, Typeable)
 
+instance NFData BlockCode where
+    rnf !_ = ()
+
 data Bool_ =
     Alphabetic
   | ASCIIHexDigit
@@ -422,30 +478,45 @@
   -- ^ Hex digit character class.
     deriving (Eq, Enum, Show, Typeable)
 
+instance NFData Bool_ where
+    rnf !_ = ()
+
 class Property p v | p -> v where
     fromNative :: p -> Int32 -> v
     toUProperty :: p -> UProperty
 
 data BidiClass_ = BidiClass deriving (Show, Typeable)
 
+instance NFData BidiClass_ where
+    rnf !_ = ()
+
 instance Property BidiClass_ Direction where
     fromNative _  = toEnum . fromIntegral
     toUProperty _ = (#const UCHAR_BIDI_CLASS)
 
 data Block_ = Block
 
+instance NFData Block_ where
+    rnf !_ = ()
+
 instance Property Block_ BlockCode where
     fromNative _  = toEnum . fromIntegral
     toUProperty _ = (#const UCHAR_BLOCK)
 
 data CanonicalCombiningClass_ = CanonicalCombiningClass deriving (Show,Typeable)
 
+instance NFData CanonicalCombiningClass_ where
+    rnf !_ = ()
+
 instance Property CanonicalCombiningClass_ Int where
     fromNative _  = fromIntegral
     toUProperty _ = (#const UCHAR_CANONICAL_COMBINING_CLASS)
 
 data Decomposition_ = Decomposition deriving (Show, Typeable)
 
+instance NFData Decomposition_ where
+    rnf !_ = ()
+
 data Decomposition =
     Canonical
   | Compat
@@ -467,12 +538,18 @@
   | Count
     deriving (Eq, Enum, Show, Typeable)
 
+instance NFData Decomposition where
+    rnf !_ = ()
+
 instance Property Decomposition_ (Maybe Decomposition) where
     fromNative _  = maybeEnum
     toUProperty _ = (#const UCHAR_DECOMPOSITION_TYPE)
 
 data EastAsianWidth_ = EastAsianWidth deriving (Show, Typeable)
 
+instance NFData EastAsianWidth_ where
+    rnf !_ = ()
+
 data EastAsianWidth = EANeutral
                     | EAAmbiguous
                     | EAHalf
@@ -482,6 +559,9 @@
                     | EACount
                     deriving (Eq, Enum, Show, Typeable)
 
+instance NFData EastAsianWidth where
+    rnf !_ = ()
+
 instance Property EastAsianWidth_ EastAsianWidth where
     fromNative _  = toEnum . fromIntegral
     toUProperty _ = (#const UCHAR_EAST_ASIAN_WIDTH)
@@ -492,6 +572,9 @@
 
 data GeneralCategory_ = GeneralCategory deriving (Show, Typeable)
 
+instance NFData GeneralCategory_ where
+    rnf !_ = ()
+
 data GeneralCategory =
     GeneralOtherType
   | UppercaseLetter
@@ -525,12 +608,18 @@
   | FinalPunctuation
     deriving (Eq, Enum, Show, Typeable)
 
+instance NFData GeneralCategory where
+    rnf !_ = ()
+
 instance Property GeneralCategory_ GeneralCategory where
     fromNative _  = toEnum . fromIntegral
     toUProperty _ = (#const UCHAR_GENERAL_CATEGORY)
 
 data JoiningGroup_ = JoiningGroup deriving (Show, Typeable)
 
+instance NFData JoiningGroup_ where
+    rnf !_ = ()
+
 maybeEnum :: Enum a => Int32 -> Maybe a
 maybeEnum 0 = Nothing
 maybeEnum n = Just $! toEnum (fromIntegral n-1)
@@ -592,12 +681,18 @@
   | BurushaskiYehBarree
     deriving (Eq, Enum, Show, Typeable)
 
+instance NFData JoiningGroup where
+    rnf !_ = ()
+
 instance Property JoiningGroup_ (Maybe JoiningGroup) where
     fromNative _  = maybeEnum
     toUProperty _ = (#const UCHAR_JOINING_GROUP)
 
 data JoiningType_ = JoiningType deriving (Show, Typeable)
 
+instance NFData JoiningType_ where
+    rnf !_ = ()
+
 data JoiningType =
     JoinCausing
   | DualJoining
@@ -606,12 +701,18 @@
   | Transparent
     deriving (Eq, Enum, Show, Typeable)
 
+instance NFData JoiningType where
+    rnf !_ = ()
+
 instance Property JoiningType_ (Maybe JoiningType) where
     fromNative _  = maybeEnum
     toUProperty _ = (#const UCHAR_JOINING_TYPE)
 
 data LineBreak_ = LineBreak deriving (Show, Typeable)
 
+instance NFData LineBreak_ where
+    rnf !_ = ()
+
 data LineBreak =
     Ambiguous
   | LBAlphabetic
@@ -650,21 +751,33 @@
   | JV
     deriving (Eq, Enum, Show, Typeable)
 
+instance NFData LineBreak where
+    rnf !_ = ()
+
 instance Property LineBreak_ (Maybe LineBreak) where
     fromNative _  = maybeEnum
     toUProperty _ = (#const UCHAR_LINE_BREAK)
 
 data NumericType_ = NumericType deriving (Show, Typeable)
 
+instance NFData NumericType_ where
+    rnf !_ = ()
+
 data NumericType = NTDecimal | NTDigit | NTNumeric
                    deriving (Eq, Enum, Show, Typeable)
 
+instance NFData NumericType where
+    rnf !_ = ()
+
 instance Property NumericType_ (Maybe NumericType) where
     fromNative _  = maybeEnum
     toUProperty _ = (#const UCHAR_NUMERIC_TYPE)
 
 data HangulSyllableType_ = HangulSyllableType deriving (Show, Typeable)
 
+instance NFData HangulSyllableType_ where
+    rnf !_ = ()
+
 data HangulSyllableType =
     LeadingJamo
   | VowelJamo
@@ -673,6 +786,9 @@
   | LVTSyllable
     deriving (Eq, Enum, Show, Typeable)
 
+instance NFData HangulSyllableType where
+    rnf !_ = ()
+
 instance Property HangulSyllableType_ (Maybe HangulSyllableType) where
     fromNative _  = maybeEnum
     toUProperty _ = (#const UCHAR_HANGUL_SYLLABLE_TYPE)
@@ -682,6 +798,18 @@
 data NFKCQuickCheck_ = NFKCQuickCheck deriving (Show, Typeable)
 data NFKDQuickCheck_ = NFKDQuickCheck deriving (Show, Typeable)
 
+instance NFData NFCQuickCheck_ where
+    rnf !_ = ()
+
+instance NFData NFDQuickCheck_ where
+    rnf !_ = ()
+
+instance NFData NFKCQuickCheck_ where
+    rnf !_ = ()
+
+instance NFData NFKDQuickCheck_ where
+    rnf !_ = ()
+
 instance Property NFCQuickCheck_ (Maybe Bool) where
     fromNative  _ = toNCR . fromIntegral
     toUProperty _ = (#const UCHAR_NFC_QUICK_CHECK)
@@ -701,6 +829,9 @@
 data LeadCanonicalCombiningClass_ = LeadCanonicalCombiningClass
                                     deriving (Show, Typeable)
 
+instance NFData LeadCanonicalCombiningClass_ where
+    rnf !_ = ()
+
 instance Property LeadCanonicalCombiningClass_ Int where
     fromNative  _ = fromIntegral
     toUProperty _ = (#const UCHAR_LEAD_CANONICAL_COMBINING_CLASS)
@@ -708,12 +839,18 @@
 data TrailingCanonicalCombiningClass_ = TrailingCanonicalCombiningClass
                                    deriving (Show, Typeable)
 
+instance NFData TrailingCanonicalCombiningClass_ where
+    rnf !_ = ()
+
 instance Property TrailingCanonicalCombiningClass_ Int where
     fromNative  _ = fromIntegral
     toUProperty _ = (#const UCHAR_TRAIL_CANONICAL_COMBINING_CLASS)
 
 data GraphemeClusterBreak_ = GraphemeClusterBreak deriving (Show, Typeable)
 
+instance NFData GraphemeClusterBreak_ where
+    rnf !_ = ()
+
 data GraphemeClusterBreak =
     Control
   | CR
@@ -728,12 +865,18 @@
   | Prepend
     deriving (Eq, Enum, Show, Typeable)
 
+instance NFData GraphemeClusterBreak where
+    rnf !_ = ()
+
 instance Property GraphemeClusterBreak_ (Maybe GraphemeClusterBreak) where
     fromNative  _ = maybeEnum
     toUProperty _ = (#const UCHAR_GRAPHEME_CLUSTER_BREAK)
 
 data SentenceBreak_ = SentenceBreak deriving (Show, Typeable)
 
+instance NFData SentenceBreak_ where
+    rnf !_ = ()
+
 data SentenceBreak =
     SBATerm
   | SBClose
@@ -751,12 +894,18 @@
   | SBSContinue
     deriving (Eq, Enum, Show, Typeable)
 
+instance NFData SentenceBreak where
+    rnf !_ = ()
+
 instance Property SentenceBreak_ (Maybe SentenceBreak) where
     fromNative  _ = maybeEnum
     toUProperty _ = (#const UCHAR_SENTENCE_BREAK)
 
 data WordBreak_ = WordBreak deriving (Show, Typeable)
 
+instance NFData WordBreak_ where
+    rnf !_ = ()
+
 data WordBreak =
     WBALetter
   | WBFormat
@@ -772,6 +921,9 @@
   | WBNewline
     deriving (Eq, Enum, Show, Typeable)
 
+instance NFData WordBreak where
+    rnf !_ = ()
+
 instance Property WordBreak_ (Maybe WordBreak) where
     fromNative  _ = maybeEnum
     toUProperty _ = (#const UCHAR_WORD_BREAK)
@@ -907,6 +1059,7 @@
 -- 10646 names list.
 isoComment :: Char -> String
 isoComment c = fillString $ u_getISOComment (fromIntegral (ord c))
+{-# DEPRECATED isoComment "Will be removed from next major release." #-}
 
 charName' :: UCharNameChoice -> Char -> String
 charName' choice c = fillString $ u_charName (fromIntegral (ord c)) choice
diff --git a/Data/Text/ICU/Collate.hsc b/Data/Text/ICU/Collate.hsc
--- a/Data/Text/ICU/Collate.hsc
+++ b/Data/Text/ICU/Collate.hsc
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP, DeriveDataTypeable, ForeignFunctionInterface #-}
+{-# LANGUAGE BangPatterns, CPP, DeriveDataTypeable, ForeignFunctionInterface #-}
 -- |
 -- Module      : Data.Text.ICU.Collate
 -- Copyright   : (c) 2010 Bryan O'Sullivan
@@ -26,7 +26,6 @@
     , collate
     , collateIter
     -- ** Utility functions
-    , equals
     , getAttribute
     , setAttribute
     , sortKey
@@ -36,6 +35,7 @@
 
 #include <unicode/ucol.h>
 
+import Control.DeepSeq (NFData(..))
 import Data.ByteString (empty)
 import Data.ByteString.Internal (ByteString(..), create, mallocByteString,
                                  memcpy)
@@ -44,7 +44,7 @@
 import qualified Data.Text as T
 import Data.Text.Foreign (useAsPtr)
 import Data.Text.ICU.Collate.Internal (Collator(..), MCollator, UCollator,
-                                       equals, withCollator, wrap)
+                                       withCollator, wrap)
 import Data.Text.ICU.Error.Internal (UErrorCode, handleError)
 import Data.Text.ICU.Internal
     (LocaleName, UChar, CharIterator, UCharIterator,
@@ -71,6 +71,9 @@
                          -- quaternary level.
                          deriving (Eq, Bounded, Enum, Show, Typeable)
 
+instance NFData AlternateHandling where
+    rnf !_ = ()
+
 -- | Control the ordering of upper and lower case letters.
 data CaseFirst = UpperFirst     -- ^ Force upper case letters to sort before
                                 -- lower case.
@@ -78,6 +81,9 @@
                                 -- upper case.
                 deriving (Eq, Bounded, Enum, Show, Typeable)
 
+instance NFData CaseFirst where
+    rnf !_ = ()
+
 -- | The strength attribute. The usual strength for most locales (except
 -- Japanese) is tertiary. Quaternary strength is useful when combined with
 -- shifted setting for alternate handling attribute and for JIS x 4061
@@ -93,6 +99,9 @@
               | Identical
                 deriving (Eq, Bounded, Enum, Show, Typeable)
 
+instance NFData Strength where
+    rnf !_ = ()
+
 data Attribute = French Bool
                -- ^ Direction of secondary weights, used in French.  'True',
                -- results in secondary weights being considered backwards,
@@ -135,6 +144,16 @@
                  -- a way to get '100' to sort /after/ '2'.
                  deriving (Eq, Show, Typeable)
 
+instance NFData Attribute where
+    rnf (French !_)                 = ()
+    rnf (AlternateHandling !_)      = ()
+    rnf (CaseFirst c)               = rnf c
+    rnf (CaseLevel !_)              = ()
+    rnf (NormalizationMode !_)      = ()
+    rnf (Strength !_)               = ()
+    rnf (HiraganaQuaternaryMode !_) = ()
+    rnf (Numeric !_)                = ()
+
 type UColAttribute = CInt
 type UColAttributeValue = CInt
 
@@ -214,7 +233,7 @@
     _ -> valueError "fromUAttribute" key
 
 valueError :: Show a => String -> a -> z
-valueError func bad = error ("Data.Text.ICU.Collate.IO." ++ func ++
+valueError func bad = error ("Data.Text.ICU.Collate." ++ func ++
                              ": invalid value " ++ show bad)
 
 type UCollationResult = CInt
@@ -279,7 +298,7 @@
             i <- withForeignPtr fp $ \p -> ucol_getSortKey cptr tptr len p n
             let j = fromIntegral i
             case undefined of
-              _ | i == 0         -> error "Data.Text.ICU.Collate.IO.sortKey: internal error"
+              _ | i == 0         -> error "Data.Text.ICU.Collate.sortKey: internal error"
                 | i > n          -> loop i
                 | i <= n `div` 2 -> create j $ \p -> withForeignPtr fp $ \op ->
                                     memcpy p op (fromIntegral i)
diff --git a/Data/Text/ICU/Collate/Internal.hs b/Data/Text/ICU/Collate/Internal.hs
--- a/Data/Text/ICU/Collate/Internal.hs
+++ b/Data/Text/ICU/Collate/Internal.hs
@@ -16,16 +16,13 @@
       MCollator(..)
     , Collator(..)
     , UCollator
-    , equals
     , withCollator
     , wrap
     ) where
 
-import Data.Text.ICU.Internal (UBool, asBool)
 import Data.Typeable (Typeable)
 import Foreign.ForeignPtr (ForeignPtr, newForeignPtr, withForeignPtr)
 import Foreign.Ptr (FunPtr, Ptr)
-import System.IO.Unsafe (unsafePerformIO)
 
 -- $api
 --
@@ -41,9 +38,6 @@
 newtype Collator = C MCollator
     deriving (Typeable)
 
-instance Eq Collator where
-    (C a) == (C b) = unsafePerformIO $ equals a b
-
 withCollator :: MCollator -> (Ptr UCollator -> IO a) -> IO a
 withCollator (MCollator col) action = withForeignPtr col action
 {-# INLINE withCollator #-}
@@ -52,16 +46,5 @@
 wrap = fmap MCollator . newForeignPtr ucol_close
 {-# INLINE wrap #-}
 
--- | 'MCollator's are considered equal if they will sort strings
--- identically. This means that both the current attributes and the rules
--- must be equivalent.
-equals :: MCollator -> MCollator -> IO Bool
-equals a b = fmap asBool .
-  withCollator a $ \aptr ->
-    withCollator b $ ucol_equals aptr
-
 foreign import ccall unsafe "hs_text_icu.h &__hs_ucol_close" ucol_close
     :: FunPtr (Ptr UCollator -> IO ())
-
-foreign import ccall unsafe "hs_text_icu.h __hs_ucol_equals" ucol_equals
-    :: Ptr UCollator -> Ptr UCollator -> IO UBool
diff --git a/Data/Text/ICU/Convert.hs b/Data/Text/ICU/Convert.hs
--- a/Data/Text/ICU/Convert.hs
+++ b/Data/Text/ICU/Convert.hs
@@ -101,8 +101,7 @@
     _ -> return ()
   return c
 
--- | Convert the Unicode string into a codepage string using the given
--- converter.
+-- | Encode a Unicode string into a codepage string using the given converter.
 fromUnicode :: Converter -> Text -> ByteString
 fromUnicode cnv t =
   unsafePerformIO . useAsPtr t $ \tptr tlen ->
@@ -113,8 +112,7 @@
         fmap fromIntegral . handleError $
            ucnv_fromUChars cptr (castPtr sptr) capacity tptr (fromIntegral tlen)
 
--- | Convert the codepage string into a Unicode string using the given
--- converter.
+-- | Decode an encoded string into a Unicode string using the given converter.
 toUnicode :: Converter -> ByteString -> Text
 toUnicode cnv bs =
   unsafePerformIO . unsafeUseAsCStringLen bs $ \(sptr, slen) ->
diff --git a/Data/Text/ICU/Error/Internal.hsc b/Data/Text/ICU/Error/Internal.hsc
--- a/Data/Text/ICU/Error/Internal.hsc
+++ b/Data/Text/ICU/Error/Internal.hsc
@@ -1,5 +1,5 @@
-{-# LANGUAGE DeriveDataTypeable, ForeignFunctionInterface,
-    ScopedTypeVariables #-}
+{-# LANGUAGE BangPatterns, DeriveDataTypeable, ForeignFunctionInterface,
+    RecordWildCards, ScopedTypeVariables #-}
 
 module Data.Text.ICU.Error.Internal
     (
@@ -20,10 +20,11 @@
     , withError
     ) where
 
+import Control.DeepSeq (NFData(..))
 import Control.Exception (Exception, throwIO)
 import Data.Function (fix)
 import Foreign.Ptr (Ptr)
-import Foreign.Marshal.Alloc (alloca)
+import Foreign.Marshal.Alloc (alloca, allocaBytes)
 import Foreign.Marshal.Utils (with)
 import Foreign.Marshal.Array (allocaArray)
 import Data.Int (Int32)
@@ -50,6 +51,9 @@
 
 instance Exception ICUError
 
+instance NFData ICUError where
+    rnf !_ = ()
+
 -- | Detailed information about parsing errors.  Used by ICU parsing
 -- engines that parse long rules, patterns, or programs, where the
 -- text being parsed is long enough that more information than an
@@ -71,19 +75,13 @@
     -- 'Nothing'.
     } deriving (Show, Typeable)
 
+instance NFData ParseError where
+    rnf ParseError{..} = rnf errError `seq` rnf errLine `seq` rnf errOffset
+
 type UParseError = ParseError
 
 instance Exception ParseError
 
-instance Storable ParseError where
-    sizeOf _    = #{size UParseError}
-    alignment _ = alignment (undefined :: CString)
-    peek ptr = do
-      (line::Int32) <- #{peek UParseError, line} ptr
-      (offset::Int32) <- #{peek UParseError, offset} ptr
-      let wrap k = if k == -1 then Nothing else Just $! fromIntegral k
-      return $! ParseError undefined (wrap line) (wrap offset)
-
 -- | Indicate whether the given error code is a success.
 isSuccess :: ICUError -> Bool
 {-# INLINE isSuccess #-}
@@ -145,15 +143,20 @@
 handleParseError :: (ICUError -> Bool)
                  -> (Ptr UParseError -> Ptr UErrorCode -> IO a) -> IO a
 handleParseError isParseError action = with 0 $ \uerrPtr ->
-  alloca $ \perrPtr -> do
+  allocaBytes (#{size UParseError}) $ \perrPtr -> do
     ret <- action perrPtr uerrPtr
     err <- ICUError `fmap` peek uerrPtr
     case undefined of
-     _| isParseError err -> do
-                         perr <- peek perrPtr
-                         throwIO perr { errError = err }
+     _| isParseError err -> throwParseError perrPtr err
       | isFailure err -> throwIO err
       | otherwise     -> return ret
+
+throwParseError :: Ptr UParseError -> ICUError -> IO a
+throwParseError ptr err = do
+  (line::Int32) <- #{peek UParseError, line} ptr
+  (offset::Int32) <- #{peek UParseError, offset} ptr
+  let wrap k = if k == -1 then Nothing else Just $! fromIntegral k
+  throwIO $! ParseError err (wrap line) (wrap offset)
 
 -- | Return a string representing the name of the given error code.
 errorName :: ICUError -> String
diff --git a/Data/Text/ICU/Internal.hsc b/Data/Text/ICU/Internal.hsc
--- a/Data/Text/ICU/Internal.hsc
+++ b/Data/Text/ICU/Internal.hsc
@@ -17,6 +17,7 @@
 
 #include <unicode/uiter.h>
 
+import Control.DeepSeq (NFData(..))
 import Data.ByteString.Internal (ByteString(..))
 import Data.Int (Int8, Int32)
 import Data.String (IsString(..))
@@ -26,10 +27,9 @@
 import Data.Word (Word16, Word32)
 import Foreign.C.String (CString, withCString)
 import Foreign.C.Types (CChar)
-import Foreign.Marshal.Alloc (alloca)
+import Foreign.Marshal.Alloc (allocaBytes)
 import Foreign.ForeignPtr (withForeignPtr)
 import Foreign.Ptr (Ptr, castPtr, nullPtr)
-import Foreign.Storable (Storable(..))
 
 -- | A type that supports efficient iteration over Unicode characters.
 --
@@ -47,18 +47,14 @@
 
 data UCharIterator
 
-instance Storable UCharIterator where
-    sizeOf _    = #{size UCharIterator}
-    alignment _ = alignment (undefined :: CString)
-
 -- | Temporarily allocate a 'UCharIterator' and use it with the
 -- contents of the to-be-iterated-over string.
 withCharIterator :: CharIterator -> (Ptr UCharIterator -> IO a) -> IO a
 withCharIterator (CIUTF8 (PS fp _ l)) act =
-    alloca $ \i -> withForeignPtr fp $ \p ->
+    allocaBytes (#{size UCharIterator}) $ \i -> withForeignPtr fp $ \p ->
     uiter_setUTF8 i (castPtr p) (fromIntegral l) >> act i
 withCharIterator (CIText t) act =
-    alloca $ \i -> useAsPtr t $ \p l ->
+    allocaBytes (#{size UCharIterator}) $ \i -> useAsPtr t $ \p l ->
     uiter_setString i p (fromIntegral l) >> act i
 
 type UBool   = Int8
@@ -89,6 +85,11 @@
                 | Locale String -- ^ A specific locale.
                 | Current       -- ^ The program's current locale.
                   deriving (Eq, Ord, Read, Show)
+
+instance NFData LocaleName where
+    rnf Root       = ()
+    rnf (Locale l) = rnf l
+    rnf Current    = ()
 
 instance IsString LocaleName where
     fromString = Locale
diff --git a/Data/Text/ICU/Regex.hs b/Data/Text/ICU/Regex.hs
--- a/Data/Text/ICU/Regex.hs
+++ b/Data/Text/ICU/Regex.hs
@@ -20,7 +20,7 @@
 --
 -- /Note/: The functions in this module are not thread safe.  For
 -- thread safe use, see 'clone' below, or use the pure functions in
--- 'Data.Text.ICU'.
+-- "Data.Text.ICU".
 
 module Data.Text.ICU.Regex
     (
diff --git a/Data/Text/ICU/Regex/Pure.hs b/Data/Text/ICU/Regex/Pure.hs
--- a/Data/Text/ICU/Regex/Pure.hs
+++ b/Data/Text/ICU/Regex/Pure.hs
@@ -14,7 +14,7 @@
 --
 -- The functions in this module are pure and hence thread safe, but
 -- may not be as fast or as flexible as those in the
--- 'Data.Text.ICU.Regex.IO' module.
+-- "Data.Text.ICU.Regex" module.
 --
 -- The syntax and behaviour of ICU regular expressions are Perl-like.
 -- For complete details, see the ICU User Guide entry at
diff --git a/cbits/text_icu.c b/cbits/text_icu.c
--- a/cbits/text_icu.c
+++ b/cbits/text_icu.c
@@ -139,11 +139,6 @@
     return ucol_getSortKey(coll, source, sourceLength, result, resultLength);
 }
 
-UBool __hs_ucol_equals(const UCollator *source, const UCollator *target)
-{
-    return ucol_equals(source, target);
-}
-
 int __get_max_bytes_for_string(UConverter *cnv, int src_length)
 {
     return UCNV_GET_MAX_BYTES_FOR_STRING(src_length, ucnv_getMaxCharSize(cnv));
@@ -426,7 +421,7 @@
     return uregex_getText(regexp, textLength, status);
 }
 
-UBool __hs_uregex_find(URegularExpression *regexp, int32_t startIndex, 
+UBool __hs_uregex_find(URegularExpression *regexp, int32_t startIndex,
 		       UErrorCode *status)
 {
     return uregex_find(regexp, startIndex, status);
@@ -460,4 +455,3 @@
 {
     return uregex_group(regexp, groupNum, dest, destCapacity, status);
 }
-
diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,11 @@
+0.7.0.0
+
+* Built and tested against ICU 53.
+
+* The isoComment function has been deprecated, and will be removed in
+  the next major release.
+
+* The Collator type is no longer an instance of Eq, as this
+  functionality has been removed from ICU 53.
+
+* Many NFData instances have been added.
diff --git a/tests/Properties.hs b/tests/Properties.hs
--- a/tests/Properties.hs
+++ b/tests/Properties.hs
@@ -19,8 +19,9 @@
 import qualified Data.Text as T
 import qualified Data.Text.Encoding as T
 import qualified Data.Text.ICU as I
+import qualified Data.Text.ICU.Char as I
 
-t_rnf :: (NFData a) => (Text -> a) -> Text -> Bool
+t_rnf :: (NFData b) => (a -> b) -> a -> Bool
 t_rnf f t = rnf (f t) == ()
 
 t_nonEmpty :: (Text -> Text) -> Text -> Bool
@@ -62,7 +63,23 @@
 
 t_collate_root txt = t_rnf $ I.collate I.uca txt
 
+-- Unicode character database
 
+-- These tests are weak.
+
+t_blockCode = t_rnf I.blockCode
+t_charFullName c = I.charFromFullName (I.charFullName c) == Just c
+t_charName c = maybe True (==c) $ I.charFromName (I.charName c)
+t_combiningClass = t_rnf I.combiningClass
+t_direction = t_rnf I.direction
+-- t_property p = t_rnf $ I.property p
+t_isoComment = t_rnf $ I.isoComment
+t_isMirrored = t_rnf $ I.isMirrored
+t_mirror = t_rnf $ I.mirror
+t_digitToInt = t_rnf $ I.digitToInt
+t_numericValue = t_rnf $ I.numericValue
+
+
 tests :: Test
 tests =
   testGroup "Properties" [
@@ -75,4 +92,15 @@
   , testProperty "t_normalize" t_normalize
   , testProperty "t_quickCheck_isNormalized" t_quickCheck_isNormalized
   , testProperty "t_collate_root" t_collate_root
+  , testProperty "t_blockCode" t_blockCode
+  , testProperty "t_charFullName" t_charFullName
+  , testProperty "t_charName" t_charName
+  , testProperty "t_combiningClass" t_combiningClass
+  , testProperty "t_direction" t_direction
+--, testProperty "t_property" t_property
+  , testProperty "t_isoComment" t_isoComment
+  , testProperty "t_isMirrored" t_isMirrored
+  , testProperty "t_mirror" t_mirror
+  , testProperty "t_digitToInt" t_digitToInt
+  , testProperty "t_numericValue" t_numericValue
   ]
diff --git a/tests/QuickCheckUtils.hs b/tests/QuickCheckUtils.hs
--- a/tests/QuickCheckUtils.hs
+++ b/tests/QuickCheckUtils.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE BangPatterns #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 module QuickCheckUtils () where
@@ -11,7 +12,7 @@
 import qualified Data.Text.ICU as I
 
 instance NFData Ordering where
-    rnf v  = v `seq` ()
+    rnf !_  = ()
 
 instance Arbitrary T.Text where
     arbitrary = T.pack `fmap` arbitrary
diff --git a/text-icu.cabal b/text-icu.cabal
--- a/text-icu.cabal
+++ b/text-icu.cabal
@@ -1,5 +1,5 @@
 name:           text-icu
-version:        0.6.3.7
+version:        0.7.0.0
 synopsis:       Bindings to the ICU library
 homepage:       https://github.com/bos/text-icu
 bug-reports:    https://github.com/bos/text-icu/issues
@@ -30,20 +30,24 @@
   .
   * Regular expression search and replace.
 maintainer:     Bryan O'Sullivan <bos@serpentine.com>
-copyright:      2009-2013 Bryan O'Sullivan
+copyright:      2009-2014 Bryan O'Sullivan
 category:       Data, Text
 license:        BSD3
 license-file:   LICENSE
 build-type:     Simple
 cabal-version:  >= 1.10
 extra-source-files:
-  README.markdown include/hs_text_icu.h benchmarks/Breaker.hs
+  README.markdown
+  benchmarks/Breaker.hs
+  changelog.md
+  include/hs_text_icu.h
 
 library
   default-language:  Haskell98
   build-depends:
     base >= 4 && < 5,
     bytestring,
+    deepseq,
     text >= 0.9.1.0
 
   exposed-modules:
@@ -77,9 +81,7 @@
   else
     extra-libraries: icui18n icudata
 
-  ghc-options: -Wall
-  if impl(ghc >= 6.8)
-    ghc-options: -fwarn-tabs
+  ghc-options: -Wall -fwarn-tabs
 
 test-suite tests
   default-language: Haskell98
