diff --git a/reflex-dom-contrib.cabal b/reflex-dom-contrib.cabal
--- a/reflex-dom-contrib.cabal
+++ b/reflex-dom-contrib.cabal
@@ -1,5 +1,5 @@
 name:                reflex-dom-contrib
-version:             0.2
+version:             0.3
 synopsis:            A playground for experimenting with infrastructure and common code for reflex applications
 description:         This library is intended to be a public playground for
                      developing infrastructure, higher level APIs, and widget
@@ -32,6 +32,7 @@
     Reflex.Contrib.Utils
     Reflex.Dom.Contrib.KeyEvent
     Reflex.Dom.Contrib.Pagination
+    Reflex.Dom.Contrib.Time
     Reflex.Dom.Contrib.Utils
     Reflex.Dom.Contrib.Xhr
     Reflex.Dom.Contrib.Widgets.BoundedList
@@ -39,25 +40,29 @@
     Reflex.Dom.Contrib.Widgets.Common
     Reflex.Dom.Contrib.Widgets.DynTabs
     Reflex.Dom.Contrib.Widgets.EditInPlace
+    Reflex.Dom.Contrib.Widgets.Modal
+    Reflex.Dom.Contrib.Widgets.Svg
 
   build-depends:
-    aeson        >= 0.8  && < 0.10,
+    aeson        >= 0.8  && < 0.11,
     base         >= 4.6  && < 4.9,
     bifunctors   >= 4.0  && < 5.1,
     bytestring   >= 0.10 && < 0.11,
     containers   >= 0.5  && < 0.6,
     data-default >= 0.5  && < 0.6,
     ghcjs-dom    >= 0.1  && < 0.2,
-    http-types   >= 0.8  && < 0.9,
-    lens         >= 4.9  && < 4.13,
+    http-types   >= 0.8  && < 0.10,
+    lens         >= 4.9  && < 4.14,
     mtl          >= 2.0  && < 2.3,
+    random       >= 1.0  && < 1.2,
     readable     >= 0.3  && < 0.4,
     reflex       >= 0.2  && < 0.4,
-    reflex-dom   >= 0.1  && < 0.3,
+    reflex-dom   >= 0.2  && < 0.3,
     safe         >= 0.3  && < 0.4,
     string-conv  >= 0.1  && < 0.2,
     text         >= 1.2  && < 1.3,
-    time         >= 1.5  && < 1.6
+    time         >= 1.5  && < 1.6,
+    transformers >= 0.4  && < 0.5
 
   if impl(ghcjs)
     build-depends:
