diff --git a/System/USB/Safe.hs b/System/USB/Safe.hs
--- a/System/USB/Safe.hs
+++ b/System/USB/Safe.hs
@@ -73,7 +73,7 @@
       * Run regions using 'runRegionT'.
 
       * Concurrently run /top-level/ regions inside another region using
-        'forkTopRegion'.
+        'forkIOTopRegion'.
 
        * Duplicate a 'RegionalDeviceHandle' to a parent region using 'dup'.
       -}
@@ -126,22 +126,29 @@
 
       -- * Endpoints
     , Endpoint
-    , getEndpoints
-    , clearHalt
+    , getEndpoints, getEndpoints'
 
       -- *** Transfer directions
     , TransferDirection(..)
+
     , Out
     , In
 
+    , MkTransferDirection(..)
+
       -- *** Transfer types
     , TransferType(..)
+
     , Control
     , Isochronous
     , Bulk
     , Interrupt
 
+    , MkTransferType(..)
+
       -- * Endpoint I/O
+    , clearHalt
+
     , ReadAction
     , WriteAction
 
@@ -206,14 +213,20 @@
 -- from MonadCatchIO-transformers:
 import Control.Monad.CatchIO      ( MonadCatchIO, bracket_, throw, block )
 
--- from iteratee:
-import Data.Iteratee.Base             ( EnumeratorGM )
-import Data.Iteratee.Base.StreamChunk ( ReadableChunk )
-
 -- from regions:
 import Control.Monad.Trans.Region.OnExit ( CloseHandle, onExit )
 import Control.Monad.Trans.Region     -- (re-exported entirely)
 
+-- from iteratee:
+#if MIN_VERSION_iteratee(0,4,0)
+import Data.Iteratee.Iteratee           ( Enumerator )
+import Data.Iteratee.Base.ReadableChunk ( ReadableChunk )
+import Data.NullPoint                   ( NullPoint )
+#else
+import Data.Iteratee.Base               ( EnumeratorGM )
+import Data.Iteratee.Base.StreamChunk   ( ReadableChunk )
+#endif
+
 -- from usb:
 import qualified System.USB.Initialization as USB
     ( Ctx )
@@ -981,31 +994,22 @@
          transDirUSB  = USB.transferDirection $ USB.endpointAddress endpointDesc
          transTypeUSB = USB.endpointAttribs endpointDesc
 
-instance GetDescriptor (Endpoint transDir transType sAlt r)
-                       USB.EndpointDesc where
+-- | Similar to 'getEndpoints' but will retrieve the endpoints based on the
+-- inferred type of transfer direction and transfer type.
+--
+-- Note that:
+-- @getEndpoints' altHndl = 'getEndpoints' altHndl 'mkTransferDirection' 'mkTransferType'@.
+getEndpoints' ∷ ∀ transDir transType sAlt r
+              . MkTransferDirection transDir
+              ⇒ MkTransferType transType
+              ⇒ AlternateHandle sAlt r
+              → [Endpoint transDir transType sAlt r]
+getEndpoints' altHndl = getEndpoints altHndl mkTransferDirection mkTransferType
+
+instance GetDescriptor (Endpoint transDir transType sAlt r) USB.EndpointDesc where
     getDesc (Endpoint _ endpointDesc) = endpointDesc
 
-{-| Clear the halt/stall condition for an endpoint.
 
-Endpoints with halt status are unable to receive or transmit data until the halt
-condition is stalled.
-
-You should cancel all pending transfers before attempting to clear the halt
-condition.
-
-This is a blocking function.
-
-Exceptions:
-
- * 'USB.NoDeviceException' if the device has been disconnected.
-
- * Another 'USB.USBException'.
--}
-clearHalt ∷ (pr `ParentOf` cr, MonadIO cr)
-          ⇒ Endpoint transDir transType sAlt pr → cr ()
-clearHalt (Endpoint internalDevHndl endpointDesc) =
-    liftIO $ USB.clearHalt internalDevHndl $ USB.endpointAddress endpointDesc
-
 --------------------------------------------------------------------------------
 -- *** Transfer directions
 --------------------------------------------------------------------------------
@@ -1020,6 +1024,13 @@
 -- | In transfer direction (device -> host) used for reading.
 data In
 
+class MkTransferDirection transDir where
+    -- | An overloaded constructor function for transfer directions.
+    mkTransferDirection ∷ TransferDirection transDir
+
+instance MkTransferDirection Out where mkTransferDirection = Out
+instance MkTransferDirection In  where mkTransferDirection = In
+
 --------------------------------------------------------------------------------
 -- *** Transfer types
 --------------------------------------------------------------------------------
@@ -1035,11 +1046,44 @@
 data Bulk
 data Interrupt
 
+class MkTransferType transType where
+    -- | An overloaded constructor function for transfer types.
+    mkTransferType ∷ TransferType transType
 
+instance MkTransferType Control     where mkTransferType = Control
+instance MkTransferType Isochronous where mkTransferType = Isochronous
+instance MkTransferType Bulk        where mkTransferType = Bulk
+instance MkTransferType Interrupt   where mkTransferType = Interrupt
+
+
 --------------------------------------------------------------------------------
 -- * Endpoint I/O
 --------------------------------------------------------------------------------
 
