// This method firstly groups geometries by dimension (points, lines,
        // areas),
        // then simplifies each group such that each group is reduced to a single
        // geometry.
        // As a result there are at most three geometries, each geometry is Simple.
        // Afterwards
        // it produces a single OGCGeometry.
        private com.epl.geometry.ogc.OGCGeometry SimplifyBunch_(com.epl.geometry.GeometryCursor gc)
        {
            // Combines geometries into multipoint, polyline, and polygon types,
            // simplifying them and unioning them,
            // then produces OGCGeometry from the result.
            // Can produce OGCConcreteGoemetryCollection
            com.epl.geometry.MultiPoint dstMultiPoint = null;
            System.Collections.Generic.List <com.epl.geometry.Geometry> dstPolylines = new System.Collections.Generic.List <com.epl.geometry.Geometry>();
            System.Collections.Generic.List <com.epl.geometry.Geometry> dstPolygons  = new System.Collections.Generic.List <com.epl.geometry.Geometry>();
            for (com.epl.geometry.Geometry g = gc.Next(); g != null; g = gc.Next())
            {
                switch (g.GetType())
                {
                case com.epl.geometry.Geometry.Type.Point:
                {
                    if (dstMultiPoint == null)
                    {
                        dstMultiPoint = new com.epl.geometry.MultiPoint();
                    }
                    dstMultiPoint.Add((com.epl.geometry.Point)g);
                    break;
                }

                case com.epl.geometry.Geometry.Type.MultiPoint:
                {
                    if (dstMultiPoint == null)
                    {
                        dstMultiPoint = new com.epl.geometry.MultiPoint();
                    }
                    dstMultiPoint.Add((com.epl.geometry.MultiPoint)g, 0, -1);
                    break;
                }

                case com.epl.geometry.Geometry.Type.Polyline:
                {
                    dstPolylines.Add((com.epl.geometry.Polyline)g.Copy());
                    break;
                }

                case com.epl.geometry.Geometry.Type.Polygon:
                {
                    dstPolygons.Add((com.epl.geometry.Polygon)g.Copy());
                    break;
                }

                default:
                {
                    throw new System.NotSupportedException();
                }
                }
            }
            System.Collections.Generic.List <com.epl.geometry.Geometry> result = new System.Collections.Generic.List <com.epl.geometry.Geometry>(3);
            if (dstMultiPoint != null)
            {
                com.epl.geometry.Geometry resMP = com.epl.geometry.OperatorSimplifyOGC.Local().Execute(dstMultiPoint, esriSR, true, null);
                result.Add(resMP);
            }
            if (dstPolylines.Count > 0)
            {
                if (dstPolylines.Count == 1)
                {
                    com.epl.geometry.Geometry resMP = com.epl.geometry.OperatorSimplifyOGC.Local().Execute(dstPolylines[0], esriSR, true, null);
                    result.Add(resMP);
                }
                else
                {
                    com.epl.geometry.GeometryCursor res         = com.epl.geometry.OperatorUnion.Local().Execute(new com.epl.geometry.SimpleGeometryCursor(dstPolylines), esriSR, null);
                    com.epl.geometry.Geometry       resPolyline = res.Next();
                    com.epl.geometry.Geometry       resMP       = com.epl.geometry.OperatorSimplifyOGC.Local().Execute(resPolyline, esriSR, true, null);
                    result.Add(resMP);
                }
            }
            if (dstPolygons.Count > 0)
            {
                if (dstPolygons.Count == 1)
                {
                    com.epl.geometry.Geometry resMP = com.epl.geometry.OperatorSimplifyOGC.Local().Execute(dstPolygons[0], esriSR, true, null);
                    result.Add(resMP);
                }
                else
                {
                    com.epl.geometry.GeometryCursor res        = com.epl.geometry.OperatorUnion.Local().Execute(new com.epl.geometry.SimpleGeometryCursor(dstPolygons), esriSR, null);
                    com.epl.geometry.Geometry       resPolygon = res.Next();
                    com.epl.geometry.Geometry       resMP      = com.epl.geometry.OperatorSimplifyOGC.Local().Execute(resPolygon, esriSR, true, null);
                    result.Add(resMP);
                }
            }
            return(com.epl.geometry.ogc.OGCGeometry.CreateFromEsriCursor(new com.epl.geometry.SimpleGeometryCursor(result), esriSR));
        }