diff --git a/src/Reflex/Contrib/Interfaces.hs b/src/Reflex/Contrib/Interfaces.hs
--- a/src/Reflex/Contrib/Interfaces.hs
+++ b/src/Reflex/Contrib/Interfaces.hs
@@ -4,7 +4,6 @@
 {-# LANGUAGE MultiWayIf                #-}
 {-# LANGUAGE NoMonomorphismRestriction #-}
 {-# LANGUAGE OverloadedStrings         #-}
-{-# LANGUAGE RankNTypes                #-}
 {-# LANGUAGE RecordWildCards           #-}
 {-# LANGUAGE RecursiveDo               #-}
 {-# LANGUAGE ScopedTypeVariables       #-}
@@ -18,16 +17,15 @@
   , rlist2rmap
   , toReflexMap
   , rmDeleteFunc
-  , selectViewListWithKey
   ) where
 
 ------------------------------------------------------------------------------
+import           Control.Monad.Fix
 import           Data.Map (Map)
 import qualified Data.Map as M
 import           Data.Set (Set)
 import qualified Data.Set as S
 import           Reflex
-import           Reflex.Dom
 ------------------------------------------------------------------------------
 
 
@@ -74,7 +72,7 @@
 ------------------------------------------------------------------------------
 -- | Converts a ReflexList to a Dynamic list.
 toReflexMap
-    :: (MonadWidget t m, Eq a)
+    :: (Reflex t, MonadFix m, MonadHold t m, Eq a)
     => ReflexList t a
     -> (ReflexMap t Int a -> m (Dynamic t (Map Int a)))
     -> m (Dynamic t [a])
@@ -89,21 +87,5 @@
 -- a map.
 rmDeleteFunc :: Ord k => Set k -> Map k v -> Map k v
 rmDeleteFunc s m = foldr M.delete m (S.toList s)
-
-
-------------------------------------------------------------------------------
--- | A generalized version of the one in reflex-dom.
-selectViewListWithKey
-    :: forall t m k v a. (MonadWidget t m, Ord k)
-    => Dynamic t k
-    -> Dynamic t (Map k v)
-    -> (k -> Dynamic t v -> Dynamic t Bool -> m a)
-    -> m (Dynamic t (Map k a))
-selectViewListWithKey selection vals mkChild = do
-  let selectionDemux = demux selection
-  listWithKey vals $ \k v -> do
-    selected <- getDemuxed selectionDemux k
-    mkChild k v selected
-
 
 
diff --git a/src/Reflex/Dom/Contrib/Time.hs b/src/Reflex/Dom/Contrib/Time.hs
new file mode 100644
--- /dev/null
+++ b/src/Reflex/Dom/Contrib/Time.hs
@@ -0,0 +1,120 @@
+{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables, TypeFamilies #-}
+
+module Reflex.Dom.Contrib.Time (
+    poissonLossyFrom
+  , poissonLossy
+  , inhomogeneousPoissonFrom
+  , inhomogeneousPoisson
+  ) where
+
+import Reflex
+import Reflex.Dom.Class
+import Reflex.Dom.Time
+
+import Control.Concurrent
+import Control.Monad
+import Control.Monad.IO.Class
+import Data.Time.Clock
+import System.Random
+
+
+-- | Send events with Poisson timing with the given basis and rate
+--   Each occurence of the resulting event will contain the index of
+--   the current interval, with 0 representing the basis time
+poissonLossyFrom
+  :: (RandomGen g, MonadWidget t m)
+  => g
+  -> Double
+  -- ^ Poisson event rate (Hz)
+  -> UTCTime
+  -- ^ Baseline time for events
+  -> Event t a
+  -- ^ Event that starts a tick generation thread. Usually you want this to
+  -- be something like the result of getPostBuild that only fires once. But
+  -- there could be uses for starting multiple timer threads.
+  -- Start sending events in response to the event parameter.
+  -> m (Event t TickInfo)
+poissonLossyFrom rnd rate t0 t =
+  inhomogeneousPoissonFrom rnd (current $ constDyn rate) rate t0 t
+
+
+-- | Send events with Poisson timing with the given basis and rate
+--   Each occurence of the resulting event will contain the index of
+--   the current interval, with 0 representing the basis time.
+--   Automatically begin sending events when the DOM is built
+poissonLossy
+  :: (RandomGen g, MonadWidget t m)
+  => g
+  -> Double
+  -- ^ Poisson event rate (Hz)
+  -> UTCTime
+  -- ^ Baseline time for events
+  -> m (Event t TickInfo)
+poissonLossy rnd rate t0 = poissonLossyFrom rnd rate t0 =<< getPostBuild
+
+-- | Send events with inhomogeneous Poisson timing with the given basis
+--   and variable rate. Provide a maxRate that you expect to support.
+inhomogeneousPoissonFrom
+  :: (RandomGen g, MonadWidget t m)
+  => g
+  -> Behavior t Double
+  -> Double
+  -> UTCTime
+  -> Event t a
+  -> m (Event t TickInfo)
+inhomogeneousPoissonFrom rnd rate maxRate t0 e = do
+
+  -- Create a thread for producing homogeneous poisson events
+  -- along with random Doubles (usage of Double's explained below)
+  ticksWithRateRand <- performEventAsync $
+                       fmap callAtNextInterval e
+
+  -- Filter homogeneous events according to associated
+  -- random values and the current rate parameter
+  return $ attachWithMaybe filterFun rate ticksWithRateRand
+
+  where
+
+    -- Inhomogeneous poisson processes are built from faster
+    -- homogeneous ones by randomly dropping events from the
+    -- fast process. For each fast homogeneous event, choose
+    -- a uniform random sample from (0, rMax). If the
+    -- inhomogeneous rate at this moment is greater than the
+    -- random sample, then keep this event, otherwise drop it
+    filterFun :: Double -> (TickInfo, Double) -> Maybe TickInfo
+    filterFun r (tInfo, p)
+      | r >= p    = Just tInfo
+      | otherwise = Nothing
+
+    callAtNextInterval _ cb = void $ liftIO $ forkIO $ go t0 rnd cb 0
+
+    go tTargetLast lastGen cb lastN = do
+      t <- getCurrentTime
+
+      -- Generate random numbers for this poisson interval (u)
+      -- and sample-retention likelihood (p)
+      let (u, nextGen)            = randomR (0,1) lastGen
+          (p :: Double, nextGen') = randomR (0,maxRate) nextGen
+
+      -- Inter-event interval is drawn from exponential
+      -- distribution accourding to u
+      let dt             = realToFrac $ -1 * log(u)/maxRate :: NominalDiffTime
+          nEvents        = lastN + 1
+          alreadyElapsed = diffUTCTime t tTargetLast
+          tTarget        = addUTCTime dt tTargetLast
+          thisDelay      = realToFrac $ diffUTCTime tTarget t :: Double
+      threadDelay $ ceiling $ thisDelay * 1000000
+      void $ cb $ (TickInfo t nEvents alreadyElapsed, p)
+      go tTarget nextGen' cb nEvents
+
+-- | Send events with inhomogeneous Poisson timing with the given basis
+--   and variable rate. Provide a maxRate that you expect to support
+inhomogeneousPoisson
+  :: (RandomGen g, MonadWidget t m)
+  => g
+  -> Behavior t Double
+  -> Double
+  -> UTCTime
+  -> m (Event t TickInfo)
+inhomogeneousPoisson rnd rate maxRate t0 =
+  inhomogeneousPoissonFrom rnd rate maxRate t0 =<< getPostBuild
diff --git a/src/Reflex/Dom/Contrib/Utils.hs b/src/Reflex/Dom/Contrib/Utils.hs
--- a/src/Reflex/Dom/Contrib/Utils.hs
+++ b/src/Reflex/Dom/Contrib/Utils.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE CPP                      #-}
 {-# LANGUAGE ForeignFunctionInterface #-}
 {-# LANGUAGE JavaScriptFFI            #-}
+{-# LANGUAGE RankNTypes               #-}
 
 {-|
 
@@ -19,11 +20,13 @@
   , widgetHoldHelper
   , putDebugLn
   , putDebugLnE
+  , listWithKeyAndSelection
   ) where
 
 ------------------------------------------------------------------------------
 import           Control.Monad
 import           Control.Monad.Reader
+import           Data.Map               (Map)
 import           GHCJS.DOM.Types hiding (Event)
 #ifdef ghcjs_HOST_OS
 import           GHCJS.Foreign
@@ -138,4 +141,19 @@
 putDebugLnE :: MonadWidget t m => Event t a -> (a -> String) -> m ()
 putDebugLnE e mkStr = do
     performEvent_ (liftIO . putStrLn . mkStr <$> e)
+
+
+------------------------------------------------------------------------------
+-- | A generalized version of the one in reflex-dom.
+listWithKeyAndSelection
+    :: forall t m k v a. (MonadWidget t m, Ord k)
+    => Dynamic t k
+    -> Dynamic t (Map k v)
+    -> (k -> Dynamic t v -> Dynamic t Bool -> m a)
+    -> m (Dynamic t (Map k a))
+listWithKeyAndSelection selection vals mkChild = do
+  let selectionDemux = demux selection
+  listWithKey vals $ \k v -> do
+    selected <- getDemuxed selectionDemux k
+    mkChild k v selected
 
diff --git a/src/Reflex/Dom/Contrib/Widgets/BoundedList.hs b/src/Reflex/Dom/Contrib/Widgets/BoundedList.hs
--- a/src/Reflex/Dom/Contrib/Widgets/BoundedList.hs
+++ b/src/Reflex/Dom/Contrib/Widgets/BoundedList.hs
@@ -32,6 +32,7 @@
 ------------------------------------------------------------------------------
 import           Reflex.Contrib.Interfaces
 import           Reflex.Contrib.Utils
+import           Reflex.Dom.Contrib.Utils
 ------------------------------------------------------------------------------
 
 
@@ -118,7 +119,7 @@
       boundedInsert itemLimit <$>
       attachDynWith (\c (k,v) -> (c, (k, (k,v))))
         counter (fmapMaybe id $ updated curItem)
-    selectViewListWithKey curSelected activeItems wrapSingle
+    listWithKeyAndSelection curSelected activeItems wrapSingle
   where
     --wrapSingle :: k -> Dynamic t (BornAt, (k,v)) -> Dynamic t Bool -> m a
     wrapSingle k v b = do
diff --git a/src/Reflex/Dom/Contrib/Widgets/Common.hs b/src/Reflex/Dom/Contrib/Widgets/Common.hs
--- a/src/Reflex/Dom/Contrib/Widgets/Common.hs
+++ b/src/Reflex/Dom/Contrib/Widgets/Common.hs
@@ -24,7 +24,6 @@
 
 module Reflex.Dom.Contrib.Widgets.Common where
 
-import Debug.Trace
 ------------------------------------------------------------------------------
 import           Control.Lens
 import           Control.Monad
diff --git a/src/Reflex/Dom/Contrib/Widgets/Modal.hs b/src/Reflex/Dom/Contrib/Widgets/Modal.hs
new file mode 100644
--- /dev/null
+++ b/src/Reflex/Dom/Contrib/Widgets/Modal.hs
@@ -0,0 +1,107 @@
+{-# LANGUAGE ConstraintKinds           #-}
+{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE LambdaCase                #-}
+{-# LANGUAGE MultiWayIf                #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE OverloadedStrings         #-}
+{-# LANGUAGE RankNTypes                #-}
+{-# LANGUAGE RecordWildCards           #-}
+{-# LANGUAGE RecursiveDo               #-}
+{-# LANGUAGE ScopedTypeVariables       #-}
+{-# LANGUAGE TemplateHaskell           #-}
+{-# LANGUAGE TupleSections             #-}
+{-# LANGUAGE TypeFamilies              #-}
+
+module Reflex.Dom.Contrib.Widgets.Modal where
+
+------------------------------------------------------------------------------
+import           Data.Either
+import           Data.Map (Map)
+import           Data.Monoid
+import           Reflex
+import           Reflex.Contrib.Utils
+import           Reflex.Dom
+import           Reflex.Dom.Contrib.Utils
+------------------------------------------------------------------------------
+
+
+------------------------------------------------------------------------------
+-- | When the hiding strategy is RemoveFromDOM, the widget adds and removes
+-- the modal markup from the DOM when the modal is opened and closed.  For
+-- @DisplayNone@ and @VisibilityInvisible@ the modal markup is always kept in
+-- the DOM and visibility is controlled by setting the style to @display:none@
+-- or @visibility:invisible@ respectively.  @DisplayNone@ causes the elements
+-- to be completely taken out of the document flow.  This means that widgets
+-- in the modal will only be able to get things like height when the modal is
+-- visible.  Using @VisibilityInvisible@ gets around this limitation.
+data HidingStrategy = DisplayNone
+                    | VisibilityInvisible
+                    | RemoveFromDOM
+  deriving (Eq,Show,Ord,Enum,Bounded)
+
+
+data ModalConfig = ModalConfig
+    { modalHidingStrategy :: HidingStrategy
+    , modalAttributes     :: Map String String
+    -- ^ Attributes to put on the modal's outermost div
+    }
+
+
+------------------------------------------------------------------------------
+modal
+  :: MonadWidget t m
+  => ModalConfig
+  -> Event t Bool
+  -- ^ Event to open and/or close the model
+  -> m (Event t a, Event t ())
+  -- ^ Widget rendering the body of the modal.  Returns an event with a
+  -- success value and an event triggering the close of the modal.
+  -> m (Event t a)
+modal cfg showm body = do
+    rec let visE = leftmost [showm, False <$ closem]
+        (resE, closem) <- case modalHidingStrategy cfg of
+          RemoveFromDOM -> do
+            res <- widgetHoldHelper removeFromDOMWrapper False visE
+            a <- extractEvent fst res
+            b <- extractEvent snd res
+            return (a,b)
+          _ -> go =<< holdDyn False visE
+    return resE
+  where
+    removeFromDOMWrapper False = return (never, never)
+    removeFromDOMWrapper True = go $ constDyn True
+    go vis = do
+        attrs <- mapDyn (\b -> modalAttributes cfg <> visibility b) vis
+        elDynAttr "div" attrs body
+
+    visibility True = "style" =: "display:block;"
+    visibility False =
+      case modalHidingStrategy cfg of
+        VisibilityInvisible -> "style" =: "visibility:hidden; display:block;"
+        DisplayNone -> "style" =: "display:none;"
+        RemoveFromDOM -> mempty
+
+
+------------------------------------------------------------------------------
+-- | Template for a modal with a header, body, and footer where the header has
+-- a close icon and the footer has a cancel and save button.
+mkModalBody
+    :: MonadWidget t m
+    => m (Event t ())
+    -- ^ A header widget returning an event that closes the modal.
+    -> (Dynamic t (Either e a) -> m (Event t (), Event t ()))
+    -- ^ Footer widget that takes the current state of the body and returns
+    -- a pair of a cancel event and an ok event.
+    -> m (Dynamic t (Either e a))
+    -> m (Event t (Either e a), Event t ())
+mkModalBody header footer body = do
+    divClass "modal-dialog" $ divClass "modal-content" $ do
+      dismiss <- header
+      bodyRes <- divClass "modal-body" body
+      (cancel, ok) <- footer bodyRes
+      let resE1 = tagDyn bodyRes ok
+      let closem1 = leftmost
+            [dismiss, cancel, () <$ ffilter isRight resE1]
+      return (resE1, closem1)
+
+
diff --git a/src/Reflex/Dom/Contrib/Widgets/Svg.hs b/src/Reflex/Dom/Contrib/Widgets/Svg.hs
new file mode 100644
--- /dev/null
+++ b/src/Reflex/Dom/Contrib/Widgets/Svg.hs
@@ -0,0 +1,57 @@
+{-# LANGUAGE ConstraintKinds           #-}
+{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE MultiParamTypeClasses     #-}
+{-# LANGUAGE MultiWayIf                #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE OverloadedStrings         #-}
+{-# LANGUAGE RankNTypes                #-}
+{-# LANGUAGE RecordWildCards           #-}
+{-# LANGUAGE RecursiveDo               #-}
+{-# LANGUAGE ScopedTypeVariables       #-}
+{-# LANGUAGE TemplateHaskell           #-}
+{-# LANGUAGE TypeFamilies              #-}
+{-# LANGUAGE UndecidableInstances      #-}
+
+{-|
+
+Convenience functions for generating SVG from reflex.
+
+-}
+
+module Reflex.Dom.Contrib.Widgets.Svg where
+
+------------------------------------------------------------------------------
+import Data.Map (Map)
+import qualified Data.Map as Map
+import Reflex
+import Reflex.Dom
+------------------------------------------------------------------------------
+
+{-# INLINABLE svgDynAttr' #-}
+svgDynAttr' :: forall t m a. MonadWidget t m => String -> Dynamic t (Map String String) -> m a -> m (El t, a)
+svgDynAttr' = elDynAttrNS' (Just "http://www.w3.org/2000/svg")
+
+{-# INLINABLE svgDynAttr #-}
+svgDynAttr :: forall t m a. MonadWidget t m => String -> Dynamic t (Map String String) -> m a -> m a
+svgDynAttr elementTag attrs child = snd <$> svgDynAttr' elementTag attrs child
+
+{-# INLINABLE svgAttr' #-}
+svgAttr' :: forall t m a. MonadWidget t m => String -> Map String String -> m a -> m (El t, a)
+svgAttr' elementTag attrs child = svgDynAttr' elementTag (constDyn attrs) child
+
+{-# INLINABLE svgAttr #-}
+svgAttr :: forall t m a. MonadWidget t m => String -> Map String String -> m a -> m a
+svgAttr elementTag attrs child = svgDynAttr elementTag (constDyn attrs) child
+
+{-# INLINABLE svg' #-}
+svg' :: forall t m a. MonadWidget t m => String -> m a -> m (El t, a)
+svg' elementTag child = svgAttr' elementTag (Map.empty :: AttributeMap) child
+
+{-# INLINABLE svg #-}
+svg :: forall t m a. MonadWidget t m => String -> m a -> m a
+svg elementTag child = svgAttr elementTag Map.empty child
+
+svgClass :: forall t m a. MonadWidget t m => String -> String -> m a -> m a
+svgClass elementTag c child = svgAttr elementTag ("class" =: c) child
+
