reflectIdsFromDomains :: (TypedGraphMorphism a b, TypedGraphMorphism a b) -> (TypedGraphMorphism a b, TypedGraphMorphism a b)
reflectIdsFromDomains (m,e) =
  let
    typedL = domainGraph m
    typedD = domainGraph e
    typedG = codomainGraph m
    typeGraph = GM.codomainGraph typedL
    m' = invert m
    e' = invert e

    newNodes = nubBy ((==) `on` (nodeId . fst)) (nodes typedL ++ nodes typedD)
    newEdges = nubBy ((==) `on` (edgeId . fst)) (edges typedL ++ edges typedD)

    typedG' = fromNodesAndEdges typeGraph newNodes newEdges
    nodeR n = if isJust (applyNodeId m' n) then (n, applyNodeIdUnsafe m' n) else (n, applyNodeIdUnsafe e' n)
    edgeR e = if isJust (applyEdgeId m' e) then (e, applyEdgeIdUnsafe m' e) else (e, applyEdgeIdUnsafe e' e)

    h' = fromGraphsAndLists typedG typedG'
            (map nodeR . nodeIds $ domainGraph m')
            (map edgeR . edgeIds $ domainGraph m')
   in (compose h' m, compose h' e)
reflectIdsFromDomains :: (TypedGraphMorphism a b, TypedGraphMorphism a b) -> (TypedGraphMorphism a b, TypedGraphMorphism a b)
reflectIdsFromDomains (m,e) =
  let
    typedL = domainGraph m
    typedD = domainGraph e
    typedG = codomainGraph m
    typeGraph = GM.codomainGraph typedL
    m' = invert m
    e' = invert e

    newNodes = nubBy ((==) `on` (nodeId . fst)) (nodes typedL ++ nodes typedD)
    newEdges = nubBy ((==) `on` (edgeId . fst)) (edges typedL ++ edges typedD)

    typedG' = fromNodesAndEdges typeGraph newNodes newEdges
    nodeR n = if isJust (applyNodeId m' n) then (n, applyNodeIdUnsafe m' n) else (n, applyNodeIdUnsafe e' n)
    edgeR e = if isJust (applyEdgeId m' e) then (e, applyEdgeIdUnsafe m' e) else (e, applyEdgeIdUnsafe e' e)

    h' = fromGraphsAndLists typedG typedG'
            (map nodeR . nodeIds $ domainGraph m')
            (map edgeR . edgeIds $ domainGraph m')
   in (compose h' m, compose h' e)
reflectIdsFromDomains (m,e) =
  let
    typedL = domainGraph m
    typedD = domainGraph e
    typedG = codomainGraph m
    typeGraph = GM.codomainGraph typedL
    m' = invert m
    e' = invert e

    newNodes = nubBy ((==) `on` (nodeId . fst)) (nodes typedL ++ nodes typedD)
    newEdges = nubBy ((==) `on` (edgeId . fst)) (edges typedL ++ edges typedD)

    typedG' = fromNodesAndEdges typeGraph newNodes newEdges
    nodeR n = if isJust (applyNodeId m' n) then (n, applyNodeIdUnsafe m' n) else (n, applyNodeIdUnsafe e' n)
    edgeR e = if isJust (applyEdgeId m' e) then (e, applyEdgeIdUnsafe m' e) else (e, applyEdgeIdUnsafe e' e)

    h' = fromGraphsAndLists typedG typedG'
            (map nodeR . nodeIds $ domainGraph m')
            (map edgeR . edgeIds $ domainGraph m')
   in (compose h' m, compose h' e)