placeAll :: LoadSpace -- ^ The loadspace
        -> PackingSelectors -- ^ The full genome
        -> [IndexedSpace] -- ^ Untranslated indexed packages
        -> ItemQuantities -- ^ The quantities for every packge
        -> Maybe ([IndexedSpace], [ResidualSpace], Int) -- ^ A packing with translated indexed packages,
        --  residual spaces and the amount of chromosomes used.
placeAll load chromosomePackages@(orientatioCs, fillCs, selectCs) ipackages iqs
-- Check prerequisites for algorithm, especially the size of the genome
  | length orientatioCs /= length fillCs ||
    length orientatioCs /= length selectCs
  = error $ "incorrectly sized genome lists (orientatioCs " ++
              show (length orientatioCs) ++ ", fillCs " ++
              show (length fillCs) ++ ", selectCs " ++
              show (length selectCs) ++ ")"
  | otherwise
  = extractData <$>
  L.foldl (\oldState ipackage -> do
      (packed, residual, (orientation, fillOrder, candidateSelect), qm, _) <- oldState
      -- check item quantity
      let q = qm ! fst ipackage
      -- skip already fully packed items
      if q == 0 then oldState
      else combinePlacements oldState $
           pickNextPack load (snd <$> packed) ipackage q
            (head orientation, head fillOrder, head candidateSelect)
            residual
    )
  -- The initial state. nothing placed, only the loadspace as residual,
  -- chromosomes unpacked and split, initialized quantities, and 0 chromosomes used.
  (Just ([], [mkResidualSpace load], chromosomePackages, M.fromList iqs, 0)) ipackages
  where extractData (placements, residuals, _, _, used) = (placements, residuals, used)
placeAll :: LoadSpace -- ^ The loadspace
        -> PackingSelectors -- ^ The full genome
        -> [IndexedSpace] -- ^ Untranslated indexed packages
        -> ItemQuantities -- ^ The quantities for every packge
        -> Maybe ([IndexedSpace], [ResidualSpace], Int)
placeAll load chromosomePackages@(orientatioCs, fillCs, selectCs) ipackages iqs
-- Check prerequisites for algorithm, especially the size of the genome
  | length orientatioCs /= length fillCs ||
    length orientatioCs /= length selectCs
  = error $ "incorrectly sized genome lists (orientatioCs " ++
              show (length orientatioCs) ++ ", fillCs " ++
              show (length fillCs) ++ ", selectCs " ++
              show (length selectCs) ++ ")"
  | otherwise
  = extractData <$>
  L.foldl (\oldState ipackage -> do
      (packed, residual, (orientation, fillOrder, candidateSelect), qm, _) <- oldState
      -- check item quantity
      let q = qm ! fst ipackage
      -- skip already fully packed items
      if q == 0 then oldState
      else combinePlacements oldState $
           pickNextPack load (snd <$> packed) ipackage q
            (head orientation, head fillOrder, head candidateSelect)
            residual
    )
  -- The initial state. nothing placed, only the loadspace as residual,
  -- chromosomes unpacked and split, initialized quantities, and 0 chromosomes used.
  (Just ([], [mkResidualSpace load], chromosomePackages, M.fromList iqs, 0)) ipackages
  where extractData (placements, residuals, _, _, used) = (placements, residuals, used)
placeAll load chromosomePackages@(orientatioCs, fillCs, selectCs) ipackages iqs
-- Check prerequisites for algorithm, especially the size of the genome
  | length orientatioCs /= length fillCs ||
    length orientatioCs /= length selectCs
  = error $ "incorrectly sized genome lists (orientatioCs " ++
              show (length orientatioCs) ++ ", fillCs " ++
              show (length fillCs) ++ ", selectCs " ++
              show (length selectCs) ++ ")"
  | otherwise
  = extractData <$>
  L.foldl (\oldState ipackage -> do
      (packed, residual, (orientation, fillOrder, candidateSelect), qm, _) <- oldState
      -- check item quantity
      let q = qm ! fst ipackage
      -- skip already fully packed items
      if q == 0 then oldState
      else combinePlacements oldState $
           pickNextPack load (snd <$> packed) ipackage q
            (head orientation, head fillOrder, head candidateSelect)
            residual
    )
  -- The initial state. nothing placed, only the loadspace as residual,
  -- chromosomes unpacked and split, initialized quantities, and 0 chromosomes used.
  (Just ([], [mkResidualSpace load], chromosomePackages, M.fromList iqs, 0)) ipackages
  where extractData (placements, residuals, _, _, used) = (placements, residuals, used)