private static void ConvertToEmbed()
        {
            var selection = GraphWindow.active?.reference?.graph?.Canvas().selection;

            if (selection != null && selection.Count > 0)
            {
                Undo.RegisterCompleteObjectUndo(GraphWindow.active?.reference.rootObject, "Add Sub Graph to Script Graph");

                var superUnit       = new NestedNode();
                var superUnitGraph  = new FlowGraph();
                var superUnitCanvas = superUnitGraph.Canvas <FlowCanvas>();
                var elements        = selection.ToList();

                superUnit.position = GetNestedNodePosition(elements);

                ((FlowGraph)GraphWindow.active.reference.graph).units.Add(superUnit);

                superUnit.nest.SwitchToEmbed(superUnitGraph);

                CopyElementsToGraph(superUnitCanvas);

                var graphInput  = new GraphInput();
                var graphOutput = new GraphOutput();

                var listWithoutInputOutput = ((FlowGraph)GraphWindow.active.reference.graph).units.ToList();

                superUnitGraph.units.Add(graphInput);
                superUnitGraph.units.Add(graphOutput);

                CopyControlConnectionData(superUnitGraph, graphInput, graphOutput, GetControlIndices(selection, superUnit));
                CopyValueConnectionData(superUnitGraph, graphInput, graphOutput, GetValueIndices(selection, superUnit));
                CopyInvalidConnectionData(superUnitGraph, graphInput, graphOutput, GetInvalidIndices(selection, superUnit));

                SetInputOutputPosition(superUnitGraph, graphInput, graphOutput);

                superUnitGraph.pan = superUnit.position;

                RemoveUnusedDefinitions(superUnitGraph);

                superUnitGraph.PortDefinitionsChanged();

                GraphWindow.active.reference.graph.Canvas <FlowCanvas>().DeleteSelection();
                GraphWindow.active.reference.graph.Canvas <FlowCanvas>().selection.Add(superUnit);
            }
        }
        private static List <ConnectionData> GetInvalidIndices(GraphSelection selection, NestedNode superUnit)
        {
            List <ConnectionData> invalidConnectionData = new List <ConnectionData>();
            var original = GraphWindow.active.reference.graph as FlowGraph;
            var units    = selection.ToListPooled();

            var invalidConnections = original.invalidConnections.Where((connection) =>
            {
                return(connection.sourceExists &&
                       connection.destinationExists &&
                       selection.Contains(connection.source.unit) &&
                       selection.Contains(connection.destination.unit));
            }).ToList();

            for (int i = 0; i < invalidConnections.Count; i++)
            {
                var connection  = invalidConnections[i];
                var connections = connection.graph.invalidConnections.ToList();
                invalidConnectionData.Add(
                    new ConnectionData()
                {
                    sourceUnitIndex       = units.ToList().IndexOf(connection.source.unit),
                    sourceOutputIndex     = connection.source.unit.outputs.ToList().IndexOf(connection.source),
                    destinationUnitIndex  = units.ToList().IndexOf(connection.destination.unit),
                    destinationInputIndex = connection.destination.unit.inputs.ToList().IndexOf(connection.destination)
                }
                    );
            }

            return(invalidConnectionData);
        }
        private static List <ConnectionData> GetValueIndices(GraphSelection selection, NestedNode superUnit)
        {
            List <ConnectionData> valueConnectionData = new List <ConnectionData>();
            var original = GraphWindow.active.reference.graph as FlowGraph;
            var units    = selection.Where((element) => { return(element.GetType() != typeof(GraphGroup)); }).ToListPooled();

            var valueConnections = original.valueConnections.Where((connection) =>
            {
                return(connection.sourceExists &&
                       connection.destinationExists &&
                       selection.Contains(connection.source.unit) &&
                       selection.Contains(connection.destination.unit));
            }).ToList();

            var valueConnectionsForInput = original.valueConnections.Where((connection) =>
            {
                return(connection.sourceExists &&
                       connection.destinationExists &&
                       !selection.Contains(connection.source.unit) &&
                       selection.Contains(connection.destination.unit));
            }).ToList();

            var valueConnectionsForOutput = original.valueConnections.Where((connection) =>
            {
                return(connection.sourceExists &&
                       connection.destinationExists &&
                       selection.Contains(connection.source.unit) &&
                       !selection.Contains(connection.destination.unit));
            }).ToList();

            for (int i = 0; i < valueConnections.Count; i++)
            {
                var connection  = valueConnections[i];
                var connections = connection.graph.valueConnections.ToList();
                valueConnectionData.Add(
                    new ConnectionData()
                {
                    sourceUnitIndex       = units.ToList().IndexOf(connection.source.unit),
                    sourceOutputIndex     = connection.source.unit.valueOutputs.ToList().IndexOf(connection.source),
                    source                = ConnectionDataSource.Node,
                    subgraph              = superUnit,
                    destinationUnitIndex  = units.ToList().IndexOf(connection.destination.unit),
                    destinationInputIndex = connection.destination.unit.valueInputs.ToList().IndexOf(connection.destination)
                }
                    );
            }

            for (int i = 0; i < valueConnectionsForInput.Count; i++)
            {
                var connection  = valueConnectionsForInput[i];
                var connections = connection.graph.valueConnections.ToList();
                valueConnectionData.Add(
                    new ConnectionData()
                {
                    sourceUnitIndex   = units.ToList().IndexOf(connection.source.unit),
                    sourceOutputIndex = connection.source.unit.valueOutputs.ToList().IndexOf(connection.source),
                    key                   = valueConnectionsForInput[i].destination.key,
                    valueType             = valueConnectionsForInput[i].destination.type,
                    source                = ConnectionDataSource.GraphInput,
                    subgraph              = superUnit,
                    externalPort          = valueConnectionsForInput[i].source,
                    destinationUnitIndex  = units.ToList().IndexOf(connection.destination.unit),
                    destinationInputIndex = connection.destination.unit.valueInputs.ToList().IndexOf(connection.destination)
                }
                    );
            }

            for (int i = 0; i < valueConnectionsForOutput.Count; i++)
            {
                var connection  = valueConnectionsForOutput[i];
                var connections = connection.graph.valueConnections.ToList();
                valueConnectionData.Add(
                    new ConnectionData()
                {
                    sourceUnitIndex   = units.ToList().IndexOf(connection.source.unit),
                    sourceOutputIndex = connection.source.unit.valueOutputs.ToList().IndexOf(connection.source),
                    key                   = valueConnectionsForOutput[i].source.key,
                    valueType             = valueConnectionsForOutput[i].source.type,
                    source                = ConnectionDataSource.GraphOutput,
                    subgraph              = superUnit,
                    externalPort          = valueConnectionsForOutput[i].destination,
                    destinationUnitIndex  = units.ToList().IndexOf(connection.destination.unit),
                    destinationInputIndex = connection.destination.unit.valueInputs.ToList().IndexOf(connection.destination)
                }
                    );
            }

            return(valueConnectionData);
        }