def UnitToLNode(u: Unit, node: Optional[LNode]=None,
                toL: Optional[dict]=None,
                optimizations=[]) -> LNode:
    if toL is None:
        toL = {}
    if node is None:
        root = LNode(name=u._name, originObj=u, node2lnode=toL)
    else:
        root = node
    stmPorts = {}
    netCtx = NetCtxs(root)
    for su in u._units:
        n = root.addNode(name=su._name, originObj=su)
        UnitToLNode(su, n, toL, optimizations)
    for stm in u._ctx.statements:
        n = addStmAsLNode(root, stm, stmPorts, netCtx)
    for intf in u._interfaces:
        addPort(root, intf)
    for stm in u._ctx.statements:
        n = toL.get(stm, None)
        if n is not None:
            if isinstance(n, VirtualLNode):
                p = None
            else:
                p = stmPorts[n]
            r = StatementRenderer(n, toL, p, netCtx)
            r.renderContent()
    for s in u._ctx.signals:
        if not s.hidden:
            net, _ = netCtx.getDefault(s)
            for e in s.endpoints:
                if isinstance(e, PortItem):
                    net.addEndpoint(toL[e])
            for d in s.drivers:
                if isinstance(d, PortItem):
                    net.addDriver(toL[d])
    netCtx.applyConnections(root)
    for opt in optimizations:
        opt(root)
    isRootOfWholeGraph = root.parent is None
    if not isRootOfWholeGraph:
        for intf in u._interfaces:
            ext_p = toL[originObjOfPort(intf)].parentNode
            nodePort = addPortToLNode(root, intf)
            if intf._direction == INTF_DIRECTION.SLAVE:
                src = nodePort
                dst = ext_p.addPort("", PortType.INPUT, PortSide.WEST)
            else:
                src = ext_p.addPort("", PortType.OUTPUT, PortSide.EAST)
                dst = nodePort
            root.addEdge(src, dst, name=repr(intf), originObj=intf)
    return root