Possible strategies:

	1) compute bbox if geometry is complex. 

	2) compute bbox if it's a simple operation (some combination
	   of input bboxes - iff all available)

	3) compute bbox if any input geoms have one

	4) never compute bbox

	5) always compute bbox

We can express the strategies with these labels:

COMPUTE_BBOX:
        1) FOR_COMPLEX_GEOMS,
        2) WHEN_SIMPLE,
        3) TAINTING,
        4) ALWAYS,
        5) NEVER

Following is a list of geometry-returning functions with the bbox cache
strategy they use. Note that current condition matching
FOR_COMPLEX_GEOMS is that geometrytype(geom) != POINTTYPE.

These marks show output creation methods (to find single entry
points where some BBOX caching strategies could be enforced).

	*SRL*	Directly works on the serialized geometries,
		uses PG_LWGEOM_construct() for final output

	**SRL**	Directly works on the serialized geometries,
		uses internal strategies to construct output.

	*EXP*	Uses LWGEOM_EXPLODED, and lwexploded_serialize()

	*LWG*	Uses LWGEOM, pglwgeom_serialize()


AUTOCACHE_BBOX is currently used by all functions using *LWG* 
(pglwgeom_serialize entry point) and *SRL* (PG_LWGEOM_construct
entry point). Other functions explicitly listed in the AUTOCACHE_BBOX
section also use it.
	

[ explicit control ]
	addBBOX(geometry) 
	dropBBOX(geometry) 

[ AUTOCACHE_BBOX==1 ? FOR_COMPLEX_GEOMS : NEVER ]
	geometry_in(cstring) **SRL**
	geometry_recv(internal) **SRL**
	geometry(text) **SRL**
	geometry(bytea) **SRL**
	GeometryFromText(geometry, SRID) *SRL*
	GeomFromWKB(bytea, SRID) **SRL**
	GeomFromEWKB(bytea) **SRL**
	GeomFromEWKT(text) **SRL**

	-- GEOS
	polygonize_garray (geometry[]) *LWG*
	intersection(geometry,geometry) *LWG*
	buffer(geometry,float8,[integer]) *LWG*
	difference(geometry,geometry) *LWG*
	boundary(geometry)  *LWG*
	symdifference(geometry,geometry) *LWG*
	symmetricdifference(geometry,geometry) *LWG*
	GeomUnion(geometry,geometry) *LWG*
	unite_garray (geometry[]) *LWG*
	GEOSnoop(geometry) *LWG*
	Centroid(geometry) *LWG*
	PointOnSurface(geometry) *LWG*

[ TAINING ]
	GeometryN(geometry,integer) *LWG*
	InteriorRingN(geometry,integer) *LWG*
	simplify(geometry, float8) *LWG*
	transform(geometry,integer) *SRL*
	snaptogrid(*) *LWG*

[ WHEN_SIMPLE (use input bbox if present) ]
	noop(geometry) *LWG*
	ExteriorRing(geometry) *LWG*
	SetSRID(geometry,int4) *SRL*

	# WARNING! these don't change bbox cache status if input is already 2d
	force_2d(geometry) *SRL*
	force_3dz(geometry) *SRL*
	force_3d(geometry) *SRL*
	force_3dm(geometry) *SRL*
	force_4d(geometry) *SRL*

	force_collection(geometry) *LWG* 
	multi(geometry) *LWG*

	envelope(geometry) *SRL*

	### computes union of
	### input bbox (if all available)
	collect(geometry, geometry) *LWG*
	collect_garray (geometry[]) *LWG*

	## transform eventually present box in input
	apply_grid(geometry, float8, float8, float8, float8); *LWG*
	translate(geometry,float8,float8,[float8]) *SRL*
	scale(geometry,float8,float8,[float8]) *SRL*

	## These use LWGEOM as a mean to access and modify SERIALIZED form
	reverse(geometry) *LWG* 
	ForceRHR(geometry) *LWG* 

	segmentize(geometry, float8) *LWG*

	convexhull(geometry) *LWG* 

[ NEVER ]
	PointN(geometry,integer) *SRL*
	StartPoint(geometry) *SRL*
	EndPoint(geometry) *SRL*

	makePoint(float8, float8, [float8], [float8]) *LWG*
	makePointM(float8, float8, float8) *LWG*
	makeline_garray (geometry[]) *LWG*
	LineFromMultiPoint(geometry) *LWG*
	MakeLine(geometry, geometry) *LWG*
	AddPoint(geometry, geometry, [integer]) *LWG*
	geometry(box2d) *SRL*
	geometry(box3d) *SRL*
	geometry(chip) *SRL*
	line_interpolate_point(geometry, float8) *SRL*
	Centroid(geometry) [the version w/out GEOS] *SRL*

[ ALWAYS ]
	expand(geometry,float8) *LWG*

