diff --git a/Language/KURE/BiTransform.hs b/Language/KURE/BiTransform.hs
--- a/Language/KURE/BiTransform.hs
+++ b/Language/KURE/BiTransform.hs
@@ -21,6 +21,15 @@
         , invertBiT
         , beforeBiR
         , afterBiR
+          -- * Bi-directional Injections
+        , extractBiT
+        , promoteBiT
+        , extractBiR
+        , promoteBiR
+        , extractWithFailMsgBiT
+        , promoteWithFailMsgBiT
+        , extractWithFailMsgBiR
+        , promoteWithFailMsgBiR
 ) where
 
 import Prelude hiding (id, (.))
@@ -29,6 +38,7 @@
 
 import Language.KURE.MonadCatch
 import Language.KURE.Transform
+import Language.KURE.Injection
 
 ------------------------------------------------------------------------------------------
 
@@ -79,5 +89,55 @@
 afterBiR :: Monad m => BiRewrite c m a -> Rewrite c m a -> BiRewrite c m a
 afterBiR b rr = bidirectional (forwardT b >>> rr) (backwardT b >>> rr)
 {-# INLINE afterBiR #-}
+
+------------------------------------------------------------------------------------------
+
+-- | As 'extractBiT', but takes a custom error message to use if extraction fails.
+extractWithFailMsgBiT :: (Monad m, Injection a u, Injection b u) => String -> BiTransform c m u u -> BiTransform c m a b
+extractWithFailMsgBiT msg (BiTransform t1 t2) = BiTransform (extractT t1 >>> projectWithFailMsgT msg)
+                                                            (extractT t2 >>> projectWithFailMsgT msg)
+{-# INLINE extractWithFailMsgBiT #-}
+
+-- | Convert a bidirectional transformation over an injected value into a bidirectional transformation over non-injected values,
+--   (failing if an injected value cannot be projected).
+extractBiT :: (Monad m, Injection a u, Injection b u) => BiTransform c m u u -> BiTransform c m a b
+extractBiT = extractWithFailMsgBiT "extractBiT failed"
+{-# INLINE extractBiT #-}
+
+-- | As 'promoteBiT', but takes a custom error message to use if promotion fails.
+promoteWithFailMsgBiT  :: (Monad m, Injection a u, Injection b u) => String -> BiTransform c m a b -> BiTransform c m u u
+promoteWithFailMsgBiT msg (BiTransform t1 t2) = BiTransform (projectWithFailMsgT msg >>> t1 >>> injectT)
+                                                            (projectWithFailMsgT msg >>> t2 >>> injectT)
+{-# INLINE promoteWithFailMsgBiT #-}
+
+-- | Promote a bidirectional transformation from value to value into a transformation over an injection of those values,
+--   (failing if an injected value cannot be projected).
+promoteBiT  :: (Monad m, Injection a u, Injection b u) => BiTransform c m a b -> BiTransform c m u u
+promoteBiT = promoteWithFailMsgBiT "promoteBiT failed"
+{-# INLINE promoteBiT #-}
+
+-- | As 'extractBiR', but takes a custom error message to use if extraction fails.
+extractWithFailMsgBiR :: (Monad m, Injection a u) => String -> BiRewrite c m u -> BiRewrite c m a
+extractWithFailMsgBiR msg (BiTransform r1 r2) = BiTransform (extractWithFailMsgR msg r1)
+                                                            (extractWithFailMsgR msg r2)
+{-# INLINE extractWithFailMsgBiR #-}
+
+-- | Convert a bidirectional rewrite over an injected value into a bidirectional rewrite over a projection of that value,
+--   (failing if an injected value cannot be projected).
+extractBiR :: (Monad m, Injection a u) => BiRewrite c m u -> BiRewrite c m a
+extractBiR = extractWithFailMsgBiR "extractBiR failed"
+{-# INLINE extractBiR #-}
+
+-- | As 'promoteBiR', but takes a custom error message to use if promotion fails.
+promoteWithFailMsgBiR :: (Monad m, Injection a u) => String -> BiRewrite c m a -> BiRewrite c m u
+promoteWithFailMsgBiR msg (BiTransform r1 r2) = BiTransform (promoteWithFailMsgR msg r1)
+                                                            (promoteWithFailMsgR msg r2)
+{-# INLINE promoteWithFailMsgBiR #-}
+
+-- | Promote a bidirectional rewrite over a value into a bidirectional rewrite over an injection of that value,
+--   (failing if an injected value cannot be projected).
+promoteBiR :: (Monad m, Injection a u) => BiRewrite c m a -> BiRewrite c m u
+promoteBiR = promoteWithFailMsgBiR "promoteBiR failed"
+{-# INLINE promoteBiR #-}
 
 ------------------------------------------------------------------------------------------
diff --git a/Language/KURE/Injection.hs b/Language/KURE/Injection.hs
--- a/Language/KURE/Injection.hs
+++ b/Language/KURE/Injection.hs
@@ -23,6 +23,7 @@
        , projectT
        , extractT
        , promoteT
+       , projectWithFailMsgT
        , promoteWithFailMsgT
        -- * Rewrite Injections
        , extractR
@@ -42,9 +43,9 @@
 --
 -- > project (inject a) == Just a
 
-class Injection a b where
-  inject  :: a -> b
-  project :: b -> Maybe a
+class Injection a u where
+  inject  :: a -> u
+  project :: u -> Maybe a
 
 -- | There is an identity injection for all types.
 instance Injection a a where
@@ -68,71 +69,71 @@
 -------------------------------------------------------------------------------
 
 -- | Injects a value and lifts it into a 'Monad'.
-injectM :: (Monad m, Injection a g) => a -> m g
+injectM :: (Monad m, Injection a u) => a -> m u
 injectM = return . inject
 {-# INLINE injectM #-}
 
 -- | As 'projectM', but takes a custom error message to use if projection fails.
-projectWithFailMsgM :: (Monad m, Injection a g) => String -> g -> m a
+projectWithFailMsgM :: (Monad m, Injection a u) => String -> u -> m a
 projectWithFailMsgM msg = maybe (fail msg) return . project
 {-# INLINE projectWithFailMsgM #-}
 
 -- | Projects a value and lifts it into a 'Monad', with the possibility of failure.
-projectM :: (Monad m, Injection a g) => g -> m a
+projectM :: (Monad m, Injection a u) => u -> m a
 projectM = projectWithFailMsgM "projectM failed"
 {-# INLINE projectM #-}
 
 -------------------------------------------------------------------------------
 
 -- | Lifted 'inject'.
-injectT :: (Monad m, Injection a g) => Transform c m a g
+injectT :: (Monad m, Injection a u) => Transform c m a u
 injectT = arr inject
 {-# INLINE injectT #-}
 
-projectWithFailMsgT :: (Monad m, Injection a g) => String -> Transform c m g a
+projectWithFailMsgT :: (Monad m, Injection a u) => String -> Transform c m u a
 projectWithFailMsgT = contextfreeT . projectWithFailMsgM
 {-# INLINE projectWithFailMsgT #-}
 
 -- | Lifted 'project', the transformation fails if the projection fails.
-projectT :: (Monad m, Injection a g) => Transform c m g a
+projectT :: (Monad m, Injection a u) => Transform c m u a
 projectT = projectWithFailMsgT "projectT failed"
 {-# INLINE projectT #-}
 
 -- | Convert a transformation over an injected value into a transformation over a non-injected value.
-extractT :: (Monad m, Injection a g) => Transform c m g b -> Transform c m a b
+extractT :: (Monad m, Injection a u) => Transform c m u b -> Transform c m a b
 extractT t = injectT >>> t
 {-# INLINE extractT #-}
 
 -- | As 'promoteT', but takes a custom error message to use if promotion fails.
-promoteWithFailMsgT  :: (Monad m, Injection a g) => String -> Transform c m a b -> Transform c m g b
+promoteWithFailMsgT  :: (Monad m, Injection a u) => String -> Transform c m a b -> Transform c m u b
 promoteWithFailMsgT msg t = projectWithFailMsgT msg >>> t
 {-# INLINE promoteWithFailMsgT #-}
 
 -- | Promote a transformation over a value into a transformation over an injection of that value,
 --   (failing if that injected value cannot be projected).
-promoteT  :: (Monad m, Injection a g) => Transform c m a b -> Transform c m g b
+promoteT  :: (Monad m, Injection a u) => Transform c m a b -> Transform c m u b
 promoteT = promoteWithFailMsgT "promoteT failed"
 {-# INLINE promoteT #-}
 
 -- | As 'extractR', but takes a custom error message to use if extraction fails.
-extractWithFailMsgR :: (Monad m, Injection a g) => String -> Rewrite c m g -> Rewrite c m a
+extractWithFailMsgR :: (Monad m, Injection a u) => String -> Rewrite c m u -> Rewrite c m a
 extractWithFailMsgR msg r = injectT >>> r >>> projectWithFailMsgT msg
 {-# INLINE extractWithFailMsgR #-}
 
 -- | Convert a rewrite over an injected value into a rewrite over a projection of that value,
 --   (failing if that injected value cannot be projected).
-extractR :: (Monad m, Injection a g) => Rewrite c m g -> Rewrite c m a
+extractR :: (Monad m, Injection a u) => Rewrite c m u -> Rewrite c m a
 extractR = extractWithFailMsgR "extractR failed"
 {-# INLINE extractR #-}
 
 -- | As 'promoteR', but takes a custom error message to use if promotion fails.
-promoteWithFailMsgR :: (Monad m, Injection a g) => String -> Rewrite c m a -> Rewrite c m g
+promoteWithFailMsgR :: (Monad m, Injection a u) => String -> Rewrite c m a -> Rewrite c m u
 promoteWithFailMsgR msg r = projectWithFailMsgT msg >>> r >>> injectT
 {-# INLINE promoteWithFailMsgR #-}
 
 -- | Promote a rewrite over a value into a rewrite over an injection of that value,
 --   (failing if that injected value cannot be projected).
-promoteR  :: (Monad m, Injection a g) => Rewrite c m a -> Rewrite c m g
+promoteR  :: (Monad m, Injection a u) => Rewrite c m a -> Rewrite c m u
 promoteR = promoteWithFailMsgR "promoteR failed"
 {-# INLINE promoteR #-}
 
diff --git a/kure.cabal b/kure.cabal
--- a/kure.cabal
+++ b/kure.cabal
@@ -1,5 +1,5 @@
 Name:                kure
-Version:             2.16.6
+Version:             2.16.8
 Synopsis:            Combinators for Strategic Programming
 Description:	     The Kansas University Rewrite Engine (KURE) is a domain-specific language for strategic rewriting.
 	 	     KURE was inspired by Stratego and StrategyLib, and has similarities with Scrap Your Boilerplate and Uniplate.
