diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Revision history for ghc-debug-brick
 
+## 0.2.1.0 -- 2022-05-06
+
+* Add function to find closures by exact name (F8)
+
 ## 0.2.0.0 -- 2021-12-06
 
 * Second release
diff --git a/ghc-debug-brick.cabal b/ghc-debug-brick.cabal
--- a/ghc-debug-brick.cabal
+++ b/ghc-debug-brick.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.4
 name:                ghc-debug-brick
-version:             0.2.0.0
+version:             0.2.1.0
 synopsis: A simple TUI using ghc-debug
 description: A simple TUI using ghc-debug
 -- bug-reports:
@@ -21,10 +21,12 @@
                      , TextCursor
                      , Common
                      , Lib
+                     , Cursor.Types
+                     , Cursor.Text
+                     , Cursor.List
   -- other-extensions:
-  build-depends:       base >=4.10 && <5
+  build-depends:       base >=4.16 && <5
                      , brick
-                     , cursor
                      , containers
                      , directory
                      , filepath
@@ -32,9 +34,10 @@
                      , text
                      , vty
                      , time
+                     , deepseq
                      , microlens
-                     , ghc-debug-client == 0.2.0.0
-                     , ghc-debug-common == 0.2.0.0
+                     , ghc-debug-client == 0.2.1.0
+                     , ghc-debug-common == 0.2.1.0
                      , ghc-debug-convention == 0.2.0.0
                      , unordered-containers
                      , exceptions
