diff --git a/Text/I18n.hs b/Text/I18n.hs
--- a/Text/I18n.hs
+++ b/Text/I18n.hs
@@ -3,14 +3,13 @@
 -- |
 -- Module      :  Text.I18n
 -- Copyright   :  (c) Eugene Grigoriev, 2008
--- License     :  BSD-style
+-- License     :  BSD3
 -- 
 -- Maintainer  :  eugene.grigoriev@gmail.com
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- Internationalization support for Haskell based on GNU gettext
---  (<http://www.gnu.org/software/gettext>).
+-- Internationalization support for Haskell.
 --  Use Text.I18n.Po module.
 --
 --  Plural forms are not yet implemented.
@@ -18,13 +17,14 @@
 -----------------------------------------------------------------------------
 module Text.I18n (
         -- * Type Declarations
-        Msgid(..), Msgstr, L10nMode(..), Locale(..), Context, I18n, L10n,
+        Msgid(..), Msgstr, Locale(..), Context, I18n, L10n,
         -- * Internationalization Monad Functions
-        gettext, localize, withContext, withLocale, localize'
+        gettext, localize, withContext, withLocale
     ) where
 
 import Control.Monad.Reader
 import Control.Monad.Trans
+import Control.Monad.Identity
 import Data.Maybe
 import Text.I18n.Printf
 import qualified Data.Map as Map
@@ -38,15 +38,10 @@
 
 newtype Locale = Locale String deriving (Show,Eq,Ord)
 
--- | Localization mode. 'L10nMust' will throw an exception if unable to
--- translate whereas 'L10nMay' will just return the original 'Msgid' String.
--- 'L10nMay' is used by 'localize'.
-data L10nMode = L10nMust | L10nMay
-
 type Context = String
 
--- | The Internationalization monad allows the use of IO through 'liftIO'.
-type I18n a = ReaderT (Locale, L10n, L10nMode, Maybe Context) IO a
+-- | The Internationalization monad built using monad transformers.
+type I18n a = ReaderT (Locale, L10n, Maybe Context) Identity a
 
 -- | The Localization structure.
 type L10n = Map.Map Locale
@@ -64,82 +59,66 @@
     The top level localization function.
 
     > import Text.I18n.Po
-    > import qualified System.IO.UTF8 as Utf8
+    > import Prelude hiding (putStr,putStrLn)
     >
     > main = do
-    >   (l10n,errors) <- getL10n "dir/to/po"
-    >   localize l10n (Locale "en") impl
+    >     (l10n,errors) <- getL10n "dir/to/po" -- directory containing PO files
+    >     putStrLn $ localize l10n (Locale "en") (example "Joe")
 -}
 localize :: L10n    -- ^ Structure containing localization data
          -> Locale  -- ^ Locale to use
-         -> I18n a  -- ^ Inernationalized action
-         -> IO a    -- ^ Localized action
-localize = flip localize' L10nMay
-
-{-|
-    The top level localization function with a mode parameter.
-
-    > main2 = localize' (Text.I18n.Po.getL10n "dir/to/po")
-    >                   L10nMust
-    >                   (Locale "en")
-    >                   impl
--}
-localize' :: L10n     -- ^ Structure containing localization data
-          -> L10nMode -- ^ Localization mode
-          -> Locale   -- ^ Locale to use
-          -> I18n a   -- ^ Inernationalized action
-          -> IO a     -- ^ Localized action
-localize' l10n mode loc action = runReaderT action (loc,l10n,mode,Nothing)
+         -> I18n a  -- ^ Inernationalized expression
+         -> a       -- ^ Localized expression
+localize l10n loc expression = runIdentity $ runReaderT expression (loc,l10n,Nothing)
 
 {-|
     The heart of I18n monad. Based on 'Text.Printf.printf'.
 
-    > impl = do
-    >       hello <- gettext "Hello, %s!"
-    >       liftIO (Utf8.putStrLn (hello "Joe"))
+    > example :: String -> I18n String
+    > example name = do
+    >     hello <- gettext "Hello, %s!"
+    >     return (hello name)
 -}
 gettext :: PrintfType a => String -> I18n a
 gettext msgid = do
-    (loc, l10n, mode, ctxt) <- ask
+    (loc, l10n, ctxt) <- ask
     case localizeMsgid l10n loc ctxt (Msgid msgid) of
         Just msgstr -> return (printf msgstr)
         Nothing     -> case ctxt of
                             Just _  -> withContext Nothing (gettext msgid)
