docs: def reconnectPorts(root: LNode, srcPort: LPort,
                     oldSplits: List[Tuple[LNode, LEdge]],
                     newSplitNode: LNode):
      """
      :ivar root: top LNode instance in which are nodes and links stored
      :ivar srcPort: for SLICE it is port which is connected to input of SLICE node
          for CONCAT it is port which is connected to output of CONCAT
      :ivar oldSplits: list of tuples (node, edge) which should be disconnected from graph
      :ivar newSplitNode: new node which should be connected to graph
      """
      # sort oldSplit nodes because they are not in same order as signals on
      # ports
      mainPortSignals = list(walkSignalPorts(srcPort))
      portOrder = {p: i for i, p in enumerate(mainPortSignals)}
      isOneToN = len(newSplitNode.west) == 1
  
      def portSortKey(x):
          n, e = x
          if e.dstNode is n:
              return portOrder[e.src]
          elif e.srcNode is n:
              return portOrder[e.dst]
          else:
              raise ValueError("Edge not connected to split node", e, n)
  
      oldSplits.sort(key=portSortKey)
      newSplitPorts = [walkSignalPorts(p) for p in
                       (newSplitNode.east if isOneToN else newSplitNode.west)]
  
      if isOneToN:
          newMainPort = newSplitNode.west[0]
      else:
          newMainPort = newSplitNode.east[0]
  
      for mainPort, splitInp, (oldSplitNode, e) in zip(
              mainPortSignals,
              walkSignalPorts(newMainPort),
              oldSplits):
          assert mainPort.direction != splitInp.direction, (
              mainPort, splitInp)
  
          # reconnect edge from src port to split node
          assert (e.src is mainPort and e.dstNode is oldSplitNode)\
              or (e.dst is mainPort and e.srcNode is oldSplitNode), e
          e.remove()
  
          _newSplitPorts = [next(p) for p in newSplitPorts]
          # reconnect part from split node to other target nodes
          if oldSplitNode.name == "CONCAT":
              root.addEdge(splitInp, mainPort,
                           originObj=e.originObj)
  
              for oldP, newP in zip(oldSplitNode.west, _newSplitPorts):
                  for e in list(oldP.incomingEdges):
                      root.addEdge(e.src, newP, originObj=e.originObj)
                      e.remove()
  
          elif oldSplitNode.name == "SLICE":
              root.addEdge(mainPort, splitInp,
                           originObj=e.originObj)
  
              for oldP, newP in zip(oldSplitNode.east, reversed(_newSplitPorts)):
                  for e in list(oldP.outgoingEdges):
                      root.addEdge(newP, e.dst, originObj=e.originObj)
                      e.remove()
          else:
              raise ValueError(oldSplitNode)
  
          root.children.remove(oldSplitNode)