main' :: Options -> [String] -> IO ()
main' opts args = do
    when (optHelp opts) $ usage >> exitSuccess

    case args of
      [] -> do
        putStrLn "-- Versions found on this system"
        findVersionsThat VersionAll >>= showVersions opts

      ["all"] -> do
        removePlan "all Haskell directories"
        removeAll opts

      ["test"] -> do
        main' testOpts []
        vers <- Map.keys `fmap` findVersions
        mapM_ (\v -> main' testOpts ["only", show v]) vers
        mapM_ (\v -> main' testOpts ["thru", show v]) vers
        main' testOpts ["all"]

      ["thru", v] -> withVersion v $ \ver -> do
        removePlan $ "version " ++ show ver ++ " and earlier"
        removeVersionsThat (VersionThru ver)

      ["only", v] -> withVersion v $ \ver -> do
        removePlan $ "just version " ++ show ver
        removeVersionsThat (VersionOnly ver)

      ["install-check", v, a] -> withVersion v $ \ver -> do
        findVersionsThat (VersionUpto ver) >>= alertOlderVersions a

      _ -> usageFailure "unregcognized args"

  where
    removePlan s = message opts $ removePrefix ++ s
    removePrefix = case optRemove opts of
        OptDryRun -> "-- Would remove "
        _         -> "-- Removing "

    withVersion v a =
        maybe (usageFailure "couldn't parse version") a $ version v

    findVersionsThat rt =
        Map.filterWithKey (const . versionTest rt) `fmap` findVersions

    removeVersionsThat rt =
        findVersionsThat rt >>= remove opts rt . concat . Map.elems

    testOpts = opts { optVerbose = True, optRemove = OptDryRun }
main' :: Options -> [String] -> IO ()
main' opts args = do
    when (optHelp opts) $ usage >> exitSuccess

    case args of
      [] -> do
        putStrLn "-- Versions found on this system"
        findVersionsThat VersionAll >>= showVersions opts

      ["all"] -> do
        removePlan "all Haskell directories"
        removeAll opts

      ["test"] -> do
        main' testOpts []
        vers <- Map.keys `fmap` findVersions
        mapM_ (\v -> main' testOpts ["only", show v]) vers
        mapM_ (\v -> main' testOpts ["thru", show v]) vers
        main' testOpts ["all"]

      ["thru", v] -> withVersion v $ \ver -> do
        removePlan $ "version " ++ show ver ++ " and earlier"
        removeVersionsThat (VersionThru ver)

      ["only", v] -> withVersion v $ \ver -> do
        removePlan $ "just version " ++ show ver
        removeVersionsThat (VersionOnly ver)

      ["install-check", v, a] -> withVersion v $ \ver -> do
        findVersionsThat (VersionUpto ver) >>= alertOlderVersions a

      _ -> usageFailure "unregcognized args"

  where
    removePlan s = message opts $ removePrefix ++ s
    removePrefix = case optRemove opts of
        OptDryRun -> "-- Would remove "
        _         -> "-- Removing "

    withVersion v a =
        maybe (usageFailure "couldn't parse version") a $ version v

    findVersionsThat rt =
        Map.filterWithKey (const . versionTest rt) `fmap` findVersions

    removeVersionsThat rt =
        findVersionsThat rt >>= remove opts rt . concat . Map.elems

    testOpts = opts { optVerbose = True, optRemove = OptDryRun }
main' opts args = do
    when (optHelp opts) $ usage >> exitSuccess

    case args of
      [] -> do
        putStrLn "-- Versions found on this system"
        findVersionsThat VersionAll >>= showVersions opts

      ["all"] -> do
        removePlan "all Haskell directories"
        removeAll opts

      ["test"] -> do
        main' testOpts []
        vers <- Map.keys `fmap` findVersions
        mapM_ (\v -> main' testOpts ["only", show v]) vers
        mapM_ (\v -> main' testOpts ["thru", show v]) vers
        main' testOpts ["all"]

      ["thru", v] -> withVersion v $ \ver -> do
        removePlan $ "version " ++ show ver ++ " and earlier"
        removeVersionsThat (VersionThru ver)

      ["only", v] -> withVersion v $ \ver -> do
        removePlan $ "just version " ++ show ver
        removeVersionsThat (VersionOnly ver)

      ["install-check", v, a] -> withVersion v $ \ver -> do
        findVersionsThat (VersionUpto ver) >>= alertOlderVersions a

      _ -> usageFailure "unregcognized args"

  where
    removePlan s = message opts $ removePrefix ++ s
    removePrefix = case optRemove opts of
        OptDryRun -> "-- Would remove "
        _         -> "-- Removing "

    withVersion v a =
        maybe (usageFailure "couldn't parse version") a $ version v

    findVersionsThat rt =
        Map.filterWithKey (const . versionTest rt) `fmap` findVersions

    removeVersionsThat rt =
        findVersionsThat rt >>= remove opts rt . concat . Map.elems

    testOpts = opts { optVerbose = True, optRemove = OptDryRun }