diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2013, João Cristóvão
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of João Cristóvão nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/src/Control/Monad/Trans/Convert.hs b/src/Control/Monad/Trans/Convert.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Trans/Convert.hs
@@ -0,0 +1,378 @@
+{-# LANGUAGE NoMonomorphismRestriction #-}
+
+module Control.Monad.Trans.Convert
+  ( -- ** to MaybeT
+    mMaybeToMaybeT
+  , mMToMT
+  , ioMaybeToMaybeT
+  , ioMToMT
+
+  , mEitherToMaybeT
+  , mEToMT
+  , ioEitherToMaybeT
+  , ioEToMT
+
+  , mPairToMaybeT
+  , mPairToMaybeT'
+  , mPairFstToMaybeT
+  , mPairSndToMaybeT
+
+  , mMonoidToMaybeT
+  , mOToMT
+
+  , mBoolToMaybeT
+  , mBToMT
+
+  , tryIOMonoidToMaybeT
+  , tryIOMT
+
+  -- ** toEitherT
+  , mMaybeToEitherT
+  , mMToET
+  , ioMaybeToEitherT
+  , ioMToET
+
+  , mEitherToEitherT
+  , mEToET
+  , ioEitherToEitherT
+  , ioEToET
+
+  , mPairToEitherT
+  , mPairToEitherT'
+  , mPairBothToEitherT
+
+  , mMonoidToEitherT
+  , mOToET
+
+  , mBoolToEitherT
+  , mBToET
+
+  , fmapLeftT
+  , fmapRightT
+
+  , tryIOMonoidToEitherT
+  , tryIOET
+  , tryIOET'
+
+
+  ) where
+
+import Data.Easy
+import Data.Monoid
+
+import Control.Applicative
+
+{-import Control.Monad-}
+import Control.Monad.Trans.Class
+import Control.Monad.Trans.Maybe
+import Control.Monad.Trans.Either
+
+import Control.Exception
+import System.IO.Error
+
+------------------------------------------------------------------------------
+-- Maybe ---------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+-- | Lift a 'Maybe' to the 'MaybeT' monad
+-- Shamelessly copied from "Control.Error.Util"
+hoistMaybe :: (Monad m) => Maybe b -> MaybeT m b
+hoistMaybe = MaybeT . return
+
+-- | Analogous to 'Just' and equivalent to 'return'
+{-just :: (Monad m) => a -> MaybeT m a-}
+{-just a = MaybeT (return (Just a))-}
+
+-- | Analogous to 'Nothing' and equivalent to 'mzero'
+nothing :: (Monad m) => MaybeT m a
+nothing = MaybeT (return Nothing)
+
+-- | Transform a maybe value encapsulated in a @Monad m@ into the equivalent
+-- MaybeT m monad transformer.
+--
+-- /NOTE/: this is not equivalent to either @lift@ or @hoistMaybe@ alone.
+-- Check the types carefully.
+mMaybeToMaybeT :: (Monad m) => m (Maybe a) -> MaybeT m a
+mMaybeToMaybeT mF = lift mF >>= hoistMaybe
+
+-- | Shorter alias for mMaybeToMaybeT
+mMToMT :: (Monad m) => m (Maybe a) -> MaybeT m a
+mMToMT = mMaybeToMaybeT
+
+-- | Transform a IO (Maybe a) value into a MaybeT IO a value
+ioMaybeToMaybeT :: IO (Maybe a) -> MaybeT IO a
+ioMaybeToMaybeT = mMaybeToMaybeT
+
+-- | Shorter alias for ioMaybeToMaybeT
+ioMToMT :: IO (Maybe a) -> MaybeT IO a
+ioMToMT = ioMaybeToMaybeT
+
+-- | Transform a either value encapsulated in a @Monad m@ into the equivalent
+-- MaybeT m monad transformer.
+--
+-- /Note/: The left value is silently discarded.
+mEitherToMaybeT :: (Functor m) => m (Either a b) -> MaybeT m b
+{-mEitherToMaybeT eF = eitherToMaybe <$> lift eF >>= hoistMaybe-}
+mEitherToMaybeT eF = MaybeT (eitherToMaybe <$> eF)
+
+-- (!?) :: Applicative m => m (Maybe a) -> e -> EitherT e m a
+-- (!?) a e = EitherT (note e <$> a)
+
+-- hoistMaybe = MaybeT . return
+
+
+-- | Shorter alias for 'mEitherToMaybeT'.
+mEToMT :: (Functor m, Monad m) => m (Either a b) -> MaybeT m b
+mEToMT = mEitherToMaybeT
+
+-- | Transform a either value encapsulated in a IO monad into the equivalent
+-- MaybeT IO monad transformer.
+--
+-- /Note/: The left value is silently discarded.
+ioEitherToMaybeT :: IO (Either a b) -> MaybeT IO b
+ioEitherToMaybeT = mEitherToMaybeT
+
+-- | Shorter alias for 'mEitherToMaybeT'.
+ioEToMT :: IO (Either a b) -> MaybeT IO b
+ioEToMT = mEitherToMaybeT
+
+-- | Case analysis of a pair of monoid values returned by a monad into
+-- a MaybeT value.
+-- The value conversion is done by @'pairToMaybe'@.
+mPairToMaybeT :: (Eq a, Monoid a, Functor m, Monad m) => m (a,a) -> MaybeT m a
+mPairToMaybeT pF = pairToMaybe <$> lift pF >>= hoistMaybe
+
+-- | Case analysis of a pair of monoid values returned by a monad into
+-- a MaybeT value.
+-- The value conversion is done by @'pairToMaybe''@.
+mPairToMaybeT' :: (Eq a, Monoid a, Functor m, Monad m) => m (a,a) -> MaybeT m a
+mPairToMaybeT' pF = pairToMaybe' <$> lift pF >>= hoistMaybe
+
+-- | Case analysis of a pair of monoid values returned by a monad into
+-- a MaybeT value.
+-- The value conversion is done by @'pairFstToMaybe'@.
+mPairFstToMaybeT :: (Eq a, Monoid a, Functor m, Monad m) => m (a,b) -> MaybeT m a
+mPairFstToMaybeT pF = pairFstToMaybe <$> lift pF >>= hoistMaybe
+
+-- | Case analysis of a pair of monoid values returned by a monad into
+-- a MaybeT value.
+-- The value conversion is done by @'pairSndToMaybe'@.
+mPairSndToMaybeT :: (Eq b, Monoid b, Functor m, Monad m) => m (a,b) -> MaybeT m b
+mPairSndToMaybeT pF = pairSndToMaybe <$> lift pF >>= hoistMaybe
+
+-- | Transform a monoid value encapsulated in a @Monad m@ into the equivalent
+-- MaybeT m monad transformer (@'mempty'@ -> @'Nothing'@).
+mMonoidToMaybeT :: (Eq o, Monoid o, Functor m, Monad m) => m o -> MaybeT m o
+mMonoidToMaybeT oF = monoidToMaybe <$> lift oF >>= hoistMaybe
+
+-- | Shorter alias for 'mMonoidToMaybeT'
+mOToMT :: (Eq o, Monoid o, Functor m, Monad m) => m o -> MaybeT m o
+mOToMT = mMonoidToMaybeT
+
+-- | Transform a boolean value encapsulated in a @Monad m@ into the equivalent
+-- MaybeT m monad transformer (@'True'@ -> @Provided Default Value@).
+mBoolToMaybeT :: (Functor m, Monad m) => a -> m Bool -> MaybeT m a
+mBoolToMaybeT def bF = boolToMaybe def <$> lift bF >>= hoistMaybe
+
+-- | Shorter alias for @'mBoolToMaybeT'@.
+mBToMT :: (Functor m, Monad m) => a -> m Bool -> MaybeT m a
+mBToMT = mBoolToMaybeT
+
+-- This function executes an IO action that returns a monoid value, or raises
+-- a @'IOException'@. If a @'IOException'@ is raised, or the return value
+-- is an empty monoid, the function returns @'Nothing'@ in the
+-- @MaybeT IO@ monad transformer.
+--
+-- /Note/: if a different type of exception is raised (@/= IOEXCEPTION@),
+-- then that exception is re-thrown.
+tryIOMonoidToMaybeT
+  :: (Eq a, Monoid a)
+  => IO a
+  -> MaybeT IO a
+tryIOMonoidToMaybeT ioF = do
+  {-join . fmap monoidToMaybe . eitherToMaybe-}
+                        {-<$> (lift . tryIOError) ioF-}
+                        {->>= hoistMaybe-}
+  res <- lift . tryIOError $ ioF
+  case res of
+    Left _  -> nothing
+    Right a -> hoistMaybe $ monoidToMaybe a
+
+-- A shorter alias for @'tryIOMonoidToMaybeT'@.
+tryIOMT
+  :: (Eq a, Monoid a)
+  => IO a
+  -> MaybeT IO a
+tryIOMT = tryIOMonoidToMaybeT
+
+
+------------------------------------------------------------------------------
+-- Either --------------------------------------------------------------------
+------------------------------------------------------------------------------
+{-ioMaybeToEitherT :: b -> IO (Maybe a) -> EitherT b IO a-}
+{-ioMaybeToEitherT err ioF = maybeToEither err <$> liftIO ioF >>= hoistEither-}
+
+-- | Transform a maybe value encapsulated in a @Monad m@ into the equivalent
+-- EitherT b m monad transformer.
+--
+-- /NOTE/: this is not equivalent to either @lift@ or @hoistEither@ alone.
+-- Check the types carefully.
+mMaybeToEitherT :: (Monad m) => b -> m (Maybe a) -> EitherT b m a
+mMaybeToEitherT err mF = maybeToEither err <$> lift mF >>= hoistEither
+
+-- | Shorter alias for mMaybeToEitherT
+mMToET :: (Monad m) => b -> m (Maybe a) -> EitherT b m a
+mMToET = mMaybeToEitherT
+
+-- | Transform a IO (Maybe a) value into a EitherT b IO a value
+ioMaybeToEitherT :: b -> IO (Maybe a) -> EitherT b IO a
+ioMaybeToEitherT = mMaybeToEitherT
+
+-- | Shorter alias for ioMaybeToEitherT
+ioMToET :: b -> IO (Maybe a) -> EitherT b IO a
+ioMToET = ioMaybeToEitherT
+
+-- | Transform a either value encapsulated in a @Monad m@ into the equivalent
+-- EitherT e m monad transformer.
+mEitherToEitherT :: Monad m => m (Either b a) -> EitherT b m a
+mEitherToEitherT eF = lift eF >>= hoistEither
+
+-- | Shorter alias for 'mEitherToEitherT'.
+mEToET :: Monad m => m (Either b a) -> EitherT b m a
+mEToET = mEitherToEitherT
+
+-- | Transform a either value encapsulated in a IO monad into the equivalent
+-- EitherT b IO monad transformer.
+ioEitherToEitherT :: IO (Either b a) -> EitherT b IO a
+ioEitherToEitherT = mEitherToEitherT
+
+-- | Shorter alias for 'mEitherToEitherT'.
+ioEToET :: IO (Either b a) -> EitherT b IO a
+ioEToET = mEitherToEitherT
+
+-- | Case analysis of a pair of monoid values returned by a monad into
+-- a EitherT value.
+-- The value conversion is done by @'pairToEither'@.
+mPairToEitherT
+  :: (Eq a, Monoid a, Functor m, Monad m)
+  => m (b,a)
+  -> EitherT b m a
+mPairToEitherT pF = pairToEither <$> lift pF >>= hoistEither
+
+-- | Case analysis of a pair of monoid values returned by a monad into
+-- a EitherT value.
+-- The value conversion is done by @'pairToEither''@.
+mPairToEitherT'
+  :: (Eq b, Monoid b, Functor m, Monad m)
+  => m (b,a)
+  -> EitherT a m b
+mPairToEitherT' pF = pairToEither' <$> lift pF >>= hoistEither
+
+-- | Case analysis of a pair of monoid values returned by a monad into
+-- a EitherT value.
+-- The value conversion is done by @'pairBothToEither'@.
+mPairBothToEitherT
+  :: (Eq a, Monoid a, Functor m, Monad m)
+  => b
+  -> m (a,a)
+  -> EitherT b m a
+mPairBothToEitherT def pF = pairBothToEither def <$> lift pF >>= hoistEither
+
+-- | Transform a monoid value encapsulated in a @Monad m@ into the equivalent
+-- EitherT e m monad transformer (@'mempty'@ -> @'Nothing'@).
+mMonoidToEitherT :: (Eq a, Monoid a, Functor m, Monad m)
+  => b
+  -> m a
+  -> EitherT b m a
+mMonoidToEitherT def oF = monoidToEither def <$> lift oF >>= hoistEither
+
+-- | Shorter alias for 'mMonoidToEitherT'
+mOToET :: (Eq a, Monoid a, Functor m, Monad m)
+  => b
+  -> m a
+  -> EitherT b m a
+mOToET = mMonoidToEitherT
+
+-- | Transform a boolean value encapsulated in a @Monad m@ into the equivalent
+-- Either m monad transformer. Uses @'boolToEither'@.
+mBoolToEitherT
+  :: (Functor m, Monad m)
+  => b
+  -> a
+  -> m Bool
+  -> EitherT b m a
+mBoolToEitherT l r bF = boolToEither l r <$> lift bF >>= hoistEither
+
+-- | Shorter alias for @'mBoolToEitherT'@.
+mBToET
+  :: (Functor m, Monad m)
+  => b
+  -> a
+  -> m Bool
+  -> EitherT b m a
+mBToET = mBoolToEitherT
+
+-- | Change the left type using the provided conversion function.
+-- This is a specialization of @'Control.Monad.Trans.Either.bimapEitherT'@.
+--
+-- > fmapLeftT f = bimapEitherT f id
+--
+-- or using the "errors" "Data.EitherR"
+--
+-- > fmapLeftT = fmapLT
+fmapLeftT
+  :: Functor m
+  => (a -> c)
+  -> EitherT a m b
+  -> EitherT c m b
+fmapLeftT f = bimapEitherT f id
+
+-- | Change the right type using the provided conversion function.
+-- This is a specialization of @'Control.Monad.Trans.Either.bimapEitherT'@.
+--
+fmapRightT
+  :: Functor m
+  => (b -> c)
+  -> EitherT a m b
+  -> EitherT a m c
+fmapRightT = bimapEitherT id
+
+-- This function executes an IO action that returns a monoid value, or raises
+-- a @'IOException'@. If a @'IOException'@ is raised, or the return value
+-- is an empty monoid, the function returns a left value in the
+-- @EitherT IOException IO@ monad transformer. In the later case (empty monoid),
+-- the exception will be of @'userErrorType'@ type, with the default string
+-- \"empty monoid\". If you wish to specify your own message, see @'tryIOET''@.
+--
+-- /Note/: if a different type of exception is raised (@/= IOEXCEPTION@),
+-- then that exception is re-thrown.
+tryIOMonoidToEitherT
+  :: (Eq a, Monoid a)
+  => IO a
+  -> EitherT IOException IO a
+tryIOMonoidToEitherT ioF
+  =   joinEitherMonoid (userError "empty monoid") <$> (lift . tryIOError) ioF
+  >>= hoistEither
+
+-- | This function executes a IO action that returns a monoid value, or raises
+-- an @'IOException'@. If a @'IOException'@ is raised, or the returned value
+-- is an empty monoid, the function returns a left value in the
+-- @EitherT IOException IO@ monad transformer. In the later case (empty monoid),
+-- the exception will be of @'userErrorType'@ type, with the provided string
+-- text.
+tryIOET'
+  :: (Eq a, Monoid a)
+  => String
+  -> IO a
+  -> EitherT IOException IO a
+tryIOET' err ioF
+  =   joinEitherMonoid (userError err) <$> (lift . tryIOError) ioF
+  >>= hoistEither
+
+-- | This function executes a IO action that could raise an @'IOException'@.
+-- If a @'IOException'@ is raised, the function returns a left value in the
+-- @EitherT IOException IO@ monad transformer.
+tryIOET :: IO a -> EitherT IOException IO a
+tryIOET ioF = (lift . tryIOError) ioF >>= hoistEither
+
+
diff --git a/test/main.hs b/test/main.hs
new file mode 100644
--- /dev/null
+++ b/test/main.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE CPP #-}
+
+import Test.Hspec
+
+import qualified CMTCTest as CMTCT
+
+main :: IO ()
+main = hspec $ do
+  CMTCT.specs
+
diff --git a/transformers-convert.cabal b/transformers-convert.cabal
new file mode 100644
--- /dev/null
+++ b/transformers-convert.cabal
@@ -0,0 +1,57 @@
+name:                transformers-convert
+version:             0.2.0.0
+synopsis:            Sensible conversions between some of the monad transformers
+description:         Sensible conversions between MaybeT and EitherT monad transformers. 
+homepage:            https://github.com/jcristovao/transformers-convert
+license:             BSD3
+license-file:        LICENSE
+author:              João Cristóvão
+maintainer:          jmacristovao@gmail.com
+category:            Control
+build-type:          Simple
+
+-- Extra files to be distributed with the package, such as examples or a README.
+-- extra-source-files:  
+
+-- Constraint on the version of Cabal needed to build this package.
+cabal-version:       >=1.18
+
+
+library
+  exposed-modules:    Control.Monad.Trans.Convert 
+
+  -- Modules included in this library but not exported.
+  -- other-modules:       
+  
+  -- Other library packages from which modules are imported.
+  build-depends:       base           >= 4.6  && < 5
+                     , transformers   >= 0.3  && < 0.5
+                     , either         >= 4.0  && < 4.2
+                     , data-easy      >= 0.4  && < 0.5
+  
+  -- Directories containing source files.
+  hs-source-dirs:    src  
+  
+  -- Base language which the package is written in.
+  default-language:    Haskell2010
+
+  ghc-options:         -Wall
+  
+test-suite test
+  type:           exitcode-stdio-1.0
+  main-is:        main.hs
+  hs-source-dirs: test, src
+  build-depends:  base             >= 4.6     && < 5
+                , transformers     >= 0.3     && < 0.5
+                , either           >= 4.1.1   && < 4.2
+                , data-easy        >= 0.4     && < 0.5
+                , text             >= 0.11.3 
+                , errors           >= 1.4.3   && < 1.5
+                , directory        >= 1.2.0.1 && < 1.3
+                , QuickCheck       >= 2.6     
+                , HUnit            >= 1.2.5.2
+                , hspec            >= 1.7.2
+                , unix             >= 2.6
+                , haskell-src-exts >= 1.14
+                , hlint
+  default-language : Haskell2010
