'Duplicate currently selected nodes.'

def __duplicateSelected(self):

    def copy_node(node):
        (x, y) = node.position
        return SchemeNode(node.description, node.title, position=((x + 20), (y + 20)), properties=copy.deepcopy(node.properties))
    def copy_link(link, source=None, sink=None):
        source = (link.source_node if (source is None) else source)
        sink = (link.sink_node if (sink is None) else sink)
        return SchemeLink(source, link.source_channel, sink, link.sink_channel, enabled=link.enabled, properties=copy.deepcopy(link.properties))
    scheme = self.scheme()
    scheme.sync_node_properties()
    selection = self.selectedNodes()
    links = [link for link in scheme.links if ((link.source_node in selection) and (link.sink_node in selection))]
    nodedups = [copy_node(node) for node in selection]
    allnames = {node.title for node in (scheme.nodes + nodedups)}
    for nodedup in nodedups:
        nodedup.title = uniquify(nodedup.title, allnames, pattern='{item}    ({_})', start=1)
    node_to_dup = dict(zip(selection, nodedups))
    linkdups = [copy_link(link, source=node_to_dup[link.source_node], sink=node_to_dup[link.sink_node]) for link in links]
    command = QUndoCommand(self.tr('Duplicate'))
    macrocommands = []
    for nodedup in nodedups:
        macrocommands.append(commands.AddNodeCommand(scheme, nodedup, parent=command))
    for linkdup in linkdups:
        macrocommands.append(commands.AddLinkCommand(scheme, linkdup, parent=command))
    self.__undoStack.push(command)
    scene = self.__scene
    for node in selection:
        item = scene.item_for_node(node)
        item.setSelected(False)
    for node in nodedups:
        item = scene.item_for_node(node)
        item.setSelected(True)