+{-| Clear the halt/stall condition for an endpoint.
+
+Endpoints with halt status are unable to receive or transmit data until the halt
+condition is stalled.
+
+You should cancel all pending transfers before attempting to clear the halt
+condition.
+
+This is a blocking function.
+
+Exceptions:
+
+ * 'USB.NoDeviceException' if the device has been disconnected.
+
+ * Another 'USB.USBException'.
+-}
+clearHalt ∷ (pr `ParentOf` cr, MonadIO cr)
+          ⇒ Endpoint transDir transType sAlt pr → cr ()
+clearHalt (Endpoint internalDevHndl endpointDesc) =
+    liftIO $ USB.clearHalt internalDevHndl $ USB.endpointAddress endpointDesc
+
+
+--------------------------------------------------------------------------------
+
 {-| Handy type synonym for read transfers.
 
 A @ReadAction@ is a function which takes a size which defines how many bytes to
@@ -1070,11 +1114,8 @@
                  ⇒ Endpoint In transType sAlt pr
                  → ReadAction cr
 
-instance ReadEndpoint Bulk where
-    readEndpoint = transferWith USB.readBulk
-
-instance ReadEndpoint Interrupt where
-    readEndpoint = transferWith USB.readInterrupt
+instance ReadEndpoint Bulk      where readEndpoint = transferWith USB.readBulk
+instance ReadEndpoint Interrupt where readEndpoint = transferWith USB.readInterrupt
 
 transferWith ∷ (pr `ParentOf` cr, MonadIO cr)
              ⇒ (USB.DeviceHandle → USB.EndpointAddress → α → USB.Timeout → IO β)
@@ -1114,11 +1155,8 @@
                   ⇒ Endpoint Out transType sAlt pr
                   → WriteAction cr
 
-instance WriteEndpoint Bulk where
-    writeEndpoint = transferWith USB.writeBulk
-
-instance WriteEndpoint Interrupt where
-    writeEndpoint = transferWith USB.writeInterrupt
+instance WriteEndpoint Bulk      where writeEndpoint = transferWith USB.writeBulk
+instance WriteEndpoint Interrupt where writeEndpoint = transferWith USB.writeInterrupt
 
 
 --------------------------------------------------------------------------------
@@ -1127,7 +1165,11 @@
 class EnumReadEndpoint transType where
     -- | An enumerator for an 'In' endpoint with either a 'Bulk' or 'Interrupt'
     -- transfer type.
-    enumReadEndpoint ∷ (pr `ParentOf` cr, MonadCatchIO cr, ReadableChunk s Word8)
+    enumReadEndpoint ∷ ( pr `ParentOf` cr, MonadCatchIO cr, ReadableChunk s Word8
+#if MIN_VERSION_iteratee(0,4,0)
+                       , NullPoint s
+#endif
+                       )
                      ⇒ Endpoint In transType sAlt pr
                      → USB.Size    -- ^ Chunk size. A good value for this would be
                                    --   the @'maxPacketSize' . 'endpointMaxPacketSize'@.
@@ -1135,13 +1177,13 @@
                                    --   should wait for each chunk before giving up
                                    --   due to no response being received.  For no
                                    --   timeout, use value 0.
+#if MIN_VERSION_iteratee(0,4,0)
+                     → Enumerator s cr α
+#else
                      → EnumeratorGM s Word8 cr α
-
-instance EnumReadEndpoint Bulk where
-    enumReadEndpoint = wrap USB.enumReadBulk
-
-instance EnumReadEndpoint Interrupt where
-    enumReadEndpoint = wrap USB.enumReadInterrupt
+#endif
+instance EnumReadEndpoint Bulk      where enumReadEndpoint = wrap USB.enumReadBulk
+instance EnumReadEndpoint Interrupt where enumReadEndpoint = wrap USB.enumReadInterrupt
 
 
 --------------------------------------------------------------------------------
diff --git a/usb-safe.cabal b/usb-safe.cabal
--- a/usb-safe.cabal
+++ b/usb-safe.cabal
@@ -1,5 +1,5 @@
 name:          usb-safe
-version:       0.8
+version:       0.9
 cabal-version: >=1.6
 build-type:    Custom
 license:       BSD3
@@ -73,9 +73,9 @@
                , base-unicode-symbols      >= 0.1.1 && < 0.3
                , usb                       >= 0.5   && < 0.6
                , usb-enumerator            >= 0.1   && < 0.2
-               , iteratee                  >= 0.3.5 && < 0.4
+               , iteratee                  >= 0.3.5 && < 0.5
                , bytestring                >= 0.9   && < 0.10
-               , regions                   >= 0.6   && < 0.7
+               , regions                   >= 0.6   && < 0.8
                , transformers              >= 0.2   && < 0.3
                , MonadCatchIO-transformers >= 0.2   && < 0.3
   exposed-modules: System.USB.Safe
