/**
         * Return a polygon which is the union of the given polygons; combines
         * vertices that form edges that are almost identical, as defined by
         * vertexMergeRadius. Note: clears the List!
         */

        public static S2Polygon DestructiveUnionSloppy(System.Collections.Generic.ICollection <S2Polygon> polygons, S1Angle vertexMergeRadius)
        {
            // Effectively create a priority queue of polygons in order of number of
            // vertices. Repeatedly union the two smallest polygons and add the result
            // to the queue until we have a single polygon to return.

            // map: # of vertices -> polygon
            //TreeMultimap<Integer, S2Polygon> queue = TreeMultimap.create();

            var queue = new MultiMap <int, S2Polygon>();

            foreach (var polygon in polygons)
            {
                queue.Add(polygon.NumVertices, polygon);
            }
            polygons.Clear();

            // Java uses a live-view that maps to the underlying structure
            //Set<Map.Entry<Integer, S2Polygon>> queueSet = queue.entries();

            var enumer = queue.SortedValues;

            while (queue.CountIsAtLeast(2))
            {
                // Pop two simplest polygons from queue.
//      queueSet = queue.entries();
                //Iterator<Map.Entry<Integer, S2Polygon>> smallestIter = queueSet.iterator();

                var smallestTwo = enumer.Take(2).ToList();

                //Map.Entry<Integer, S2Polygon> smallest = smallestIter.next();
                //int aSize = smallest.getKey().intValue();
                //S2Polygon aPolygon = smallest.getValue();
                //smallestIter.remove();

                //smallest = smallestIter.next();
                //int bSize = smallest.getKey().intValue();
                //S2Polygon bPolygon = smallest.getValue();
                //smallestIter.remove();

                foreach (var item in smallestTwo)
                {
                    queue.Remove(item);
                }


                // Union and add result back to queue.
                var unionPolygon = new S2Polygon();
                unionPolygon.InitToUnionSloppy(smallestTwo[0].Value, smallestTwo[1].Value, vertexMergeRadius);
                var unionSize = smallestTwo[0].Key + smallestTwo[1].Key;
                queue.Add(unionSize, unionPolygon);
                // We assume that the number of vertices in the union polygon is the
                // sum of the number of vertices in the original polygons, which is not
                // always true, but will almost always be a decent approximation, and
                // faster than recomputing.
            }

            if (queue.Count == 0)
            {
                return(new S2Polygon());
            }
            else
            {
                //return queue.get(queue.asMap().firstKey()).first();
                return(queue.SortedValues.First().Value);
            }
        }