buildSkeletonModel ss nsc@(L1.L1NamespaceContents c) myNSID = do
  let dtRef ss x = L2.L2DomainReference ss x
  let dummyDT ss = dtRef ss (L2.L2DomainID 0)
  let dummyCVC ss = L2.L2ClassValueContents ss (dummyDT ss)

  -- TODO - check for name conflicts.
  forM_ c $ \nsel ->
    case nsel of
      L1.L1NSNamespace { L1.l1nsSS = nsss, L1.l1nsNamespaceName = L1.L1Identifier _ nsname,
                         L1.l1nsNamespaceContents = newnsc } -> do
        newNSID <- registerNewNamespace nsss myNSID newnsc
        newLabel <- L2.l2nsNextLabel <$> getNamespaceContents "bsm nextLabel" myNSID
        -- Debug.Trace.trace ("Adding Label#" ++ show newLabel ++ " into " ++ show myNSID ++ " for " ++ (show nsname)) (return ())
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsNamespaces = M.insert nsname newNSID (L2.l2nsNamespaces l2nsc),
          L2.l2nsLabels = M.insert nsname (L2.L2Label myNSID (fromIntegral newLabel)) (L2.l2nsLabels l2nsc),
          L2.l2nsNextLabel = newLabel + 1
             }
        tmpId <- mtsNextTempId <$> get
        modify $ \mts -> mts { mtsNextTempId = tmpId - 1 }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsDomains = M.insert nsname (dtRef nsss $ L2.L2DomainID tmpId) (L2.l2nsDomains l2nsc)
          }

        buildSkeletonModel nsss newnsc newNSID
      L1.L1NSDomain { L1.l1nsSS = nsss, L1.l1nsDomainName = L1.L1Identifier _ nsname,
                      L1.l1nsNamespaceContents = newnsc, 
                      L1.l1nsDomainDefinition = dd } -> do
        newNSID <- registerNewNamespace nsss myNSID newnsc
        newLabel <- L2.l2nsNextLabel <$> getNamespaceContents "bsm domain nextlabel" myNSID
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsNamespaces = M.insert nsname newNSID (L2.l2nsNamespaces l2nsc),
          L2.l2nsLabels = M.insert nsname (L2.L2Label myNSID (fromIntegral newLabel)) (L2.l2nsLabels l2nsc),
          L2.l2nsNextLabel = newLabel + 1
             }
        buildSkeletonModel nsss newnsc newNSID
        case dd of
          L1.L1DomainDefDomainType ddss _ -> do
            -- It is an alias, but we aren't ready to process the alias yet,
            -- so we allocate a temporary ID...
            tmpId <- mtsNextTempId <$> get
            modify $ \mts -> mts { mtsNextTempId = tmpId - 1 }
            modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
              L2.l2nsDomains = M.insert nsname (dtRef ddss $ L2.L2DomainID tmpId) (L2.l2nsDomains l2nsc)
              }
          _ -> do
            -- It's a clonelike domain, so allocate an actual domain ID...
            newDomainID <- L2.l2NextDomain <$> getL2Model
            modifyL2Model $ \mod -> mod {
              L2.l2NextDomain = (\(L2.L2DomainID i) -> L2.L2DomainID (i + 1)) newDomainID,
              L2.l2AllDomains = M.insert newDomainID (L2.L2ClonelikeDomainContents nsss (dummyDT nsss) L2.L2DomainClone)
                                         (L2.l2AllDomains mod)
              }
            modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
              L2.l2nsDomains = M.insert nsname (dtRef nsss newDomainID) (L2.l2nsDomains l2nsc)
              }
      L1.L1NSNamedValue { L1.l1nsSS = nsss, L1.l1nsValueName = L1.L1Identifier _ nvname } -> do
        newValueID <- L2.l2NextValue <$> getL2Model
        modifyL2Model $ \mod -> mod {
          L2.l2NextValue = (\(L2.L2ValueID i) -> L2.L2ValueID (i + 1)) newValueID,
          L2.l2AllValues = M.insert newValueID (L2.L2ValueContents nsss Nothing)
                             (L2.l2AllValues mod)
          }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsNamedValues = M.insert nvname newValueID (L2.l2nsNamedValues l2nsc)
          }
      L1.L1NSClass { L1.l1nsSS = nsss, L1.l1nsClassName = L1.L1Identifier _ clname, L1.l1nsClassDomainFunctions = dfs, 
                     L1.l1nsClassValues = cvs, L1.l1nsClassParameters = p } -> do
        l2dfs <- forM dfs $ \(L1.L1Identifier dfss dfname, n) -> do
          newDFID <- L2.l2NextDomainFunctionID <$> getL2Model
          modifyL2Model $ \mod -> mod {
            L2.l2NextDomainFunctionID =
               (\(L2.L2DomainFunctionID i) -> L2.L2DomainFunctionID (i + 1)) newDFID,
            L2.l2AllDomainFunctions =
              M.insert newDFID (L2.L2DomainFunctionContents dfss n) (L2.l2AllDomainFunctions mod)
                                      }
          return (dfname, newDFID)
        l2cvs <- forM cvs $ \(L1.L1Identifier cvss cvname, _) -> do
          newCVID <- L2.l2NextClassValueID <$> getL2Model
          modifyL2Model $ \mod -> mod {
            L2.l2NextClassValueID =
               (\(L2.L2ClassValueID i) -> L2.L2ClassValueID (i + 1)) newCVID,
            L2.l2AllClassValues =
              M.insert newCVID (dummyCVC cvss) (L2.l2AllClassValues mod)
                                      }
          return (cvname, newCVID)
        newClassID <- L2.l2NextClassID <$> getL2Model
        l2p <- mapM (\(L1.L1ScopedID { L1.l1ScopedIdBS = sdName }, k) ->
                       (,)
                         <$> (do
                                 newSDID <- L2.l2NextScopedDomainID <$> getL2Model
                                 modifyL2Model $ \mod -> mod {
                                   L2.l2NextScopedDomainID =
                                      (\(L2.L2ScopedDomainID _ i) -> L2.L2ScopedDomainID "unnamed!" (i + 1))
                                      newSDID
                                                             }
                                 return (newSDID { L2.l2SDIDName = sdName })
                             ) <*> pure k) p
        modifyL2Model $ \mod -> mod {
          L2.l2NextClassID = (\(L2.L2ClassID i) -> L2.L2ClassID (i + 1)) newClassID,
          L2.l2AllClasses = M.insert newClassID (L2.L2ClassContents nsss l2p (M.fromList l2dfs) (M.fromList l2cvs))
                                     (L2.l2AllClasses mod)
          }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsClasses = M.insert clname newClassID (L2.l2nsClasses l2nsc),
          L2.l2nsDomainFunctions = foldl' (\s (dfname, dfid) -> M.insert dfname dfid s) (L2.l2nsDomainFunctions l2nsc) l2dfs,
          L2.l2nsClassValues = foldl' (\s (cvname, cvid) -> M.insert cvname cvid s) (L2.l2nsClassValues l2nsc) l2cvs
          }
      L1.L1NSEnsemble { L1.l1nsLabels = labs } ->
        forM_ labs $ \(L1.L1Identifier labss lab) -> do
          modifyNamespaceContents myNSID $ \l2nsc ->
            let
              newLabel = L2.l2nsNextLabel l2nsc
            in
             l2nsc { L2.l2nsNextLabel = newLabel + 1,
                     L2.l2nsLabels = M.insert lab (L2.L2Label myNSID (fromIntegral newLabel)) (L2.l2nsLabels l2nsc) }
      L1.L1NSUnit { L1.l1nsSS = nsss, L1.l1nsUnitName = L1.L1Identifier _ uname } -> do
        tmpId <- mtsNextTempId <$> get
        modify $ \mts -> mts { mtsNextTempId = tmpId - 1 }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
              L2.l2nsUnits = M.insert uname (L2.L2UnitExRef nsss (L2.L2BaseUnitsID tmpId))
                                            (L2.l2nsUnits l2nsc)
              }
      _ -> return ()

