public static List <ElementGroup> GetElementGroups(ProBuilderMesh mesh, PivotPoint pivot, HandleOrientation orientation, bool collectCoincident)
        {
            var groups     = new List <ElementGroup>();
            var trs        = mesh.transform.localToWorldMatrix;
            var selectMode = ProBuilderEditor.selectMode;

            switch (pivot)
            {
            case PivotPoint.IndividualOrigins:
            {
                if (selectMode.ContainsFlag(SelectMode.Vertex | SelectMode.TextureVertex))
                {
                    foreach (var list in GetVertexSelectionGroups(mesh, collectCoincident))
                    {
                        var bounds = Math.GetBounds(mesh.positionsInternal, list);
                        var rot    = UnityEngine.ProBuilder.HandleUtility.GetVertexRotation(mesh, orientation, list);
                        groups.Add(new ElementGroup(list, trs.MultiplyPoint3x4(bounds.center), rot));
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge))
                {
                    foreach (var list in GetEdgeSelectionGroups(mesh))
                    {
                        var bounds = Math.GetBounds(mesh.positionsInternal, list);
                        var rot    = UnityEngine.ProBuilder.HandleUtility.GetEdgeRotation(mesh, orientation, list);

                        List <int> indices;

                        if (collectCoincident)
                        {
                            indices = new List <int>();
                            mesh.GetCoincidentVertices(list, indices);
                        }
                        else
                        {
                            indices = list.SelectMany(x => new int[] { x.a, x.b }).ToList();
                        }

                        groups.Add(new ElementGroup(indices, trs.MultiplyPoint3x4(bounds.center), rot));
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Face | SelectMode.TextureFace))
                {
                    foreach (var list in GetFaceSelectionGroups(mesh))
                    {
                        var        bounds = Math.GetBounds(mesh.positionsInternal, list);
                        var        rot    = UnityEngine.ProBuilder.HandleUtility.GetFaceRotation(mesh, orientation, list);
                        List <int> indices;

                        if (collectCoincident)
                        {
                            indices = new List <int>();
                            mesh.GetCoincidentVertices(list, indices);
                        }
                        else
                        {
                            indices = list.SelectMany(x => x.distinctIndexesInternal).ToList();
                        }

                        groups.Add(new ElementGroup(indices, trs.MultiplyPoint3x4(bounds.center), rot));
                    }
                }
                break;
            }

            case PivotPoint.ActiveElement:
            {
                var indices  = GetSelectedIndicesForSelectMode(mesh, selectMode, collectCoincident);
                var position = mesh.transform.position;
                var rotation = mesh.transform.rotation;

                if (selectMode.ContainsFlag(SelectMode.Face | SelectMode.TextureFace))
                {
                    var face = mesh.GetActiveFace();

                    if (face != null)
                    {
                        position = trs.MultiplyPoint3x4(Math.GetBounds(mesh.positionsInternal, face.distinctIndexesInternal).center);
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetFaceRotation(mesh, orientation, new Face[] { face });
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge))
                {
                    var edge = mesh.GetActiveEdge();

                    if (edge != Edge.Empty)
                    {
                        position = trs.MultiplyPoint3x4(Math.GetBounds(mesh.positionsInternal, new int [] { edge.a, edge.b }).center);
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetEdgeRotation(mesh, orientation, new Edge[] { edge });
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Vertex | SelectMode.TextureVertex))
                {
                    var vertex = mesh.GetActiveVertex();

                    if (vertex > -1)
                    {
                        position = trs.MultiplyPoint3x4(mesh.positionsInternal[vertex]);
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetVertexRotation(mesh, orientation, new int[] { vertex });
                    }
                }

                groups.Add(new ElementGroup(indices, position, rotation));
                break;
            }

            default:
            {
                var indices  = GetSelectedIndicesForSelectMode(mesh, selectMode, collectCoincident);
                var position = MeshSelection.bounds.center;
                var rotation = Quaternion.identity;

                if (selectMode.ContainsFlag(SelectMode.Face | SelectMode.TextureFace))
                {
                    var face = mesh.GetActiveFace();

                    if (face != null)
                    {
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetFaceRotation(mesh, orientation, new Face[] { face });
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge))
                {
                    var edge = mesh.GetActiveEdge();

                    if (edge != Edge.Empty)
                    {
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetEdgeRotation(mesh, orientation, new Edge[] { edge });
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Vertex | SelectMode.TextureVertex))
                {
                    var vertex = mesh.GetActiveVertex();

                    if (vertex > -1)
                    {
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetVertexRotation(mesh, orientation, new int[] { vertex });
                    }
                }

                groups.Add(new ElementGroup(indices, position, rotation));
                break;
            }
            }

            return(groups);
        }