-- | Performs a fold over all namespaces where a symbol might be found.
foldOverNSScopesM :: (s -> L2.L2NamespaceID -> ModelTranslation s) -> s -> L2.L2NamespaceID -> ModelTranslation s
foldOverNSScopesM f s0 nsid
  | nsid == nsSpecial = return s0
  | otherwise = do
    s1 <- f s0 nsid
    nsc <- (fromJust . M.lookup nsid . L2.l2AllNamespaces) <$> getL2Model
    foldOverNSScopesM f s1 (L2.l2nsParent nsc)

-- | Finds a Level 2 namespace using a Level 1 RelOrAbsPath
foldOverNSScopesM :: (s -> L2.L2NamespaceID -> ModelTranslation s) -> s -> L2.L2NamespaceID -> ModelTranslation s
foldOverNSScopesM f s0 nsid
  | nsid == nsSpecial = return s0
  | otherwise = do
    s1 <- f s0 nsid
    nsc <- (fromJust . M.lookup nsid . L2.l2AllNamespaces) <$> getL2Model
    foldOverNSScopesM f s1 (L2.l2nsParent nsc)

-- | Finds a Level 2 namespace using a Level 1 RelOrAbsPath
foldOverNSScopesM f s0 nsid
  | nsid == nsSpecial = return s0
  | otherwise = do
    s1 <- f s0 nsid
    nsc <- (fromJust . M.lookup nsid . L2.l2AllNamespaces) <$> getL2Model
    foldOverNSScopesM f s1 (L2.l2nsParent nsc)

-- | Finds a Level 2 namespace using a Level 1 RelOrAbsPath