pickNextPack :: LoadSpace -- ^ The loadspace used
          -> [EuclideanSpace3D]
          -> IndexedSpace -- ^ The index package and its space
          -> Quantity -- ^ The package quantity
          -> PackingSelector -- ^ The chromosome package for the package
          -> [ResidualSpace] -- ^ The current list of residual spaces
          -> Maybe ([IndexedSpace], [ResidualSpace]) -- ^ A packing extension, defined by a number of placed packages and a new list of residual spaces
pickNextPack load packed (idx, package) quantity (orientationSelect, fillOrder, candidateSelect) rs
  | orientation <- sizePermuteReduced package
  , pickedOrientation <- select01 orientation orientationSelect
  , pickedAxeOrder <- select01 allFillOrders fillOrder
  -- sort residual spaces first, then try to get a packing extension for the supplied
  -- orientation, fill order and candidate selector
  , Just cs <- placeNextCandidates load (L.sortBy startOrd rs) pickedAxeOrder pickedOrientation quantity
  , not $ L.null cs
  , selected <- select01 cs candidateSelect
  -- A packing extension could be found, now it needs to be indexed
  = Just $ expandPlacement idx load packed rs selected
  | otherwise
  = Nothing
pickNextPack :: LoadSpace -- ^ The loadspace used
          -> [EuclideanSpace3D]
          -> IndexedSpace -- ^ The index package and its space
          -> Quantity -- ^ The package quantity
          -> PackingSelector -- ^ The chromosome package for the package
          -> [ResidualSpace] -- ^ The current list of residual spaces
          -> Maybe ([IndexedSpace], [ResidualSpace])
pickNextPack load packed (idx, package) quantity (orientationSelect, fillOrder, candidateSelect) rs
  | orientation <- sizePermuteReduced package
  , pickedOrientation <- select01 orientation orientationSelect
  , pickedAxeOrder <- select01 allFillOrders fillOrder
  -- sort residual spaces first, then try to get a packing extension for the supplied
  -- orientation, fill order and candidate selector
  , Just cs <- placeNextCandidates load (L.sortBy startOrd rs) pickedAxeOrder pickedOrientation quantity
  , not $ L.null cs
  , selected <- select01 cs candidateSelect
  -- A packing extension could be found, now it needs to be indexed
  = Just $ expandPlacement idx load packed rs selected
  | otherwise
  = Nothing
pickNextPack load packed (idx, package) quantity (orientationSelect, fillOrder, candidateSelect) rs
  | orientation <- sizePermuteReduced package
  , pickedOrientation <- select01 orientation orientationSelect
  , pickedAxeOrder <- select01 allFillOrders fillOrder
  -- sort residual spaces first, then try to get a packing extension for the supplied
  -- orientation, fill order and candidate selector
  , Just cs <- placeNextCandidates load (L.sortBy startOrd rs) pickedAxeOrder pickedOrientation quantity
  , not $ L.null cs
  , selected <- select01 cs candidateSelect
  -- A packing extension could be found, now it needs to be indexed
  = Just $ expandPlacement idx load packed rs selected
  | otherwise
  = Nothing