diff --git a/src/Cursor/List.hs b/src/Cursor/List.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/List.hs
@@ -0,0 +1,185 @@
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE TypeFamilies #-}
+{- Authored by Tom Sydney Kerckhove, copied from cursor package #-}
+
+module Cursor.List
+  ( ListCursor (..),
+    emptyListCursor,
+    makeListCursor,
+    makeListCursorWithSelection,
+    rebuildListCursor,
+    listCursorNull,
+    listCursorLength,
+    listCursorIndex,
+    listCursorSelectPrev,
+    listCursorSelectNext,
+    listCursorSelectIndex,
+    listCursorSelectStart,
+    listCursorSelectEnd,
+    listCursorPrevItem,
+    listCursorNextItem,
+    listCursorPrevUntil,
+    listCursorNextUntil,
+    listCursorInsert,
+    listCursorAppend,
+    listCursorInsertList,
+    listCursorAppendList,
+    listCursorRemove,
+    listCursorDelete,
+    listCursorSplit,
+    listCursorCombine,
+    traverseListCursor,
+    foldListCursor,
+  )
+where
+
+import Control.DeepSeq
+import Cursor.Types
+import GHC.Generics (Generic)
+
+data ListCursor a = ListCursor
+  { -- | In reverse order
+    listCursorPrev :: [a],
+    listCursorNext :: [a]
+  }
+  deriving (Show, Eq, Generic, Functor)
+
+instance NFData a => NFData (ListCursor a)
+
+emptyListCursor :: ListCursor a
+emptyListCursor = ListCursor {listCursorPrev = [], listCursorNext = []}
+
+makeListCursor :: [a] -> ListCursor a
+makeListCursor as = ListCursor {listCursorPrev = [], listCursorNext = as}
+
+makeListCursorWithSelection :: Int -> [a] -> Maybe (ListCursor a)
+makeListCursorWithSelection i as
+  | i < 0 = Nothing
+  | i > length as = Nothing
+  | otherwise = Just ListCursor {listCursorPrev = reverse $ take i as, listCursorNext = drop i as}
+
+rebuildListCursor :: ListCursor a -> [a]
+rebuildListCursor ListCursor {..} = reverse listCursorPrev ++ listCursorNext
+
+listCursorNull :: ListCursor a -> Bool
+listCursorNull ListCursor {..} = null listCursorPrev && null listCursorNext
+
+listCursorLength :: ListCursor a -> Int
+listCursorLength = length . rebuildListCursor
+
+listCursorIndex :: ListCursor a -> Int
+listCursorIndex = length . listCursorPrev
+
+listCursorSelectPrev :: ListCursor a -> Maybe (ListCursor a)
+listCursorSelectPrev tc =
+  case listCursorPrev tc of
+    [] -> Nothing
+    (c : cs) -> Just ListCursor {listCursorPrev = cs, listCursorNext = c : listCursorNext tc}
+
+listCursorSelectNext :: ListCursor a -> Maybe (ListCursor a)
+listCursorSelectNext tc =
+  case listCursorNext tc of
+    [] -> Nothing
+    (c : cs) -> Just ListCursor {listCursorPrev = c : listCursorPrev tc, listCursorNext = cs}
+
+listCursorSelectIndex :: Int -> ListCursor a -> ListCursor a
+listCursorSelectIndex ix_ lc =
+  let ls = rebuildListCursor lc
+   in case splitAt ix_ ls of
+        (l, r) -> ListCursor {listCursorPrev = reverse l, listCursorNext = r}
+
+listCursorSelectStart :: ListCursor a -> ListCursor a
+listCursorSelectStart tc =
+  case listCursorSelectPrev tc of
+    Nothing -> tc
+    Just tc' -> listCursorSelectStart tc'
+
+listCursorSelectEnd :: ListCursor a -> ListCursor a
+listCursorSelectEnd tc =
+  case listCursorSelectNext tc of
+    Nothing -> tc
+    Just tc' -> listCursorSelectEnd tc'
+
+listCursorPrevItem :: ListCursor a -> Maybe a
+listCursorPrevItem lc =
+  case listCursorPrev lc of
+    [] -> Nothing
+    (c : _) -> Just c
+
+listCursorNextItem :: ListCursor a -> Maybe a
+listCursorNextItem lc =
+  case listCursorNext lc of
+    [] -> Nothing
+    (c : _) -> Just c
+
+listCursorPrevUntil :: (a -> Bool) -> ListCursor a -> ListCursor a
+listCursorPrevUntil p = go
+  where
+    go lc =
+      case listCursorPrev lc of
+        [] -> lc
+        (c : _)
+          | p c -> lc
+        _ -> maybe lc go (listCursorSelectPrev lc)
+
+listCursorNextUntil :: (a -> Bool) -> ListCursor a -> ListCursor a
+listCursorNextUntil p = go
+  where
+    go lc =
+      case listCursorNext lc of
+        [] -> lc
+        (c : _)
+          | p c -> lc
+        _ -> maybe lc go (listCursorSelectNext lc)
+
+listCursorInsert :: a -> ListCursor a -> ListCursor a
+listCursorInsert c lc = lc {listCursorPrev = c : listCursorPrev lc}
+
+listCursorAppend :: a -> ListCursor a -> ListCursor a
+listCursorAppend c lc = lc {listCursorNext = c : listCursorNext lc}
+
+listCursorInsertList :: [a] -> ListCursor a -> ListCursor a
+listCursorInsertList l lc = lc {listCursorPrev = reverse l ++ listCursorPrev lc}
+
+listCursorAppendList :: [a] -> ListCursor a -> ListCursor a
+listCursorAppendList l lc = lc {listCursorNext = l ++ listCursorNext lc}
+
+listCursorRemove :: ListCursor a -> Maybe (DeleteOrUpdate (ListCursor a))
+listCursorRemove tc =
+  case listCursorPrev tc of
+    [] ->
+      case listCursorNext tc of
+        [] -> Just Deleted
+        _ -> Nothing
+    (_ : prev) -> Just $ Updated $ tc {listCursorPrev = prev}
+
+listCursorDelete :: ListCursor a -> Maybe (DeleteOrUpdate (ListCursor a))
+listCursorDelete tc =
+  case listCursorNext tc of
+    [] ->
+      case listCursorPrev tc of
+        [] -> Just Deleted
+        _ -> Nothing
+    (_ : next) -> Just $ Updated $ tc {listCursorNext = next}
+
+listCursorSplit :: ListCursor a -> (ListCursor a, ListCursor a)
+listCursorSplit ListCursor {..} =
+  ( ListCursor {listCursorPrev = listCursorPrev, listCursorNext = []},
+    ListCursor {listCursorPrev = [], listCursorNext = listCursorNext}
+  )
+
+listCursorCombine :: ListCursor a -> ListCursor a -> ListCursor a
+listCursorCombine lc1 lc2 =
+  ListCursor
+    { listCursorPrev = reverse $ rebuildListCursor lc1,
+      listCursorNext = rebuildListCursor lc2
+    }
+
+traverseListCursor :: ([a] -> [a] -> f b) -> ListCursor a -> f b
+traverseListCursor = foldListCursor
+
+foldListCursor :: ([a] -> [a] -> b) -> ListCursor a -> b
+foldListCursor func ListCursor {..} = func (reverse listCursorPrev) listCursorNext
+
diff --git a/src/Cursor/Text.hs b/src/Cursor/Text.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/Text.hs
@@ -0,0 +1,224 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+{- Authored by Tom Sydney Kerckhove, copied from cursor package #-}
+
+module Cursor.Text
+  ( TextCursor (..),
+    emptyTextCursor,
+    makeTextCursor,
+    makeTextCursorWithSelection,
+    rebuildTextCursor,
+    textCursorNull,
+    textCursorLength,
+    textCursorIndex,
+    textCursorSelectPrev,
+    textCursorSelectNext,
+    textCursorSelectIndex,
+    textCursorSelectStart,
+    textCursorSelectEnd,
+    textCursorPrevChar,
+    textCursorNextChar,
+    textCursorSelectBeginWord,
+    textCursorSelectEndWord,
+    textCursorSelectNextWord,
+    textCursorSelectPrevWord,
+    textCursorInsert,
+    textCursorAppend,
+    textCursorInsertString,
+    textCursorAppendString,
+    textCursorInsertText,
+    textCursorAppendText,
+    textCursorRemove,
+    textCursorDelete,
+    textCursorSplit,
+    textCursorCombine,
+  )
+where
+
+import Control.DeepSeq
+import Cursor.List
+import Cursor.Types
+import Data.Char
+import Data.Text (Text)
+import qualified Data.Text as T
+import GHC.Generics (Generic)
+import Lens.Micro
+
+-- | A cursor for single-line texts
+newtype TextCursor = TextCursor
+  { textCursorList :: ListCursor Char
+  }
+  deriving (Show, Eq, Generic)
+
+instance NFData TextCursor
+
+emptyTextCursor :: TextCursor
+emptyTextCursor = TextCursor emptyListCursor
+
+makeTextCursor :: Text -> Maybe TextCursor
+makeTextCursor t = makeTextCursorWithSelection (T.length t) t
+
+makeTextCursorWithSelection :: Int -> Text -> Maybe TextCursor
+makeTextCursorWithSelection i t =
+  case T.split (== '\n') t of
+    [l] -> TextCursor <$> makeListCursorWithSelection i (T.unpack l)
+    _ -> Nothing
+
+rebuildTextCursor :: TextCursor -> Text
+rebuildTextCursor = T.pack . rebuildListCursor . textCursorList
+
+textCursorListCursorL ::
+  Functor f => (ListCursor Char -> f (ListCursor Char)) -> TextCursor -> f TextCursor
+textCursorListCursorL = lens textCursorList (\tc lc -> tc {textCursorList = lc})
+
+textCursorNull :: TextCursor -> Bool
+textCursorNull = listCursorNull . textCursorList
+
+textCursorLength :: TextCursor -> Int
+textCursorLength = listCursorLength . textCursorList
+
+textCursorIndex :: TextCursor -> Int
+textCursorIndex = listCursorIndex . textCursorList
+
+textCursorSelectPrev :: TextCursor -> Maybe TextCursor
+textCursorSelectPrev = textCursorListCursorL listCursorSelectPrev
+
+textCursorSelectNext :: TextCursor -> Maybe TextCursor
+textCursorSelectNext = textCursorListCursorL listCursorSelectNext
+
+textCursorSelectIndex :: Int -> TextCursor -> TextCursor
+textCursorSelectIndex ix_ = textCursorListCursorL %~ listCursorSelectIndex ix_
+
+textCursorSelectStart :: TextCursor -> TextCursor
+textCursorSelectStart = textCursorListCursorL %~ listCursorSelectStart
+
+textCursorSelectEnd :: TextCursor -> TextCursor
+textCursorSelectEnd = textCursorListCursorL %~ listCursorSelectEnd
+
+textCursorPrevChar :: TextCursor -> Maybe Char
+textCursorPrevChar = listCursorPrevItem . textCursorList
+
+textCursorNextChar :: TextCursor -> Maybe Char
+textCursorNextChar = listCursorNextItem . textCursorList
+
+-- | Move to the beginning of the word
+--
+-- * @"hell|o"@ -> @"|hello"@
+-- * @"hello   | world"@ -> @"|hello    world"@
+-- * @"hello |world"@ -> @"hello |world"@
+-- * @"| hello"@ -> @"| hello"@
+textCursorSelectBeginWord :: TextCursor -> TextCursor
+textCursorSelectBeginWord tc =
+  let goLeft = maybe tc textCursorSelectBeginWord (textCursorSelectPrev tc)
+   in case textCursorPrevChar tc of
+        Nothing -> tc
+        Just p
+          | isSpace p -> case textCursorNextChar tc of
+            Nothing -> goLeft
+            Just n
+              | isSpace n -> goLeft
+              | otherwise -> tc
+          | otherwise -> goLeft
+
+-- | Move to the end of the word
+--
+-- * @"hell|o"@ -> @"hello|"@
+-- * @"hello   | world"@ -> @"hello    world|"@
+-- * @"hello| world"@ -> @"hello| world"@
+-- * @"hello |"@ -> @"hello |"@
+textCursorSelectEndWord :: TextCursor -> TextCursor
+textCursorSelectEndWord tc =
+  let goRight = maybe tc textCursorSelectEndWord (textCursorSelectNext tc)
+   in case textCursorNextChar tc of
+        Nothing -> tc
+        Just p
+          | isSpace p -> case textCursorPrevChar tc of
+            Nothing -> goRight
+            Just n
+              | isSpace n -> goRight
+              | otherwise -> tc
+          | otherwise -> goRight
+
+-- | Move to the beginning of the next word
+--
+-- * @"|hello"@ -> @"hello|"@
+-- * @"hell|o world"@ -> @"hello |world"@
+-- * @"hello| world"@ -> @"hello |world"@
+-- * @"hello |"@ -> @"hello |"@
+textCursorSelectNextWord :: TextCursor -> TextCursor
+textCursorSelectNextWord tc =
+  case (textCursorPrevChar tc, textCursorNextChar tc) of
+    (_, Nothing) -> tc
+    (Just p, Just n) ->
+      case (isSpace p, isSpace n) of
+        (_, True) -> TextCursor $ listCursorNextUntil (not . isSpace) lc
+        _ -> textCursorSelectNextWord . TextCursor $ listCursorNextUntil isSpace lc
+    _ -> textCursorSelectNextWord $ TextCursor $ listCursorNextUntil isSpace lc
+  where
+    lc = textCursorList tc
+
+-- | Move to the end of the previous word
+--
+-- * @"hello|"@ -> @"|hello"@
+-- * @"hello w|orld"@ -> @"hello| world"@
+-- * @"hello |world"@ -> @"hello| world"@
+-- * @" h|ello"@ -> @"| hello"@
+textCursorSelectPrevWord :: TextCursor -> TextCursor
+textCursorSelectPrevWord tc =
+  case (textCursorPrevChar tc, textCursorNextChar tc) of
+    (Nothing, _) -> tc
+    (Just p, Just n) ->
+      case (isSpace p, isSpace n) of
+        (True, _) -> TextCursor $ listCursorPrevUntil (not . isSpace) lc
+        _ -> textCursorSelectPrevWord . TextCursor $ listCursorPrevUntil isSpace lc
+    _ -> textCursorSelectPrevWord . TextCursor $ listCursorPrevUntil isSpace lc
+  where
+    lc = textCursorList tc
+
+textCursorInsert :: Char -> TextCursor -> Maybe TextCursor
+textCursorInsert '\n' _ = Nothing
+textCursorInsert c tc =
+  if isSafeChar c
+    then Just (tc & textCursorListCursorL %~ listCursorInsert c)
+    else Nothing
+
+textCursorAppend :: Char -> TextCursor -> Maybe TextCursor
+textCursorAppend '\n' _ = Nothing
+textCursorAppend c tc =
+  if isSafeChar c
+    then Just (tc & textCursorListCursorL %~ listCursorAppend c)
+    else Nothing
+
+textCursorInsertString :: String -> TextCursor -> Maybe TextCursor
+textCursorInsertString s tc =
+  if any (\c -> c == '\n' || not (isSafeChar c)) s
+    then Nothing
+    else Just $ tc & textCursorListCursorL %~ listCursorInsertList s
+
+textCursorAppendString :: String -> TextCursor -> Maybe TextCursor
+textCursorAppendString s tc =
+  if any (\c -> c == '\n' || not (isSafeChar c)) s
+    then Nothing
+    else Just $ tc & textCursorListCursorL %~ listCursorAppendList s
+
+textCursorInsertText :: Text -> TextCursor -> Maybe TextCursor
+textCursorInsertText = textCursorInsertString . T.unpack
+
+textCursorAppendText :: Text -> TextCursor -> Maybe TextCursor
+textCursorAppendText = textCursorAppendString . T.unpack
+
+textCursorRemove :: TextCursor -> Maybe (DeleteOrUpdate TextCursor)
+textCursorRemove = focusPossibleDeleteOrUpdate textCursorListCursorL listCursorRemove
+
+textCursorDelete :: TextCursor -> Maybe (DeleteOrUpdate TextCursor)
+textCursorDelete = focusPossibleDeleteOrUpdate textCursorListCursorL listCursorDelete
+
+textCursorSplit :: TextCursor -> (TextCursor, TextCursor)
+textCursorSplit tc =
+  let (lc1, lc2) = listCursorSplit $ textCursorList tc
+   in (TextCursor lc1, TextCursor lc2)
+
+textCursorCombine :: TextCursor -> TextCursor -> TextCursor
+textCursorCombine (TextCursor lc1) (TextCursor lc2) =
+  TextCursor {textCursorList = listCursorCombine lc1 lc2}
+
diff --git a/src/Cursor/Types.hs b/src/Cursor/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/Types.hs
@@ -0,0 +1,75 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE RankNTypes #-}
+{- Authored by Tom Sydney Kerckhove, copied from cursor package #-}
+
+module Cursor.Types where
+
+import Control.Applicative
+import Data.Functor.Compose
+import qualified Data.Text.Internal as T
+import GHC.Generics (Generic)
+import Lens.Micro
+
+isSafeChar :: Char -> Bool
+isSafeChar c = T.safe c == c
+
+data DeleteOrUpdate a
+  = Deleted
+  | Updated a
+  deriving (Show, Eq, Generic)
+
+instance Functor DeleteOrUpdate where
+  fmap _ Deleted = Deleted
+  fmap f (Updated a) = Updated (f a)
+
+instance Applicative DeleteOrUpdate where
+  pure = Updated
+  Deleted <*> _ = Deleted
+  _ <*> Deleted = Deleted
+  (Updated f) <*> (Updated a) = Updated (f a)
+
+instance Alternative DeleteOrUpdate where
+  empty = Deleted
+  Updated a <|> _ = Updated a
+  Deleted <|> doua = doua
+
+instance Monad DeleteOrUpdate where
+  dou >>= f = case dou of
+    Updated a -> f a
+    Deleted -> Deleted
+
+joinDeletes :: Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a) -> DeleteOrUpdate a
+joinDeletes m1 m2 =
+  case (m1, m2) of
+    (Nothing, Nothing) -> Deleted
+    (Nothing, Just a) -> a
+    (Just a, _) -> a
+
+joinDeletes3 ::
+  Maybe (DeleteOrUpdate a) ->
+  Maybe (DeleteOrUpdate a) ->
+  Maybe (DeleteOrUpdate a) ->
+  DeleteOrUpdate a
+joinDeletes3 m1 m2 m3 =
+  case (m1, m2, m3) of
+    (Nothing, Nothing, Nothing) -> Deleted
+    (Nothing, Nothing, Just a) -> a
+    (Nothing, Just a, _) -> a
+    (Just a, _, _) -> a
+
+joinPossibleDeletes ::
+  Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a) -> Maybe (DeleteOrUpdate a)
+joinPossibleDeletes d1 d2 = getCompose $ Compose d1 <|> Compose d2
+
+focusPossibleDeleteOrUpdate ::
+  Lens' b a -> (a -> Maybe (DeleteOrUpdate a)) -> b -> Maybe (DeleteOrUpdate b)
+focusPossibleDeleteOrUpdate l func = getCompose . l (Compose . func)
+
+dullMDelete :: Maybe (DeleteOrUpdate a) -> Maybe a
+dullMDelete Nothing = Nothing
+dullMDelete (Just dou) = dullDelete dou
+
+dullDelete :: DeleteOrUpdate a -> Maybe a
+dullDelete Deleted = Nothing
+dullDelete (Updated a) = Just a
+
diff --git a/src/Lib.hs b/src/Lib.hs
--- a/src/Lib.hs
+++ b/src/Lib.hs
@@ -226,10 +226,10 @@
   createDirectoryIfMissing True dir
   GD.makeSnapshot dbg (dir </> fp)
 
-retainersOfConstructor :: Debuggee -> String -> IO [[Closure]]
-retainersOfConstructor dbg con_name = do
+retainersOfConstructor :: Maybe [ClosurePtr] -> Debuggee -> String -> IO [[Closure]]
+retainersOfConstructor mroots dbg con_name = do
   run dbg $ do
-    roots <- GD.gcRoots
+    roots <- maybe GD.gcRoots return mroots
     stack <- GD.findRetainersOfConstructor (Just 100) roots con_name
     traverse (\cs -> zipWith Closure cs <$> (GD.dereferenceClosures cs)) stack
 
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -31,6 +31,8 @@
 import Data.Text (Text, pack)
 import qualified Data.Text as T
 import qualified Data.Map as M
+import Data.Bifunctor
+import Data.Maybe
 
 import IOTree
 import TextCursor
@@ -328,7 +330,7 @@
 
 
       mkSavedAndGCRootsIOTree manalysis = do
-        raw_roots <- map ("GC Roots",) <$> GD.rootClosures debuggee'
+        raw_roots <- take 1000 . map ("GC Roots",) <$> GD.rootClosures debuggee'
         rootClosures' <- liftIO $ mapM (completeClosureDetails debuggee' manalysis) raw_roots
         raw_saved <- map ("Saved Object",) <$> GD.savedClosures debuggee'
         savedClosures' <- liftIO $ mapM (completeClosureDetails debuggee' manalysis) raw_saved
