-- | Produces a L2DomainType linking to a new L2ClonelikeDomainContents.
makeClonelikeDomain :: ScopeInformation -> L1.SrcSpan -> L2.L2NamespaceID ->
                       L1.L1DomainExpression -> (ScopeInformation -> ModelTranslation L2.L2DomainCloneType) ->
                       ModelTranslation L2.L2DomainExpression
makeClonelikeDomain scope ss nsid dt ct = do
  domID <- L2.l2NextDomain <$> getL2Model
  (domEx, scope') <- translateDomainExpressionCrossScope scope ss nsid dt
  cldc <- L2.L2ClonelikeDomainContents ss domEx
              <$> (ct scope')
  modifyL2Model $ \mod -> mod {
      L2.l2NextDomain = (\(L2.L2DomainID n) -> L2.L2DomainID (n + 1)) domID,
      L2.l2AllDomains = M.insert domID cldc (L2.l2AllDomains mod)
    }
  return $ L2.L2DomainReference ss domID

-- | Translates an L1DomainDefinition to an L2DomainType, registering new domains
--   as required for the definition.
makeClonelikeDomain :: ScopeInformation -> L1.SrcSpan -> L2.L2NamespaceID ->
                       L1.L1DomainExpression -> (ScopeInformation -> ModelTranslation L2.L2DomainCloneType) ->
                       ModelTranslation L2.L2DomainExpression
makeClonelikeDomain scope ss nsid dt ct = do
  domID <- L2.l2NextDomain <$> getL2Model
  (domEx, scope') <- translateDomainExpressionCrossScope scope ss nsid dt
  cldc <- L2.L2ClonelikeDomainContents ss domEx
              <$> (ct scope')
  modifyL2Model $ \mod -> mod {
      L2.l2NextDomain = (\(L2.L2DomainID n) -> L2.L2DomainID (n + 1)) domID,
      L2.l2AllDomains = M.insert domID cldc (L2.l2AllDomains mod)
    }
  return $ L2.L2DomainReference ss domID

-- | Translates an L1DomainDefinition to an L2DomainType, registering new domains
--   as required for the definition.
makeClonelikeDomain scope ss nsid dt ct = do
  domID <- L2.l2NextDomain <$> getL2Model
  (domEx, scope') <- translateDomainExpressionCrossScope scope ss nsid dt
  cldc <- L2.L2ClonelikeDomainContents ss domEx
              <$> (ct scope')
  modifyL2Model $ \mod -> mod {
      L2.l2NextDomain = (\(L2.L2DomainID n) -> L2.L2DomainID (n + 1)) domID,
      L2.l2AllDomains = M.insert domID cldc (L2.l2AllDomains mod)
    }
  return $ L2.L2DomainReference ss domID

-- | Translates an L1DomainDefinition to an L2DomainType, registering new domains
--   as required for the definition.