code: def replace(self, nodes, node):
          
          nodes = nodes if isinstance(nodes, list) else [nodes]
          # Is the new node part of the replace nodes (i.e. want to collapse
          # a group of nodes into one of them)?
          collapse = self.id(node) in self.nodes
          # Add new node and edges
          if not collapse:
              self.add_node(node)
          for in_node in self.incoming(nodes):
              # TODO: check specifically for output_shape is not generic. Consider refactoring.
              self.add_edge(in_node, node, in_node.output_shape if hasattr(in_node, "output_shape") else None)
          for out_node in self.outgoing(nodes):
              self.add_edge(node, out_node, node.output_shape if hasattr(node, "output_shape") else None)
          # Remove the old nodes
          for n in nodes:
              if collapse and n == node:
                  continue
              self.remove(n)
docs: Replace nodes with node. Edges incoming to nodes[0] are connected to
          the new node, and nodes outgoing from nodes[-1] become outgoing from
          the new node.