private static double _get_position_on_shape(Models.ShapeXFormData xform, Models.ShapeRelativePosition pos)
        {
            var r = xform.GetRectangle();

            switch (pos)
            {
            case VisioScripting.Models.ShapeRelativePosition.PinY:
                return(xform.XFormPinY);

            case VisioScripting.Models.ShapeRelativePosition.PinX:
                return(xform.XFormPinX);

            case VisioScripting.Models.ShapeRelativePosition.Left:
                return(r.Left);

            case VisioScripting.Models.ShapeRelativePosition.Right:
                return(r.Right);

            case VisioScripting.Models.ShapeRelativePosition.Top:
                return(r.Top);

            case VisioScripting.Models.ShapeRelativePosition.Bottom:
                return(r.Bottom);
            }

            throw new System.ArgumentOutOfRangeException(nameof(pos));
        }
        internal static List <int> _sort_shapes_by_position(IVisio.Page page, IList <int> shapeids, Models.ShapeRelativePosition pos)
        {
            // First get the transforms of the shapes on the given axis
            var xforms = VisioScripting.Models.ShapeXFormData._get_xfrms(page, shapeids);

            // Then, sort the shapeids pased on the corresponding value in the results

            var sorted_shapeids = Enumerable.Range(0, shapeids.Count)
                                  .Select(i => new { index = i, shapeid = shapeids[i], pos = ArrangeHelper._get_position_on_shape(xforms[i], pos) })
                                  .OrderBy(i => i.pos)
                                  .Select(i => i.shapeid)
                                  .ToList();

            return(sorted_shapeids);
        }