recursivelyImportExternalNS :: L2.L2Model -> L2.Identifier -> L2.L2NamespaceID -> ModelTranslation L2.L2NamespaceID
recursivelyImportExternalNS =
  cacheWrapExternalImport mtsForeignToLocalNS (\x m -> m {mtsForeignToLocalNS=x}) $
    \foreignMod foreignURL targetNS ->
    if (((\(L2.L2NamespaceID n) -> n) targetNS) < reservedIDs) && targetNS /= nsMain
       -- Reserved IDs are a special case: We match on them numerically, and
       -- they are globally unique, so just re-use the same numerical ID. We exclude
       -- nsMain, however, because that is actually a user-defined namespace.
    then return targetNS
    else
      do
        let foreignNSC = (L2.l2AllNamespaces foreignMod) ! targetNS
        newNSID <- L2.l2NextNamespace <$> getL2Model
        modifyL2Model $ \mod -> mod {
          L2.l2NextNamespace = (\(L2.L2NamespaceID nid) -> L2.L2NamespaceID (nid + 1)) newNSID
          }
        -- The cache wrapper will eventually save the namespace, but recursivelyImportExternalNSContents
        -- might need an answer before then to retrieve its parent namespace, so cache it now...
        modify (\mts -> mts { mtsForeignToLocalNS = M.insert (foreignURL, targetNS)
                                                             newNSID (mtsForeignToLocalNS mts) })
        newNSC <- recursivelyImportExternalNSContents foreignMod foreignURL foreignNSC
        modifyL2Model $ \mod -> mod {
          L2.l2AllNamespaces = M.insert newNSID
                               newNSC (L2.l2AllNamespaces mod)
          }
        -- destURL <- (\(_,url,_) -> url) <$> ask
        -- Debug.Trace.trace ("Imported namespace " ++ show targetNS ++ " from " ++ BSC.unpack foreignURL ++
        --                    " into " ++ destURL ++
        --                    " as " ++ show newNSID) $! return ()
        return newNSID
recursivelyImportExternalNS :: L2.L2Model -> L2.Identifier -> L2.L2NamespaceID -> ModelTranslation L2.L2NamespaceID
recursivelyImportExternalNS =
  cacheWrapExternalImport mtsForeignToLocalNS (\x m -> m {mtsForeignToLocalNS=x}) $
    \foreignMod foreignURL targetNS ->
    if (((\(L2.L2NamespaceID n) -> n) targetNS) < reservedIDs) && targetNS /= nsMain
       -- Reserved IDs are a special case: We match on them numerically, and
       -- they are globally unique, so just re-use the same numerical ID. We exclude
       -- nsMain, however, because that is actually a user-defined namespace.
    then return targetNS
    else
      do
        let foreignNSC = (L2.l2AllNamespaces foreignMod) ! targetNS
        newNSID <- L2.l2NextNamespace <$> getL2Model
        modifyL2Model $ \mod -> mod {
          L2.l2NextNamespace = (\(L2.L2NamespaceID nid) -> L2.L2NamespaceID (nid + 1)) newNSID
          }
        -- The cache wrapper will eventually save the namespace, but recursivelyImportExternalNSContents
        -- might need an answer before then to retrieve its parent namespace, so cache it now...
        modify (\mts -> mts { mtsForeignToLocalNS = M.insert (foreignURL, targetNS)
                                                             newNSID (mtsForeignToLocalNS mts) })
        newNSC <- recursivelyImportExternalNSContents foreignMod foreignURL foreignNSC
        modifyL2Model $ \mod -> mod {
          L2.l2AllNamespaces = M.insert newNSID
                               newNSC (L2.l2AllNamespaces mod)
          }
        -- destURL <- (\(_,url,_) -> url) <$> ask
        -- Debug.Trace.trace ("Imported namespace " ++ show targetNS ++ " from " ++ BSC.unpack foreignURL ++
        --                    " into " ++ destURL ++
        --                    " as " ++ show newNSID) $! return ()
        return newNSID
recursivelyImportExternalNS =
  cacheWrapExternalImport mtsForeignToLocalNS (\x m -> m {mtsForeignToLocalNS=x}) $
    \foreignMod foreignURL targetNS ->
    if (((\(L2.L2NamespaceID n) -> n) targetNS) < reservedIDs) && targetNS /= nsMain
       -- Reserved IDs are a special case: We match on them numerically, and
       -- they are globally unique, so just re-use the same numerical ID. We exclude
       -- nsMain, however, because that is actually a user-defined namespace.
    then return targetNS
    else
      do
        let foreignNSC = (L2.l2AllNamespaces foreignMod) ! targetNS
        newNSID <- L2.l2NextNamespace <$> getL2Model
        modifyL2Model $ \mod -> mod {
          L2.l2NextNamespace = (\(L2.L2NamespaceID nid) -> L2.L2NamespaceID (nid + 1)) newNSID
          }
        -- The cache wrapper will eventually save the namespace, but recursivelyImportExternalNSContents
        -- might need an answer before then to retrieve its parent namespace, so cache it now...
        modify (\mts -> mts { mtsForeignToLocalNS = M.insert (foreignURL, targetNS)
                                                             newNSID (mtsForeignToLocalNS mts) })
        newNSC <- recursivelyImportExternalNSContents foreignMod foreignURL foreignNSC
        modifyL2Model $ \mod -> mod {
          L2.l2AllNamespaces = M.insert newNSID
                               newNSC (L2.l2AllNamespaces mod)
          }
        -- destURL <- (\(_,url,_) -> url) <$> ask
        -- Debug.Trace.trace ("Imported namespace " ++ show targetNS ++ " from " ++ BSC.unpack foreignURL ++
        --                    " into " ++ destURL ++
        --                    " as " ++ show newNSID) $! return ()
        return newNSID