void OnEnable()
        {
            userNodeFolder = EditorPrefs.GetString(UserNodeFolderKey, "");
            if (userNodeFolder == "")
            {
                userNodeFolder = DefaultNodeFolder;
            }

            if (window != null)
            {             // no need to reconstruct everything
                return;
            }

            window = GetWindow <OhBehaveEditorWindow>();
            window.titleContent = new GUIContent("OhBehave!");

            try
            {
                if (EditorStyles.helpBox == null)
                {                 //EditorStyle not yet initialized
                    return;
                }
            }
            catch (System.Exception)
            {             //EditorStyle not yet initialized
                return;
            }

            CreateStyles();
            if (zoomer == null)
            {
                zoomer = new EditorZoomer();
            }
            if (treeBlueprint != null)
            {
                treeBlueprint.ConstructNodes();
                zoomer.Reset(treeBlueprint.zoomerSettings);
            }
        }
        void OnGUI()
        {
            if (InPointStyle == null)
            {
                CreateStyles();
            }

            {               // Just keeping this around for future reference.
                if (NodeEditPopup.instance != null)
                {
                    if (Event.current.type == EventType.MouseDown &&
                        EditorWindow.mouseOverWindow != NodeEditPopup.instance)
                    {
                        NodeEditPopup.instance.Hide();
                    }
                }
            }

            if (treeBlueprint == null)
            {
                return;
            }

            if (zoomer == null)
            {
                zoomer = new EditorZoomer();
                zoomer.Reset(treeBlueprint.zoomerSettings);
            }

            zoomer.HandleEvents(Event.current);

            DrawHorizontalUILine(Color.gray);

            Rect lastRect = GUILayoutUtility.GetLastRect();

            if (Event.current.type == EventType.Repaint)
            {
                zoomRect.position = new Vector2(
                    ZOOM_BORDER,
                    lastRect.yMax + lastRect.height + ZOOM_BORDER);
                zoomRect.size = new Vector2(
                    window.position.width - ZOOM_BORDER * 2,
                    window.position.height
                    - (lastRect.yMax + ZOOM_BORDER * 2 + AREA_BELOW_ZOOM_HEIGHT));
            }


            zoomer.Begin(zoomRect);
            {
                treeBlueprint.OnGui(Event.current, zoomer);
            }
            zoomer.End(new Rect(
                           0, zoomRect.yMax + zoomRect.position.y - 50,
                           window.position.width, window.position.height));


            treeBlueprint.childrenMoveWithParent =
                EditorGUILayout.ToggleLeft("Reposition children with Parent",
                                           treeBlueprint.childrenMoveWithParent);
            EditorGUILayout.Vector2Field("mouse", Event.current.mousePosition);


            if (GUI.changed)
            {
                Repaint();
            }
        }
        public void OnGui(Event current, EditorZoomer zoomer)
        {
            if (serializedObject == null)
            {
                serializedObject = new SerializedObject(this);
            }

            if (nodeObjects == null)
            {
                ConstructNodes();
                return;
            }

            bool isValidTree = true;
            List <InvalidNodeMessage> errorMsgs = new List <InvalidNodeMessage>();

            // draw connections between nodes
            foreach (var node in nodeObjects.Values)
            {
                node.Offset(zoomer.GetContentOffset());
                if (node.ProcessEvents(current))
                {
                    save = true;
                }
                if (!node.CheckIsValid(out InvalidNodeMessage invalidMsg))
                {
                    isValidTree = false;
                    errorMsgs.Add(invalidMsg);
                }

                node.DrawConnectionWires();
            }

            // draw rest
            foreach (var node in nodeObjects.Values)
            {
                node.OnGUI();
            }


            if (startConnection != null)
            {            // we want to draw the line on-top of everything else
                Handles.DrawAAPolyLine(ConnectionControls.lineThickness,
                                       startConnection.rect.center,
                                       current.mousePosition);


                GUI.changed = true;
                if (current.button == 1 &&
                    current.type == EventType.MouseDown)
                {
                    startConnection.isCreatingNewConnection = false;
                    startConnection = null;
                    endConnection   = null;
                }
                else if (endConnection != null)
                {
                    CompleteConnection();
                }
                else if (current.button == 0 &&
                         current.type == EventType.MouseUp)
                {
                    // if this has not been consumed we can (?) assume that
                    //	the mouse was not released over a connection point
                    savedMousePos = current.mousePosition;
                    startConnection.isCreatingNewConnection = false;

                    if (startConnection.type == ConnectionPointType.Out)
                    {
                        CreateChildContextMenu(startConnection.nodeWindow.nodeObject, true);
                    }
                    else
                    {
                        CreateParentContextMenu(startConnection.nodeWindow.nodeObject, true);
                    }
                    startConnection = null;
                }
            }
            else if (current.button == 1 &&
                     current.type == EventType.MouseUp &&
                     !zoomer.isScreenMoved)
            {
                savedMousePos = current.mousePosition;
                CreateStandAloneContextMenu();
            }

            zoomer.DisplayInvalid(isValidTree, errorMsgs);
            zoomer.Update(zoomerSettings);

            if (save)
            {
                Save(isValidTree);
                save = false;
            }
        }