-                            Nothing -> case mode of
-                                L10nMay  -> return (printf msgid)
-                                L10nMust -> fail
-                                    ("Undefined localization: " ++
-                                     show ((Msgid msgid),loc) )
+                            Nothing -> return (printf msgid)
 
 {-|
-    Sets a local 'Context' for an internationalized action.
+    Sets a local 'Context' for an internationalized expression.
     If there is no translation, then no context version is tried.
 
-    > impl2 = withContext (Just "test") impl
+    > example2 :: String -> I18n String
+    > example2 = withContext (Just "test") . example
 -}
 withContext :: Maybe Context -- ^ Context to use
-            -> I18n a        -- ^ Internationalized action
-            -> I18n a        -- ^ New internationalized action
-withContext ctxt action = do
-    (lang, l10n, mode, _) <- ask
-    local (const (lang, l10n, mode, ctxt))
-          action
+            -> I18n a        -- ^ Internationalized expression
+            -> I18n a        -- ^ New internationalized expression
+withContext ctxt expression = do
+    (lang, l10n, _) <- ask
+    local (const (lang, l10n, ctxt))
+          expression
 
 {-|
-    Sets a local 'Locale' for an internationalized action.
+    Sets a local 'Locale' for an internationalized expression.
 
-    > impl3 = withLocale (Locale "ru") impl2
+    > example3 :: String -> I18n String
+    > example3 = withLocale (Locale "ru") . example2
 -}
 withLocale :: Locale    -- ^ Locale to use
-           -> I18n a    -- ^ Internationalized action
-           -> I18n a    -- ^ New internationalized action.
-    -- Note: while this action is localy localized already, it is to be a part
-    -- of another internationalized action.
+           -> I18n a    -- ^ Internationalized expression
+           -> I18n a    -- ^ New internationalized expression.
+    -- Note: while this expression is localy localized already, it is to be a
+    -- part of another internationalized expression.
     -- Therefore the final type is internationalized.
-withLocale loc action = do
-    (_, l10n, mode, ctxt) <- ask
-    local (const (loc, l10n, mode, ctxt))
-          action
+withLocale loc expression = do
+    (_, l10n, ctxt) <- ask
+    local (const (loc, l10n, ctxt))
+          expression
 
 localizeMsgid :: L10n -> Locale -> Maybe Context -> Msgid -> Maybe String
 localizeMsgid l10n loc ctxt msgid = do
diff --git a/Text/I18n/Po.hs b/Text/I18n/Po.hs
--- a/Text/I18n/Po.hs
+++ b/Text/I18n/Po.hs
@@ -2,30 +2,32 @@
 -- |
 -- Module      :  Text.I18n.Po
 -- Copyright   :  (c) Eugene Grigoriev, 2008
--- License     :  BSD-style
+-- License     :  BSD3
 -- 
 -- Maintainer  :  eugene.grigoriev@gmail.com
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- Internationalization support for Haskell based on GNU gettext
---  (<http://www.gnu.org/software/gettext>). This module contains
+-- Internationalization support for Haskell. This module contains
 --  PO parser. PO files are assumed to be in UTF-8 encoding.
 --
 --  Plural forms are not yet implemented.
 --
---  Text.I18n and Control.Monad.Trans are exported for convenience.
+--  modules Text.I18n, Control.Monad.Trans, and function putStrLn and putStr
+--  from System.IO.UTF8 are exported for convenience.
 --
---  Use System.IO.UTF8 whenever you need to output a localized string.
+-- > import Prelude hiding (putStr,putStrLn)
 --
 -----------------------------------------------------------------------------
 module Text.I18n.Po (
         -- * Type Declarations
-        Msgid(..), Msgstr, L10nMode(..), Locale(..), Context, I18n, L10n,
+        Msgid(..), Msgstr, Locale(..), Context, I18n, L10n,
         -- * PO parsing
         getL10n,
         -- * I18n Monad Functions
-        localize, gettext, withContext, withLocale, localize',
+        localize, gettext, withContext, withLocale,
+        -- * UTF-8 Output Functions
+        Utf8.putStrLn, Utf8.putStr,
         module Control.Monad.Trans
     ) where
 
@@ -40,7 +42,7 @@
 import Control.Arrow
 import System.Directory
 import System.FilePath
-import System.IO.UTF8 as Utf8
+import qualified System.IO.UTF8 as Utf8
 
 -------------------------------------------------------------------------------
 -- Type declarations
diff --git a/i18n.cabal b/i18n.cabal
--- a/i18n.cabal
+++ b/i18n.cabal
@@ -1,6 +1,7 @@
 Name:                i18n
-Version:             0.2
+Version:             0.3
 Cabal-Version:       >= 1.2
+build-type:          Simple
 Synopsis:            Internationalization for Haskell
 Category:            Text
 License:             BSD3