@@ -470,8 +472,8 @@
             continue $ os & treeMode .~ Reverse
                           & treeReverse . _Just . reverseIOTree %~ setIOTreeRoots rs'
                           -}
---        VtyEvent (Vty.EvKey (KFun 8) _) ->
---          continue $ os & footerMode .~ (FooterInput FSearch emptyTextCursor)
+        VtyEvent (Vty.EvKey (KFun 8) _) ->
+          continue $ os & footerMode .~ (FooterInput FSearch emptyTextCursor)
 
         VtyEvent (Vty.EvKey (KFun 3) _) ->
           continue $ os & footerMode .~ (FooterInput FProfile emptyTextCursor)
@@ -525,26 +527,23 @@
                     -> OperationalState
                     -> EventM n (Next OperationalState)
 dispatchFooterInput dbg FSearch tc os = do
-  case view heapGraph os of
-    Just hg -> do
-      -- limit to 100 results
-      let new_roots = take 100 $ map (\cp -> ("Searched", CP (hgeClosurePtr cp)))
-                        (findConstructors (T.unpack (rebuildTextCursor tc)) hg)
-      let manalysis = view getDominatorAnalysis <$> view treeDominator os
-      raw_roots <- liftIO $ mapM (traverse (dereferencePtr dbg)) new_roots
-      root_details <-
-        liftIO $ mapM (completeClosureDetails dbg manalysis) raw_roots
-      continue (os & resetFooter
-                   & rootsFrom .~ SearchedRoots new_roots
-                   & treeMode .~ SavedAndGCRoots
-                   & treeSavedAndGCRoots %~ setIOTreeRoots root_details)
-    -- Should never happen
-    Nothing -> continue os
+   cps <- map head <$> (liftIO $ retainersOfConstructor Nothing dbg (T.unpack (rebuildTextCursor tc)))
+   let cps' = (zipWith (\n cp -> (T.pack (show n),cp)) [0 :: Int ..]) cps
+   res <- liftIO $ mapM (completeClosureDetails dbg Nothing) cps'
+   let new_roots = map (second toPtr) cps'
+       root_details  = res
+   continue (os & resetFooter
+                & rootsFrom .~ SearchedRoots new_roots
+                & treeMode .~ SavedAndGCRoots
+                & treeSavedAndGCRoots %~ setIOTreeRoots root_details)
 dispatchFooterInput dbg FProfile tc os = do
    liftIO $ profile dbg (T.unpack (rebuildTextCursor tc))
    continue (os & resetFooter)
 dispatchFooterInput dbg FRetainer tc os = do
-   cps <- liftIO $ retainersOfConstructor dbg (T.unpack (rebuildTextCursor tc))
+   let roots = mapMaybe go (map snd (currentRoots (view rootsFrom os)))
+       go (CP p) = Just p
+       go (SP p)   = Nothing
+   cps <- liftIO $ retainersOfConstructor (Just roots) dbg (T.unpack (rebuildTextCursor tc))
    let cps' = map (zipWith (\n cp -> (T.pack (show n),cp)) [0 :: Int ..]) cps
    res <- liftIO $ mapM (mapM (completeClosureDetails dbg Nothing)) cps'
    let tree = mkRetainerTree dbg res
