public void SetUp()
        {
            m_Window  = EditorWindow.GetWindowWithRect <VseWindow>(new Rect(Vector2.zero, new Vector2(800, 600)));
            m_Stencil = new ClassStencil();

            var AssetModel = ScriptableObject.CreateInstance <VSGraphAssetModel>();
            var graphModel = AssetModel.CreateGraph <VSGraphModel>("test", typeof(ClassStencil), false);

            var portModelMock = new Mock <IPortModel>();

            portModelMock.Setup(x => x.GraphModel).Returns(graphModel);
            portModelMock.Setup(x => x.PortType).Returns(PortType.Event);
            portModelMock.Setup(x => x.Direction).Returns(Direction.Input);
            portModelMock.Setup(x => x.Name).Returns("port");
            portModelMock.Setup(x => x.DataType).Returns(typeof(float).GenerateTypeHandle(m_Stencil));
            m_Port = Port.Create(portModelMock.Object, m_Window.Store, Orientation.Horizontal);

            VariableDeclarationModel intVariableModel = graphModel.CreateGraphVariableDeclaration(
                "int", typeof(int).GenerateTypeHandle(m_Stencil), false
                );
            VariableDeclarationModel stringVariableModel = graphModel.CreateGraphVariableDeclaration(
                "string", typeof(string).GenerateTypeHandle(m_Stencil), false
                );

            m_IntField    = new BlackboardVariableField(m_Window.Store, intVariableModel, m_Window.GraphView);
            m_StringField = new BlackboardVariableField(m_Window.Store, stringVariableModel, m_Window.GraphView);

            m_IntTokenModel = Activator.CreateInstance <VariableNodeModel>();
            m_IntTokenModel.DeclarationModel = intVariableModel;
            m_IntTokenModel.GraphModel       = graphModel;

            m_StringTokenModel = Activator.CreateInstance <VariableNodeModel>();
            m_StringTokenModel.DeclarationModel = stringVariableModel;
            m_StringTokenModel.GraphModel       = graphModel;
        }
        void UpdatePortsFromModels(IEnumerable <IPortModel> portModelsToCreate, string portCollectionName)
        {
            VisualElement portsElement = this.MandatoryQ(portCollectionName);

            foreach (IPortModel inputPortModel in portModelsToCreate)
            {
                if (inputPortModel.PortType != PortType.Execution && inputPortModel.PortType != PortType.Loop)
                {
                    continue;
                }

                var port = Port.Create(inputPortModel, m_Store, Orientation.Vertical);
                portsElement.Add(port);
            }
        }
        static void GetTokenPorts(Store store, INodeModel model, out Port inputPort, out Port outputPort)
        {
            inputPort  = null;
            outputPort = null;

            // TODO: weirdly VariableNodeModels implement IHasMainOutputPort, but that 'output port' can be an input

            // Token only support one input port, we use the first one found.
            if (model is IHasMainInputPort inputModel)
            {
                var port = Port.Create(inputModel.InputPort, store, Orientation.Horizontal);
                SetupPort(port, ref inputPort, ref outputPort);
            }

            // Token only support one output port, we use the first one found.
            if (model is IHasMainOutputPort outputModel)
            {
                var port = Port.Create(outputModel.OutputPort, store, Orientation.Horizontal);
                SetupPort(port, ref inputPort, ref outputPort);
            }

            void SetupPort(Port port, ref Port resultInputPort, ref Port resultOutputPort)
            {
                var className = port.direction == Direction.Input ? "left" : "right";

                port.AddToClassList(className);
                if (port.direction == Direction.Input)
                {
                    resultInputPort = port;
                }
                else
                {
                    resultOutputPort = port;
                }
            }
        }
        public static void GetTokenPorts(Store store, INodeModel model, out Port inputPort, out Port outputPort, Orientation?orientation = null)
        {
            inputPort  = null;
            outputPort = null;

            // TODO: weirdly VariableNodeModels implement IHasMainOutputPort, but that 'output port' can be an input

            Port newPort = null;

            switch (model)
            {
            // Token only support one input port, we use the first one found.
            case IHasMainExecutionInputPort inputTriggerModel:
                newPort = Port.Create(inputTriggerModel.ExecutionInputPort, store, GetPortOrientation(inputTriggerModel.ExecutionInputPort));
                break;

            case IHasMainExecutionOutputPort outputTriggerModel:
                newPort = Port.Create(outputTriggerModel.ExecutionOutputPort, store, GetPortOrientation(outputTriggerModel.ExecutionOutputPort));
                break;

            case IHasMainInputPort inputModel:
                newPort = Port.Create(inputModel.InputPort, store, GetPortOrientation(inputModel.InputPort));
                break;

            case IHasMainOutputPort outputModel:
                if (outputModel.OutputPort != null)
                {
                    newPort = Port.Create(outputModel.OutputPort, store, GetPortOrientation(outputModel.OutputPort));
                }
                break;
            }

            if (newPort != null)
            {
                SetupPort(newPort, ref inputPort, ref outputPort);
            }

            void SetupPort(Port port, ref Port resultInputPort, ref Port resultOutputPort)
            {
                var className = port.direction == Direction.Input ? "left" : "right";

                port.AddToClassList(className);
                if (port.direction == Direction.Input)
                {
                    resultInputPort = port;
                }
                else
                {
                    resultOutputPort = port;
                }
            }

            Orientation GetPortOrientation(IPortModel port)
            {
                if (orientation != null)
                {
                    return(orientation.Value);
                }
                if (port == null)
                {
                    return(Orientation.Horizontal);
                }

                switch (port.PortType)
                {
                case PortType.Data:
                case PortType.Event:
                case PortType.Instance:
                    return(Orientation.Horizontal);

                case PortType.Execution:
                    return(Orientation.Vertical);

                case PortType.Loop:
                    return(port.Direction == Direction.Output ? Orientation.Vertical : Orientation.Horizontal);

                default:
                    return(Orientation.Horizontal);
                }
            }
        }