startGroupN
    :: (Serializable a, Serializable b)
    => [Resources] -- ^ Resources for actors
    -> GroupType   -- ^ How individual failures should be handled
    -> Int         -- ^ Number of tasks to run
    -> Closure (Actor a b)
    -> DNA (Shell (Val a) (Grp b))
startGroupN res groupTy nTasks child = do
    (shellS,shellR) <- liftP newChan
    let clos = $(mkStaticClosure 'runActorManyRanks) `closureApply` child
    sendACP $ ReqSpawnGroupN clos shellS res nTasks groupTy
    (gid,mbox) <- liftP (receiveChan shellR)
    msgs <- mapM unwrapMessage mbox
    case sequence msgs of
      Nothing -> error "Bad shell message"
      Just  s -> return $ broadcast $ assembleShellGroup gid s
    

-- | Start group of collector processes
startGroupN
    :: (Serializable a, Serializable b)
    => [Resources] -- ^ Resources for actors
    -> GroupType   -- ^ How individual failures should be handled
    -> Int         -- ^ Number of tasks to run
    -> Closure (Actor a b)
    -> DNA (Shell (Val a) (Grp b))
startGroupN res groupTy nTasks child = do
    (shellS,shellR) <- liftP newChan
    let clos = $(mkStaticClosure 'runActorManyRanks) `closureApply` child
    sendACP $ ReqSpawnGroupN clos shellS res nTasks groupTy
    (gid,mbox) <- liftP (receiveChan shellR)
    msgs <- mapM unwrapMessage mbox
    case sequence msgs of
      Nothing -> error "Bad shell message"
      Just  s -> return $ broadcast $ assembleShellGroup gid s
    

-- | Start group of collector processes
startGroupN res groupTy nTasks child = do
    (shellS,shellR) <- liftP newChan
    let clos = $(mkStaticClosure 'runActorManyRanks) `closureApply` child
    sendACP $ ReqSpawnGroupN clos shellS res nTasks groupTy
    (gid,mbox) <- liftP (receiveChan shellR)
    msgs <- mapM unwrapMessage mbox
    case sequence msgs of
      Nothing -> error "Bad shell message"
      Just  s -> return $ broadcast $ assembleShellGroup gid s
    

-- | Start group of collector processes