-- | Recursively imports symbols into namespaces from other models (leaving local
--   imports alone).
--   ns is the namespace we are requesting be processed now.
--   This imports everything (not just namespaces) required in this namespace from
--   other files, allowing all further processing to focus on the contents of this file.
buildSkeletonModel ss nsc@(L1.L1NamespaceContents c) myNSID = do
  let dtRef ss x = L2.L2DomainReference ss x
  let dummyDT ss = dtRef ss (L2.L2DomainID 0)
  let dummyCVC ss = L2.L2ClassValueContents ss (dummyDT ss)

  -- TODO - check for name conflicts.
  forM_ c $ \nsel ->
    case nsel of
      L1.L1NSNamespace { L1.l1nsSS = nsss, L1.l1nsNamespaceName = L1.L1Identifier _ nsname,
                         L1.l1nsNamespaceContents = newnsc } -> do
        newNSID <- registerNewNamespace nsss myNSID newnsc
        newLabel <- L2.l2nsNextLabel <$> getNamespaceContents "bsm nextLabel" myNSID
        -- Debug.Trace.trace ("Adding Label#" ++ show newLabel ++ " into " ++ show myNSID ++ " for " ++ (show nsname)) (return ())
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsNamespaces = M.insert nsname newNSID (L2.l2nsNamespaces l2nsc),
          L2.l2nsLabels = M.insert nsname (L2.L2Label myNSID (fromIntegral newLabel)) (L2.l2nsLabels l2nsc),
          L2.l2nsNextLabel = newLabel + 1
             }
        tmpId <- mtsNextTempId <$> get
        modify $ \mts -> mts { mtsNextTempId = tmpId - 1 }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsDomains = M.insert nsname (dtRef nsss $ L2.L2DomainID tmpId) (L2.l2nsDomains l2nsc)
          }

        buildSkeletonModel nsss newnsc newNSID
      L1.L1NSDomain { L1.l1nsSS = nsss, L1.l1nsDomainName = L1.L1Identifier _ nsname,
                      L1.l1nsNamespaceContents = newnsc, 
                      L1.l1nsDomainDefinition = dd } -> do
        newNSID <- registerNewNamespace nsss myNSID newnsc
        newLabel <- L2.l2nsNextLabel <$> getNamespaceContents "bsm domain nextlabel" myNSID
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsNamespaces = M.insert nsname newNSID (L2.l2nsNamespaces l2nsc),
          L2.l2nsLabels = M.insert nsname (L2.L2Label myNSID (fromIntegral newLabel)) (L2.l2nsLabels l2nsc),
          L2.l2nsNextLabel = newLabel + 1
             }
        buildSkeletonModel nsss newnsc newNSID
        case dd of
          L1.L1DomainDefDomainType ddss _ -> do
            -- It is an alias, but we aren't ready to process the alias yet,
            -- so we allocate a temporary ID...
            tmpId <- mtsNextTempId <$> get
            modify $ \mts -> mts { mtsNextTempId = tmpId - 1 }
            modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
              L2.l2nsDomains = M.insert nsname (dtRef ddss $ L2.L2DomainID tmpId) (L2.l2nsDomains l2nsc)
              }
          _ -> do
            -- It's a clonelike domain, so allocate an actual domain ID...
            newDomainID <- L2.l2NextDomain <$> getL2Model
            modifyL2Model $ \mod -> mod {
              L2.l2NextDomain = (\(L2.L2DomainID i) -> L2.L2DomainID (i + 1)) newDomainID,
              L2.l2AllDomains = M.insert newDomainID (L2.L2ClonelikeDomainContents nsss (dummyDT nsss) L2.L2DomainClone)
                                         (L2.l2AllDomains mod)
              }
            modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
              L2.l2nsDomains = M.insert nsname (dtRef nsss newDomainID) (L2.l2nsDomains l2nsc)
              }
      L1.L1NSNamedValue { L1.l1nsSS = nsss, L1.l1nsValueName = L1.L1Identifier _ nvname } -> do
        newValueID <- L2.l2NextValue <$> getL2Model
        modifyL2Model $ \mod -> mod {
          L2.l2NextValue = (\(L2.L2ValueID i) -> L2.L2ValueID (i + 1)) newValueID,
          L2.l2AllValues = M.insert newValueID (L2.L2ValueContents nsss Nothing)
                             (L2.l2AllValues mod)
          }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsNamedValues = M.insert nvname newValueID (L2.l2nsNamedValues l2nsc)
          }
      L1.L1NSClass { L1.l1nsSS = nsss, L1.l1nsClassName = L1.L1Identifier _ clname, L1.l1nsClassDomainFunctions = dfs, 
                     L1.l1nsClassValues = cvs, L1.l1nsClassParameters = p } -> do
        l2dfs <- forM dfs $ \(L1.L1Identifier dfss dfname, n) -> do
          newDFID <- L2.l2NextDomainFunctionID <$> getL2Model
          modifyL2Model $ \mod -> mod {
            L2.l2NextDomainFunctionID =
               (\(L2.L2DomainFunctionID i) -> L2.L2DomainFunctionID (i + 1)) newDFID,
            L2.l2AllDomainFunctions =
              M.insert newDFID (L2.L2DomainFunctionContents dfss n) (L2.l2AllDomainFunctions mod)
                                      }
          return (dfname, newDFID)
        l2cvs <- forM cvs $ \(L1.L1Identifier cvss cvname, _) -> do
          newCVID <- L2.l2NextClassValueID <$> getL2Model
          modifyL2Model $ \mod -> mod {
            L2.l2NextClassValueID =
               (\(L2.L2ClassValueID i) -> L2.L2ClassValueID (i + 1)) newCVID,
            L2.l2AllClassValues =
              M.insert newCVID (dummyCVC cvss) (L2.l2AllClassValues mod)
                                      }
          return (cvname, newCVID)
        newClassID <- L2.l2NextClassID <$> getL2Model
        l2p <- mapM (\(L1.L1ScopedID { L1.l1ScopedIdBS = sdName }, k) ->
                       (,)
                         <$> (do
                                 newSDID <- L2.l2NextScopedDomainID <$> getL2Model
                                 modifyL2Model $ \mod -> mod {
                                   L2.l2NextScopedDomainID =
                                      (\(L2.L2ScopedDomainID _ i) -> L2.L2ScopedDomainID "unnamed!" (i + 1))
                                      newSDID
                                                             }
                                 return (newSDID { L2.l2SDIDName = sdName })
                             ) <*> pure k) p
        modifyL2Model $ \mod -> mod {
          L2.l2NextClassID = (\(L2.L2ClassID i) -> L2.L2ClassID (i + 1)) newClassID,
          L2.l2AllClasses = M.insert newClassID (L2.L2ClassContents nsss l2p (M.fromList l2dfs) (M.fromList l2cvs))
                                     (L2.l2AllClasses mod)
          }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsClasses = M.insert clname newClassID (L2.l2nsClasses l2nsc),
          L2.l2nsDomainFunctions = foldl' (\s (dfname, dfid) -> M.insert dfname dfid s) (L2.l2nsDomainFunctions l2nsc) l2dfs,
          L2.l2nsClassValues = foldl' (\s (cvname, cvid) -> M.insert cvname cvid s) (L2.l2nsClassValues l2nsc) l2cvs
          }
      L1.L1NSEnsemble { L1.l1nsLabels = labs } ->
        forM_ labs $ \(L1.L1Identifier labss lab) -> do
          modifyNamespaceContents myNSID $ \l2nsc ->
            let
              newLabel = L2.l2nsNextLabel l2nsc
            in
             l2nsc { L2.l2nsNextLabel = newLabel + 1,
                     L2.l2nsLabels = M.insert lab (L2.L2Label myNSID (fromIntegral newLabel)) (L2.l2nsLabels l2nsc) }
      L1.L1NSUnit { L1.l1nsSS = nsss, L1.l1nsUnitName = L1.L1Identifier _ uname } -> do
        tmpId <- mtsNextTempId <$> get
        modify $ \mts -> mts { mtsNextTempId = tmpId - 1 }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
              L2.l2nsUnits = M.insert uname (L2.L2UnitExRef nsss (L2.L2BaseUnitsID tmpId))
                                            (L2.l2nsUnits l2nsc)
              }
      _ -> return ()

