/// <summary>
        /// Handles portalling.
        /// </summary>
        /// <param name="unitData">This unit's UnitFacade.</param>
        /// <param name="group">This unit's current/old group.</param>
        /// <param name="vectorField">The vector field.</param>
        /// <param name="pathPortalIndex">Index of the portal in the current path.</param>
        /// <param name="grid">The grid.</param>
        private void HandlePortal(IUnitFacade unitData, DefaultSteeringTransientUnitGroup group, IVectorField vectorField, int pathPortalIndex, IGrid grid)
        {
            var portal = _currentPath[pathPortalIndex] as IPortalNode;

            if (portal == null)
            {
                // if the path node that was reported as a portal turns out not to be - return
                return;
            }

            if (object.ReferenceEquals(unitData, group.modelUnit))
            {
                // don't ever let model unit jump portal
                return;
            }

            int groupCount = group.count;
            var to         = _currentPath[pathPortalIndex + 1];

            // we consider a portal a "far portal" when the distance between it and its partner is more than the diagonal cell size
            // 'far portal' means that it is NOT considered a grid stitching connector portal
            // Requires that grid stitching portals are always placed adjacent to each other
            float portalNewGroupThreshold = (grid.cellSize * Consts.SquareRootTwo) + 0.1f;
            bool  isFarPortal             = (portal.position - portal.partner.position).sqrMagnitude > (portalNewGroupThreshold * portalNewGroupThreshold);

            if (isFarPortal)
            {
                // if it is a far portal, we need to make or use the next group
                if (group.nextGroup == null)
                {
                    // new group does not exist yet, so create it and tell the old group about it
                    var groupStrat = GroupingManager.GetGroupingStrategy <IUnitFacade>();
                    if (groupStrat == null)
                    {
                        Debug.Log("No Grouping Strategy has been registered for IUnitFacade");
                        return;
                    }

                    var newGroup = groupStrat.CreateGroup(groupCount) as DefaultSteeringTransientUnitGroup;
                    if (newGroup == null)
                    {
                        return;
                    }

                    group.nextGroup = newGroup;
                    _nextGroup      = newGroup;
                }
                else
                {
                    // new group exists, so just use it
                    _nextGroup = group.nextGroup;
                }

                // make sure to remove the unit from the old group
                group.Remove(unitData);
            }

            _isPortalling = true;
            // actually execute the portal
            portal.Execute(
                unitData.transform,
                to,
                () =>
            {
                _isPortalling = false;

                if (isFarPortal)
                {
                    // if it is a far portal, we are supposed to join up with the new group
                    _nextGroup.Add(unitData);
                    unitData.transientGroup = _nextGroup;

                    if (_nextGroup.count == 1)
                    {
                        // let the first unit in the new group be responsible for setting the new group up
                        if (vectorField.destination != null)
                        {
                            // the new group's path starts on the other side of the portal...
                            int pathCount = _currentPath.count;
                            var newPath   = new Path(pathCount - (pathPortalIndex + 2));
                            for (int i = pathCount - 1; i >= pathPortalIndex + 2; i--)
                            {
                                newPath.Push(_currentPath[i]);
                            }

                            // the first member that joins the new group tells the new group to move along the path of the old group
                            Vector3 destination = vectorField.destination.position;
                            if ((to.position - destination).sqrMagnitude > 1f)
                            {
                                // check though that the destination is not the same as the starting position
                                _nextGroup.MoveAlong(newPath);
                            }

                            // pass along old group's waypoints to new group
                            if (group.currentWaypoints.count > 0)
                            {
                                _nextGroup.SetWaypoints(group.currentWaypoints);
                            }

                            // pass along old group's formation to the new group
                            if (group.currentFormation != null)
                            {
                                _nextGroup.TransferFormation(group.currentFormation, groupCount, group);
                            }
                        }
                    }
                }
            });
        }