initUserFeature :: ServerEnv -> IO (IO UserFeature)
initUserFeature ServerEnv{serverStateDir} = do
  -- Canonical state
  usersState  <- usersStateComponent  serverStateDir
  adminsState <- adminsStateComponent serverStateDir

  -- Ephemeral state
  groupIndex   <- newMemStateWHNF emptyGroupIndex

  -- Extension hooks
  userAdded     <- newHook
  authFailHook  <- newHook

  return $ do
    -- Slightly tricky: we have an almost recursive knot between the group
    -- resource management functions, and creating the admin group
    -- resource that is part of the user feature.
    --
    -- Instead of trying to pull it apart, we just use a 'do rec'
    --
    rec let (feature@UserFeature{groupResourceAt}, adminGroupDesc)
              = userFeature usersState
                            adminsState
                            groupIndex
                            userAdded authFailHook
                            adminG adminR

        (adminG, adminR) <- groupResourceAt "/users/admins/" adminGroupDesc

    return feature
initUserFeature :: ServerEnv -> IO (IO UserFeature)
initUserFeature ServerEnv{serverStateDir} = do
  -- Canonical state
  usersState  <- usersStateComponent  serverStateDir
  adminsState <- adminsStateComponent serverStateDir

  -- Ephemeral state
  groupIndex   <- newMemStateWHNF emptyGroupIndex

  -- Extension hooks
  userAdded     <- newHook
  authFailHook  <- newHook

  return $ do
    -- Slightly tricky: we have an almost recursive knot between the group
    -- resource management functions, and creating the admin group
    -- resource that is part of the user feature.
    --
    -- Instead of trying to pull it apart, we just use a 'do rec'
    --
    rec let (feature@UserFeature{groupResourceAt}, adminGroupDesc)
              = userFeature usersState
                            adminsState
                            groupIndex
                            userAdded authFailHook
                            adminG adminR

        (adminG, adminR) <- groupResourceAt "/users/admins/" adminGroupDesc

    return feature
initUserFeature ServerEnv{serverStateDir} = do
  -- Canonical state
  usersState  <- usersStateComponent  serverStateDir
  adminsState <- adminsStateComponent serverStateDir

  -- Ephemeral state
  groupIndex   <- newMemStateWHNF emptyGroupIndex

  -- Extension hooks
  userAdded     <- newHook
  authFailHook  <- newHook

  return $ do
    -- Slightly tricky: we have an almost recursive knot between the group
    -- resource management functions, and creating the admin group
    -- resource that is part of the user feature.
    --
    -- Instead of trying to pull it apart, we just use a 'do rec'
    --
    rec let (feature@UserFeature{groupResourceAt}, adminGroupDesc)
              = userFeature usersState
                            adminsState
                            groupIndex
                            userAdded authFailHook
                            adminG adminR

        (adminG, adminR) <- groupResourceAt "/users/admins/" adminGroupDesc

    return feature