docs: Geometry buffer(Geometry geometry, double distance,
  			SpatialReference sr, double densify_dist,
  			int max_vertex_in_complete_circle, ProgressTracker progress_tracker) {
  		if (geometry == null)
  			throw new IllegalArgumentException();
  
  		if (densify_dist < 0)
  			throw new IllegalArgumentException();
  
  		if (geometry.isEmpty())
  			return new Polygon(geometry.getDescription());
  
  		Envelope2D env2D = new Envelope2D();
  		geometry.queryLooseEnvelope2D(env2D);
  		if (distance > 0)
  			env2D.inflate(distance, distance);
  
  		m_progress_tracker = progress_tracker;
  
  		m_original_geom_type = geometry.getType().value();
  		m_geometry = geometry;
  		m_tolerance = InternalUtils.calculateToleranceFromGeometry(sr,
  				env2D, true);// conservative to have same effect as simplify
  		m_small_tolerance = InternalUtils
  				.calculateToleranceFromGeometry(null, env2D, true);// conservative
  																	// to have
  																	// same
  																	// effect as
  																	// simplify
  
  		if (max_vertex_in_complete_circle <= 0) {
  			max_vertex_in_complete_circle = 96;// 96 is the value used by SG.
  												// This is the number of
  												// vertices in the full circle.
  		}
  		
  		m_spatialReference = sr;
  		m_distance = distance;
  		m_abs_distance = Math.abs(m_distance);
  		m_abs_distance_reversed = m_abs_distance != 0 ? 1.0 / m_abs_distance
  				: 0;
  
  		if (NumberUtils.isNaN(densify_dist) || densify_dist == 0) {
  			densify_dist = m_abs_distance * 1e-5;
  		} else {
  			if (densify_dist > m_abs_distance * 0.5)
  				densify_dist = m_abs_distance * 0.5;// do not allow too
  																// large densify
  																// distance (the
  																// value will be
  																// adjusted
  																// anyway later)
  		}
  
  		if (max_vertex_in_complete_circle < 12)
  			max_vertex_in_complete_circle = 12;
  
  		
  		double max_dd = Math.abs(distance)
  				* (1 - Math.cos(Math.PI / max_vertex_in_complete_circle));
  
  		if (max_dd > densify_dist)
  			densify_dist = max_dd;// the densify distance has to agree with the
  									// max_vertex_in_complete_circle
  		else {
  			double vertex_count = Math.PI
  					/ Math.acos(1.0 - densify_dist / Math.abs(distance));
  			if (vertex_count < (double) max_vertex_in_complete_circle - 1.0) {
  				max_vertex_in_complete_circle = (int) vertex_count;
  				if (max_vertex_in_complete_circle < 12) {
  					max_vertex_in_complete_circle = 12;
  					densify_dist = Math.abs(distance)
  							* (1 - Math.cos(Math.PI
  									/ max_vertex_in_complete_circle));
  				}
  			}
  		}
  
  		m_densify_dist = densify_dist;
  		m_max_vertex_in_complete_circle = max_vertex_in_complete_circle;
  		// when filtering close points we do not want the filter to distort
  		// generated buffer too much.
  		m_filter_tolerance = Math.min(m_small_tolerance,
  				densify_dist * 0.25);
  		
  		
  		m_circle_template_size = calcN_();
  		if (m_circle_template_size != m_old_circle_template_size) {
  			// we have an optimization for this method to be called several
  			// times. Here we detected too many changes and need to regenerate
  			// the data.
  			m_circle_template.clear();
  			m_old_circle_template_size = m_circle_template_size;
  		}
  
  		Geometry result_geom = buffer_();
  		m_geometry = null;
  		return result_geom;		
  	}