       hyperclientDestroy hc
       sequence_ $ Map.elems handles 
       putMVar c (Nothing, Map.empty)
+
+doExponentialBackoff :: Int -> Double -> (Int, BackoffMethod)
+doExponentialBackoff b x = 
+  let result = ceiling (fromIntegral b ** x) in
+    (result, BackoffExponential result x)
+
+cappedBackoff :: Int -> Maybe Int -> (Int, Bool)
+cappedBackoff n Nothing = (n, False)
+cappedBackoff n (Just c) | n  < c  = (n, False)
+                         | n >= c  = (c, True)
+
+performBackoff :: BackoffMethod -> Maybe Int -> IO (BackoffMethod)
+performBackoff method cap = do
+  let (delay, newBackoff) = case method of
+            BackoffYield      -> (0, method)
+            BackoffConstant n -> (0, method)
+            BackoffLinear m b -> (m, BackoffLinear (m+b) b)
+            BackoffExponential b x -> doExponentialBackoff b x
+      (backoff, capped) = cappedBackoff delay cap
+  let delay = case backoff of
+                0 -> yield
+                n -> threadDelay n
+      next  = case capped of
+                True  -> BackoffConstant backoff
+                False -> newBackoff
+  delay >> return next
 
 -- | Runs hyperclient_loop exactly once, setting the appropriate MVar.
 loopClient' :: Bool -> Client -> IO (Maybe Handle)

import Data.Map (Map)
import qualified Data.Map as Map

import Control.Concurrent.MVar

import Data.Word (Word16)

        (Just _, handles)  -> do
          case Map.member h handles of
            False -> return True
            True  -> do
              back' <- performBackoff back (backoffCap . getConnectOptions $ client)
              loopClientUntil client back' h (Just $ n - 1) v
    False -> return True

loopClientUntil client back h (Nothing) v = do
  empty <- isEmptyMVar v
  case empty of
    True -> do