-- | Recursively imports symbols into namespaces from other models (leaving local
--   imports alone).
--   ns is the namespace we are requesting be processed now.
--   This imports everything (not just namespaces) required in this namespace from
--   other files, allowing all further processing to focus on the contents of this file.
buildSkeletonModel ss nsc@(L1.L1NamespaceContents c) myNSID = do
  let dtRef ss x = L2.L2DomainReference ss x
  let dummyDT ss = dtRef ss (L2.L2DomainID 0)
  let dummyCVC ss = L2.L2ClassValueContents ss (dummyDT ss)

  -- TODO - check for name conflicts.
  forM_ c $ \nsel ->
    case nsel of
      L1.L1NSNamespace { L1.l1nsSS = nsss, L1.l1nsNamespaceName = L1.L1Identifier _ nsname,
                         L1.l1nsNamespaceContents = newnsc } -> do
        newNSID <- registerNewNamespace nsss myNSID newnsc
        newLabel <- L2.l2nsNextLabel <$> getNamespaceContents "bsm nextLabel" myNSID
        -- Debug.Trace.trace ("Adding Label#" ++ show newLabel ++ " into " ++ show myNSID ++ " for " ++ (show nsname)) (return ())
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsNamespaces = M.insert nsname newNSID (L2.l2nsNamespaces l2nsc),
          L2.l2nsLabels = M.insert nsname (L2.L2Label myNSID (fromIntegral newLabel)) (L2.l2nsLabels l2nsc),
          L2.l2nsNextLabel = newLabel + 1
             }
        tmpId <- mtsNextTempId <$> get
        modify $ \mts -> mts { mtsNextTempId = tmpId - 1 }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsDomains = M.insert nsname (dtRef nsss $ L2.L2DomainID tmpId) (L2.l2nsDomains l2nsc)
          }

        buildSkeletonModel nsss newnsc newNSID
      L1.L1NSDomain { L1.l1nsSS = nsss, L1.l1nsDomainName = L1.L1Identifier _ nsname,
                      L1.l1nsNamespaceContents = newnsc, 
                      L1.l1nsDomainDefinition = dd } -> do
        newNSID <- registerNewNamespace nsss myNSID newnsc
        newLabel <- L2.l2nsNextLabel <$> getNamespaceContents "bsm domain nextlabel" myNSID
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsNamespaces = M.insert nsname newNSID (L2.l2nsNamespaces l2nsc),
          L2.l2nsLabels = M.insert nsname (L2.L2Label myNSID (fromIntegral newLabel)) (L2.l2nsLabels l2nsc),
          L2.l2nsNextLabel = newLabel + 1
             }
        buildSkeletonModel nsss newnsc newNSID
        case dd of
          L1.L1DomainDefDomainType ddss _ -> do
            -- It is an alias, but we aren't ready to process the alias yet,
            -- so we allocate a temporary ID...
            tmpId <- mtsNextTempId <$> get
            modify $ \mts -> mts { mtsNextTempId = tmpId - 1 }
            modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
              L2.l2nsDomains = M.insert nsname (dtRef ddss $ L2.L2DomainID tmpId) (L2.l2nsDomains l2nsc)
              }
          _ -> do
            -- It's a clonelike domain, so allocate an actual domain ID...
            newDomainID <- L2.l2NextDomain <$> getL2Model
            modifyL2Model $ \mod -> mod {
              L2.l2NextDomain = (\(L2.L2DomainID i) -> L2.L2DomainID (i + 1)) newDomainID,
              L2.l2AllDomains = M.insert newDomainID (L2.L2ClonelikeDomainContents nsss (dummyDT nsss) L2.L2DomainClone)
                                         (L2.l2AllDomains mod)
              }
            modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
              L2.l2nsDomains = M.insert nsname (dtRef nsss newDomainID) (L2.l2nsDomains l2nsc)
              }
      L1.L1NSNamedValue { L1.l1nsSS = nsss, L1.l1nsValueName = L1.L1Identifier _ nvname } -> do
        newValueID <- L2.l2NextValue <$> getL2Model
        modifyL2Model $ \mod -> mod {
          L2.l2NextValue = (\(L2.L2ValueID i) -> L2.L2ValueID (i + 1)) newValueID,
          L2.l2AllValues = M.insert newValueID (L2.L2ValueContents nsss Nothing)
                             (L2.l2AllValues mod)
          }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsNamedValues = M.insert nvname newValueID (L2.l2nsNamedValues l2nsc)
          }
      L1.L1NSClass { L1.l1nsSS = nsss, L1.l1nsClassName = L1.L1Identifier _ clname, L1.l1nsClassDomainFunctions = dfs, 
                     L1.l1nsClassValues = cvs, L1.l1nsClassParameters = p } -> do
        l2dfs <- forM dfs $ \(L1.L1Identifier dfss dfname, n) -> do
          newDFID <- L2.l2NextDomainFunctionID <$> getL2Model
          modifyL2Model $ \mod -> mod {
            L2.l2NextDomainFunctionID =
               (\(L2.L2DomainFunctionID i) -> L2.L2DomainFunctionID (i + 1)) newDFID,
            L2.l2AllDomainFunctions =
              M.insert newDFID (L2.L2DomainFunctionContents dfss n) (L2.l2AllDomainFunctions mod)
                                      }
          return (dfname, newDFID)
        l2cvs <- forM cvs $ \(L1.L1Identifier cvss cvname, _) -> do
          newCVID <- L2.l2NextClassValueID <$> getL2Model
          modifyL2Model $ \mod -> mod {
            L2.l2NextClassValueID =
               (\(L2.L2ClassValueID i) -> L2.L2ClassValueID (i + 1)) newCVID,
            L2.l2AllClassValues =
              M.insert newCVID (dummyCVC cvss) (L2.l2AllClassValues mod)
                                      }
          return (cvname, newCVID)
        newClassID <- L2.l2NextClassID <$> getL2Model
        l2p <- mapM (\(L1.L1ScopedID { L1.l1ScopedIdBS = sdName }, k) ->
                       (,)
                         <$> (do
                                 newSDID <- L2.l2NextScopedDomainID <$> getL2Model
                                 modifyL2Model $ \mod -> mod {
                                   L2.l2NextScopedDomainID =
                                      (\(L2.L2ScopedDomainID _ i) -> L2.L2ScopedDomainID "unnamed!" (i + 1))
                                      newSDID
                                                             }
                                 return (newSDID { L2.l2SDIDName = sdName })
                             ) <*> pure k) p
        modifyL2Model $ \mod -> mod {
          L2.l2NextClassID = (\(L2.L2ClassID i) -> L2.L2ClassID (i + 1)) newClassID,
          L2.l2AllClasses = M.insert newClassID (L2.L2ClassContents nsss l2p (M.fromList l2dfs) (M.fromList l2cvs))
                                     (L2.l2AllClasses mod)
          }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
          L2.l2nsClasses = M.insert clname newClassID (L2.l2nsClasses l2nsc),
          L2.l2nsDomainFunctions = foldl' (\s (dfname, dfid) -> M.insert dfname dfid s) (L2.l2nsDomainFunctions l2nsc) l2dfs,
          L2.l2nsClassValues = foldl' (\s (cvname, cvid) -> M.insert cvname cvid s) (L2.l2nsClassValues l2nsc) l2cvs
          }
      L1.L1NSEnsemble { L1.l1nsLabels = labs } ->
        forM_ labs $ \(L1.L1Identifier labss lab) -> do
          modifyNamespaceContents myNSID $ \l2nsc ->
            let
              newLabel = L2.l2nsNextLabel l2nsc
            in
             l2nsc { L2.l2nsNextLabel = newLabel + 1,
                     L2.l2nsLabels = M.insert lab (L2.L2Label myNSID (fromIntegral newLabel)) (L2.l2nsLabels l2nsc) }
      L1.L1NSUnit { L1.l1nsSS = nsss, L1.l1nsUnitName = L1.L1Identifier _ uname } -> do
        tmpId <- mtsNextTempId <$> get
        modify $ \mts -> mts { mtsNextTempId = tmpId - 1 }
        modifyNamespaceContents myNSID $ \l2nsc -> l2nsc {
              L2.l2nsUnits = M.insert uname (L2.L2UnitExRef nsss (L2.L2BaseUnitsID tmpId))
                                            (L2.l2nsUnits l2nsc)
              }
      _ -> return ()

-- | Recursively imports symbols into namespaces from other models (leaving local
--   imports alone).
--   ns is the namespace we are requesting be processed now.
--   This imports everything (not just namespaces) required in this namespace from
--   other files, allowing all further processing to focus on the contents of this file.