getFunInfo :: (Readable (Local s), Readable (Shared s))  =>
  SiteState s -> Map (FunName,TaskGroup,Text) String ->
      FunName -> IO (Either SomeException (Name, [TaskInfo]))
                          -- real name, and a list of solutions for each task
getFunInfo s cats f =
  try $
  do tgd <- loadTaskGroupData s f
     name <- getRealName s f
     let safetyTaskNames = taskNames f SafetyLevels tgd
     es <- forM safetyTaskNames $ \tn ->
            do slnNames <- listSolutions s tn
               tags <- listTags s tn
               let auto = any (`elem` [ "copy-up"
                                      , "copy-multi"
                                      , "only-freebies-simple"
                                      , "only-freebies-advanced"
                                      ]) tags

               es <- forM slnNames $ \sln ->
                     do (_,_,e) <- loadSolutionPre s tn sln
                        return e


               return TaskInfo { taskTags = tags
                               , taskSlns = es
                               , taskCat = Map.lookup (taskFun tn
                                                      ,taskGroup tn
                                                      ,taskName tn)  cats
                               , taskAuto = auto
                               , taskLabel = Text.unpack (showTaskGroup
                                              (taskGroup tn)) ++ " / " ++
                                                  Text.unpack (taskName tn)
                               }
     return (name,es)
getFunInfo :: (Readable (Local s), Readable (Shared s))  =>
  SiteState s -> Map (FunName,TaskGroup,Text) String ->
      FunName -> IO (Either SomeException (Name, [TaskInfo]))
getFunInfo s cats f =
  try $
  do tgd <- loadTaskGroupData s f
     name <- getRealName s f
     let safetyTaskNames = taskNames f SafetyLevels tgd
     es <- forM safetyTaskNames $ \tn ->
            do slnNames <- listSolutions s tn
               tags <- listTags s tn
               let auto = any (`elem` [ "copy-up"
                                      , "copy-multi"
                                      , "only-freebies-simple"
                                      , "only-freebies-advanced"
                                      ]) tags

               es <- forM slnNames $ \sln ->
                     do (_,_,e) <- loadSolutionPre s tn sln
                        return e


               return TaskInfo { taskTags = tags
                               , taskSlns = es
                               , taskCat = Map.lookup (taskFun tn
                                                      ,taskGroup tn
                                                      ,taskName tn)  cats
                               , taskAuto = auto
                               , taskLabel = Text.unpack (showTaskGroup
                                              (taskGroup tn)) ++ " / " ++
                                                  Text.unpack (taskName tn)
                               }
     return (name,es)
getFunInfo s cats f =
  try $
  do tgd <- loadTaskGroupData s f
     name <- getRealName s f
     let safetyTaskNames = taskNames f SafetyLevels tgd
     es <- forM safetyTaskNames $ \tn ->
            do slnNames <- listSolutions s tn
               tags <- listTags s tn
               let auto = any (`elem` [ "copy-up"
                                      , "copy-multi"
                                      , "only-freebies-simple"
                                      , "only-freebies-advanced"
                                      ]) tags

               es <- forM slnNames $ \sln ->
                     do (_,_,e) <- loadSolutionPre s tn sln
                        return e


               return TaskInfo { taskTags = tags
                               , taskSlns = es
                               , taskCat = Map.lookup (taskFun tn
                                                      ,taskGroup tn
                                                      ,taskName tn)  cats
                               , taskAuto = auto
                               , taskLabel = Text.unpack (showTaskGroup
                                              (taskGroup tn)) ++ " / " ++
                                                  Text.unpack (taskName tn)
                               }
     return (name,es)