public static void DuplicateNodeOrNodes(NodeEditorInputInfo inputInfo)
        {
            if (inputInfo.editorState.selectedNode == null && NodeEditor.curEditorState.selectedNodes.Count == 0)
            {
                return;
            }
            inputInfo.SetAsCurrentEnvironment();
            NodeEditorState state = inputInfo.editorState;

            if (inputInfo.editorState.selectedNode != null && !NodeEditor.curEditorState.selectedNodes.Contains(inputInfo.editorState.selectedNode))
            {
                NodeEditor.curEditorState.selectedNodes.Add(inputInfo.editorState.selectedNode);
            }

            {
//                if(m_CacheOff!=null)
//                    m_CacheOff();

                Dictionary <Node, Node> nodeMap     = new Dictionary <Node, Node>();
                List <Node>             newSelected = new List <Node>();
                foreach (var n in NodeEditor.curEditorState.selectedNodes)
                {
                    Node duplicated = Node.Create(n.GetID, n.rect.center, null, false);   //state.connectOutput);
//                    Debug.Log("dupe n "+n);
                    duplicated.CloneFieldsFrom(n);
                    state.selectedNode = state.focusedNode = duplicated;
                    newSelected.Add(duplicated);
                    nodeMap.Add(n, duplicated);
                }
                //handle connections
                foreach (var n in NodeEditor.curEditorState.selectedNodes)
                {
                    for (int index = 0; index < n.Inputs.Count; index++)
                    {
                        NodeInput nodeInput = n.Inputs[index];
                        if (nodeInput.connection != null)
                        {
                            Node connectTo = nodeInput.connection.body;
                            if (nodeMap.ContainsKey(nodeInput.connection.body))
                            {
                                connectTo = nodeMap[nodeInput.connection.body];
                            }

                            foreach (NodeOutput on in connectTo.Outputs)
                            {
                                if (on.name == nodeInput.connection.name)
                                {
                                    if (index < nodeMap[n].Inputs.Count)
                                    {
                                        nodeMap[n].Inputs[index].ApplyConnection(on);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    for (int index = 0; index < n.Outputs.Count; index++)
                    {
                        NodeOutput nodeOutput = n.Outputs[index];

                        for (int index1 = 0; index1 < nodeOutput.connections.Count; index1++)
                        {
                            NodeInput nodeInput = nodeOutput.connections[index1];
                            if (nodeInput == null)
                            {
                                continue;
                            }

                            Node connectTo = nodeInput.body;
                            if (nodeMap.ContainsKey(connectTo))
                            {
                                continue; //we did it allready
                            }
                            for (int i = 0; i < connectTo.Inputs.Count; i++)
                            {
                                NodeInput inputnode = connectTo.Inputs[i];
                                if (inputnode.name == nodeInput.name)
                                {
                                    inputnode.ApplyConnection(nodeOutput);
                                    break;
                                }
                            }
                        }
                    }
                }

                NodeEditor.curEditorState.selectedNodes.Clear();
                NodeEditor.curEditorState.selectedNodes = newSelected;
                NodeEditor.curEditorState.selectedNode  = newSelected[0];
//                foreach (var x in newSelected)
//                    Debug.Log(" selected node "+x);
//                if (m_CacheOn != null)
//                    m_CacheOn();
                NodeEditorCallbacks.IssueOnAddNode(NodeEditor.curEditorState.selectedNode); //just do it on one node, so it saves the canvas/repaints
            }

            state.connectOutput = null;

            if (m_FinishedDupe != null)
            {
                m_FinishedDupe();
            }
        }