internal static com.epl.geometry.Geometry CalculateConvexHull_(com.epl.geometry.Geometry geom, com.epl.geometry.ProgressTracker progress_tracker)
 {
     if (geom.IsEmpty())
     {
         return(geom.CreateInstance());
     }
     com.epl.geometry.Geometry.Type type = geom.GetType();
     if (com.epl.geometry.Geometry.IsSegment(type.Value()))
     {
         // Segments are always returned either as a Point or Polyline
         com.epl.geometry.Segment segment = (com.epl.geometry.Segment)geom;
         if (segment.GetStartXY().Equals(segment.GetEndXY()))
         {
             com.epl.geometry.Point point = new com.epl.geometry.Point();
             segment.QueryStart(point);
             return(point);
         }
         else
         {
             com.epl.geometry.Point    pt       = new com.epl.geometry.Point();
             com.epl.geometry.Polyline polyline = new com.epl.geometry.Polyline(geom.GetDescription());
             segment.QueryStart(pt);
             polyline.StartPath(pt);
             segment.QueryEnd(pt);
             polyline.LineTo(pt);
             return(polyline);
         }
     }
     else
     {
         if (type == com.epl.geometry.Geometry.Type.Envelope)
         {
             com.epl.geometry.Envelope   envelope = (com.epl.geometry.Envelope)geom;
             com.epl.geometry.Envelope2D env      = new com.epl.geometry.Envelope2D();
             envelope.QueryEnvelope2D(env);
             if (env.xmin == env.xmax && env.ymin == env.ymax)
             {
                 com.epl.geometry.Point point = new com.epl.geometry.Point();
                 envelope.QueryCornerByVal(0, point);
                 return(point);
             }
             else
             {
                 if (env.xmin == env.xmax || env.ymin == env.ymax)
                 {
                     com.epl.geometry.Point    pt       = new com.epl.geometry.Point();
                     com.epl.geometry.Polyline polyline = new com.epl.geometry.Polyline(geom.GetDescription());
                     envelope.QueryCornerByVal(0, pt);
                     polyline.StartPath(pt);
                     envelope.QueryCornerByVal(1, pt);
                     polyline.LineTo(pt);
                     return(polyline);
                 }
                 else
                 {
                     com.epl.geometry.Polygon polygon = new com.epl.geometry.Polygon(geom.GetDescription());
                     polygon.AddEnvelope(envelope, false);
                     return(polygon);
                 }
             }
         }
     }
     if (IsConvex_(geom, progress_tracker))
     {
         if (type == com.epl.geometry.Geometry.Type.MultiPoint)
         {
             // Downgrade to a Point for simplistic output
             com.epl.geometry.MultiPoint multi_point = (com.epl.geometry.MultiPoint)geom;
             com.epl.geometry.Point      point       = new com.epl.geometry.Point();
             multi_point.GetPointByVal(0, point);
             return(point);
         }
         return(geom);
     }
     System.Diagnostics.Debug.Assert((com.epl.geometry.Geometry.IsMultiVertex(type.Value())));
     com.epl.geometry.Geometry convex_hull = com.epl.geometry.ConvexHull.Construct((com.epl.geometry.MultiVertexGeometry)geom);
     return(convex_hull);
 }