static GameObject PickClosestGameObjectDelegated(Vector2 position, ref GameObject[] ignore, ref GameObject[] filter, out ChiselIntersection intersection)
        {
            var camera       = Camera.current;
            int layers       = camera.cullingMask;
            var pickposition = GUIClip.GUIClipUnclip(position);

            pickposition   = EditorGUIUtility.PointsToPixels(pickposition);
            pickposition.y = Screen.height - pickposition.y - camera.pixelRect.yMin;

            var gameObject = PickNodeOrGameObject(camera, pickposition, layers, ref ignore, ref filter, out var model, out var node, out intersection);

            if (!model)
            {
                return(gameObject);
            }

            if (node)
            {
                return(gameObject);
            }

            return(null);
        }
        // TODO: rewrite this, why do we need hashes?
        public static GameObject PickClosestGameObject(Vector2 mousePosition, out CSGTreeBrushIntersection intersection)
        {
            intersection = new CSGTreeBrushIntersection
            {
                surfaceID   = -1,
                brushUserID = -1
            };

            s_RetainHashes = true;

            if (enumerator == null ||
                (prevMousePosition - mousePosition).sqrMagnitude > 2)
            {
                enumerator        = GetAllOverlapping(mousePosition).GetEnumerator();
                prevMousePosition = mousePosition;
            }
            if (!enumerator.MoveNext())
            {
                enumerator = GetAllOverlapping(mousePosition).GetEnumerator();
                if (!enumerator.MoveNext())
                {
                    return(null);
                }
            }

            var topmost = enumerator.Current;

            var selectionBase = GUIClip.FindSelectionBase(topmost.Key);
            var first         = (selectionBase == null ? topmost.Key : selectionBase);
            int topmostHash   = topmost.GetHashCode();
            int prefixHash    = topmostHash;

            if (Selection.activeGameObject == null)
            {
                // Nothing selected
                // Return selection base if it exists, otherwise topmost game object
                s_PreviousTopmostHash = topmostHash;
                s_PreviousPrefixHash  = prefixHash;
                intersection          = topmost.Value;
                return(first);
            }

            if (topmostHash != s_PreviousTopmostHash)
            {
                // Topmost game object changed
                // Return selection base if exists and is not already selected, otherwise topmost game object
                s_PreviousTopmostHash = topmostHash;
                s_PreviousPrefixHash  = prefixHash;
                intersection          = topmost.Value;
                return(Selection.activeGameObject == selectionBase ? topmost.Key : first);
            }

            s_PreviousTopmostHash = topmostHash;

            // Pick potential selection base before topmost game object
            if (Selection.activeGameObject == selectionBase)
            {
                intersection = topmost.Value;
                if (prefixHash != s_PreviousPrefixHash)
                {
                    s_PreviousPrefixHash = prefixHash;
                    return(selectionBase);
                }
                return(topmost.Key);
            }

            // Check if active game object will appear in selection stack
            GameObject[] ignore = null;
            GameObject[] filter = new GameObject[] { Selection.activeGameObject };
            var          picked = PickClosestGameObjectDelegated(mousePosition, ref ignore, ref filter, out intersection);

            if (picked == Selection.activeGameObject)
            {
                // Advance enumerator to active game object
                while (enumerator.Current.Key != Selection.activeGameObject)
                {
                    if (!enumerator.MoveNext())
                    {
                        s_PreviousPrefixHash = topmostHash;
                        intersection         = topmost.Value;
                        return(first); // Should not occur
                    }

                    UpdateHash(ref prefixHash, enumerator.Current);
                }
            }

            if (prefixHash != s_PreviousPrefixHash)
            {
                // Prefix hash changed, start over
                s_PreviousPrefixHash = topmostHash;
                intersection         = topmost.Value;
                return(first);
            }

            // Move on to next game object
            if (!enumerator.MoveNext())
            {
                s_PreviousPrefixHash = topmostHash;
                intersection         = topmost.Value;
                return(first); // End reached, start over
            }

            UpdateHash(ref prefixHash, enumerator.Current);

            if (enumerator.Current.Key == selectionBase)
            {
                // Skip selection base
                if (!enumerator.MoveNext())
                {
                    s_PreviousPrefixHash = topmostHash;
                    intersection         = topmost.Value;
                    return(first); // End reached, start over
                }

                UpdateHash(ref prefixHash, enumerator.Current);
            }

            s_PreviousPrefixHash = prefixHash;

            return(enumerator.Current.Key);
        }